sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Transforming an array of points

    Scheduled Pinned Locked Moved Developers' Forum
    27 Posts 7 Posters 531 Views 7 Watching
    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.
    • jolranJ Offline
      jolran
      last edited by

      Ok. Did some tests and it seams like Polygonmesh transform scales quite well.

      Note this test may not be constructed optimaly, I'm still green. But still quite interesting to see how fast polygonMesh transforms many Points.
      The test might provide different result if arrays are flattended, but I need to keep the polygon/Points hierarchy.

      Edit: I saw that newlist actually don't keep the hierarchy So the result would probably be slower. Can't really Output the result in ruby consol 😉

      # Square Polygon
      pts = [
        Geom;;Point3d.new(-5,-5,0),
        Geom;;Point3d.new(5,-5,0),
        Geom;;Point3d.new(5,5,0),
        Geom;;Point3d.new(-5,5,0)
      ]
      
      vec = [10,0,0]
      tr = Geom;;Transformation.new( vec )
      
      # Create som polygons for testing..
      polys = {}
      vec2 = vec.clone
      for i in 0...50
        polys[i] = pts.collect{|pt| pt.offset(vec2) }
        vec2.offset!([15,10,0])
      end
      
      # Mesh
      msh = Geom;;PolygonMesh.new
      for k,v in polys
        msh.add_polygon(v)
      end
      
      # Array of points
      polygonials = polys.values
      puts "total nr Point3dObjects; #{polygonials.flatten.length}"
      
      #group = Sketchup.active_model.active_entities.add_group
      #group.entities.fill_from_mesh(msh, true, 12)
      
      #Tests On My computer Gave;
      #PolygonMesh Transforms; 0.03
      #Array Transforms; 1.052
      #Array Transforms And Collect; 2.335
      
      start = Time.now
      10000.times {
          msh.transform!(tr)
      }
      puts "PolygonMesh Transforms; #{Time.now - start}"
      
      
      start = Time.now
      10000.times {
      for list in polygonials
        for p in list do p.transform!(tr) end
      end
      }
      puts "Array Transforms; #{Time.now - start}"
      
      start = Time.now
      newlist = []
      10000.times {
      for list in polygonials
        newlist << list.collect{|p| p.transform(tr) }
      end
      }
      puts "Array Transforms And Collect; #{Time.now - start}"
      
      1 Reply Last reply Reply Quote 0
      • G Offline
        Garry K
        last edited by

        What about a benchmark for a hash?

        1 Reply Last reply Reply Quote 0
        • jolranJ Offline
          jolran
          last edited by

          
          start = Time.now
          10000.times {
          for key,val in polys
            for p in val do p.transform!(tr) end
          end
          }
          puts "Nested Hash Transforms; #{Time.now - start}" # => 1.274
          
          
          

          It is a Hash? If I don't nest the Hash the "polygon-Points" relation will be impossible to retrieve afterwards:
          Hash = { 0 => [pt,pt,pt,pt] etc }

          Do you mean 1 layer Hash structure { key => pointd3d etc } ?

          There may off course be better structures for this, I'm all ears.

          Edit: I tried running each test separately muting the other timers with following result:

          PolygonMesh Transforms: 0.047
          Nested Hash Transforms: 1.191
          Array Transforms: 1.066
          Array Transforms And Collect: 2.328

          Maybe I'm confusing the matter... And I haven't outputed the resulting mesh(which would stall Sketchup) so there is a matter of knowing if the resulting Mesh is qualified as well.

          1 Reply Last reply Reply Quote 0
          • jolranJ Offline
            jolran
            last edited by

            Ah you mean put result in Hash ?

            start = Time.now
            newHash = {}
            10000.times {
            for i in 0...polygonials.length
              newHash[i] = polygonials[i].collect{|p| p.transform(tr) }
            end
            }
            puts "HASH Transforms And Collect; #{Time.now - start}"
            

            =>2.381

            1 Reply Last reply Reply Quote 0
            • G Offline
              Garry K
              last edited by

              You could render the mesh after the timers to maintain benchmark validity.

              Have you tried traversing your polygons?
              mesh.polygon_points_at( index )
              Shouldn't this give you the same results as an outer_loop on a face?
              The question I would have is although you can get the points for each polygon - Is there a way to tie in a reference to the faces in the model once you have rendered the mesh?
              I would hope that the entities in the group immediately after a fill_from_mesh would be in mesh polygon index order. So there should be a 1 to 1 relationship.

              I haven't played with hashes yet - so my question is probably confusing to you. Although I've programmed for many years and also played with CAD for many years I've only logged 3 or so months with Sketchup since I got serious about it (guess I caught the Sketchup virus).

              1 Reply Last reply Reply Quote 0
              • jolranJ Offline
                jolran
                last edited by

                @unknownuser said:

                You could render the mesh after the timers to maintain benchmark validity.

                Yeah, for those tests that edit in Place. Otherwise it would be too intense for Sketchup.

                @unknownuser said:

                The question I would have is although you can get the points for each polygon - Is there a way to tie in a reference to the faces in the model once you have rendered the mesh?

                I'm just moving Points in this code. I reckon you'd have to recollect faces afterwards
                and do some boolean tests. There's normal_at which could be used for ex.
                It all depends on (referring to your other question) if face order == polygon index order. I should test that as well unless someone else already knows..

                I'm pretty new to programming, so there can be lots of holes in the logic of my tests.
                But what better way to learn than trying to solve a problem, right?

                Hashes in Ruby are supposed to have much faster lookup than arrays. I think that's what Thomthom tried to point out earlier.

                1 Reply Last reply Reply Quote 0
                • tt_suT Offline
                  tt_su
                  last edited by

                  @garry k said:

                  I think that we gain performance in the actual transform but may loose it accessing the points in the mesh.

                  Geom::PolygonMesh.points? http://www.sketchup.com/intl/en/developer/docs/ourdoc/polygonmesh.php#points

                  1 Reply Last reply Reply Quote 0
                  • G Offline
                    Garry K
                    last edited by

                    Sorry - bad terminology. I was talking read and write access.
                    the only write access we have is mesh.add_point.
                    I'm still thinking as a C / C++ programmer.

                    1 Reply Last reply Reply Quote 0
                    • tt_suT Offline
                      tt_su
                      last edited by

                      @garry k said:

                      Sorry - bad terminology. I was talking read and write access.
                      the only write access we have is mesh.add_point.

                      PolygonMesh.set_point
                      http://www.sketchup.com/intl/en/developer/docs/ourdoc/polygonmesh.php#set_point

                      1 Reply Last reply Reply Quote 0
                      • jolranJ Offline
                        jolran
                        last edited by

                        Yet Another test 👊

                        Don't know how reliable this test is but it appears face get appended in the same order as indexed in Polygonmesh. But Polygonmesh Count indexes starting at 1.

                        Edit: Updated for adding c_point in polygonmesh index as well. But wonder how hidden edges affect the Index ordering..

                        The API says:

                        @unknownuser said:

                        The negative values should not be used as an index for point_at, take the positive value of the index value in the polygon array

                        Perhaps hidden edges will only happend if mesh is constructed from a collection of Sketchup::Face's. Not relevant in this case.
                        In that case maybe use index.abs or perhaps double negation: index = index<0 ? -index : index

                        ents = Sketchup.active_model.active_entities
                        
                        def centerpoints(f)
                          cx = (f[0].x + f[1].x + f[2].x + f[3].x)/4
                          cy = (f[0].y + f[1].y + f[2].y + f[3].y)/4
                          cz = (f[0].z + f[1].z + f[2].z + f[3].z)/4
                          return Geom;;Point3d.new(cx, cy, cz)
                        end
                        
                        
                        face1 = [ 
                          Geom;;Point3d.new(-5,-5,0), Geom;;Point3d.new(5,-5,0),
                          Geom;;Point3d.new(5,5,0), Geom;;Point3d.new(-5,5,0) 
                        ]
                        
                        #create points for 4 faces
                        faceHash = {}
                        for i in (0...4) 
                           faceHash[i] = face1
                           face1 = face1.collect{|pt| pt.offset([20,0,0])}
                        end
                        
                        #get refference to the center of "face"#3 Before appending to mesh.
                        
                        fC = centerpoints(faceHash[2])
                        ents.add_cpoint(fC)
                        
                        # Bit strange to loop hash this way, but they get ordered.
                        msh = Geom;;PolygonMesh.new
                        for n in (0...faceHash.length)
                          msh.add_polygon(faceHash[n])
                        end
                        
                        #Test PolygonMesh index. How does hidden edges affect indexes for this ?
                        # +1 index for polygons in Mesh. 2 c_points should get added at same spot
                        meshface3 = msh.polygon_points_at(2+1)
                        mc = centerpoints(meshface3)
                        ents.add_cpoint(mc)
                        
                        
                        group = ents.add_group
                        group.entities.add_faces_from_mesh(msh)
                        faces = group.entities.grep(Sketchup;;Face)
                        
                        #Red material to face 3
                        faces[2].material = "red"
                        
                        
                        
                        1 Reply Last reply Reply Quote 0
                        • 1
                        • 2
                        • 2 / 2
                        • First post
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement