【动态组件的一些尝试】批量更新显示
共 2389字,需浏览 5分钟
·
2021-12-31 11:24
尝试 前段时间接触了一点动态组件,深刻体会到了动态组件的复杂,也不由的思考起如何使用ruby代码控制动态组件的问题。但是目前我仍然出于对动态组件一知半解的状态,所以这个系列我更多地只是在进行一些尝试,有一些进展就发出来以供参考。
动态组件会根据属性的不同而有很大的结构差异,当属性被修改后,有可能出现组件没有自动重绘的情况,此时需要手工重绘。当模型中有大量未更新的动态组件时,一个一个右键点击重绘就太过于繁琐,因此需要一个批量重绘的方法。
一、判断是否为动态组件
动态组件在 SketchUp Ruby API 中目前还没有专门划分为一个类,和普通的组件都是属于 ComponentInstance 类。唯一的区别在于动态组件有其特有的属性:
这些属性可以在“动态组件”工具条的“组件属性”窗口中查看,而通过 ruby 的查看方法,则需要使用 AttributeDictionaries 类:
可见动态组件的属性全部储存在名为 "dynamic_attributes" 的属性目录中;相反地,如果一个组件有这个属性目录就说明这个组件是动态组件。所以可以用以下代码判断组件实例 ins 是否是动态组件:
ins.attribute_dictionary("dynamic_attributes")!=nil
#对于ruby而言,nil相当于false,其他实例相当于true
#所以也可以直接使用以下表达:
ins.attribute_dictionary("dynamic_attributes")
二、重绘动态组件
单个动态组件的重绘参考以下方法:
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)
end
nil # (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 是否有动态组件的插件,第3、4行判断组件是否是动态组件,第5行就通过动态组件的插件提供的全局变量接口 $dc_observers 进行重绘。
重绘动态组件 ins 只需要以下代码:
recalc(ins)
如果批量重绘选中的动态组件则需要:
sels=Sketchup.active_model.selection.to_a
sels.grep(Sketchup::ComponentInstance).select{|i|
i.attribute_dictionary('dynamic_attributes')
}.each{|i|recalc_dc(i)}
三、更新组件并重绘
动态组件的替换也不同于一般的组件替换,例如有两个具有相同参数的动态组件,可以相互替换定义以实现替换组件形态,同时替换前后保持相同的动态组件参数。例如以下尝试的代码:
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_h
i.definition=defi
hash.each{|k,v|
i.attribute_dictionaries["dynamic_attributes"][k]=v
}
recalc_dc(i)
}
end
选择其中一个动态组件,获取其组件定义:
执行 update_dynamic_component 方法,将另一个组件替换为前者:
本期仅是一些尝试,大多没有很详细的解释和设计思路,只是公布了一些草稿,仅供参考。
本文编号:SU-2021-12