• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Calculating the final vertices of a nested face

Scheduled Pinned Locked Moved Developers' Forum
3 Posts 2 Posters 283 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    shotgunefx
    last edited by 3 Mar 2011, 22:56

    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

    http://farm6.static.flickr.com/5293/5494975921_63bd7d0e3a_z.jpg

    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....

    http://farm6.static.flickr.com/5259/5494975933_05f17d3207_z.jpg

    If you've read this far, I commend you 😄

    Any insight on what I'm not understanding would truly be appreciated.

    Thanks!
    -Lee

    1 Reply Last reply Reply Quote 0
    • T Online
      TIG Moderator
      last edited by 4 Mar 2011, 13:55

      Have you tried tr=container.transformation.inverse and applying it to the initial object and then iterating and getting/setting the transformation for the container's container etc until you get to the model level...

      TIG

      1 Reply Last reply Reply Quote 0
      • S Offline
        shotgunefx
        last edited by 5 Mar 2011, 04:22

        @tig said:

        Have you tried tr=container.transformation.inverse and applying it to the initial object and then iterating and getting/setting the transformation for the container's container etc until you get to the model level...

        That didn't seem to work (inverse), though I may very well have misunderstood what you meant, but what you said gave me an answer anyway. By applying the transform to the points at each container successively, it works perfectly! (or at least in every test so far)

        Which is how I should have tried it initially but I was thinking from a performance standpoint, and forgot the old adage "premature optimization is the root of all evil"

        
        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
        
           vertices = orig.outer_loop.vertices.map {|v| v.position.clone}
           
           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
                        vertices.each_with_index do |v,i|
                            vertices[i].transform! t 
                        end
                    end     
                    ent =  ent.instances[0]     # become the instance
                end
                ent = ent.parent
           end
           f = @newg.entities.add_face vertices    # create the face
           f.material=m
           Sketchup.active_model.commit_operation
        end   
        
        
        

        Thanks again for the help!

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        1 / 1
        • First post
          1/3
          Last post
        Buy SketchPlus
        Buy SUbD
        Buy WrapR
        Buy eBook
        Buy Modelur
        Buy Vertex Tools
        Buy SketchCuisine
        Buy FormFonts

        Advertisement