Hello. I’am trying to make my projects a little bit lighter by replacing dynamic components by usual ones.
I want to explode a dynamic component then make a group from it and then make a usual component again.
selection = $SpawnedComponent.explode
puts "COMPONENT EXPLODED #{selection}"
Sketchup.active_model.definitions.purge_unused
Sketchup.active_model.active_entities.add_group(selection)
My way doesn’t work because some dynamic component information stays. Please be adviced how could I avoid it.
-
Do not use global variables. Use a module variable or a instance variable within our own modules or classes.
-
The only thing that makes a component dynamic is an attribute dictionary named “dynamic_attributes”.
selected_component_instance.attribute_dictionaries.delete("dynamic_attributes")
selected_component_instance.definition.attribute_dictionaries.delete("dynamic_attributes")
1 Like
If you wish to treat the whole model, then …
Sketchup.active_model.definitions.each do |cdef|
cdef.attribute_dictionaries.delete("dynamic_attributes")
cdef.instances.each {|inst|
inst.attribute_dictionaries.delete("dynamic_attributes")
}
end
1 Like
Tried different variations but doesn’t work… Probably I’am doing something wrong but tried both in console and in script… Result still the same
Yes you are. The Sketchup::Selection
object does not have an attribute_dictionaries
method.
Only subclasses of Sketchup::Entity
have this method. So you’ll need to get an entity object FROM the selection and verify that it responds_to?(:attribute_dictionaries)
.
Use a recursive method …
def undynamicize(obj)
return if obj.attribute_dictionaries.nil?
obj.attribute_dictionaries.delete("dynamic_attributes")
cdef = obj.definition
cdef.attribute_dictionaries.delete("dynamic_attributes") unless cdef.attribute_dictionaries.nil?
cdef.instances.each { |inst|
inst.attribute_dictionaries.delete("dynamic_attributes") unless inst.attribute_dictionaries.nil?
}
cdef.entities.each { |ent|
undynamicize(ent) if ent.respond_to?(:definition)
}
end
Then in other code use it …
UI.add_context_menu_handler do |context_menu|
selection = Sketchup.active_model.selection
if selection.single_object? &&
selection.first.responds_to?(:definition) &&
selection.first.attribute_dictionary("dynamic_attributes",false)
context_menu.add_item("Undynamicize Component") {
undynamicize(selection.first)
}
end
1 Like
Thank’s a lot. That’s a perfect solution in my case!
1 Like
No problem. Be aware that some times for very complex models with many nesting levels, that the recursive pattern in the example above may fail with a Stack Level Too Deep error.
Also, the example is meant to be inside your namespace / plugin modules according to good behavior in a shared environment.
An alternative solution?
Christina Eneroth @eneroth3 has a plugin that seems to do most of what you want, to remove DC elements from a component:
https://extensions.sketchup.com/en/content/eneroth-de-dc-ify
It doesn’t make groups, though, just components.