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…
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] Post correctly formatted and colorized code on the forum?
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!
Thank you again, everyone.
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 include
s the Enumerable
module.
The #flat_map
method comes from the Enumerable
module, and is inherited by classes that mix it in using Module#include
…
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.