Add_polygon seems very slow
-
Hi guys, I want to ask if there is something faster than add_polygon, I see much difference when I commented the lines 15 and 16. with this pair of lines becomes 130 times slower!
seems that the command "add_poligon" does something very complicated or is very inefficient or I'm using it in the wrong way
in the following code I make a rectangle subdivided;t = Time.now lados_x = 100 lados_y = 100 mesh = Geom;;PolygonMesh.new((lados_x+1)*(lados_y+1),lados_x*lados_y) l1 = [] for i in 0..lados_x l1[i] = Geom;;Point3d.new(i,0,0) end l2 = [] for j in 1..lados_y for k in 0..lados_x l2[k] = Geom;;Point3d.new(k,j,0) end for i in 0..lados_x-1 #mesh.add_polygon l1[i], l1[i+1], l2[i+1] #mesh.add_polygon l1[i], l2[i+1], l2[i] end l1 = l2.clone end =begin ent=Sketchup.active_model.active_entities grupo = ent.add_group entities = grupo.entities entities.fill_from_mesh mesh, true, 0 =end Time.now-t
Does anyone have any suggestions?
(google translator)
-
The problem is you are using Point3d arguments - this means each call to add_polygon needs to call add_point three times. You can add all the points beforehand and then use their index to add the polygons. This should add a significant speed boost.
Here's the code:
t = Time.now lados_x = 100 lados_y = 100 mesh = Geom;;PolygonMesh.new((lados_x+1)*(lados_y+1),lados_x*lados_y) l1 = [] for i in 0..lados_x l1[i] = mesh.add_point(Geom;;Point3d.new(i,0,0)) end l2 = [] for j in 1..lados_y for k in 0..lados_x l2[k] = mesh.add_point(Geom;;Point3d.new(k,j,0)) end for i in 0..lados_x-1 mesh.add_polygon l1[i], l1[i+1], l2[i+1] mesh.add_polygon l1[i], l2[i+1], l2[i] end l1 = l2.clone end ent=Sketchup.active_model.active_entities grupo = ent.add_group entities = grupo.entities entities.fill_from_mesh mesh, true, 0 puts Time.now-t
-
!woooow this reduces the time to less than one-third!
thank you very much Daniel!
-
Also, if you ever need PolygonMesh.point_index http://www.sketchup.com/intl/en/developer/docs/ourdoc/polygonmesh#point_index - don't use it. It's slow. Instead, store the point and index you get from PolygonMesh.add_point into a hash and it'll be much much faster.
And, if you are adding the geometry to an Entities collection that has no other entities in it, use Entities.fill_from_mesh as it's faster.
-
Thanks for the tips Thom, this will be very useful at some time
I have a question, how can get the vertices of this surface?
-
Ah, very good question. I've been struggling with that myself. Trying to compare and map based on position - but floating precision might cause problems.
-
Ok - here is a bare bone test:
https://gist.github.com/thomthom/5160068 -
@thomthom said:
Ah, very good question. I've been struggling with that myself. Trying to compare and map based on position - but floating precision might cause problems.
In your code you have:
%(#008000)[# Because Geom::Point3d objects cannot be compared ...]
.. BUT the API overrides the==()
method for theGeom::Point3d
class, that WILL test the objects co-ordinates within SketchUp's internal tolerance.Also...
Sketchup::Vertex.position
returns aGeom::Point3d
Geom::Point3d.x
(.y
and.z
) all returnLength
class objects, ...
and ALL of the comparison methods for theLength
class have been overridden to use SketchUp's internal tolerance.BTW, the
Sketchup::Vertex
class could use a wrapper:class Sketchup;;Vertex def ==(other) return false unless other.is_a?(self.class) return false unless other.position.is_a?(Geom;;Point3d) self.position == other.position end end
-
@thomthom said:
` %(#008000)[# What what if you generate a mesh, then add it to SketchUp - is there a
chance that SketchUp slightly adjusts the points within it's tolerance range
in order to merge vertices etc?]`
Should the general rule of thumb be to use arrays of
Length
objects to buildGeom::Point3d
objects, rather than arrays ofFloat
objects ?? -
@dan rathbun said:
@thomthom said:
Ah, very good question. I've been struggling with that myself. Trying to compare and map based on position - but floating precision might cause problems.
In your code you have:
%(#008000)[# Because Geom::Point3d objects cannot be compared ...]
.. BUT the API overrides the==()
method for theGeom::Point3d
class, that WILL test the objects co-ordinates within SketchUp's internal tolerance.@dan rathbun said:
@thomthom said:
` %(#008000)[# What what if you generate a mesh, then add it to SketchUp - is there a
chance that SketchUp slightly adjusts the points within it's tolerance range
in order to merge vertices etc?]`
Should the general rule of thumb be to use arrays of
Length
objects to buildGeom::Point3d
objects, rather than arrays ofFloat
objects ??Ah yea - I meant to clean up that comment. It is misleading. What I actually had in mind was what happens when you use Geom::Point3d as a key in a hash - if you create a Point3d object with the exact same values the hash is different.
-
thank you very much for the replies dan and Thomthom, I'll take a look at the code Thomthom experimental, to see if I can use some of this code
(google translator)
Advertisement