Normal Hull direction vector for extruding geometry

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

Normal Hull direction vector for extruding geometry

Leo_Stef
Hi Everyone! I'm writing to You to get a little helping hand on the project
I'm involved with right now.

I'll briefly try to sum up what I'm trying to achieve and what did I manage
to do until now. First of all I'm new to openscad. I grasp the basics of it
and see its huge potential but I don't have enough knowledge to perfectly
get the result I'm looking for.

The project is about reversing gcode generated for 3d printing to get a
solid 3d model of the object passed through the slicing process. I want to
do it to perform FEM structural analysis on specimens that will be printed
in plastic and to determine the mechanical characteristics of the different
types of Infill pattern available for slicing.

So, I managed to find an openscad script which served my purpose: a
polyline3d module with hull function to simulate the linear extrusion of a
sphere through consecutive X,Y,Z points. And it works. The problem is that
the real world extrusion on a plane is not spherical but looks a bit more
like a little tiny "sausage". For this reason I've tried to modify the
polyline 3d module by substituting the sphere geometry with a sausage-like
one.

I obtained the sausage-like geometry in two ways. By adding two spheres at
the ends of a cylindrical shape or by "hulling" a sphere to the desired
length. Both ways seem to kind work out. In fact they really only work when
the hull goes the opposite direction (i.e. X axis) than the direction of
construction (i.e. Y axis) of the sausage-like geometry. If the direction of
hull (i.e. Y axis) is the same as the direction of construction (i.e. Y
axis) of the sausage-like geometry the result is no more a sausage but a
sphere. This is because i couldn't find the command or the way to tell the
program which one is normal direction of hull/extrusion from the base
geometry allowing me to obtain a consistent extrusion in all the directions,
diagonals included.

The only way to by-pass this that came to my mind was to make a double
extrusion by hulling a sausage built on the X axis and one built on the Y
axis. This way the problem is kinda solved but other problems are generated:
the calculation takes double the time (in my case is a very long time) and I
don't really know whether or how the 3d solid model generated by this two
overlapping CSGs can be affected by this ploy.

So I thought I could pass-by and ask You guys how to solve this issue of
mine. How can I set a normal direction of hull/extrusion referred to my
sausage-like geometry? There must be a way, right ?!
Here is the code to generate the hull of the sausage:
---------------------------------------------------------------------------------------

layer_height = .2;
 
layer_width = .4;
 
 module hull_polyline3d(points, layer_height) {
    leng = len(points);
     
     module hull_extrusion_unit1(layer_height){                                  
// hull method for generating the sausage geometry
        hull()
         sphere(r=layer_height);
        translate([layer_width,0,0])sphere(r=layer_height);
         }      
         
     module hull_extrusion_unit2(layer_height){
        hull()
         sphere(r=layer_height);
        translate([0,layer_width,0])sphere(r=layer_height);
         }  
         
    module hull_line3d(index) {
        point1 = points[index - 1];
        point2 = points[index];

        hull() {
            translate(point1)
                hull_extrusion_unit1(layer_height);              
            translate(point2)
                hull_extrusion_unit1(layer_height);              
        }      
       
        hull() {
            translate(point1)            
                hull_extrusion_unit2(layer_height);
            translate(point2)              
                hull_extrusion_unit2(layer_height);
        }
       
        // hook for testing
        test_hull_polyline3d_line_segment(index, point1, point2);        
    }
   
    module polyline3d_inner(index) {
        if(index < leng) {
            hull_line3d(index);
            polyline3d_inner(index + 1);
        }
    }
    polyline3d_inner(1);
}

// override it to test
module test_hull_polyline3d_line_segment(index, point1, point2) {

}
echo("This is an Extrusion Unit with LAYER_HEIGHT=", layer_height, " and
LAYER_WIDTH=", layer_width);

echo(layer_height=layer_height,layer_width=layer_width); // shortcut

----------------------------------------------------------------------------------

The last image show the hull issue mitigated by doubling the hull with the
geometry built on the other axis.

I hope the explanation was not too confusing.

Thanks so much for your priceless help.

Bless  You all.

Leo

<http://forum.openscad.org/file/t2859/Modulo_ExtrusionUnit_con_angolo_dritto_ma_pesante3.png>
<http://forum.openscad.org/file/t2859/Modulo_ExtrusionUnit_con_angolo_dritto_ma_pesante1.png>

<http://forum.openscad.org/file/t2859/Hull_issue_.png>
<http://forum.openscad.org/file/t2859/Hull_issue_mitigated_by_double_hull.png>






--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

JordanBrown
I'm not really following your description of your problem, but...

Very small gcode files have thousands of individual instructions, most of which are extrusions.  (My 1cm test cube has >500 extrusions.)  Even modest sized objects often have hundreds of thousands of individual instructions.  I would be very doubtful that OpenSCAD could handle that kind of scale.

Maybe I'm just not understanding the problem, or maybe my imagination is lacking, but I'm not coming up with any kind of "orientation" for hull operations.  A hull operation stretches a rubber balloon around the objects, so that the result is entirely concave.  I don't think there are ever multiple solutions for how to do that.

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

Re: Normal Hull direction vector for extruding geometry

adrianv
In reply to this post by Leo_Stef
I'm not sure if I understand your question, but I have two thoughts.  

1.  Would it work to simply apply scale([1,1,layerheight/layerwidth]) or
something like that to the original program?  That's going to be the
simplest way to get a squished look like a 3d printed extrusion.

2.  If you want to do this directly it sounds like the problem you're having
is that you are using two spheres to define the "sausage" geometry.  Would
it work to use one squished sphere?  So for example,

module squished() { scale([.4,.4,.2]) sphere(d=1);}

hull(){
   squished();
   translate([3,4]) squished();
}

3.  If you really need to you can do this by calculating the angle and
rotating the end shapes into the correct angle.  There is no shortcut or
simpler way: just use the atan2 function.  



--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

Leo_Stef
Thank You so much for your kind hints. Actually I managed to achieve what I
was trying to do by choosing a smarter geometry to hull: a torus! It took me
a while to realize this very simple fact. Amazing!



--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

Parkinbot
Nice approach and good solution.

this will work for a couple of paths quite well. But when it comes to a
union of hundreds of extrusion paths, an F6 build will be extremely slow in
OpenSCAD. So better keep your model simple.



--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

Ronaldo
this will work for a couple of paths quite well. But when it comes to a
union of hundreds of extrusion paths, an F6 build will be extremely slow in
OpenSCAD. So better keep your model simple. 

That is true. Why not sweep an appropriate section along all the filament paths for each layer? As each layer has a planar path, it would not be so hard to detect possible path self intersections, chopping the path accordingly. That would be a very big change in your project, increasing its complexity but rewarded by a huge gain in run time. I don't think non planar layers, as in spiral extrusions, would be hard to deal with.


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

Re: Normal Hull direction vector for extruding geometry

Parkinbot

> That is true. Why not sweep an appropriate section along all the filament
> paths for each layer?

Hmm, I also considered, whether some sweep() operations could be at least
helpful. But to my understanding two adjacent paths in a layer are usually
meant to melt together. So, they'll have to intersect more or less and a
union is unavoidable, unless you calculate the intersection which could be a
possible option.  



--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

nophead
They don't intersect because one is solid and the other liquid. What happens is the liquid filament gets deformed by being squished between the nozzle, the layer below and the adjacent filament. So you would need a sweep with different profiles depending on what is on each side and below the extrusion path and a model that caters for several possibilities.

E.g. 
An outline on the bed.
An outline on a layer below.
An outline that overhangs the layer below.
An outline that spans a bridge.
Infill on the bed bounded on no sides, one side and two sides.
Infil over a layer below bounded on no sides, one side and two sides.
Infil over a bridge bounded on no sides, one side and two sides.

These all give different shaped extrusions.

On Tue, 23 Jun 2020 at 15:21, Parkinbot <[hidden email]> wrote:

> That is true. Why not sweep an appropriate section along all the filament
> paths for each layer?

Hmm, I also considered, whether some sweep() operations could be at least
helpful. But to my understanding two adjacent paths in a layer are usually
meant to melt together. So, they'll have to intersect more or less and a
union is unavoidable, unless you calculate the intersection which could be a
possible option. 



--
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: Normal Hull direction vector for extruding geometry

Ronaldo
In reply to this post by Parkinbot
Hmm, I also considered, whether some sweep() operations could be at least
helpful. But to my understanding two adjacent paths in a layer are usually
meant to melt together. So, they'll have to intersect more or less and a
union is unavoidable, unless you calculate the intersection which could be a
possible option. 

I didn't mean to avoid all unions, just to reduce their number. Each layer would be the union of non self-intersecting sweeps and their union would be the final object. That is better than the union of each elementary linear_extrude. In a simple print without infill, we will have the union of 2 times the number of layers.

To have a comparison I have done a lazy simulation of both ways:

fh = 1;      // filament section height
lh = 1.05;  // layer height
nl = 3;      // number of layers
rad = 10;    // radius of the circular layers

module section() { circle(d=fh,$fn=20); }

module fake_sweep(rad, angle) {
  rotate_extrude(angle=angle,$fn=36)
    translate([rad,0])
       children() ;
}

module with_sweep() {
  union(){
    for(h=[0:lh:lh*(nl-1)])
      translate([0,0,h])
        union(){
          fake_sweep(rad,180) section() ;
          rotate(180)
            fake_sweep(rad,180) section() ;
        }
  }
}

module without_sweep() {
  union(){
    for(h=[0:lh:lh*(nl-1)]) {
      translate([0,0,h])
        for(ang=[0:10:360]) {
          rotate(ang)
            rotate_extrude(angle=10,$fn=1)
              translate([rad,0])
                section() ;
        }
    }
  }
}

Module fake_sweep simulates a sweep of section() along a half circular path with radius rad. In my computer, module with_sweep() runs in 16 sec. while without_sweep() requires 50  sec. It is not a huge gain as I expected. We can estimate the gain of disjoint layers by setting lh greater than the filament height lh. With lh=1.05, the module with_sweep() runs in 13 sec.

It is not unthinkable to generate one huge-sized polyhedron representing the whole print. It would be a very hard work to write a code to slice the layers in finer ones to melt them but that is all we need. 


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

Re: Normal Hull direction vector for extruding geometry

Peter Ragosch
Am Tue, 23 Jun 2020 19:47:55 +0100
schrieb Ronaldo Persiano <[hidden email]>:

> >
> > Hmm, I also considered, whether some sweep() operations could be at
> > least helpful. But to my understanding two adjacent paths in a
> > layer are usually meant to melt together. So, they'll have to
> > intersect more or less and a union is unavoidable, unless you
> > calculate the intersection which could be a
> > possible option.
> >
>
> I didn't mean to avoid all unions, just to reduce their number. Each
> layer would be the union of non self-intersecting sweeps and their
> union would be the final object. That is better than the union of
> each elementary linear_extrude. In a simple print without infill, we
> will have the union of 2 times the number of layers.
>
> To have a comparison I have done a lazy simulation of both ways:
>
>
> fh = 1;      // filament section height
> lh = 1.05;  // layer height
> nl = 3;      // number of layers
> rad = 10;    // radius of the circular layers
>
> module section() { circle(d=fh,$fn=20); }
>
> module fake_sweep(rad, angle) {
>   rotate_extrude(angle=angle,$fn=36)
>     translate([rad,0])
>        children() ;
> }
>
> module with_sweep() {
>   union(){
>     for(h=[0:lh:lh*(nl-1)])
>       translate([0,0,h])
>         union(){
>           fake_sweep(rad,180) section() ;
>           rotate(180)
>             fake_sweep(rad,180) section() ;
>         }
>   }
> }
>
> module without_sweep() {
>   union(){
>     for(h=[0:lh:lh*(nl-1)]) {
>       translate([0,0,h])
>         for(ang=[0:10:360]) {
>           rotate(ang)
>             rotate_extrude(angle=10,$fn=1)
>               translate([rad,0])
>                 section() ;
>         }
>     }
>   }
> }
>
> Module fake_sweep simulates a sweep of section() along a half
> circular path with radius rad. In my computer, module with_sweep()
> runs in 16 sec. while without_sweep() requires 50  sec. It is not a
> huge gain as I expected. We can estimate the gain of disjoint layers
> by setting lh greater than the filament height lh. With lh=1.05, the
> module with_sweep() runs in 13 sec.
>
> It is not unthinkable to generate one huge-sized polyhedron
> representing the whole print. It would be a very hard work to write a
> code to slice the layers in finer ones to melt them but that is all
> we need.

Just for comparison ....
with_sweep();

Compiling design (CSG Tree generation)...
Compiling design (CSG Products generation)...
Geometries in cache: 3
Geometry cache size in bytes: 55384
CGAL Polyhedrons in cache: 0
CGAL cache size in bytes: 0
Compiling design (CSG Products normalization)...
Normalized CSG tree has 6 elements
Compile and preview finished.
Total rendering time: 0:00:00.052
Parsing design (AST generation)...
Compiling design (CSG Tree generation)...
Rendering Polygon Mesh using CGAL...
Geometries in cache: 4
Geometry cache size in bytes: 109968
CGAL Polyhedrons in cache: 5
CGAL cache size in bytes: 12487024
Total rendering time: 0:00:03.283 <--------
   Top level object is a 3D object:
   Simple:        yes
   Vertices:     2160
   Halfedges:   12480
   Edges:        6240
   Halffacets:   8160
   Facets:       4080
   Volumes:         4
Rendering finished.

without_sweep();

Saved design '/home/peter/Dokumente/work/openscad/sweep_w_wo.scad'.
Loaded design '/home/peter/Dokumente/work/openscad/sweep_w_wo.scad'.
Compiling design (CSG Tree generation)...
Compiling design (CSG Products generation)...
Geometries in cache: 6
Geometry cache size in bytes: 115592
CGAL Polyhedrons in cache: 5
CGAL cache size in bytes: 12487024
Compiling design (CSG Products normalization)...
Normalized CSG tree has 111 elements
Compile and preview finished.
Total rendering time: 0:00:00.083
Parsing design (AST generation)...
Compiling design (CSG Tree generation)...
Rendering Polygon Mesh using CGAL...
Geometries in cache: 42
Geometry cache size in bytes: 318056
CGAL Polyhedrons in cache: 9
CGAL cache size in bytes: 31551664
Total rendering time: 0:00:28.405 <------
   Top level object is a 3D object:
   Simple:        yes
   Vertices:     4482
   Halfedges:   22044
   Edges:       11022
   Halffacets:  13080
   Facets:       6540
   Volumes:         4
Rendering finished.

OpenSCAD 2020.06.14.nightly (git be16bd8)

System:
Linux raven 5.7.3-1.g44c4af0-default #1 SMP Thu Jun 18 05:19:22 UTC 2020 (44c4af0) x86_64 x86_64 x86_64 GNU/Linux
NAME="openSUSE Leap"
VERSION="15.1"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.1"
PRETTY_NAME="openSUSE Leap 15.1"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.1"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
Memory=32GiB
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
Address sizes:       39 bits physical, 48 bits virtual
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               60
Model name:          Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz
Stepping:            3
CPU MHz:             844.698
CPU max MHz:         3800.0000
CPU min MHz:         800.0000
BogoMIPS:            6784.84
Virtualization:      VT-x
L1d cache:           32K
L1i cache:           32K
L2 cache:            256K
L3 cache:            6144K
NUMA node0 CPU(s):   0-3
--
Mit freundlichen Grüßen
Best Regards

Peter Ragosch


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

Re: Normal Hull direction vector for extruding geometry

Parkinbot
In reply to this post by Ronaldo
Ronaldo wrote
> To have a comparison I have done a lazy simulation of both ways:

You are right, of course, but you will have a hard time to properly
implement sweep() for this kind of extrusion with arbitrary paths (and with
a couple of shapes, as mophead mentioned), because you need some means to
avoid self intersections. Leo's approach made me think of code like:

R=5;      // nozzle width
r = 2.5;  // layer height
$fn=10;

P = [[0,0, 0], [50, 10, 0], [50, 50, 0], [170, -150, 0], [170, 150, 0]];
multiline(P);    

module multiline(P)  for(i=[0:len(P)-2]) line(P[i], P[i+1]);


module line(p1, p2)
  hull()
  {
    translate(p1)torus();
    translate(p2)torus();
  }

module torus(R=R, r=r)
  rotate_extrude() translate([R, 0, 0])circle(r);

So, some appropriate sweep() operation can save time and will obviously be
faster than multiline() in my code example. However, the implemenation is
demanding and if you have to union a significant number of such paths,
OpenSCAD again will make you cry. So better use multiline() right away,
spare the programming time and give your machine the time it needs, while
you are on your sommer leave.

@Leo, Maybe you can give us some hint about the complexity of the FEM
analysis you are planning to do. Is it just some layers with, say, a hundred
strokes all together, or are you planning to analyse more complex prints?



--
Sent from: http://forum.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: Normal Hull direction vector for extruding geometry

nophead
mophead? I could have been called that a few weeks ago as I last went to the barbers in December but I managed to buy some clippers and my wife cut my hair, so back to nophead. 

On Wed, 24 Jun 2020 at 23:54, Parkinbot <[hidden email]> wrote:
Ronaldo wrote
> To have a comparison I have done a lazy simulation of both ways:

You are right, of course, but you will have a hard time to properly
implement sweep() for this kind of extrusion with arbitrary paths (and with
a couple of shapes, as mophead mentioned), because you need some means to
avoid self intersections. Leo's approach made me think of code like:

R=5;      // nozzle width
r = 2.5;  // layer height
$fn=10;

P = [[0,0, 0], [50, 10, 0], [50, 50, 0], [170, -150, 0], [170, 150, 0]];
multiline(P);     

module multiline(P)  for(i=[0:len(P)-2]) line(P[i], P[i+1]);


module line(p1, p2)
  hull()
  {
    translate(p1)torus();
    translate(p2)torus();
  }

module torus(R=R, r=r)
  rotate_extrude() translate([R, 0, 0])circle(r);

So, some appropriate sweep() operation can save time and will obviously be
faster than multiline() in my code example. However, the implemenation is
demanding and if you have to union a significant number of such paths,
OpenSCAD again will make you cry. So better use multiline() right away,
spare the programming time and give your machine the time it needs, while
you are on your sommer leave.

@Leo, Maybe you can give us some hint about the complexity of the FEM
analysis you are planning to do. Is it just some layers with, say, a hundred
strokes all together, or are you planning to analyse more complex prints?



--
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: Normal Hull direction vector for extruding geometry

Parkinbot
*g*, sorry for the typo



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

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