sketchucation logo sketchucation
    • Login
    ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

    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

      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
      • TIGT Offline
        TIG Moderator
        last edited by

        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

          @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
          • First post
            Last post
          Buy SketchPlus
          Buy SUbD
          Buy WrapR
          Buy eBook
          Buy Modelur
          Buy Vertex Tools
          Buy SketchCuisine
          Buy FormFonts

          Advertisement