【動態(tài)組件的一些嘗試】批量更新顯示
?嘗試? 前段時(shí)間接觸了一點(diǎn)動態(tài)組件,深刻體會到了動態(tài)組件的復(fù)雜,也不由的思考起如何使用ruby代碼控制動態(tài)組件的問題。但是目前我仍然出于對動態(tài)組件一知半解的狀態(tài),所以這個系列我更多地只是在進(jìn)行一些嘗試,有一些進(jìn)展就發(fā)出來以供參考。
動態(tài)組件會根據(jù)屬性的不同而有很大的結(jié)構(gòu)差異,當(dāng)屬性被修改后,有可能出現(xiàn)組件沒有自動重繪的情況,此時(shí)需要手工重繪。當(dāng)模型中有大量未更新的動態(tài)組件時(shí),一個一個右鍵點(diǎn)擊重繪就太過于繁瑣,因此需要一個批量重繪的方法。
一、判斷是否為動態(tài)組件
動態(tài)組件在 SketchUp Ruby API 中目前還沒有專門劃分為一個類,和普通的組件都是屬于 ComponentInstance 類。唯一的區(qū)別在于動態(tài)組件有其特有的屬性:

這些屬性可以在“動態(tài)組件”工具條的“組件屬性”窗口中查看,而通過 ruby 的查看方法,則需要使用 AttributeDictionaries 類:

可見動態(tài)組件的屬性全部儲存在名為?"dynamic_attributes" 的屬性目錄中;相反地,如果一個組件有這個屬性目錄就說明這個組件是動態(tài)組件。所以可以用以下代碼判斷組件實(shí)例?ins 是否是動態(tài)組件:
ins.attribute_dictionary("dynamic_attributes")!=nil#對于ruby而言,nil相當(dāng)于false,其他實(shí)例相當(dāng)于true#所以也可以直接使用以下表達(dá):ins.attribute_dictionary("dynamic_attributes")
二、重繪動態(tài)組件
單個動態(tài)組件的重繪參考以下方法:
def recalc_dc(inst)return nil unless defined?($dc_observers)if inst.is_a?(Sketchup::ComponentInstance) &&inst.attribute_dictionary('dynamic_attributes')$dc_observers.get_latest_class.redraw_with_undo(inst)endnil # (there is no particular return value)end#by?@DanRathbun?on?https://forums.sketchup.com/t/method-to-ask-a-dynamic-component-instance-to-recalc-itself/13905/3
此方法摘自官方論壇 @DanRathbun 的帖子,此方法第2行判斷 SketchUp 是否有動態(tài)組件的插件,第3、4行判斷組件是否是動態(tài)組件,第5行就通過動態(tài)組件的插件提供的全局變量接口?$dc_observers?進(jìn)行重繪。
重繪動態(tài)組件?ins?只需要以下代碼:
recalc(ins)如果批量重繪選中的動態(tài)組件則需要:
sels=Sketchup.active_model.selection.to_asels.grep(Sketchup::ComponentInstance).select{|i|i.attribute_dictionary('dynamic_attributes')}.each{|i|recalc_dc(i)}
三、更新組件并重繪
動態(tài)組件的替換也不同于一般的組件替換,例如有兩個具有相同參數(shù)的動態(tài)組件,可以相互替換定義以實(shí)現(xiàn)替換組件形態(tài),同時(shí)替換前后保持相同的動態(tài)組件參數(shù)。例如以下嘗試的代碼:
def?update_dynamic_component(defi,sels=nil)raise AugmentError("ComponentDefinition expected but #{defi.class} found.") unless defi.is_a?(Sketchup::ComponentDefinition)raise AugmentError("Parameter is NOT a dynamic component.") unless defi.attribute_dictionary("dynamic_attributes")sels=Sketchup.active_model.selection.to_a if sels.nil?sels=[sels] unless sels.is_a?(Array)sels.each{|i|next unless i.is_a?(Sketchup::ComponentInstance)next unless i.attribute_dictionary("dynamic_attributes")hash=i.attribute_dictionary("dynamic_attributes").to_hi.definition=defihash.each{|k,v|i.attribute_dictionaries["dynamic_attributes"][k]=v}recalc_dc(i)}end
選擇其中一個動態(tài)組件,獲取其組件定義:

執(zhí)行?update_dynamic_component 方法,將另一個組件替換為前者:

本期僅是一些嘗試,大多沒有很詳細(xì)的解釋和設(shè)計(jì)思路,只是公布了一些草稿,僅供參考。
本文編號:SU-2021-12
