To ‘Move’ a group into another context and keep all of its original ‘properties’ - so it appears you have haven’t actually ‘Copied’ it - you make references to them apply them to the new ‘instance’, then erase the original group…
grp ### the reference to the original group
newgrp = cdef.entities.add_instance( grp.entities.parent, grp.transformation )
newgrp.material = grp.material
newgrp.layer = grp.layer
newgrp.name = grp.name
attds = grp.attribute_dictionaries
attds.each{|d|
n = d.name
d.each_pair{|k, v|
newgrp.set_attribute(n, k, v)
}
} if attds
### you can also transfer any other properties like hidden?, locked? etc
grp.erase!
I suppose that depending on what cdef actually refers to it might BugSplat, and that would be a bug because SketchUp should trap and reject illegal operations. But I tried setting cdef to be the ComponentDefinition for a group and grp to be another group, and it ran correctly without a BugSplat. What were the classes and validity status of the objects referenced by cdef and grp when you got the BugSplat, and were there any prior relationships between them such as nested in the same parent?
Are we talking about add_instance or add_group now? I’ve gotten the latter to crash by passing entities not in the active drawing context, but never the former.
Correct.
You can add_ geometry etc, or instances of component definitions or groups into any entities context - i.e. to the model.entities, model.active_entities, and group.entities and definition.entities
A new group can be added to any entities context using gp = some_entities.add_group()
If ents==model.active_entities you can also add the new group with entities [just as you might manually]
e.g. gp = model.active_entities.add_group(model.selection.to_a)
BUT if you try that in an entities context that’s not ‘active’ it’ll BugSplat!
In such a case you must first add a new empty group, and then add things into its entities collection afterwards…
In your example: gp = model.entities.add_group(model.selection.to_a)
it will BugSplat if the model.entities are NOT the model.active_entities
That’s because the manually created* model.selection is taken from the model.active_entities, and if you are inside a group/component edit when you invoke that code you would be trying to add a group containing those selected things outside of that context [i.e. directly in the model’s entities] - thereby cross threading the data-base.
*You can add objects to the model’s selection across entities contexts using the API but there is almost never a need to do this and a BugSplat awaits you if you try to use that cross-threaded selection !
Your second example is wrong: gp = some_group.add_group(model.selection.to_a)
But you cannot add a group to some other group, you can add a group to some other group’s entities collection - e.g. gp = some_group.entities.add_group(model.selection.to_a)
And provided that the selection is in the some_group.entities context you’re OK.
However, a ‘check’ on the contexts might be safer… gp = some_group.entities.add_group(model.selection.to_a) if some_group.entities==model.active_entities
If you know that some_group.entities is NOT the model.active_entities context, then you must find another way of adding the selection into a new empty group within some_group.entities… gp = some_group.entities.add_group()
If the selected object is a group[s] or a component-instance[s] you can add new instances into ‘gp’, thus: new_group = gp.entities.add(selected_group.definition, selected_group.transformation)
That ‘copies’ the group into the other context.
If you want to ‘move’ it, then you can simply erase the original with selected_group.erase!
Leaving the copy in place…
To copy ‘geometry’ you can recreate that inside the other non-active groups entities context…