Components
-
When I build a component out of 2 components,
entities=model.entities entities.each do |e| if e.typename == "ComponentInstance" puts "Component; #{e.definition.name}" else puts e.typename end end
can not see the original 2 components, but
definitions=model.definitions definitions.each do |d| puts d.name end
can. "Model Info" corectly reports all the component instances in the model. Is there another procedure that I can use to find all the component instances other then by definitions?
Is there a way to extract the information regarding the 2 original components, from the one that they are made into? I have tried but failed to do so.
-
Yes! There is.
So the model.entities collection is a collection of all TOP LEVEL entities. This is anything un grouped, and the components that are on the top most level. It does not return any components or geometry inside of groups/components. So your code:
entities=model.entities entities.each do |e| if e.typename == "ComponentInstance" puts "Component; #{e.definition.name}" else puts e.typename end end
Is going through all the top level entities and finding all top level components and listing their name. So in your case, you only had 1 top level component, that had 2 components inside of it.
So just as the model has a list of entities, so does each group or component. You get them like this:
my_comp_instance.entities
And that returns all entities within that component. Which you can then iterate through and find all compononts in there. Somthing like this:
entities=model.entities entities.each do |e| if e.typename == "ComponentInstance" puts e.entities.to_a else puts e.typename end end
So now it will puts the entire entities collection of that componentinstance. You will want to then take that entities collection and sort through it, find all components and instances and start making an array of all found components/groups. Then work your way through your array of components, looking at their entities and adding all groups and components into your array.
Did that make any sense? I think I worded it poorly. But that is the idea. Make a list of groups and components, then look at all those groups/components entities collections for and groups and components that they might contain. repeat until there are no more groups/components in your list that you compiled.
Chris
-
@honoluludesktop said:
if e.typename == "ComponentInstance"
.typename
is slow - very slow.
.is_a?
is much quicker.
if e.is_a?(Sketchup::ComponentInstance)
-
Thomas, Thanks, I now recall reading that somewhere.
Chris, I understand the logic, but so far can't find the correct procedure. Will work on it tomorrow:-(
-
I have never written a script that has to mine down through all the components the way I've vaguely described. So I'm sure i've missed some key things.
Chris
-
You can get a component-instance.
You can get that component-instance's definition.
You can get a component-definition.
You can get that component-definition's instances.
A group is a special kind of instance.
There is no built in method to get a group's definition - but it can be done in a convoluted way - there are other threads on this -group.real_parent
will return it as below...class Sketchup;;Group # Some times the group.entities.parent refer to the wrong definition. This method checks for this error and locates the correct parent definition. def real_parent if self.entities.parent.instances.include?(self) return self.entities.parent else Sketchup.active_model.definitions.each { |definition| return definition if definition.instances.include?(self) } end#if return nil # Should not happen. end#def end#class
A model has entities.
A group has entities.
A component-definition has entities.
A component-instance does not have entities - you must refer to its component-definition for these.Hope that's clear
-
@honoluludesktop said:
Is there a way to extract the information regarding the 2 original components, from the one that they are made into? I have tried but failed to do so.
What "information" are you looking for? What are you trying to do?
@honoluludesktop said:
Is there another procedure that I can use to find all the component instances other then by definitions?
You could scan the whole model, but that would be very inefficient. looping through
model.definitions
and getting theinstances
for each definition is the fastest and most efficient way to get to all the model's instances. -
@honoluludesktop said:
Is there another procedure that I can use to find all the component instances other then by definitions?
If you already have a reference to a component instance, and you want to find the other instance, then:
myInstance.definition.instances
-
@thomthom said:
@honoluludesktop said:
if e.typename == "ComponentInstance"
.typename
is slow - very slow.
.is_a?
is much quicker.
if e.is_a?(Sketchup::ComponentInstance)
I think I remember reading that
e.instance_of? Sketchup::ComponentInstance
is even faster.@thomthom said:
You could scan the whole model, but that would be very inefficient. looping through
model.definitions
and getting theinstances
for each definition is the fastest and most efficient way to get to all the model's instances.I concur. While recursion is elegant from a coding standpoint, it's grossly inefficient and prone to crashing SU. Best to find what you're looking for in the
definitions.instances
. -
TIG, do I get it?
A component-instance, and that component-instance's definition.model = Sketchup.active_model selection = model.selection selection.each do |i| if i.is_a? Sketchup;;ComponentInstance puts i.definition.name end end
A component-definition, and that component-definition's instances.
model = Sketchup.active_model model.definitions.each do |d| d.instances.each do |i| puts i.definition.name end end
A model has entities.
model = Sketchup.active_model model.entities.each do |e| puts e.typename end
A component-definition has entities.
model = Sketchup.active_model model.definitions.each do |d| d.entities.each do |i| puts i.typename end end
Haven't worked with groups yet.
See image below, I am still unable to get the name of the component (small boxA within the big boxB) within a selection of the component that is both (boxC).
Thomas:
Am doing 2 things: First going through the API trying to learn how to ruby, and also trying to get a list of entities (including sub components) that are inside a specific component. Is myInstance.definition.instances what I have above?RickW:
Good tips.
-
You missed out the variant...
model = Sketchup.active_model selection = model.selection selection.each do |i| if i.is_a? Sketchup;;ComponentInstance i.definition.entities.each{|ent| puts ent.class } end end
This will show you that you can find component-instances inside a component, then you can get the instance's definition and then that's entities etc... If you have nested items you need to do make a 'def' that's reused to iterate through them...
... if i.is_a? Sketchup;;ComponentInstance i.definition.entities.each{|ent| if ent.is_a? Sketchup;;ComponentInstance ent.definition.entities.each{|dent| puts dent.class ###etc } end } end ...
-
TIG, Got it, thanks:
model = Sketchup.active_model selection = model.selection selection.each do |i| puts "Component(s)" if i.is_a? Sketchup;;ComponentInstance puts i.definition.name i.definition.entities.each do|j| if j.is_a? Sketchup;;ComponentInstance puts j.definition.name j.definition.entities.each do|k| if k.is_a? Sketchup;;ComponentInstance puts k.definition.name end end end end end end
Now, to organize as a proceedure to accomplish the above (3 levels) to the nth level:-}
Advertisement