Group.to_component method is not working correctly


#1

I spent several days to test group conversion to component instance.
According to the documetattion it should be only two lines ruby code

compDef=grpDef.to_component
compDef.name=compName

where compDef is the component definition and grpDef is the group definition

It was found that the above code is not working correctly.
My guess is that a component instance is not a component definition.
So it can be used in a big ruby script.

Instead of the one line the following lines should be used

grpDef=find_group_by_name(grpName)
compDef=Sketchup.active_model.definitions[compName] # create new component
compDef.entities.add_instance(grpDef.entities.parent,grpDef.transformation)
grpDef.erase!


#2

That’s not a guess, ComponentInstance and ComponentDefinition are different Ruby Classes and have different meanings!

Could you provide more info about what you mean by this? In what sense is it not working correctly?

Your code will nest an instance of the Group inside the Component, which is not the same thing as converting the Group into a Component.


#3

You are muddling up ‘definition’ and ‘instance’.
A component definition [i.e. what is shown in the Components Browser model-tab list] can have instances placed in the model or within other containers in the model - like groups - or even within other component definitions in the model [it could also have 0 instances].
definition.instances returns an array of that definition’s instances
instance.definition returns the definition to which that instance is linked
You can also set an instance to be linked to another definition… e.g.
instance.defintion=some_other_definition
Because a definition can have multiple instances editing one instance changes all other instances.
The ‘make_unique’ tool splits specific instances off from their parent definition so changing one of those instances does not affect its previously connected siblings.
An instance can have a name different from its definition’s name.

A group is simply a special kind of instance of a definition.
Groups are not displayed in the Components Browser and if you delete a group its definition is gone - unlike deleting an component’s instance which would leave its now unused definition in the Components Browser.
You can copy a group so that there are more than one in the model, but editing one of those automatically makes it unique and separates it from its sibling[s].
A group can have a name different from its definition’s name [which remains hidden].

The group.to_component method works on a group, NOT on its definition.
It returns a component-instance - i.e. its definition is now displayed in the Components Browser
The definition is named after the group - e.g “Group#5” - unlike the context-menu equivalent tool which asks the user for a definition name - so you’ll probably want to rename it just after it’s been created?
So…
instance=group.to_component
definition=instance.definition
definition.name=‘some_new_name’


Incidentally Images are also another special kind of instance of a definition...

#4

Some background information.
I am developing a parametric modelling system in SU Pro.
(It can create arbitary objects and place luminaire 3D models at the exact location and orientation)

It is based on the roo plugin.
So an excel table is parsed by my ruby script.
Due to excel table properties every object (component or group ) MUST be referenced by name.

As far as possible components are used and later transformed to the exact location.

Recently it was found that groups should be used too.
Whenever a hole to be cut and/or openings should be made on walls; groups should be used.
When a complex object (group) is created following the a/m logic the group is to be converted into component.
This newly created component is to be placed at several positions.

When the .to_component method was used something very strange happened.
The new component could not be accessed by the ruby script however it was clearly visible in the SU GUI.
If this new component was moved in the GUI then the ruby script could find it by name.

The second code sniplet does exactly what is needed.

grpDef=find_group_by_name(grpName)
compDef=Sketchup.active_model.definitions[compName] # create new component
compDef.entities.add_instance(grpDef.entities.parent,grpDef.transformation)
grpDef.erase!

Convert the group into a component which can be found by name (and erase the unnecessary group definition)


#5

Yes, you are right.
I want the converted group to be renamed so that it can be used later on as a component.


#6

This is not an API method, but I believe refers to the example method I posted here …

That method does NOT return the group’s component definition, … it returns the group instance who’s name matches the 2nd argument.

(Again, a group is a special kind of component instance, who’s definition has the #group? flag set to true and is hidden from the “In Model” collection Component Inspector / Browser panel.)

You yourself prove that the returned object is a group instance by later calling grpDef.transformation upon it. The #transformation method is an instance method of the Sketchup::Group and Sketchup::ComponentInstance classes.
The Sketchup::ComponentDefinition class does not have a #transformation method.

This does NOT create a new component !

compDef = Sketchup.active_model.definitions["Dan"]
compDef.inspect
#=> nil

The Sketchup::DefinitionList#[] method is a lookup method only.

Use the Sketchup::DefinitionList#add factory method to create a new component definition in the model’s definitions collection.

You likely do not understand that Sketchup::Group#entities is an old “wrapper” method, that is shorthand for … group.definition.entities.

The API authors tried to mask the fact that a group was a component instance, and make it appear to act like a definition object. So they did not have a #defintion method defined for the Sketchup::Group for many versions until SketchUp v2015.

News Flash: Component Instances (and Groups) do not “own” an entities collection. Their definitions do.

So, … since v2015 you can just go ahead and call group.definition instead of the “clunkygroup.entities.parent call.


It is working just fine. You are confused is all. It looks better this way …

grpInst  = find_group_by_name(grpName)
compInst = grpInst.to_component
compInst.definition.name = compName # give new definition a better name
compInst.name = instName # give the new instance a better name

#7

Thanks for your comments and advices.

First about find_group_by_name method.
To tell truth this method combined from two sources
the first one is yours
the second one is from here
https://groups.google.com/forum/#!topic/sketchupruby/C34YIFaJ_kk

About groups and components
I think so now I understand them. Your explanation made it clear.
By the way it is very tricky. One can be lost very easily.


#8

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.