Apply material to all nested or non-nested instances that have the dynamic attribute "x" in the selection

Ruby uses 2 space indents.

Do not use entity.typename == "some string"
It is very slow and deprecated for most use.
Use entities.grep(SomeClass) instead. It is a very fast filter.
Or for a single object, use entity.is_a?(CertainClass)


Component Instances do not “own” entities. Only their definition has an entities collection.
If the instance is not unique, then changing the nested instances will change them in ALL of the instances of that definition.

Try not to create a new string literal object in every loop. Define them before and outside the looping construct.

model = Sketchup.active_model
selection = model.selection

mat   = "Green"
valor = "portas" # "doors"
dict  = "dynamic_attributes"
key   = "materialoptions"

dcs = selection.grep(Sketchup::ComponentInstance).find_all { |dc|
  dc.get_attribute(dict,key) == valor
}

defs = dcs.map { |dc| dc.definition }.uniq!

defs.each { |cdef|
  cdef.entities.grep(Sketchup::ComponentInstance).each { |inst|
    inst.material = mat 
  }
}

Many of the SketchUp API collection classes have the Ruby core Enumerable module mixed into them.

:nerd_face:

2 Likes