Unfortunately there is no 'simple' way to do what you want.
Basically you have to keep track of a group's or component's
transformation towards global space while you're descending
down a parent-child tree of groups.
One way is to keep a stack of transformations that's extended
and reduced with every nesting level. Here is an example that
might do that (untested):
##begin##
# first initialise the stack with a unity transformation
$transformationStack = [Geom::Transformation.new()]
def descend(entity):
## push new transformation matrix of entity onto stack
## entity.transformation is the transformation relative to parent
## newTrans is the transformation to global space
newTrans = $transformationStack[0] *= entity.transformation
$transformationStack.push(newTrans)
if entity.class == Sketchup::ComponentInstance
entities = entity.definition.entities
else
entities = entity.entities
end
entities.each { |e|
if e.class == Sketchup::ComponentInstance
doStuffWithComponent(e)
descend(e)
elsif e.class == Sketchup::Group
doStuffWithGroup(e)
descend(e)
else
doStuffWithFaceOrEdge(e)
end
}
## don't forget to pop() the transformation stack
## after you're done with 'entity'
$transformationStack.pop()
end
def doStuffWithComponent(e)
## for you to fill in
## you can access the transformation to global space via
toGlobal = $transformationStack[-1]
showTransformation(toGlobal)
end
def doStuffWithGroup(e)
## dito
end
def doStuffWithFaceOrEdge(e)
## for you to fill in
## here is some code that prints every vertex of a face
if e.class == Sketchup::Face
polymesh = e.mesh 7
polymesh.transform!($transformationStack[-1])
polymesh.points.each { |p|
printf "point: %s\n" % p
}
end
end
def showTransformation(trans)
## first row is x, second is y, third is z-axis
## origin (x,y,z) is last row, units is inches!
a = trans.to_a
printf " %5.2f %5.2f %5.2f %5.2f\n" % a[0..3]
printf " %5.2f %5.2f %5.2f %5.2f\n" % a[4..7]
printf " %5.2f %5.2f %5.2f %5.2f\n" % a[8..11]
printf " %5.2f %5.2f %5.2f %5.2f\n" % a[12..15]
end
##end##
Regards,
Thomas
class FindOpenings
# initialize objects@@mod = Sketchup.active_model@@ent = @@mod.entities@@lay = @@mod.layers@@sel = @@mod.selection@@temp_opening_primitives = Sketchup.active_model.active_entities.add_group@@temp_opening_primitives.name = "OPENINGS_TEMP_PRIMATIVES"
$context_stack = [Geom::Transformation.new()]$trans_level = 0
def FindOpenings::descend(ent_in) # handle ComponentInstance entities differently from others if ent_in.class == Sketchup::ComponentInstance e_ents = ent_in.definition.entities else e_ents = ent_in.entities end
if((ent_in.parent.class == Sketchup::Model) && (ent_in.class == Sketchup::Group) && (ent_in.layer.name=="OPENING_PRIMATIVES"))
puts "TOP PRIMATIVE GROUP - ADDING GROUP USING THIS_TRANS:" report_trans(ent_in)
@@temp_opening_primitives.entities.add_instance(e_ents.parent, ent_in.transformation)
else # everything else should be descended if(ent_in.name != "OPENINGS_TEMP_PRIMATIVES") if(ent_in.parent.class == Sketchup::Model)
newTrans = $context_stack[0] = ent_in.transformation $context_stack.push(newTrans)
puts "TOP NON PRIMATIVE GROUP OR COMP - DESCENDING NATURALLY" report_trans(ent_in) $trans_level += 1
end e_ents.each {|entity| if(entity.class == Sketchup::ComponentInstance)
newTrans = $context_stack[0] *= entity.transformation $context_stack.push(newTrans)
puts "COMPONENT INSTANCE - DESCENDING" report_trans(entity) $trans_level += 1
descend(entity)
elsif(entity.class == Sketchup::Group) if(entity.layer.name=="OPENING_PRIMATIVES")
puts "PRIMATIVE GROUP - ADD USING THIS_TRANS * STACK AT THIS LEVEL" report_trans(entity) @@temp_opening_primitives.entities.add_instance(entity.entities.parent, $context_stack[$trans_level]*entity.transformation)
else
newTrans = $context_stack[0] = $context_stack[$trans_level]*entity.transformation $context_stack.push(newTrans)
puts "NON PRIMATIVE GROUP - DESCENDING" report_trans(entity) $trans_level += 1
descend(entity) end end } $context_stack.pop() $trans_level -= 1 end # end of OPENINGS_TEMP_PRIMATIVES skip end # end of top level check @@temp_opening_primitives.entities.each{|tg| if tg.is_a? Sketchup::Group tg.explode end } end # end of def
def FindOpenings::report_trans(e_in) puts "---------------------------#{e_in.name}------------------------------" puts "THIS_TRANS:" show_trans(e_in.transformation) puts "CURRENT_STACK:" $context_stack.each_with_index{|ts,index| show_trans(ts,index) } puts "STACK AT LEVEL #{$trans_level}:" show_trans($context_stack[$trans_level]) puts "THIS_TRANS * STACK AT THIS LEVEL:" show_trans($context_stack[$trans_level]*e_in.transformation) puts "-----------------------"end #report_trans def
def FindOpenings::show_trans(trans,i=nil) # i is optional #first 3 rows are scale (x,y,z) 4th row is origin (x,y,z) a = trans.to_a if i!=nil printf("%d: " %i) printf("%d,%d\n" %a[12..13]) # + %d,%d\n" %i %a[12] a[13] else printf "%d,%d\n" %a[12..14] endend # showTransformation def
# define cut_wallsdef FindOpenings::cut_walls
SKETCHUP_CONSOLE.clear @@ent.each{|ents| descend(ents) } end # end cut_walls def
end # class FindOpenings