sketchucation logo sketchucation
    • Login
    1. Home
    2. jolran
    3. Posts
    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!
    πŸ«› Lightbeans Update | Metallic and Roughness auto-applied in SketchUp 2025+ Download
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 37
    • Posts 1,027
    • Groups 2

    Posts

    Recent Best Controversial
    • RE: Transforming an array of points

      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"
      
      
      
      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

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

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

      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

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points
      
      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.

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

      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}"
      
      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

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

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

      @unknownuser said:

      You probably already know this, but you can traverse the points this way:
      pt = mesh.point_at( index )
      You can then store your indexes in an array or hash and work with them instead.

      Yes I know, but In my case I desired an Array of Point-arrays(polygon) from mesh simply from Calling mesh.polygons. This still mean I'll have to recollect the Points from the returning indexes, unless I'm misstaken. Maybe one can chain methods I don't know.
      Havent tried that hard yet..

      @unknownuser said:

      If you're applying the same transform to all the points, generally you'd be better off both in performance and accuracy with changing the container entity's transform rather than changing the Points themselves.

      So there is a way to group Point3d objects ? Or are you referring to the Mesh.transform ?

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

      TIG.
      I think this thread is related.
      http://sketchucation.com/forums/viewtopic.php?f=180&t=54786

      Actually the topic title describes the question quite good..

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Transforming an array of points

      Garry, we seam both to have a fascination of Points currently πŸ˜„

      I'm trying to find out the optimal way to transform Points "en mass" too.

      Can one really Group Point3d objects? Don't Think so..

      
      
      arrayofpoints2 = arrayofpoints1.collect{|p| p.offset(vec) }
      
      

      This seams to work when you don't want to alter the original Points Array.

      I'm wondering if creating a dup of the original array and perform edit in Place(offset!) is faster. You mention that also, btw.
      It might not be as easy as Array.dup... Might not work with Point3d objects..

      I started to fiddle around with the polygonmesh object. Yes it's convenient that one can transform the meshobject as whole. But found the polygons and Points methods a bit difficult for traversing Points, since for ex the polygon method returns indexes and not arrays of Points. I'm sure there's a reason for that I'm not aware off, but I had to add Another loop in the loop to reach the correct Points. And that is expensive.

      Keep posted. Interesting subject.

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      @unknownuser said:

      Not necessarily. A Ruby Hash lookup will be faster than the linear traversing the C code is doing. When I need performance in Ruby I often find that creating a Hash cache object yields the most performance gain.

      As always with these things - never assume - test it.

      Thanks! That IS what I was wondering.

      WIll do some test indeed πŸ˜„

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      Right.. Had to google a bit there πŸ˜„
      Very interesting BTW.

      My program cant decide on in advance how many Points there will be, so preallocation won't apply(probably) in my case.

      I was speculating more about if there would be any advantages in using polygonmesh VS arrays/hashes as a storage for Points building up during the program phase.
      As a container, in the case when the endproduct will be a mesh from Points. Also fething data will be frequent.. And I'm talking plural polygonmeshes.

      I can see some advantages with lookup methods built into the class. But creating a new Polygonmesh.object must come at a price though, so I'm still wondering whether I should wait with the polygonmesh object for when it's actually needed and keep creating nested lists of arrays..

      Anyway. It looks like you got what you came for πŸ˜„

      This question might not belong to this topic..

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      @unknownuser said:

      The fastest way I found to create PolygonMesh is to feed all the 3d points you are going to use to the PolygonMesh and then use the index that mesh.add_point returns to build a set of indicies which you use to make the polygons (add_polygon).

      This sounds great.

      I was relying on building nested arrays/Hashes for storing hiearchies of polygonial-Points to build geometry, but PolygonMesh.class seams more suitable to the task.
      Completely overlooked.
      Wasent such a big deal in the beggining dealing with only 1 "mesh-points object", but multiple objects starting to make the array lookups nastier.
      See there are som nice API methods in there as well for looking up polygons, quickly. No digging..

      I persume Calling methods (polygons & Points) to Polygonmesh.class is a Little faster than using Ruby Array/Hash lookups as well ? Since I gather they are dealt in C ?

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      Cheers!

      Will definately try fill_from_mesh later. I'm experiencing same thing as you, poly_mesh.add_polygon works fine for a while but times adds up exponentially when geometry gets denser.

      In my case I'm storing Points in nested arrays. Might not be optimal to do so.
      Saw some benchmark at StackOFLW from Array VS Hash lookups, and there where quite some difference in speed there.

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Learning Ruby by Writing a Working Shell?

      It could be the if statement your using assignment instead of comparison ?
      = to ==

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      @unknownuser said:

      I've got the fill_from_mesh code working and I can now generate the handrail in 0.326 seconds and this is using commit with the disable UI argument.

      πŸ‘

      Fill_from_mesh, huh ? I'll try to switch to that.

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      Ahh, my misstake. The handrail looked like pushpulled geometry with some boolean operation done on it. Nicely done creating that from code πŸ˜„

      I Believe Thomas is right(as usual) on the money about ordering Points.
      And yeah, I think he means clockwise / counter clockwise for the faces outer loop.
      That determines the face normal direction.

      If you do a pushpull in Sketchup you are moving in the "normal direction. Does that explain?

      Maybe he should continue further the explaination..

      Meanwhile, here's some code that creates mesh from Points. Ripped out
      some code I'm using for some tests..

      I believe fill from mesh is faster, but this is what I have for now..
      Wont work with faces with holes..

      model.start_operation("create_mesh", true)
      	
      #polygns is array with arrays of Polygonal Points.
      		
      poly_mesh = Geom;;PolygonMesh.new
      
      for plg in polygns do poly_mesh.add_polygon(plg.to_a) end
      
      mesh_group = Sketchup.active_model.active_entities.add_group
      mesh_group.entities.add_faces_from_mesh(poly_mesh)
      
      #Some smoothing..
      for e in mesh_group.entities 
      	if e.class==Sketchup;;Edge and e.faces.length==2 ###***
      		ang=e.faces[0].normal.angle_between(e.faces[1].normal)
      		e.soft=false if ang > 20.degrees
      		e.smooth=false if ang > 20.degrees
      	end
      end
      
      model.commit_operation
      
      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      Glad it worked!

      About reversed faces. Always difficult to decide what to reverse or not. Especially when dealing with that complicated type of geometry.

      If aligned to axes one could Always use something like: face.reverse! if face.normal.z <= 0 (for ground flat faces)

      But it doesent look like that would work in your case..

      Are you doing a pushpull ?

      One sketchy idea is that if you know that an operation will lead to reversed faces . Collect faces Before operation and reverse all but Collection..
      You would have to collect all faces after operation and minus Array..

      I Think there is an "Orient-faces" script from TIG there somewhere you could look at.

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Co planar test

      maybe fit plane from 3 Points and check if Points are on plane ?

      http://www.sketchup.com/intl/en/developer/docs/ourdoc/geom.php?hl=sv-SE

      posted in Developers' Forum
      jolranJ
      jolran
    • RE: Triangulate triangles ?

      I Think you could use the circumcentre as well, for skewed triangles.. Maybe that's what Pilou is trying to Point out.

      Here's some code I'm using for that. You might have to rewrite it to fit your needs..
      I just ripped it out from a plugin I'm working on..

      # Arguments need 3 point3D objects from triangle.
      def points3_circumC(p1,p2,p3) #(Only 2 lines is actually needed for calculation)
      	
      	#Init Vectors for calculation.
      	vec1  = p1.vector_to(p2) 
      	vec2  = p1.vector_to(p3) 
      	fakeZ = vec1.cross(vec2) #cross Plane...
      	#midpoints
      	mp1 = p1.offset(vec1, vec1.length/2)
      	mp2 = p1.offset(vec2, vec2.length/2)
      	#cross vectors..
      	vec1 = vec1.cross(fakeZ)
      	vec2 = vec2.cross(fakeZ)
      	#lines
      	line1 = [mp1, vec1]
      	line2 = [mp2, vec2]
      	return c = Geom.intersect_line_line(line1, line2) #point3D
      end
      

      edit: Ehh.. looks like TIG already bashed out a working plugin for this.

      posted in Plugins
      jolranJ
      jolran
    • RE: Donation to Dan Rathbun

      get well. + Some more cash..

      posted in Corner Bar
      jolranJ
      jolran
    • 1
    • 2
    • 13
    • 14
    • 15
    • 16
    • 17
    • 51
    • 52
    • 15 / 52