【动态组件的一些尝试】批量更新显示

Apiglio

共 2389字,需浏览 5分钟

 · 2021-12-31

 尝试  前段时间接触了一点动态组件,深刻体会到了动态组件的复杂,也不由的思考起如何使用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_asels.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

浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报