@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