To_group Method?

I would like to quickly and easily convert a component to a group. Unfortunately, there does not seem to be an appropriate method for this.

Is the appropriate workaround to simply explode the component instance and then collect up the entities and utilize the add_group method?

def insert_switch (switch_file)

	@all_groups = []

	switch_compdef = MedeekMethods.load_component_switch switch_file

	xtrans = @Switch_loc
	ytrans = @Switchy
	ztrans = @Switch_height
			
	trans_switch = Geom::Transformation.new([xtrans,ytrans,ztrans])
 	instance_switch = @Wall_group.entities.add_instance(switch_compdef, trans_switch)
			
	array_ent = instance_switch.explode
	array_ent.each {|x| @all_groups << x }

	@switchmaingroup = @Wall_group.entities.add_group(@all_groups)
	
end

The last line of this short block of code is causing SketchUp to bugsplat… I can’t figure out why. I’m just taking a bunch of entities that were exploded from a previous component and trying to create a new group within my main wall group.

When I comment out the last line of code, the method shown works exactly as expected. The entities of the component are positioned within my main wall group per the origin of this group as I would expect.

When the last line is enabled a ghost copy of the entities appears to be dropped at the origin of the main group and then the switchmaingroup is created outside of the main wall group. Then it eventually bugsplats. I seem to have hit upon something that is not allowed, but I’m not sure why.

I wonder if exploding a reference to an instance will give you a reference to the entities in that instance.

What happens if you try switching the above to:

instance_switch.entities.each {|x| @all_groups << x }

and afterwards delete the instance_switch ?

Instead of your last 3 lines maybe the #.to_a method can be better…(?)

@switchmaingroup = @Wall_group.entities.add_group(instance_switch.explode.to_a)

I’ve also wanted such a method for quite a long time. Perhaps you could file a request in the API issue tracker?

Or add the component instance to a group and then explode it (no collection of entities / cleanup needed, no possibility of intersecting entities).

What would you see as benefits considering that groups are already a special type of component?

2 Likes

I only use components for things that I know to be identical by definitions. If I ever edit objects on individual bases, e.g. a beam being cut to fit at one specific place in the building, I prefer it to be a group. This both prevents it from showing in the component browser, and clearly tells this is a unique part, typically made on the construction site.

1 Like

I see, when doing the same from code: Modifying a copy of a component to be a unique part.

.to_group would be somewhat equivalent to instance.make_unique followed by instance.definition.hidden = true (on the new definition). Although I am not sure if this hidden= (inherited from Drawingelement) has been overriden to correspond to hidden? (ComponentDefinition visibility in components browser).

To hide a component from the component browser I think you have to set an attribute in the Dynamic Component directory. However it would still be a component and if new copies were made editing one would affect all.

You’ve hit the nail on the head with this one. As much as would love for all of these switches to remain as components it doesn’t really work. Each one can have a number of unique properties (ie. faceplate and switch may have unique material applied). I basically start with a base geometry (the component) then bring it in, convert it to a group and then begin modifying it. Based on this workflow groups make more sense.

This modified code completely freezes up SketchUp and then bugsplat, I don’t even get to see what happened:

def insert_switch (switch_file)

	switch_compdef = MedeekMethods.load_component_switch switch_file

	xtrans = @Switch_loc
	ytrans = @Switchy
	ztrans = @Switch_height
			
	trans_switch = Geom::Transformation.new([xtrans,ytrans,ztrans])
 	instance_switch = @Wall_group.entities.add_instance(switch_compdef, trans_switch)
	
	@switchmaingroup = @Wall_group.entities.add_group(instance_switch)
		
	array_ent = instance_switch.explode
	
end

I’m trying to add the instance to a group within the main wall group and then explode the component instance.

Correct. We’ve discussed this and asked for such an API method years ago.

This was from October of 2016 …

@thomthom, can you confirm if it’s been logged internally ?

No, … because …

@Aerilius, describes the simplest and safest pattern if the instance has no attribute dictionaries, you want to discard any attribute dictionaries and you care not for any of the instance’s properties (ie, material, hidden, layer settings, etc.)

We’ve posted Ruby workarounds several times. I remember @TIG posting a really good example that copied the properties and then all the instance’s attribute dictionaries over to the new group instance.

I think that the hidden= was bugged in this regard, if I remember correctly.
That then makes the purpose of the #hidden? method kind of moot.

I asked about the hidden flag in the following Issue for the C API, but got no response then.
The issue is still open, as “Needs Information” and has not been fully processed (ie, logged internally.)

1 Like

This modified block of code gives the same result as the initial method at top of thread:

def insert_switch (switch_file)

	switch_compdef = MedeekMethods.load_component_switch switch_file

	xtrans = @Switch_loc
	ytrans = @Switchy
	ztrans = @Switch_height
			
	trans_switch = Geom::Transformation.new([xtrans,ytrans,ztrans])
 	instance_switch = @Wall_group.entities.add_instance(switch_compdef, trans_switch)

	@switchmaingroup = @Wall_group.entities.add_group(instance_switch.explode.to_a)
	
end

I can see there has been plenty of discussion regarding this issue and plenty of suggestions from SU minds that are far superior to mine but I don’t really see a clear path forward.

The component instance that I am exploding contains three groups (each is a solid). I would like to retain layer and material information if possible, however I can always re-assign those properties if required. I have not attribute libraries or meta data with these three groups other than the group/instance name.

I tried Aeriluis’s method of assigning the component instance to a group and then exploding the component inside the new group but this bugsplats as well. (See my second code block in this thread).

Review TIG’s famous words of wisdom …

1 Like

This block of code works, and also retains the layers and materials of the groups within the component instance:

def insert_switch (switch_file)

	switch_compdef = MedeekMethods.load_component_switch switch_file

	xtrans = @Switch_loc
	ytrans = @Switchy
	ztrans = @Switch_height
			
	trans_switch = Geom::Transformation.new([xtrans,ytrans,ztrans])

	@switchmaingroup = @Wall_group.entities.add_group()
 	instance_switch = @switchmaingroup.entities.add_instance(switch_compdef, trans_switch)

	if @Wallside == "INT"
		rotpt = Geom::Point3d.new xtrans, ytrans, 0
		switch_rot_trans = Geom::Transformation.rotation(rotpt, Z_AXIS, PI)
 		instance_switch.transform! switch_rot_trans
	end
	
	instance_switch.explode
	
end

Once again Dan and TIG have come to my rescue, Thank-you.

1 Like

The key take away from this discussion seems to be that you want to create an empty group first then add your component instance into it, then explode the component instance. It all seems so simple now. :slight_smile:

3 Likes

There is an issue like this for the C API in the GitHub issue tracker: C API Feature Request: SUComponentDefinitionCreateGroup() · Issue #51 · SketchUp/api-issue-tracker · GitHub

I found an internal issue logged as SU-28030 for the Ruby API.

3 Likes

Thank you Thomas !

1 Like