sketchucation logo sketchucation
    • 登入
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.6b introduces important bugfixes for Fredo's Extensions Update

    Transforming an array of points

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    27 貼文 7 Posters 788 瀏覽 7 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • tt_suT 離線
      tt_su
      最後由 編輯

      The data set you currently work with is probably so small that you won't gain that much. But I'd think as the data set increases you'd see bigger and bigger differences.

      1 條回覆 最後回覆 回覆 引用 0
      • G 離線
        Garry K
        最後由 編輯

        That is why I suggested it would be a viable option in some circumstances.

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

        If there was a bulk operation to move points from one mesh to another without invoking the built in check - then you would probably benefit even on a smaller data set.

        1 條回覆 最後回覆 回覆 引用 0
        • Dan RathbunD 離線
          Dan Rathbun
          最後由 編輯

          @jolran said:

          So there is a way to group Point3d objects ?

          Yes there is. Create a Geom::BoundingBox object and add points to it.

          However I do not see a transform method that applies to bounding boxes.

          😞

          I'm not here much anymore.

          1 條回覆 最後回覆 回覆 引用 0
          • jolranJ 離線
            jolran
            最後由 編輯

            @unknownuser said:

            Yes there is. Create a Geom::BoundingBox object and add points to it.
            However I do not see a transform method that applies to bounding boxes

            ☀ Forgot about that one. Will be useful, even if not in this case.

            @unknownuser said:

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

            If polygonmesh.polygons returned arrays of Points that woulden't be the case.

            Have you tried recollecting points to a new Array and Transform! them in place ?
            Array.Dup does not work with Point3D objects 😞
            As far as I know one have to recollect points into new Array. Comes with a timecost of course..

            1 條回覆 最後回覆 回覆 引用 0
            • jolranJ 離線
              jolran
              最後由 編輯

              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 條回覆 最後回覆 回覆 引用 0
              • G 離線
                Garry K
                最後由 編輯

                What about a benchmark for a hash?

                1 條回覆 最後回覆 回覆 引用 0
                • jolranJ 離線
                  jolran
                  最後由 編輯

                  
                  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 條回覆 最後回覆 回覆 引用 0
                  • jolranJ 離線
                    jolran
                    最後由 編輯

                    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 條回覆 最後回覆 回覆 引用 0
                    • G 離線
                      Garry K
                      最後由 編輯

                      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 條回覆 最後回覆 回覆 引用 0
                      • jolranJ 離線
                        jolran
                        最後由 編輯

                        @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 條回覆 最後回覆 回覆 引用 0
                        • tt_suT 離線
                          tt_su
                          最後由 編輯

                          @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 條回覆 最後回覆 回覆 引用 0
                          • G 離線
                            Garry K
                            最後由 編輯

                            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 條回覆 最後回覆 回覆 引用 0
                            • tt_suT 離線
                              tt_su
                              最後由 編輯

                              @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 條回覆 最後回覆 回覆 引用 0
                              • jolranJ 離線
                                jolran
                                最後由 編輯

                                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 條回覆 最後回覆 回覆 引用 0
                                • 1
                                • 2
                                • 2 / 2
                                • 第一個貼文
                                  最後的貼文
                                Buy SketchPlus
                                Buy SUbD
                                Buy WrapR
                                Buy eBook
                                Buy Modelur
                                Buy Vertex Tools
                                Buy SketchCuisine
                                Buy FormFonts

                                Advertisement