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")

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

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

Thank’s a lot. That’s a perfect solution in my case!

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.