Ruby API - to which layer a component belongs


#1

I would like to find the distance of each component in layer 1 from each component in layer 2.
How one knows to which layer a component belongs? and how can I perform a loop on all components belong to a layer?

Thanks, Sharon


#2

Unfortunately, the relationship between layers and DrawingElements is one way. That is, the DrawingElement has a link to a layer, but a layer has no collection or list of the DrawingElements that link to it. So, you have to search the model’s entities collection to find the ones tagged with the layers of interest and then do whatever distance calculation you have in mind. For example

#somehow pick the two layers of interest, layer_a and layer_b
ents=Sketchup.active_model.entities
layer_a_ents = ents.find_all {|ent| ent.is_a?(Sketchup::ComponentInstance) && ent.layer==layer_a}
layer_b_ents = ents.find_all{|ent| ent.is_a?(Sketchup::ComponentInstance) && ent.layer==layer_b}
#perform your distance calculation on each pair from the two arrays

Retrieve the geometry of an entity
#3

Thanks. Very helpful.
Another question: How can I use the geometry of an entity, (e.g. points, and planes). In other words, I would like to measure the distance between each point, line and plane of an entity and another point.


#4

That kind of operation is very messy. I won’t give code here, as it would take me some time to write and check, but I’ll discuss the issues and approach. Geom::Point3d has the necessary methods to calculate distances, but first you need to get the relevant Point3d’s.

To begin, the actual Entities belong to the ComponentDefinition, not to the ComponentInstance, so they need to be transformed into the model’s coordinates using the ComponentInstance’s Transformation before your calculation. In addition, the Point3d location information is kept in the Vertices, which are shared by the Edges and Faces that use them. So you have to access each Edge and Face of the ComponentInstance, retrieve its Vertices, and then test their Point3d positions. You need to take care about testing the same Vertex again (or not) for each of the Entities that uses it.

Then there’s the question of whether by “line and plane” you mean “Edge and Face” or really “line and plane”. Edges and Faces are finite, real geometry in SketchUp. Lines and planes are infinite, abstract geometry. I’ll assume that you really meant Edge and Face. I’ll also assume that you meant “distance to the closest point of”. But that’s still ambiguous: do you mean “the closest Vertex of” or really “the closest point of”, which might be located somewhere in the middle of an Edge or the interior of a Face? The former question is simpler, as you can just test the Vertex positions.

For the real “closest point”, you must test whether the actual closest point isn’t a Vertex. You can do this be getting the line corresponding to an Edge or the plane corresponding to a Face (they provide methods for this), then using Point3d methods project_to_line or project_to_plane to get the Point3d on the line or plane closest to the reference point. Then you need to test whether this point is on the Edge or Face, or on the extended line or plane outside it.

For a Face you can then use classify_point to see whether this project-to-plane point is inside the the Face, on its boundary, or elsewhere. If it is inside or on the boundary, it is the point you want. If not, you will need to find the Edge of the Face that is closest and use the closest point on that Edge.

Unlike Face, Edge doesn’t provide a classify_point method to test whether a point is on the Edge, even if you know it is on the Edge’s line. So you will have to do the calculations yourself. They are basic linear geometry. Ask again if you can’t figure them out (though that probably means you are in way over your head already!).


Ordering components by distance from each other?