Entities used by a Component Instance

Hello everyone. How to find, by the Ruby code, the entities in a component instance?

A ComponentInstance does not have entities.
However, it does have a definition, and a definition does have entities.
So let’s assume you somehow get an instance, this code finds its definition’s entities:

ents = instance.definition.entities

We need further info to advise you in more detail…

1 Like

Thank you for your answer TIG. I am trying to extract 3D points from an instance of a component via the syntax :
entities = Component.model.entities

My goal is indeed to find the 3D points
of the component in order to exploit them for another use

It appears that the code below is working:
indent preformatted text by 4 spaces def recupedge ( comp )
entities = comp.model.entities

tab =[]
entities.each { | entity| 
if  entity.typename == "Edge" 
    puts entity.line[0]
    tab << entity.line[0]
end
}  
tab

end
indent preformatted text by 4 spaces
Except I don’t know why yet, I get aberrant points in my scoreboard!

indent preformatted text by 4 spaces

def recupedge ( comp )
entities = comp.model.entities

tab =[]
entities.each { | entity| 
if  entity.typename == "Edge" 
    puts entity.line[0]
    tab << entity.line[0]
end
}  
tab

end
indent preformatted text by 4 spaces

Please use this method of posting code … [How to] Colourize code on the forum? (wiki)


Where comp is the reference of a component instance, …

Does not return a reference to a component instance’s definition’s entities.
It rather returns a reference to the “root level” entities collection of the model, which can always be gotten via:

ents = Sketchup.active_model.entities

Do not use the .typename method for class typing as Ruby string comparison is very slow.

Use instead a class identity comparison which is very fast. Example:

  if entity.is_a?(Sketchup::Edge)

But to quickly collect a certain class of entity from an entities collection, use the .grep method that most API collection classes inherit from the Ruby Enumerable mixin module.

edges = entities.grep(Sketchup::Edge)

To find the points of edges, you use the .start and .end instance methods.
These method return Sketchup::Vertex objects. To get the 3D points, use the vertex’s .position method.
Example:

pt1 = edge1.start.position
pt2 = edge1.end.position

To collect points from a number of edges …

ents = instance.definition.entities
edges = ents.grep(Sketchup::Edge)
vertices = edges.flat_map(&:vertices).uniq
points = vertices.map(&:position)

Now the points are local to the instance's transformation.
They need to be converted to “global” coordinates…

xform = instance.transformation
global_points = points.map {|pt| pt.transform(xform) }

Thank you very much, DanEathbun for your valuable advice. The solution is in sight

Sorry for getting back to the load, but I cannot for my purposes. When I’m looking for the methods by

Puts comp.methods.sort

I can’t find the grep method. How should I do? I use SketchUp Make 2017

comp also has no entities to grep…

# :grep in Ruby is an Enumerable method, have a look...
Enumerable.instance_methods

# and you can check that the definition has the 'grep' method...
comp.definition.entities.respond_to?('grep') # => true

# if 'comp.definition' is valid and has entities, than you can grep it...
tab = comp.definition.entities.grep(Sketchup::Edge) # returns an array of edges...

john

Thank you john.
Here’s what works, put it because I always have aberrant points:

def recupedge ( instance )

  ents = instance.definition.entities
  edges = ents.grep(Sketchup::Edge)
  vertices = edges.flat_map(&:vertices).uniq
  points = vertices.map(&:position)
  xform = instance.transformation
  tab = points.map {|pt| pt.transform(xform) }
puts tab
    tab
  
 end 	

As much for me, the aberrant points already exist in my input data. flop!:-1:

Thank you again, everyone.:+1:

1 Like

Hello again DanRathbun
It’s me again. I’m having a hard time finding documentation on the “flat_map” method. It doesn’t even appear anywhere in Ruby’s core 2.6.3 documentation! Could you tell me about it?

If you are still using SketchUp 2017, then it uses Ruby version 2.2.4 and you should use …
https://ruby-doc.org/core-2.2.4/index.html
… to look up Ruby core modules, classes and methods.


Okay … the SketchUp API’s Sketchup::Entities class includes the Enumerable module from the Ruby core. (Many, if not all, of the API’s collection classes will include the Enumerable module. I would have to say that all of the Ruby core’s collection classes also include the Enumerable module.)

To see what library modules an API class includes or what superclass functionality they inherit, look at the top of the class / module documentation page.

So the Enumerable module is how the Sketchup::Entities class gets the #grep method (which returns an Array.)

If you look at the Ruby core doc for Array in the left navigation column, below the method list, … you’ll see that the Array class also includes the Enumerable module.

The #flat_map method comes from the Enumerable module, and is inherited by classes that mix it in using Module#include …

image

The SketchUp Ruby API documentation does not list include or inherited methods from the Ruby core or Ruby standard libraries (if loaded.)

OK. Thank you Dan Rathbun.