I've tried to boil this down to a small as example as possible, what I need to do is given a face, calculate it's absolute final position in XYZ (taking into account transforms, etc). It's for a paint tool I'm working on that works (and aligns regardless of grouping. I happen to use Sketchup for game mapping and the particulars of the exporter force pretty much everything to be a group.
A less than compelling example video of the paint tool http://www.youtube.com/watch?v=hb63D7Cmt50
I've mostly got it working, except for the origin is off when dealing with groups within groups, there is just something I'm not grokking here. So after many hours of head scratching, I figured I'd see if anyone can enlighten me.
So I take the face, I walk up the hierarchy, adding transforms, (and in theory, transformation origins) and compute the new points. The code below just adds the transformation.origin, I know this is wrong, and it's what trying to solve. I've tried a dozen things (transforming them by the container, etc,) but there is just something I'm not understanding.
Here's the code
module WALK
def WALK.setface
model = Sketchup.active_model
@newg = model.entities.add_group
@s = nil
if model.selection.empty?
UI.messagebox "Selection empty"
return nil
else
if model.selection[0].is_a? Sketchup;;Face
@s = model.selection[0]
else
UI.messagebox "Face not selected"
end
end
end
# make sure groups are unique
Sketchup.active_model.definitions.each{|d|d.instances[1..-1].each{|i|i.make_unique}if d.group? and d.instances[1]}
def WALK.main
WALK.GetParent(@s)
end
def WALK.GetParent(ent)
Sketchup.active_model.start_operation("Walk")
model = Sketchup.active_model
@newg = model.entities.add_group
m = model.materials.add "test"
m.color="red"
orig = ent
tpos = Geom;;Point3d.new 0,0,0 # keep track of origin
trans = Geom;;Transformation.new(Geom;;Point3d.new(0,0,0)) # add transforms to this
while (ent.respond_to?('parent') ) # walk up hierarchy
if ((ent.is_a? Sketchup;;ComponentDefinition))
if ent.group?
t = ent.instances[0].transformation # Get the group's transform
tpos += t.origin.transform(trans).to_a # !!!WRONG
trans *= t # combine transforms
end
ent = ent.instances[0] # become the instance
end
ent = ent.parent
end
vertices = orig.outer_loop.vertices
newverts = []
vertices.each do |v|
np = v.position.clone
np+= tpos.to_a # !!! Wrong
np.transform! trans
newverts.push np
end
f = @newg.entities.add_face newverts # create the face
f.material=m
Sketchup.active_model.commit_operation
end
end # end mod
if !file_loaded?(__FILE__)
UI.menu("Plugins").add_item("Select Walk Face") { WALK.setface }
UI.menu("Plugins").add_item("Make Walk Face") { WALK.main }
end
file_loaded(__FILE__)
It adds two items to the plugin menu
Select Walk Face and Make Walk Face
Take the example here
The geom looks like this...
Group
--Group
----Wide Cylinder faces
--Group
----Group
------Cube faces
----Group
------ Tall Cylinder Faces
Seeing backing out of a group clears the selection, here's where Select Walk Face comes in. Click down into the inner group of the cube and select a face and then select Select Walk Face, this simply stashes the face for Make Walk Face
Now if you actually ran Make Walk Face here, it works fine, making a new face, respecting transforms and in the right place.
But back all the way out of the group and run Make Walk Face
and you get this....
If you've read this far, I commend you
Any insight on what I'm not understanding would truly be appreciated.
Thanks!
-Lee