Find the global position of a Vertex in a Group/Component
-
Adam, that code returns the transformation of all the copies of that instance? But no way to track back a single path to the model, like you get with PickHelper?
-
@gbabcock said:
From there you can walk UP the hierarchy of ComponentInstances
Well, not quite...
The Parent of a ComponentInstance is a ComponentDefinition, which can exist in more than one ComponentInstance (for example, if you have multiple instances of a Component that has nested Components). So you can't even walk up the hierarchy of ComponentInstances.
But walking down works well! My use case is where I have selected a Group/Component (but not opened it) and need the global position of every Vertex. With limited testing performed, this code seems to give an accurate position report:
#get vertices def Start #get vertices verts=[] #initialize vertices array trans_h=[] #initialize transformation array use to store hierarchy of transformations verts=createVerticesArray(sel,trans_h,verts) end def createVerticesArray(sel,trans_h,verts) sel.each{|ent| if (ent.is_a? Sketchup;;Group) || (ent.is_a? Sketchup;;ComponentInstance) trans_h.push(ent.transformation) #push the Group/Component tranformation onto the array ents=ent.definition.entities #get the entities in this Group/Component instance verts=createVerticesArray(ents, trans_h, verts) #recurse elsif (ent.is_a? Sketchup;;Edge) ent.vertices.each{|vert| #begin analysis of vertices in this edge puts vert if @debugFFD #get global position of the vertex by applying the hierarchy of transformations v_gpos=vert.position #returns local Point3d position of vertex puts v_gpos if @debugFFD flat_t=flatten(trans_h) #get the flattened transformation for the hierarchy puts flat_t if @debugFFD v_gpos.transform! flat_t #transform the vertex to get the global position vert.set_attribute("vert","gpos",v_gpos) verts.push(vert) } end } #verts now contains redundant verts. remove duplicates. verts.uniq! return verts end #thanks to Adam for the idea! def flatten(trans_h) #returns a flattened transformation from an array of transformations for the instance hierarchy flat_t=Geom;;Transformation.new #create an entity transformation object #apply the hierarchy of transformations to the entity transformation trans_h.each{|t| flat_t=flat_t* t } return flat_t end
It performs well too, though I'm sure it could be improved. I have used it on a component with ~8400 entities and 1720 vertices, and get the results back in 0.25 seconds consistently.
Glenn
-
Interesting thread. I'm trying to do figure out how to apply transformations to SU mesh objects for exporting. The object.transform! method seems to only perform rotation and scaling but not translation (e.g. the delta movement along the x, y, and z axis). I see that the transform matrix does indeed contain the translation values in the last row (row 4) of the matrix. Why doesn't the transform! method also perform the translation? Is this a bug or a feature?
-
Never had any problems with translation and
.tranform!
.
Maybe post a code snippet? (though in a new thread - as we're moving towards a new topic) -
one small correction to the code posted by Glenn: after calling createVerticesArray on line 14, add the line:
trans_h.pop
otherwise, if there are multiple sub-components in the entities collection, you will take into account the transformation of any entity that came before.
Otherwise, great code, very useful.
Thanks!
--
Karen
Advertisement