[OpenSCAD] Improve rendering speed

wolf wv99999 at gmail.com
Thu Jun 9 05:29:52 EDT 2016


I am now in a position to quantify my claims about improved rendering speed.
Parkinbot  published <http://www.thingiverse.com/thing:648813>  has 
published a routine to generate a coil. When set to 200 slices per winding
and 10 windings, this routine renders on my machine in 52 minutes. The
equivalent coil, also having 2000 slices, renders in 11 seconds using my
approach:

// Reverse Slicer
// build a complex shape from user definable functions
// as a faster alternative to multiple unions


// Start user definable data
$fn=100;
Slices=2000;
SliceAngle=[for( i=[0:1:Slices-1]) 1.8*i];         // angle by which each
slice is tilted
SlicePosition=[for( i=[1:1:Slices]) [0.125*i,50,0]];       // position of
each slice relative to origin
SliceRadius=[for( i=[1:1:Slices]) 10];
function CircularSlice(r=1)=[let(Step=360/$fn)  for( i=[0:1:$fn-1])
[r*cos(i*Step),r*sin(i*Step),0]]; // returns a list of vertices, called a
slice, centered around the origin, by which a circle of radius r and height
0 will be approximated
// End user definable data


// Start shape generating list
VertexList=flatten([for( i=[0:1:Slices-1]) 
 
TiltSlice_X(MoveSlice(CircularSlice(SliceRadius[i]),SlicePosition[i]),SliceAngle[i])]);    
// list of all vertices needed to construct shape
EndFace1=[for( i=[2:1:$fn-1]) [0,i-1,i]];                                //
list of all triangular faces needed to close shape at one end
EndFace2=[let(F=(Slices-1)*$fn) for( i=[F:1:F+$fn-3]) [F,i+2,i+1]];      //
list of all triangular faces needed to close shape at other end
SideFaces=flatten([for( i=[0:1:$fn-1]) for( k=[0:1:Slices])
[[i+k*$fn,(i+$fn)+k*$fn,((i+1)%$fn)+k*$fn],[((i+1)%$fn)+k*$fn,(i+$fn)+k*$fn,((i+1)%$fn+$fn)+k*$fn]]
]); 
FacesList=concat(EndFace1,SideFaces,EndFace2);                      // list
of all faces needed to close shape

function flatten(l) = [ for (a = l) for (b = a) b ] ;                                                              
// remove brackets
function ExtractSlice(List,Element)=flatten([for( i=Element) List[i]]);                                             
// extract a vector from a slice
function TiltSlice_X(Sl,A) = [for( i=[0:1:$fn-1]) let (v=ExtractSlice(Sl,i))
[v[0], v[1]*cos(A), v[1]*sin(A)]];         // tilt slice around x axis
function MoveSlice(Sl,SP) = [for( i=[0:1:$fn-1]) let (v=ExtractSlice(Sl,i))
[v[0]+SP[0], v[1]+SP[1], v[2]+SP[2] ]];   // move slice to SP=[x,y,z]
// End shape generating list


polyhedron(VertexList,FacesList); 

Except for the increase in speed, my approach also does away with the need
to have a faces list. A few extra brackets in the VertexList is all it takes
for the computer to be able to generate the faces list by itself. But it
also exposes shortcomings in the language: nested lists can currently be
read only one level deep, and thus I was forced to develop,  with function
ExtractSlice, the ability to access deeper nesting levels.
The current implementation has only two nesting levels and thus cannot
handle holes. By adding a third nesting level, I expect that holes can also
be accomodated.
Vertices, innermost nesting level, contains a list of numbers to define a
vertex.
Slices, second nesting level, contains the list of all vertices belonging to
a slice.
Groups of slices, third nesting level: counting from the outside, the first
slice represents material, the second a hole, the third material, etc. That
this works will have to be demonstrated, though.

Thanks, Ronaldo, for pointing out that my approach is not quite new. Were
you aware of the gains in rendering speed that are achieved using this
approach over the more conventional approach of using unions() or hulls()?
Or that the faces list can be computer generated and need not be provided by
the user?

Parkinbot, I have difficulties understanding what you mean: what properties
does a polygon need to have that you will call it simple? Can you explain?
Self-intersection is not a problem for me, as I design by eye, and my eye
will pick up any funny shapes immediately. Whether self-intersection is a
problem with CGAL remains to be seen, as at some stage I will have to try to
design a Klein bottle in OpenSCAD. If CGAL is true to its mathematical
roots, then I do not foresee any problem in constructing the bottle, nor do
I foresee restrictions regarding convex or concave slices. 
Lastly, what do you mean with "because z-coordinate of a 3D shape cannot be
quested in current OpenSCAD to grand for non-interscection" With "quested" I
suppose you wanted to write "queried", but what in a Palainian hell is "to
grand" supposed to mean?

wolf






--
View this message in context: http://forum.openscad.org/Improve-rendering-speed-tp17580p17613.html
Sent from the OpenSCAD mailing list archive at Nabble.com.




More information about the Discuss mailing list