Slicing a 3D object to SVG

Uit MakerSpace Leiden
Ga naar: navigatie, zoeken

One can use OpenSCAD to slice a 3D STL or an object made in OpenSCAD into SVG usable with the Lasersaur.

Or in other words, turning Sphere-on-box-example.png into Sphere-on-box-as-slices-Flat.png.

Needed: http://www.openscad.org/ - OpenScad (free).

The typical workflow is

  1. Create an OpenSCAD object, or import an STL of an object into OpenScad
  2. Add the slicing code below
  3. Adjust the parameters
  4. Render the object
  5. Save the resulting object as SVG
  6. Open the SVG in Inkscape to check and perhaps make it a bit more efficient by moving things around and/or nesting things
  7. Export/upload the SVG from Inkscape to the Lasersaur

Example of a CSG object

Below is an example of a hollow sphere on top of a hollow cube (thing() in below code) which is sliced; and each slice is then laid out flat.

$fn = 30; // setting the resolution to high values can seriously increase rendering time!
  
module thing() // a random object, in this case a hollow sphere on top of a hollow cube.
{
    difference() 
    {
        union() 
        {
            translate([0, 0, 5 ]) cube(10,true);
            translate([0, 0, 12]) sphere(d=20);
        }
        union() 
        {
            translate([0, 0, 5 ]) cube(8,true);
            translate([0, 0, 12]) sphere(d=18);
        }
    }
}

// change these (measurements all in mm) -------------------------------------------------------------
x_dist      = 21; // desired horizontal distance between centre lines of projected cuts
y_dist      = 20; // desired vertical distance between centre lines of projected cuts

z_min       = 0;  // smallest z-coordinate object
z_max       = 23; // biggest z-coordinate object (add 1 to be safe)
slice       = 1;  // desired distance between cuts

explode     = false; // not in mm. false does nothing, x_dist and y_dist don't matter if this is true
// stop changing here --------------------------------------------------------------------------------

// some useful numbers
slicecount = (z_max - z_min)/slice; // this be the number of slices you get
rowlength  = floor(sqrt(slicecount)) + 1; // make rows and columns of projected cuts of equal length

// business end
for(s = [0:slicecount]) 
{ 
    x = x_dist * (s % rowlength); // calculate coordinates per cut
    y = y_dist * floor(s / rowlength);
    z = z_min + s * slice; // calculate height at which the cut should be made

    translate(explode ? [-x, -y, z * 2] : [0, 0, 0]) // translation if explode==true
        projection(cut = true)        // actual cut
            translate([x, y, -z])     // -z gets the correct layer, x and y do the grid move
                thing();
}

Example with an STL

An example of an STL that is loaded from a file and then sliced. You will have to manually adjust the Z range & slice distance.

 // 30x150x20 bbx
 import("dino.stl", convexity=3); 
 
 z_min = 0;
 z_max = 30;
 x_max = 20;
 y_max = 150;
 slice = 0.5;
 
 n = floor(sqrt((z_max - z_min)/slice)+1);
 for(z = [-z_max:slice:z_min]) { 
   i = (z + z_max) / slice;
   x = x_max * (i % n);
   y = Y_max * floor(i / n);
   translate([x,y,0]) {
       projection(cut=true) 
           translate([0,0,z]) thing();
   };
 };