Okay, fixed that error. It was my booboo. In the second level (and third) it should call …
get_dc_instances(primario.definition.entities).each
… instead of …
get_dc_instances(primario).each
… _etc., …
Also I forgot to pass the first member of the array returned by UI.inputbox(), rather than the whole array.
Fixed that and now color choosing works.
Then I got lockup for too long and this error …
Error: #<SystemStackError: stack level too deep>
.../sketchup/plugins/su_dynamiccomponents/ruby/dcclass_v1.rbe:3322
… which was an unneeded recursive call in the add_attribut_mat() method in the last loop after the dc redraws. I commented out the recursive method call, so you could take note of it.
I also wrapped everything up in one named undo operation.
So afterward the user sees on the “Edit” menu a "Pinte todo o #{color name}" as an undo.
latest version:
# Código melhor
module Tequin
extend self
DCDICT ||= 'dynamic_attributes'
@@loaded ||= false
def get_dc_instances(ents)
ents.grep(Sketchup::ComponentInstance).find_all {|ci|
ci.definition.attribute_dictionaries[DCDICT] rescue false
}
end
def dc_def_matlopts?(inst,key,valor)
inst.definition.get_attribute(DCDICT,key) == valor
end
def add_attribut_mat(
ents,
valor = 'portas',
matl = 'Green'
)
key = 'materialoptions'
attb = 'material'
form = '_material_formula'
indx = '0'
model = Sketchup.active_model
selection = model.selection
return "Empty Selection!" if selection.empty?
ents = []
get_dc_instances(selection).each {|primario|
if dc_def_matlopts?(primario,key,valor)
ents << primario
get_dc_instances(primario.definition.entities).each {|secundario|
if dc_def_matlopts?(secundario,key,valor)
ents << secundario
get_dc_instances(secundario.definition.entities).each {|terciario|
if dc_def_matlopts?(terciario,key,valor)
ents << terciario
end # terciario
}
end # secundario
}
end # primario
}
ents.uniq!
model.start_operation("Pinte todo o "<<matl,true,true)
#
ents.each do |e|
e.set_attribute( DCDICT, attb, indx )
e.set_attribute( DCDICT, form, matl.inspect )
$dc_observers.get_latest_class.redraw_with_undo(e)
#add_attribut_mat(e.definition.entities)
end
#
model.commit_operation
end
if !@@loaded # Execute uma vez na inicialização
UI.add_context_menu_handler {|popup|
mod = Sketchup.active_model
sel = mod.selection
if !sel.empty?
popup.add_item("Pinte todo o Aqua") {
add_attribut_mat(sel,'portas','Aqua')
}
popup.add_item("Escolha a cor ...") {
matl = UI.inputbox(
["Cor"],
["Aqua"],
[Sketchup::Color::names[0..24].join('|')],
"Escolha a cor ..."
)
if matl
add_attribut_mat(sel,'portas',matl[0])
end
}
end
}
@@loaded = true
end
end