Slicing a 3D object to SVG: verschil tussen versies

Uit MakerSpace Leiden
Ga naar: navigatie, zoeken
(Example of a CSG object)
(Example of a CSG object: code cleanup, clarification and comments)
Regel 20: Regel 20:
 
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.
 
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.
  
  module thing() {
+
<pre>
    difference() {
+
$fn = 30; // setting the resolution to high values can seriously increase rendering time!
        union() {
 
            translate([-5,-5,0])
 
                cube([10,10,10]);
 
            translate([0,0,12])
 
                sphere(r=10);
 
            };
 
        union() {
 
            translate([-5,-5,0])
 
                translate([1,1,1]) cube([8,8,8]);
 
            translate([0,0,12])
 
                sphere(r=9);
 
            };
 
        };
 
  }
 
 
    
 
    
  z_min = 0;
+
module thing() // a random object, in this case a hollow sphere on top of a hollow cube.
  z_max = 23;
+
{
  slice = 1;
+
    difference()
  n = 5; // floor(sqrt((z_max - z_min)/slice+10));
+
    {
  for(z = [-z_max:slice:z_min]) {  
+
        union()
    i = (z + z_max) / slice;
+
        {
     x = 40 * (i % n);
+
            translate([0, 0, 5 ]) cube(10,true);
     y = 40 * floor(i / n);
+
            translate([0, 0, 12]) sphere(d=20);
     translate([x,y,0]) {
+
        }
        projection(cut=true)  
+
        union()
            translate([0,0,z]) thing();
+
        {
    };
+
            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
 +
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 of the cut to be made
 +
 
 +
     translate(explode ? [-x, -y, z * 2] : [0, 0, 0]) // translation for 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();          
 +
}
 +
</pre>
  
 
== Example with an STL ==
 
== Example with an STL ==

Versie van 3 mrt 2018 om 22:10

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 sizes
  4. Render the object
  5. Save the resulting SVG
  6. Open this in Inktscape to check and perhaps make a bit more efficient by moving things around/nesting things.
  7. Export/upload the SVG from Inktscape 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
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 of the cut to be made

    translate(explode ? [-x, -y, z * 2] : [0, 0, 0]) // translation for 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();
   };
 };