Dynamic component to group

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.

  1. Do not use global variables. Use a module variable or a instance variable within our own modules or classes.

  2. 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 :roll_eyes:

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.