discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

How I Automated STL Generation

J
jon
Sun, Feb 13, 2022 6:38 PM

I have no idea if this is A) already well known and understood or B)
novel or C) uninteresting.  You be the judge.

I have an OpenSCAD program that generates about 100 distinct objects in
each of about a dozen families.  Each family is generated by a single
module in which a loop (or two loops) create the objects.  Typically
there is one module that generates a 2D version of each object, another
module that generates a 3D version, and then the iterator module that
calls the 3D module to create the variety of objects for the family. 
The objects are created on an 80x80 grid, because some of the objects
are that large; the result is that the grid is too large to print.

I needed to generate each object as a separate STL.  If each module
created one object, that would be easier, but such was not the case.

First, I wrote the following module to emit a command line string each
time an object is created. "mod" is the name of the module that creates
the family of shapes, while p1..p5 are the optional parameters, since
each family of objects takes different numbers of parameters.  I take
care to eliminate unused parameters: that takes up a lot of the code,
which otherwise would be just a single echo() statement.

module EmitCmdLine(mod, p1, p2=0, p3=0, p4=0, p5=0) {
    // parameter strings
    p1p =                  str("-D p1=", p1, " ");
    p2p = (p2 == 0) ? "" : str("-D p2=", p2, " ");
    p3p = (p3 == 0) ? "" : str("-D p3=", p3, " ");
    p4p = (p4 == 0) ? "" : str("-D p4=", p4, " ");
    p5p = (p5 == 0) ? "" : str("-D p5=", p5, " ");
    // file name strings
    p1f =                  p1;
    p2f = (p2 == 0) ? "" : str("-", p2);
    p3f = (p3 == 0) ? "" : str("-", p3);
    p4f = (p4 == 0) ? "" : str("-", p4);
    p5f = (p5 == 0) ? "" : str("-", p5);
    echo(str(
        ""c:/program files/openscad/openscad.com" ",
        "-o "d:/stl files/John Tools-", mod, "-", p1f, p2f, p3f, p4f,
p5f, ".stl" ",
        "-D auto=true ",
        "-D "mod="""", mod, """ ",
        p1p, p2p, p3p, p4p, p5p,
        ""John Painting Tools.scad""));
    }

Then in each iterator module, I carefully call the EmitCmdLine module
each time I create an object.  maDs is a vector containing the diameters
I need:

maDs = [8, 12, 15, 20];

module Circles()
    for (i = [0:3]) {
        d = maDs[i];
        Circle(d);
        EmitCmdLine("Circle", d, 0, 0, 0);
        }

This results in hundreds of lines in the console output like this (after
I strip off the leading 'Echo: "' and the trailing '"':

"c:/program files/openscad/openscad.com" -o "d:/stl files/John
Tools-Circle-12.stl" -D auto=true -D "mod="""Circle"" -D p1=12 "John
Painting Tools.scad"

I then needed a dispatcher inside the code.  That logic looks like this:

if (mod == "Circle") Circle(p1);

I use the "auto" variable so that the program runs normally (ignoring
the dispatcher) when I am editing it and testing it, but runs the
dispatcher when run from the command line (where I force "auto" to be
true).  Running the non-auto version of the program generates the
command line output on the console.  This is a simplified version of
that part of the program.

auto = false;

if (!auto) {
    Ellipses();
    Circles();
    SemiCircles();
    }

else {
    /// auto: runs from cmd line
            if (mod == "Ellipse")        Ellipse(p1, p2);
    else if (mod == "Circle")         Circle(p1);
    else if (mod == "SemiCircle")     SemiCircle(p1);

I have no idea if this is A) already well known and understood or B) novel or C) uninteresting.  You be the judge. I have an OpenSCAD program that generates about 100 distinct objects in each of about a dozen families.  Each family is generated by a single module in which a loop (or two loops) create the objects.  Typically there is one module that generates a 2D version of each object, another module that generates a 3D version, and then the iterator module that calls the 3D module to create the variety of objects for the family.  The objects are created on an 80x80 grid, because some of the objects are that large; the result is that the grid is too large to print. I needed to generate each object as a separate STL.  If each module created one object, that would be easier, but such was not the case. First, I wrote the following module to emit a command line string each time an object is created. "mod" is the name of the module that creates the family of shapes, while p1..p5 are the optional parameters, since each family of objects takes different numbers of parameters.  I take care to eliminate unused parameters: that takes up a lot of the code, which otherwise would be just a single echo() statement. module EmitCmdLine(mod, p1, p2=0, p3=0, p4=0, p5=0) {     // parameter strings     p1p =                  str("-D p1=", p1, " ");     p2p = (p2 == 0) ? "" : str("-D p2=", p2, " ");     p3p = (p3 == 0) ? "" : str("-D p3=", p3, " ");     p4p = (p4 == 0) ? "" : str("-D p4=", p4, " ");     p5p = (p5 == 0) ? "" : str("-D p5=", p5, " ");     // file name strings     p1f =                  p1;     p2f = (p2 == 0) ? "" : str("-", p2);     p3f = (p3 == 0) ? "" : str("-", p3);     p4f = (p4 == 0) ? "" : str("-", p4);     p5f = (p5 == 0) ? "" : str("-", p5);     echo(str(         "\"c:/program files/openscad/openscad.com\" ",         "-o \"d:/stl files/John Tools-", mod, "-", p1f, p2f, p3f, p4f, p5f, ".stl\" ",         "-D auto=true ",         "-D \"mod=\"\"\"", mod, "\"\" ",         p1p, p2p, p3p, p4p, p5p,         "\"John Painting Tools.scad\""));     } Then in each iterator module, I carefully call the EmitCmdLine module each time I create an object.  maDs is a vector containing the diameters I need: maDs = [8, 12, 15, 20]; module Circles()     for (i = [0:3]) {         d = maDs[i];         Circle(d);         EmitCmdLine("Circle", d, 0, 0, 0);         } This results in hundreds of lines in the console output like this (after I strip off the leading 'Echo: "' and the trailing '"': "c:/program files/openscad/openscad.com" -o "d:/stl files/John Tools-Circle-12.stl" -D auto=true -D "mod="""Circle"" -D p1=12 "John Painting Tools.scad" I then needed a dispatcher inside the code.  That logic looks like this: if (mod == "Circle") Circle(p1); I use the "auto" variable so that the program runs normally (ignoring the dispatcher) when I am editing it and testing it, but runs the dispatcher when run from the command line (where I force "auto" to be true).  Running the non-auto version of the program generates the command line output on the console.  This is a simplified version of that part of the program. auto = false; if (!auto) {     Ellipses();     Circles();     SemiCircles();     } else {     /// auto: runs from cmd line             if (mod == "Ellipse")        Ellipse(p1, p2);     else if (mod == "Circle")         Circle(p1);     else if (mod == "SemiCircle")     SemiCircle(p1);