<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SketchUp文本標(biāo)注的層級顯示

          共 1541字,需瀏覽 4分鐘

           ·

          2022-03-18 15:30

          在電子地圖中文本標(biāo)注有其顯示層級的區(qū)別,因此重要的標(biāo)注能夠在更小的比例尺下顯示,這樣控制標(biāo)注可以在保持圖面簡潔的同時盡量保留關(guān)鍵信息。如果一個 SketchUp 模型擁有過多的文本標(biāo)注,能不能使用類似的顯示方式予以篩選呢?答案是肯定的,效果如下:

          文中是實現(xiàn)思路與方法,其中最后一部分是完整的代碼呈現(xiàn)和使用方法。


          〇、基本思路


          對于平面地圖來說,文本標(biāo)注的顯示與否取決于地圖的比例尺,即地圖顯示層級;而對于 SketchUp 中的三維場景,可以用視點位置與顯示位置之間的距離來替代。因此判斷文本標(biāo)注顯示與否,就需要讀取當(dāng)前視圖的相機位置。如果希望每次變換視角都可以更新標(biāo)注圖元的顯隱狀態(tài),就需要使用視圖監(jiān)控 ViewObserver,即通過向當(dāng)前視圖添加監(jiān)控,在?onViewChanged ?方法中對標(biāo)注圖元進(jìn)行顯隱性的判斷。


          另外,不同重要性的標(biāo)注有不同的顯隱需求,因此需要給每一個需要控制顯隱性的標(biāo)注圖元一個專門的自定義屬性(Attribute)。同時為了更快速地更新所有文本標(biāo)注的顯隱性,需要創(chuàng)建一個標(biāo)注圖元的列表,以便快速地枚舉需要判斷是否顯示的圖元。


          一、標(biāo)注層級的設(shè)置


          具有引線定位的文本標(biāo)注圖元都能夠通過 .point 方法獲取其所附著的點位,通過計算其與當(dāng)前視圖視點(?model .active_view .camera .eye )的距離可以近似地用于表示類似平面地圖中比例尺(層級)的概念。因此文本標(biāo)注圖元的分層級顯示可以表述成以下兩條規(guī)則:


          ①標(biāo)注距離視點越遠(yuǎn),則越有可能被隱藏;

          ②標(biāo)注圖元越重要,其剛開始被隱藏的視點距離越大。


          基于這兩條規(guī)則,可以用視點距離表示標(biāo)注圖元的重要性,將其作為一個參數(shù)保存在圖元中:

          #?text?為一個文本標(biāo)注圖元#?value?為表示重要性的距離值value=100.m#?設(shè)置重要性:text.set_attribute("APIGLIO","LabelRank",value)#?讀取重要性:value=text.get_attribute("APIGLIO","LabelRank")


          二、控制標(biāo)注的顯影


          在確定了標(biāo)注圖元的重要性后,根據(jù)當(dāng)前的視圖視角便可以計算具體位置上特定重要程度的標(biāo)注圖元是否顯示。

          #?text?為一個文本標(biāo)注圖元view=Sketchup.active_model.active_viewmax_dist=text.get_attribute("APIGLIO","LabelRank")distance=view.camera.eye.distance(text.point)text.visible=true?if?distance<=max_dist?and?text.hidden?text.hidden=true?if??distance>max_dist?and?text.visible?

          以上代碼中讀取文本標(biāo)注的視點距離閾值?max_dist,并和實際與視點距離?distance 進(jìn)行比較,若不大于閾值且圖元不可見,則使其可見;若大于閾值且實際可見,則將其隱藏。


          需要注意的是,這里為了演示的簡便,忽略了文本標(biāo)注所在的模型層次,即文本標(biāo)注可能在模型中,也可能在群組或者組件之中。后一種情況不能簡單地通過?.point 方法獲取其位置,實現(xiàn)方法相對復(fù)雜。


          三、監(jiān)控視圖的改變


          由于希望文本標(biāo)注的顯隱能夠自動地同步于視圖的變化,因此需要增加一個實時的視圖監(jiān)控,在每一次視角改變時重新計算。這需要通過創(chuàng)建視圖監(jiān)控實現(xiàn),在每一次視圖變換后,計算和更新文本標(biāo)注的顯隱情況。

          class?NewViewObserver???def?onViewChanged(view)??????#?此處更新標(biāo)注顯隱性??endend


          視圖變換時需要一次性更新所有文本標(biāo)注的顯隱性,這需要遍歷所有文本標(biāo)注,因此需要首先獲得文本標(biāo)注的圖元列表:

          model=Sketchup.active_modeltext_list=model.entities.grep(Sketchup::Text)


          當(dāng)然,在圖元較多時,每次變換視圖都計算一次標(biāo)注圖元列表是非常不明智的,這會造成嚴(yán)重的卡頓。因此最好的處理方式是在開始監(jiān)控時創(chuàng)建一次標(biāo)注圖元列表,之后僅在模型發(fā)生改變時增減列表中的圖元。而這種處理方式需要 ModelObserver 和 EntitiesObserver 的輔助,才能完整實現(xiàn)。


          四、監(jiān)控標(biāo)注的增減


          標(biāo)注的增減監(jiān)控的大致邏輯如下:通過圖元容器監(jiān)控?EntitiesObserver?中的?.onElementAdded?和?.onElementRemoved?方法,監(jiān)控當(dāng)前圖元容器的圖元增減情況,在將新增的標(biāo)注圖元加入列表的同時刪除列表中已刪除的圖元。同時通過模型監(jiān)控 ModelObserver 中的?.onActivePathChanged?方法監(jiān)控編輯路徑的修改,在新的圖元容器中進(jìn)行圖元增減的監(jiān)控。


          這部分實現(xiàn)方法可直接參考最終的代碼,其包括兩個部分:一是監(jiān)控類的定義部分,二是對監(jiān)控的開關(guān)控制部分。


          五、代碼實現(xiàn)


          整個功能通過?LabelRanker 模塊實現(xiàn),完整代碼在此部分最后,同時也可以在以下網(wǎng)址中獲?。?/p>

          Apiglio/SketchupScriptTool

          https://github.com/Apiglio/SketchupScriptTool/blob/main/Cam.rb

          將整段代碼復(fù)制到控制臺中按回車鍵執(zhí)行(或者通過?load?方法調(diào)用),之后便可以通過以下代碼啟用層級顯示功能:

          LabelRanker.start

          如果是從GitHub中下載的代碼,由于?LabelRanker?模塊定義在?Cam?模塊中,需要使用如下代碼啟用:

          Cam::LabelRanker.start

          之后選擇一個文本標(biāo)注,令其在遠(yuǎn)于視點一公里的位置下隱藏則需要如下代碼:

          #?僅選擇一個文本標(biāo)注圖元text=Sketchup.active_model.selection[0]LabelRanker.set_rank(text,1000.m)#或Cam::LabelRanker.set_rank(text,1000.m)

          當(dāng)然,如果有需要也可以通過自定義的 HtmlDialog 類創(chuàng)建專門的顯示層級參數(shù)的編輯器,本篇文章暫不做演示,后續(xù)或在 GitHub 中更新。


          關(guān)閉層次顯示功能則與啟用代碼類似:

          LabelRanker.stop#或Cam::LabelRanker.stop


          完整的代碼公布如下:

          #用來做分級標(biāo)注顯示,等級較低的標(biāo)注在距視點較遠(yuǎn)距離時會隱藏module?LabelRanker??@ents_lnk=0??@ents_obs=0??@view_lnk=0??@view_obs=0??$apiglio_Cam_LabelRanker_list=[]??@mod_obs=nil
          ??class?EntsObserver?????def?onElementAdded(entities,?entity)??????$apiglio_Cam_LabelRanker_list|=[entity]?if?entity.is_a?(Sketchup::Text)?or?entity.is_a?(Sketchup::Dimension)????end????def?onElementRemoved(entities,?entity_id)??????$apiglio_Cam_LabelRanker_list.reject!{|i|i.deleted?}????end??end
          ??class?ViewObserver?????def?text_world_position(text)??????tmp=text??????res=text.point??????mod=Sketchup.active_model??????while?tmp.parent!=mod????????inst=tmp.parent.instances????????return?nil?unless?inst.length==1?#?排除標(biāo)注在組件(或有多個實例的群組)中的情況????????tmp=inst[0]????????res=tmp.transformation.inverse*res??????end??????return?res????end????private?:text_world_position
          ????def?onViewChanged(view)??????#puts?"onViewChanged:?#{view}"??????$apiglio_Cam_LabelRanker_list.each{|text|????????if?text.is_a?(Sketchup::Text)?then??????????next?if?text_world_position(text).nil???????????max_dist=Cam::LabelRanker.get_rank(text)??????????next?if?max_dist.nil???????????distance=view.camera.eye.distance(text.point)??????????text.visible=true?if?distance<=max_dist?and?text.hidden???????????text.hidden=true?if??distance>max_dist?and?text.visible?????????elsif?text.is_a?(Sketchup::Dimension)?then??????????#????????else??????????#????????end??????}????end??end
          ??class?ModObserver?????def?onActivePathChanged(model)??????LabelRanker.update_obs????end??end
          ??def?self.test????return?[@ents_lnk,@ents_obs,@view_lnk,@view_obs,@mod_obs,$apiglio_Cam_LabelRanker_list]??end
          ??def?self.update_obs????@ents_lnk.remove_observer(@ents_obs)?if?@ents_lnk!=0????@view_lnk.remove_observer(@view_obs)?if?@view_lnk!=0
          ????if?Sketchup.active_model.active_path.nil??then??????@ents_lnk=Sketchup.active_model????else??????@ents_lnk=Sketchup.active_model.active_path.last????end
          ????@ents_obs=EntsObserver.new????@ents_lnk.entities.add_observer(@ents_obs)
          ????@view_lnk=Sketchup.active_model.active_view????@view_obs=ViewObserver.new????@view_lnk.add_observer(@view_obs)??end
          ??def?self.all_text_into_list(model_or_defs)????model_or_defs.entities.grep(Sketchup::Text).each{|e|$apiglio_Cam_LabelRanker_list|=[e]}????model_or_defs.entities.grep(Sketchup::Group).each{|g|all_text_into_list(g.definition)}??end??def?self.all_dimension_into_list(model_or_defs)????model_or_defs.entities.grep(Sketchup::Dimension).each{|e|$apiglio_Cam_LabelRanker_list|=[e]}????model_or_defs.entities.grep(Sketchup::Group).each{|g|all_dimension_into_list(g.definition)}??end??private_class_method?:all_text_into_list??private_class_method?:all_dimension_into_list????def?self.start????Sketchup.active_model.remove_observer(@mod_obs)?unless?@mod_obs.nil?????@mod_obs=ModObserver.new????Sketchup.active_model.add_observer(@mod_obs)????update_obs()????all_text_into_list(Sketchup.active_model)????all_dimension_into_list(Sketchup.active_model)????Sketchup.active_model.active_view.invalidate??end????def?self.stop????@ents_lnk.remove_observer(@ents_obs)????@view_lnk.remove_observer(@view_obs)????$apiglio_Cam_LabelRanker_list.each{|l|l.visible=true}????$apiglio_Cam_LabelRanker_list.clear????GC.start??end????def?self.set_rank(text,value)????text.set_attribute("APIGLIO","LabelRank",value)??end??def?self.get_rank(text)????text.get_attribute("APIGLIO","LabelRank")??endend


          (完)




          從本期開始,本人的 SketchUp Ruby “小功能與靈感” 的文章中涉及的功能會在 GitHub 中相應(yīng)更新。這樣一來,如果日后發(fā)現(xiàn)存在bug需要修正或者是想追加相關(guān)的功能,都有極大的便利。


          這個代碼倉庫同樣也包含大部分之前文章的代碼,可以訪問以下網(wǎng)址查看,也歡迎大家共同提交修改:

          https://github.com/Apiglio/SketchupScriptTool





          本文編號:SU-2022-01

          瀏覽 120
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人77777 | 欧美丰满老熟妇XXXXX性 精品人妻一区二区三区蜜桃 | A片在线观看视频 | 黄片www. | 男女日皮视频完整版在线观看 |