Profiling of hull- and cylinder-based line drawings

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Profiling of hull- and cylinder-based line drawings

runsun
Following a discussion on line drawing algorithm in other thread, I decided to do a profiling to check the speed of hull() in comparison to that of a cylinder-based one when used in drawing lines of multi-segments.

The cylinder-based one is the Line() here. The hull-based is named Rod(), made by replacing the cylinder part of Line()
   v = pts[i+1]-pts[i]; 
   L = norm(v); 
   if( L > 1e-12) 
     translate(pts[i]) 
     rotate([0, acos(v[2]/L), atan2(v[1],v[0])]) 
     rotate(45) cylinder(h=L, r=r, $fn=fn); 
with hull:
 hull()
       { translate( pts[i] ) sphere(r);
         translate( pts[i+1] ) sphere(r);
       } 
(See the full code in the end)

Data points of various lengths are generated randomly in advance and saved and named pts20(20 pts), pts30 ... etc so they are not re-generated anew in each test. The drawing of pts100 looks like this:


Data length tested are: 20,30,40,50,75,100. Each test is performed with 3 steps: [Flush Cache]+[Preview]+[Render], and repeated at least once. The time (in sec) required is recorded. The time for [preview] is 0 for all tests conducted, so it is not displayed in the following table :

  n   Rod  Line Line Rod   
 20     7   2     2     7
 30    13   4     4    13
 40    20   8     8    20
 50    27   9     9    25
 75    69   25    25   67 
100   101   35    35   101
100   100   36    36   99 (* 2 sets of pts100 are used)
In average, Line (cylinder-based) is about 3 times faster than Rod (hull-based) in rendering.



The [Preview] time is 0 sec in all cases above. However, a quick check (on [Preview] only) with larger # of pts shows that, for [Preview], Line (cylinder-based) has a huge advantage, as much as ~50 times faster when n reaches 2000. This confirms the previous observation that it has an efficiency the hull-based approach can't compete:
    n   Rod  Line 
  500    12   0     
 1000    24   0    
 2000    47   1    
 
Below is the code for this test. Data points up to pts50 are included.
module Line( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )
{
  if(len(pts)>1 && len(pts[0])>1 && r>0) 
  { 
    // Convert to 3d if 2d; Attach 1st pt if closed
    pts  = concat( [for(p=pts) [ p[0],p[1],p[2]==undef?0:p[2] ]],  
                  closed? [[ pts[0][0], pts[0][1], pts[0][2]==undef?0:pts[0][2] ]] : []
    ); 
    color(color,transp)
    for(i=[0:len(pts)-2]) 
    { 
       v = pts[i+1]-pts[i]; 
       L = norm(v); 
       if( L > 1e-12) 
         translate(pts[i]) 
         rotate([0, acos(v[2]/L), atan2(v[1],v[0])]) 
         rotate(45) cylinder(h=L, r=r, $fn=fn); 
    } 
  } 
}

module Rod( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )
{
  if(len(pts)>1 && len(pts[0])>1 && r>0) 
  { 
    // Convert to 3d if 2d; Attach 1st pt if closed
    pts  = concat( [for(p=pts) [ p[0],p[1],p[2]==undef?0:p[2] ]],  
                  closed? [[ pts[0][0], pts[0][1], pts[0][2]==undef?0:pts[0][2] ]] : []
    ); 
    color(color,transp)
    for(i=[0:len(pts)-2]) 
    { 
       hull()
       { translate( pts[i] ) sphere(r);
         translate( pts[i+1] ) sphere(r);
       }   
    } 
  } 
}

module Rod_test(){ Rod(pts50); } //Rod_test();
module Line_test(){Line(pts50); } //Line_test();

pts20= [[-0.59, 0.78, 0.9], [1.31, -0.99, 1.34], [0.82, -2.75, -2.79], [-2.64, 2.15, -1.27], [0.33, 0.39, 1.29], [0.74, 0.84, -2.01], [2, -1.28, -1.37], [2.66, -1.58, -0.57], [-1.01, 0.39, -1.52], [-1.79, 2.68, -0.63], [2.48, -1.23, -1.02], [0.81, 0.55, 1.15], [-0.43, -0.99, -1.55], [0.27, 0.76, -0.85], [-2.21, -2.16, 2.34], [-2.98, 0.91, 0.8], [-2.47, 2.03, -2.25], [1.88, -2.05, 1.42], [0.94, 2.11, 2.74], [-1.47, -0.3, -2.18]];
pts30= [[2.86, -0.25, -0.93], [2.22, -0.59, -0.58], [-1.46, 1.22, 1.27], [1.11, -2.13, -2.58], [-2.25, 1.22, -0.93], [-2.01, -2.3, 0.05], [-1.34, 1.42, -1.56], [0.04, 1.35, 1.4], [-0.93, -2.72, -2.12], [-1.58, 1.89, -2.59], [1.19, 0.67, 1.13], [-2.07, 2.35, -2.66], [0.05, 1.51, 0.88], [0.84, 2.7, -0.85], [-2.3, 1.58, -0.04], [-2.4, -2.63, 1.54], [0.97, 2.65, -1.5], [1.68, -0.96, -1.1], [-0.65, -1.87, -1.2], [2.02, 0.03, -2.13], [1.56, -2.42, 1.37], [-2.41, 1.45, 2.88], [1.87, 2.7, 2.65], [1.1, -0.98, -0.72], [2.32, 1, 2.11], [2.35, 2.92, -1.23], [-1.85, 0.12, -2.23], [1.43, -0.43, -1.1], [0.05, 2, 0.18], [-1.43, -2.28, -1.07]];
pts40= [[0.65, -0.85, -1.26], [2.68, 0.92, 0.53], [-0.47, -0.41, 1.79], [0.71, 1.8, 0.06], [-1.41, -0.44, -1.38], [-2.56, 2.24, 2.09], [1.26, 0.81, 1.46], [2.58, 2.74, -1.24], [-0.99, 2.69, 2.79], [-2.6, -2.55, 2.61], [1.87, -2.7, 0.78], [0.6, -0.44, -1.15], [2.13, -2.8, 1.57], [0.43, -0.25, -1.23], [-1.86, -0.88, 1.92], [1.35, 2.12, -1.8], [2.86, -2.28, -1.54], [2.13, 0.39, 2.95], [-2.54, -0.83, 1.74], [0.99, 1.92, 2.12], [2.23, -0.07, -0.97], [-0.65, -2.04, -0.24], [0.12, -0.98, -1.86], [1.21, -2.97, 2.76], [-1.1, 2.8, -1.98], [-0.37, 0.89, 0.66], [0.5, 0.71, -2.12], [0.01, 0.58, -2.14], [1.05, -1.34, -0.4], [1.63, -0.26, -2.35], [-2.76, -0.57, 1.94], [-0.14, -0.12, -0.66], [-1.88, 0, 0.95], [1.14, -0.9, 2.26], [1.03, -2.49, -0.23], [-2.07, -1.56, -0.47], [-2.81, 2.79, -1.22], [-0.74, 1.71, -1.49], [2.74, 0.29, 2.56], [-0.14, 1.51, 0.45]];
pts50= [[2.83, 2.08, 0.25], [-0.56, -0.02, -0.5], [2.12, -2.13, 0.42], [2.24, -0.67, -2.29], [1.24, 1.57, -1.1], [0.02, 1.41, -0.99], [-0.28, 1.73, -1.53], [-0.15, 1.15, -0.93], [-2.24, 0.09, 1.88], [2.44, 2.64, 0.61], [0.02, -1.33, 1.46], [2.11, -1.09, -0.36], [2.51, -1.51, -2.86], [-0.84, -2.48, 1.62], [1.09, -0.98, 0.99], [2.32, -1.3, -0.26], [-1.95, 2.21, 1.61], [0.1, 1.95, -1.55], [-0.32, 2.1, 1.08], [-2.76, -0.97, 0.09], [-1.48, 1.54, -1.97], [-1.42, 0.4, 1.96], [1.73, 0.42, 2.55], [2.47, 0.34, -2.51], [-1.52, -0.45, 0.02], [0.81, 0.16, -1.28], [-0.62, 0.43, -1.93], [0.06, -1.16, -1.74], [2.18, 0.38, 2.95], [1.17, 1.78, 1.54], [-2.54, 1.92, -0.96], [0.44, -1.65, -2.2], [0.85, -2, 0.64], [-2.76, -2.46, 2.23], [-1.08, 0.49, -2.18], [-2.35, -0.96, 1.39], [-2.1, 1.23, -2.87], [1.44, -1.32, -0.35], [-0.91, -1.3, 2.02], [-2.72, 0.03, -1.44], [-0.08, 1.6, -2.02], [-0.94, 0.1, 0.92], [-2.5, -1.61, 2.76], [0.81, 1.48, -1.68], [-0.55, 0.81, 2.94], [1.17, -2.06, 2.49], [-1.22, 0.62, 1.39], [2.41, 1.74, 2.82], [1.93, 0.8, -1.87], [-0.67, -0.63, -0.12]];
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

nophead
I think you are comparing apples to pears. Without the hull() the preview does nothing but draw the cylinders on top of each other. With the hull() the actual hull has to be computed because OpenCSG cannot fake it like it can with union() and differences(). Not sure if CGAL is involved there to union the spheres first or not.

On Thu, 10 Jan 2019 at 18:48, runsun <[hidden email]> wrote:
Following a discussion on line drawing algorithm in other thread, I decided to do a profiling to check the speed of hull() in comparison to that of a cylinder-based one when used in drawing lines of multi-segments.

The cylinder-based one is the Line() here. The hull-based is named Rod(), made by replacing the cylinder part of Line()
   v = pts[i+1]-pts[i]; 
   L = norm(v); 
   if( L > 1e-12) 
     translate(pts[i]) 
     rotate([0, acos(v[2]/L), atan2(v[1],v[0])]) 
     rotate(45) cylinder(h=L, r=r, $fn=fn); 
with hull:
 hull()
       { translate( pts[i] ) sphere(r);
         translate( pts[i+1] ) sphere(r);
       } 
(See the full code in the end)

Data points of various lengths are generated randomly in advance and saved and named pts20(20 pts), pts30 ... etc so they are not re-generated anew in each test. The drawing of pts100 looks like this:


Data length tested are: 20,30,40,50,75,100. Each test is performed with 3 steps: [Flush Cache]+[Preview]+[Render], and repeated at least once. The time (in sec) required is recorded. The time for [preview] is 0 for all tests conducted, so it is not displayed in the following table :

  n   Rod  Line Line Rod   
 20     7   2     2     7
 30    13   4     4    13
 40    20   8     8    20
 50    27   9     9    25
 75    69   25    25   67 
100   101   35    35   101
100   100   36    36   99 (* 2 sets of pts100 are used)
In average, Line (cylinder-based) is about 3 times faster than Rod (hull-based) in rendering.



The [Preview] time is 0 sec in all cases above. However, a quick check (on [Preview] only) with larger # of pts shows that, for [Preview], Line (cylinder-based) has a huge advantage, as much as ~50 times faster when n reaches 2000. This confirms the previous observation that it has an efficiency the hull-based approach can't compete:
    n   Rod  Line 
  500    12   0     
 1000    24   0    
 2000    47   1    
 
Below is the code for this test. Data points up to pts50 are included.
module Line( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )
{
  if(len(pts)>1 && len(pts[0])>1 && r>0) 
  { 
    // Convert to 3d if 2d; Attach 1st pt if closed
    pts  = concat( [for(p=pts) [ p[0],p[1],p[2]==undef?0:p[2] ]],  
                  closed? [[ pts[0][0], pts[0][1], pts[0][2]==undef?0:pts[0][2] ]] : []
    ); 
    color(color,transp)
    for(i=[0:len(pts)-2]) 
    { 
       v = pts[i+1]-pts[i]; 
       L = norm(v); 
       if( L > 1e-12) 
         translate(pts[i]) 
         rotate([0, acos(v[2]/L), atan2(v[1],v[0])]) 
         rotate(45) cylinder(h=L, r=r, $fn=fn); 
    } 
  } 
}

module Rod( pts, r=0.05, closed=false, color=undef, transp=1, fn=4 )
{
  if(len(pts)>1 && len(pts[0])>1 && r>0) 
  { 
    // Convert to 3d if 2d; Attach 1st pt if closed
    pts  = concat( [for(p=pts) [ p[0],p[1],p[2]==undef?0:p[2] ]],  
                  closed? [[ pts[0][0], pts[0][1], pts[0][2]==undef?0:pts[0][2] ]] : []
    ); 
    color(color,transp)
    for(i=[0:len(pts)-2]) 
    { 
       hull()
       { translate( pts[i] ) sphere(r);
         translate( pts[i+1] ) sphere(r);
       }   
    } 
  } 
}

module Rod_test(){ Rod(pts50); } //Rod_test();
module Line_test(){Line(pts50); } //Line_test();

pts20= [[-0.59, 0.78, 0.9], [1.31, -0.99, 1.34], [0.82, -2.75, -2.79], [-2.64, 2.15, -1.27], [0.33, 0.39, 1.29], [0.74, 0.84, -2.01], [2, -1.28, -1.37], [2.66, -1.58, -0.57], [-1.01, 0.39, -1.52], [-1.79, 2.68, -0.63], [2.48, -1.23, -1.02], [0.81, 0.55, 1.15], [-0.43, -0.99, -1.55], [0.27, 0.76, -0.85], [-2.21, -2.16, 2.34], [-2.98, 0.91, 0.8], [-2.47, 2.03, -2.25], [1.88, -2.05, 1.42], [0.94, 2.11, 2.74], [-1.47, -0.3, -2.18]];
pts30= [[2.86, -0.25, -0.93], [2.22, -0.59, -0.58], [-1.46, 1.22, 1.27], [1.11, -2.13, -2.58], [-2.25, 1.22, -0.93], [-2.01, -2.3, 0.05], [-1.34, 1.42, -1.56], [0.04, 1.35, 1.4], [-0.93, -2.72, -2.12], [-1.58, 1.89, -2.59], [1.19, 0.67, 1.13], [-2.07, 2.35, -2.66], [0.05, 1.51, 0.88], [0.84, 2.7, -0.85], [-2.3, 1.58, -0.04], [-2.4, -2.63, 1.54], [0.97, 2.65, -1.5], [1.68, -0.96, -1.1], [-0.65, -1.87, -1.2], [2.02, 0.03, -2.13], [1.56, -2.42, 1.37], [-2.41, 1.45, 2.88], [1.87, 2.7, 2.65], [1.1, -0.98, -0.72], [2.32, 1, 2.11], [2.35, 2.92, -1.23], [-1.85, 0.12, -2.23], [1.43, -0.43, -1.1], [0.05, 2, 0.18], [-1.43, -2.28, -1.07]];
pts40= [[0.65, -0.85, -1.26], [2.68, 0.92, 0.53], [-0.47, -0.41, 1.79], [0.71, 1.8, 0.06], [-1.41, -0.44, -1.38], [-2.56, 2.24, 2.09], [1.26, 0.81, 1.46], [2.58, 2.74, -1.24], [-0.99, 2.69, 2.79], [-2.6, -2.55, 2.61], [1.87, -2.7, 0.78], [0.6, -0.44, -1.15], [2.13, -2.8, 1.57], [0.43, -0.25, -1.23], [-1.86, -0.88, 1.92], [1.35, 2.12, -1.8], [2.86, -2.28, -1.54], [2.13, 0.39, 2.95], [-2.54, -0.83, 1.74], [0.99, 1.92, 2.12], [2.23, -0.07, -0.97], [-0.65, -2.04, -0.24], [0.12, -0.98, -1.86], [1.21, -2.97, 2.76], [-1.1, 2.8, -1.98], [-0.37, 0.89, 0.66], [0.5, 0.71, -2.12], [0.01, 0.58, -2.14], [1.05, -1.34, -0.4], [1.63, -0.26, -2.35], [-2.76, -0.57, 1.94], [-0.14, -0.12, -0.66], [-1.88, 0, 0.95], [1.14, -0.9, 2.26], [1.03, -2.49, -0.23], [-2.07, -1.56, -0.47], [-2.81, 2.79, -1.22], [-0.74, 1.71, -1.49], [2.74, 0.29, 2.56], [-0.14, 1.51, 0.45]];
pts50= [[2.83, 2.08, 0.25], [-0.56, -0.02, -0.5], [2.12, -2.13, 0.42], [2.24, -0.67, -2.29], [1.24, 1.57, -1.1], [0.02, 1.41, -0.99], [-0.28, 1.73, -1.53], [-0.15, 1.15, -0.93], [-2.24, 0.09, 1.88], [2.44, 2.64, 0.61], [0.02, -1.33, 1.46], [2.11, -1.09, -0.36], [2.51, -1.51, -2.86], [-0.84, -2.48, 1.62], [1.09, -0.98, 0.99], [2.32, -1.3, -0.26], [-1.95, 2.21, 1.61], [0.1, 1.95, -1.55], [-0.32, 2.1, 1.08], [-2.76, -0.97, 0.09], [-1.48, 1.54, -1.97], [-1.42, 0.4, 1.96], [1.73, 0.42, 2.55], [2.47, 0.34, -2.51], [-1.52, -0.45, 0.02], [0.81, 0.16, -1.28], [-0.62, 0.43, -1.93], [0.06, -1.16, -1.74], [2.18, 0.38, 2.95], [1.17, 1.78, 1.54], [-2.54, 1.92, -0.96], [0.44, -1.65, -2.2], [0.85, -2, 0.64], [-2.76, -2.46, 2.23], [-1.08, 0.49, -2.18], [-2.35, -0.96, 1.39], [-2.1, 1.23, -2.87], [1.44, -1.32, -0.35], [-0.91, -1.3, 2.02], [-2.72, 0.03, -1.44], [-0.08, 1.6, -2.02], [-0.94, 0.1, 0.92], [-2.5, -1.61, 2.76], [0.81, 1.48, -1.68], [-0.55, 0.81, 2.94], [1.17, -2.06, 2.49], [-1.22, 0.62, 1.39], [2.41, 1.74, 2.82], [1.93, 0.8, -1.87], [-0.67, -0.63, -0.12]];
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
@nophead, I don't see your statement is valid. The comparison is to check how
efficient an approach is for the user to see the same result. It doesn't
matter how OpenSCAD works it out behind the scene.  



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

nophead
Hull is much faster than union but in preview unions are faked so it appears slower. In all my previews I render everything, so for me Hull is much faster. 

On Thu, 10 Jan 2019, 20:23 runsun <[hidden email] wrote:
@nophead, I don't see your statement is valid. The comparison is to check how
efficient an approach is for the user to see the same result. It doesn't
matter how OpenSCAD works it out behind the scene. 



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
nophead wrote
> Hull is much faster than union but in preview unions are faked so it
> appears slower. In all my previews I render everything, so for me Hull is
> much faster.

mmmhhh ... not sure how you conclude that but it's shown in my test that in
average hull is 3 times slower in rendering.




-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

nophead
By "render" I mean render() { } around all my top level objects. So they are all calculated by CGAL and then coloured and displayed as polyhedra in OpenCSG. Union is definitely at least and order of magnitude slower than hull().

On Thu, 10 Jan 2019 at 22:14, runsun <[hidden email]> wrote:
nophead wrote
> Hull is much faster than union but in preview unions are faked so it
> appears slower. In all my previews I render everything, so for me Hull is
> much faster.

mmmhhh ... not sure how you conclude that but it's shown in my test that in
average hull is 3 times slower in rendering.




-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
My test code is designed to differ ONLY on the part limited to hull vs
cylinder. That's the very first thing I mentioned in the post. There's no
"union" anywhere, and if an implicit union is performed it would have been
performed on both Line() and Rod().

From your responses it seems to me that you made the judgement without
actually checking out my test or code to understand what the test is about.

The test code and data are all there so whoever interested is welcome to
check it out.

nophead wrote
> By "render" I mean render() { } around all my top level objects. So they
> are all calculated by CGAL and then coloured and displayed as polyhedra in
> OpenCSG. Union is definitely at least and order of magnitude slower than
> hull().





-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

Ronaldo
In reply to this post by runsun
Em qui, 10 de jan de 2019 às 18:48, runsun <[hidden email]> escreveu:
In average, Line (cylinder-based) is about 3 times faster than Rod (hull-based) in rendering

runsun,

Your test code deludes. The cylinder in Line have 8 vertices and the spheres in Rod have 15 vertices. The hull of the two spheres have 20 vertices. To be fair the Line cylinders should be defined with $fn = 10 and not the default of 4. (alternatively we could hull cubes instead of spheres in Rod.)

I have tested your code using fair cylinders ($fn=10) in Line, Rod as is and a third case where the hull in Rod is dropped. I got the following times with F6:
        Rod     Line   Rod w/o hull
PT30    15        25       8
PT50    30        56      15

Should we conclude that Line is 70% slower than Rod? Certainly not. The (implicit) union deals with distinct objects in those cases and it consumes much more time than the hull. To evaluate the hulling time we have to discard the union and go to the preview.

With F5, we have a very different framework and a new test is needed. In Rod, I preceded the hull() with render(). And used the following test code:

N = 2000;
seed = 181;
rnd = rands(-3,3,3*N, seed);
pts = [ for(i=[0:N-1]) 
          [ rnd[3*i], rnd[3*i+1], rnd[3*i+2] ] ];
//Rod(pts);
//Line(pts);

I have found out the following times with F5:

  N        Rod     Line
1000        7        0  
2000       15        0  
4000       28        1  

As preview uses a fake union, the Rod times express essentially the hulling time. And, yes, it is much greater than the time to preview cylinders. The hull() operation in Rod spends 7ms per rod. And we may conclude that Rod with F6 spends around 350ms with the hull of pts50 and 30sec with their union, confirming what nophead has said.



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
Ronaldo, Thx for checking the test code. I have been wondering that the
discrepancy (between me and you guys) could be due to the lack of knowledge
on my part. But (to me) it's hard to explore that without verifying the
validity of the test code.

A quick question before I do more tests with the code as you corrected it:
both you and nophead argue that the *Line()* approach requires a *union()*
which makes it slower. It implies that the approach in *Rod()*, which uses a
hull() to generate multiple segments, does NOT require or go through a
union() during rendering. Is this correct? Note that they (Line and Rod)
both generate multiple segments of objects.  
 



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

Ronaldo
An implicit union is present in both codes of Line and Rod. Under F6, as the union process time is much greater than the hull, it is irrelevant if you make the sticks with cylinders or hulling spheres. Under F5 and with a great number of sticks, there is an efficiency difference as the implicit union is faked by a fast process. My general use Line uses cylinders and I apply it just in previews. To illustrate something here in the forum I define line with hull because it is a simpler and smaller code.

Em sex, 11 de jan de 2019 às 19:36, runsun <[hidden email]> escreveu:
Ronaldo, Thx for checking the test code. I have been wondering that the
discrepancy (between me and you guys) could be due to the lack of knowledge
on my part. But (to me) it's hard to explore that without verifying the
validity of the test code.

A quick question before I do more tests with the code as you corrected it:
both you and nophead argue that the *Line()* approach requires a *union()*
which makes it slower. It implies that the approach in *Rod()*, which uses a
hull() to generate multiple segments, does NOT require or go through a
union() during rendering. Is this correct? Note that they (Line and Rod)
both generate multiple segments of objects.   




-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
Ronaldo wrote
> An implicit union is present in both codes of Line and Rod. Under F6, as
> the union process time is much greater than the hull, it is irrelevant if
> you make the sticks with cylinders or hulling spheres.

That makes sense. Thx.



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
In reply to this post by Ronaldo
Ronaldo wrote
> Rod as is and a third case where the hull in Rod is dropped. I got ...

Our purpose is to test the speed of line drawing. In the Rod() case, it IS
the hull() that makes it a line. By dropping the hull, the outcome is no
longer a line. Which means it is comparing a "translation of 2 pts" to a
"drawing of line." That doesn't make sense to me.





-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
Upon further studies I realized the mistakes I made in previous test.

First of all, I shouldn't have claimed it a comparison between hull and cylinder, 'cos that's a mis-representation of my intent. My intention is user experiences, in which process other than hull and cylinder also take place (including the implicit union upon rendering). By claiming it's a comparison between the two, I misled the readers. I believe that's what made the discussion between nophead and myself look like on different channels. My apology for this mistake.

A somewhat more proper claim would be "Using hull vs using cylinder," but it is still not quite there.

The second mistake is what Ronaldo points out in the test code, i.e., Rod() uses more vertices than Line() did.

A new module, Rodc(), is created by replacing the spheres with cubes :
  hull()
  { translate( pts[i] )   cube(r*2);  // <===== using cube() instead of sphere()
    translate( pts[i+1] ) cube(r*2);
  }  
This gives both Line() and Rodc() the same # of vertices to handle.

The result shows that "Using hull" is actually faster than "Using cylinder" and it's very significant :
Render Time (sec) 

n    Rod Line Rodc
20   7     2    2  
40   20    8    5
75   66   24   17
That is, a rejection to my original observations.

This is somewhat understandable (I assume), 'cos, by "hulling cubes" in Rodc(), some of the vertices from cubes are hidden inside the hulled object, while Line() needs to handle all vertices of participating cylinders. This can be verified by comparing the vertices count after rendering ( Rod: 475 , Line: 375, Rodc: 253 when # of pts = 20).

In terms of [preview], I have hard time understanding the purpose of introducing "render()" as what Ronaldo and nophead proposed. The [preview] is to see what it is, and if both with or without "render()" reaches that goal, there's no reason to add it. But again, my misleading claim might be a contributing factor to this approach.

Nonetheless, a new module Rodcr() is created by adding a "render()" before the "hull" and here is their preview times:
Preview Time (sec)

n    Rod Line Rodc Rodcr
1000  2    0   2     2
2000 10    0   3     3
It shows no effect of "render()" and also support that, in [preview], "using hull" is still slower than using the Line() approach. But this is seen with >1000 objects, so the difference would be insignificant in most cases.
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

nophead
I use render() for several reasons:

When you have a large assembly to preview, like a 3D printer, OpenCSG slows right down because it has hundreds or thousands of differences to fake. Any intersections really slow it down as well as they cause the OpenCSG products to explode. So by adding render all OpenCSG then has to do is draw lots of polyhedrons, so it draws faster and is much more responsive to the mouse. Shame it can't draw as fast as a game engine when it has no CSG ops to fake.

Another issue is that all the negative objects are drawn in OpenCSG, so if you put parts close to each other their negative objects can interfere and cause Z-fighting. With a large assembly of lots of parts this is almost inevitable with screw holes, for example.

Negative objects add the to size when View All is used, so if they are large they can make the result far too small. If you zoom too close they don't get drawn, so holes in your object can disappear.

On individual parts if you have faces that line up you get Z-fighting. I generally avoid that, but sometimes, rather than adding a small offset that might actually end up in the final part, I simply render it because CGAL can handle coincident faces, if they are exactly coincident, OpenCSG can't. When you do use a small offset it fails to stop Z-fighting if you zoom out far enough.

You don't have to worry about convexity if render is at the top level. I.e. it doesn't matter to all the operations below it because they are done with CGAL. If you have OpenCSG ops on the rendered object then you do need to set the convexity in the render.

The downside is when I open a design it can take several minutes to preview the first time. It is fast after that. I don't have render in my 3D parts, so that I can display them on their own and preview modifications quickly. I do however render them at the point of use in my assemblies. On the other hand vitamins all have a render at their top level for each colour, and so do things like polyholes that get used many times. That forces them to be cached as a polyhedron and reused.


On Sat, 12 Jan 2019 at 00:42, runsun <[hidden email]> wrote:
Upon further studies I realized the mistakes I made in previous test.

First of all, I shouldn't have claimed it a comparison between hull and cylinder, 'cos that's a mis-representation of my intent. My intention is user experiences, in which process other than hull and cylinder also take place (including the implicit union upon rendering). By claiming it's a comparison between the two, I misled the readers. I believe that's what made the discussion between nophead and myself look like on different channels. My apology for this mistake.

A somewhat more proper claim would be "Using hull vs using cylinder," but it is still not quite there.

The second mistake is what Ronaldo points out in the test code, i.e., Rod() uses more vertices than Line() did.

A new module, Rodc(), is created by replacing the spheres with cubes :
  hull()
  { translate( pts[i] )   cube(r*2);  // <===== using cube() instead of sphere()
    translate( pts[i+1] ) cube(r*2);
  }  
This gives both Line() and Rodc() the same # of vertices to handle.

The result shows that "Using hull" is actually faster than "Using cylinder" and it's very significant :
Render Time (sec) 

n    Rod Line Rodc
20   7     2    2  
40   20    8    5
75   66   24   17
That is, a rejection to my original observations.

This is somewhat understandable (I assume), 'cos, by "hulling cubes" in Rodc(), some of the vertices from cubes are hidden inside the hulled object, while Line() needs to handle all vertices of participating cylinders. This can be verified by comparing the vertices count after rendering ( Rod: 475 , Line: 375, Rodc: 253 when # of pts = 20).

In terms of [preview], I have hard time understanding the purpose of introducing "render()" as what Ronaldo and nophead proposed. The [preview] is to see what it is, and if both with or without "render()" reaches that goal, there's no reason to add it. But again, my misleading claim might be a contributing factor to this approach.

Nonetheless, a new module Rodcr() is created by adding a "render()" before the "hull" and here is their preview times:
Preview Time (sec)

n    Rod Line Rodc Rodcr
1000  2    0   2     2
2000 10    0   3     3
It shows no effect of "render()" and also support that, in [preview], "using hull" is still slower than using the Line() approach. But this is seen with >1000 objects, so the difference would be insignificant in most cases.
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Profiling of hull- and cylinder-based line drawings

runsun
Thx, nophead. That helps, a lot.



-----

$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets

--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets