discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Pattern to call a module depending on variable value?

RV
Roel Vanhout
Tue, Feb 23, 2021 10:03 AM

Hi,

As I am learning more about OpenSCAD, I found that building new designs by
putting each 'part' into a separate module so that I can export separate
STL's for each part is a much more convenient workflow than putting
everything into one big design and trying to extract parts later on. I do
basically this:

build_config = "clip";
echo("Using build config ", build_config);

if (build_config == "all") {
all();
} else if (build_config == "body") {
body();
} else if (build_config == "lid") {
lid();
} else if (build_config == "screw") {
screw();
} else if (build_config == "clip") {
clip();
}

I then have a batch file where I basically pass a value for build_config
using -D in a loop, so that all parts are exported. The 'all' module
positions the parts in relation to each other, so that it renders an
overview of how the parts fit together (and I add some details like screws
etc that I don't need to 3d print separately). When in 'development mode'
(with the file open in a text editor), I can manually adjust the
build_config variable to see a specific component.

As I get more parts in my designs, it becomes more annoying to update this
if structure, and sync it with the list of part module names in the batch
file. So I'm wondering if there is a way to call modules based on a string
value, so that I can do the equivalent of 'build_config();' ?

Ideally, I also want to get rid of the list of parts in the batch file, but
I'm not sure how I would go about that as it seems there is no way to
iterate and export from within a loop in OpenSCAD.

I would think that this would be a common problem, and maybe I'm barking up
the wrong tree completely. How do you all deal with this, writing modular
designs but still have a convenient way to export the STLs for the parts
separately?

cheers,

Roel

Hi, As I am learning more about OpenSCAD, I found that building new designs by putting each 'part' into a separate module so that I can export separate STL's for each part is a much more convenient workflow than putting everything into one big design and trying to extract parts later on. I do basically this: build_config = "clip"; echo("Using build config ", build_config); if (build_config == "all") { all(); } else if (build_config == "body") { body(); } else if (build_config == "lid") { lid(); } else if (build_config == "screw") { screw(); } else if (build_config == "clip") { clip(); } I then have a batch file where I basically pass a value for build_config using -D in a loop, so that all parts are exported. The 'all' module positions the parts in relation to each other, so that it renders an overview of how the parts fit together (and I add some details like screws etc that I don't need to 3d print separately). When in 'development mode' (with the file open in a text editor), I can manually adjust the build_config variable to see a specific component. As I get more parts in my designs, it becomes more annoying to update this if structure, and sync it with the list of part module names in the batch file. So I'm wondering if there is a way to call modules based on a string value, so that I can do the equivalent of 'build_config();' ? Ideally, I also want to get rid of the list of parts in the batch file, but I'm not sure how I would go about that as it seems there is no way to iterate and export from within a loop in OpenSCAD. I would think that this would be a common problem, and maybe I'm barking up the wrong tree completely. How do you all deal with this, writing modular designs but still have a convenient way to export the STLs for the parts separately? cheers, Roel
AG
Alex Gibson
Tue, Feb 23, 2021 1:02 PM

Hi Roel,

I don’t know whether this is anything close to good practice, but I have several designs I’ve been evolving for years, which express or do not express features contained in modules or separate files.

To enable this to happen as a result of logic, in my parameters I name a value such as:

            dual_z_azis_present = 1;  

(value can be 1 or 0)

Then, I can make the module for the Z axis components, including all sorts of variant versions of components – and all I need to do is wrap each component, module, etc, in

scale([dual_z_azis_present, dual_z_azis_present, dual_z_azis_present])

This effectively ‘disappears’ the geometry.

This absolutely may not be the best way to do things, but I like it because I can make the dependency on some Boolean logic easily using the 1 or 0 value.

Cheers,

Alex Gibson

admg consulting

edumaker limited

·        Project management

·        Operations & Process improvement

·        3D Printing

From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Roel Vanhout
Sent: 23 February 2021 10:04
To: OpenSCAD general discussion
Subject: [OpenSCAD] Pattern to call a module depending on variable value?

Hi,

As I am learning more about OpenSCAD, I found that building new designs by putting each 'part' into a separate module so that I can export separate STL's for each part is a much more convenient workflow than putting everything into one big design and trying to extract parts later on. I do basically this:

build_config = "clip";
echo("Using build config ", build_config);

if (build_config == "all") {
all();
} else if (build_config == "body") {
body();
} else if (build_config == "lid") {
lid();
} else if (build_config == "screw") {
screw();
} else if (build_config == "clip") {
clip();
}

I then have a batch file where I basically pass a value for build_config using -D in a loop, so that all parts are exported. The 'all' module positions the parts in relation to each other, so that it renders an overview of how the parts fit together (and I add some details like screws etc that I don't need to 3d print separately). When in 'development mode' (with the file open in a text editor), I can manually adjust the build_config variable to see a specific component.

As I get more parts in my designs, it becomes more annoying to update this if structure, and sync it with the list of part module names in the batch file. So I'm wondering if there is a way to call modules based on a string value, so that I can do the equivalent of 'build_config();' ?

Ideally, I also want to get rid of the list of parts in the batch file, but I'm not sure how I would go about that as it seems there is no way to iterate and export from within a loop in OpenSCAD.

I would think that this would be a common problem, and maybe I'm barking up the wrong tree completely. How do you all deal with this, writing modular designs but still have a convenient way to export the STLs for the parts separately?

cheers,

Roel

http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient

Virus-free.  http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient www.avg.com

Hi Roel, I don’t know whether this is anything close to good practice, but I have several designs I’ve been evolving for years, which express or do not express features contained in modules or separate files. To enable this to happen as a result of logic, in my parameters I name a value such as: dual_z_azis_present = 1; (value can be 1 or 0) Then, I can make the module for the Z axis components, including all sorts of variant versions of components – and all I need to do is wrap each component, module, etc, in scale([dual_z_azis_present, dual_z_azis_present, dual_z_azis_present]) This effectively ‘disappears’ the geometry. This absolutely may not be the best way to do things, but I like it because I can make the dependency on some Boolean logic easily using the 1 or 0 value. Cheers, Alex Gibson admg consulting edumaker limited · Project management · Operations & Process improvement · 3D Printing From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Roel Vanhout Sent: 23 February 2021 10:04 To: OpenSCAD general discussion Subject: [OpenSCAD] Pattern to call a module depending on variable value? Hi, As I am learning more about OpenSCAD, I found that building new designs by putting each 'part' into a separate module so that I can export separate STL's for each part is a much more convenient workflow than putting everything into one big design and trying to extract parts later on. I do basically this: build_config = "clip"; echo("Using build config ", build_config); if (build_config == "all") { all(); } else if (build_config == "body") { body(); } else if (build_config == "lid") { lid(); } else if (build_config == "screw") { screw(); } else if (build_config == "clip") { clip(); } I then have a batch file where I basically pass a value for build_config using -D in a loop, so that all parts are exported. The 'all' module positions the parts in relation to each other, so that it renders an overview of how the parts fit together (and I add some details like screws etc that I don't need to 3d print separately). When in 'development mode' (with the file open in a text editor), I can manually adjust the build_config variable to see a specific component. As I get more parts in my designs, it becomes more annoying to update this if structure, and sync it with the list of part module names in the batch file. So I'm wondering if there is a way to call modules based on a string value, so that I can do the equivalent of 'build_config();' ? Ideally, I also want to get rid of the list of parts in the batch file, but I'm not sure how I would go about that as it seems there is no way to iterate and export from within a loop in OpenSCAD. I would think that this would be a common problem, and maybe I'm barking up the wrong tree completely. How do you all deal with this, writing modular designs but still have a convenient way to export the STLs for the parts separately? cheers, Roel <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> Virus-free. <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> www.avg.com
NH
nop head
Tue, Feb 23, 2021 1:28 PM

If you use the command line you can take advantage of the fact that -D
passes a statement. E.g.

openscad -D!lid() -o lid.stl parts.scad

The exclamation mark ensures only the specified module is drawn

On Tue, 23 Feb 2021 at 13:03, Alex Gibson alex@alexgibson.net wrote:

Hi Roel,

I don’t know whether this is anything close to good practice, but I have
several designs I’ve been evolving for years, which express or do not
express features contained in modules or separate files.

To enable this to happen as a result of logic, in my parameters I name a
value such as:

             dual_z_azis_present = 1;

(value can be 1 or 0)

Then, I can make the module for the Z axis components, including all sorts
of variant versions of components – and all I need to do is wrap each
component, module, etc, in

scale([dual_z_azis_present, dual_z_azis_present, dual_z_azis_present])

This effectively ‘disappears’ the geometry.

This absolutely may not be the best way to do things, but I like it
because I can make the dependency on some Boolean logic easily using the 1
or 0 value.

Cheers,

Alex Gibson

admg consulting

edumaker limited

·        Project management

·        Operations & Process improvement

·        3D Printing

From: Discuss [mailto:discuss-bounces@lists.openscad.org] *On Behalf Of
*Roel Vanhout
Sent: 23 February 2021 10:04
To: OpenSCAD general discussion
Subject: [OpenSCAD] Pattern to call a module depending on variable
value?

Hi,

As I am learning more about OpenSCAD, I found that building new designs by
putting each 'part' into a separate module so that I can export separate
STL's for each part is a much more convenient workflow than putting
everything into one big design and trying to extract parts later on. I do
basically this:

build_config = "clip";
echo("Using build config ", build_config);

if (build_config == "all") {
all();
} else if (build_config == "body") {
body();
} else if (build_config == "lid") {
lid();
} else if (build_config == "screw") {
screw();
} else if (build_config == "clip") {
clip();
}

I then have a batch file where I basically pass a value for build_config
using -D in a loop, so that all parts are exported. The 'all' module
positions the parts in relation to each other, so that it renders an
overview of how the parts fit together (and I add some details like screws
etc that I don't need to 3d print separately). When in 'development mode'
(with the file open in a text editor), I can manually adjust the
build_config variable to see a specific component.

As I get more parts in my designs, it becomes more annoying to update this
if structure, and sync it with the list of part module names in the batch
file. So I'm wondering if there is a way to call modules based on a string
value, so that I can do the equivalent of 'build_config();' ?

Ideally, I also want to get rid of the list of parts in the batch file,
but I'm not sure how I would go about that as it seems there is no way to
iterate and export from within a loop in OpenSCAD.

I would think that this would be a common problem, and maybe I'm barking
up the wrong tree completely. How do you all deal with this, writing
modular designs but still have a convenient way to export the STLs for the
parts separately?

cheers,

Roel

http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient

Virus-free. www.avg.com
http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

If you use the command line you can take advantage of the fact that -D passes a statement. E.g. openscad -D!lid() -o lid.stl parts.scad The exclamation mark ensures only the specified module is drawn On Tue, 23 Feb 2021 at 13:03, Alex Gibson <alex@alexgibson.net> wrote: > Hi Roel, > > > > I don’t know whether this is anything close to good practice, but I have > several designs I’ve been evolving for years, which express or do not > express features contained in modules or separate files. > > > > To enable this to happen as a result of logic, in my parameters I name a > value such as: > > dual_z_azis_present = 1; > > (value can be 1 or 0) > > > > Then, I can make the module for the Z axis components, including all sorts > of variant versions of components – and all I need to do is wrap each > component, module, etc, in > > scale([dual_z_azis_present, dual_z_azis_present, dual_z_azis_present]) > > > > This effectively ‘disappears’ the geometry. > > > > This absolutely may not be the best way to do things, but I like it > because I can make the dependency on some Boolean logic easily using the 1 > or 0 value. > > > > Cheers, > > > > Alex Gibson > > > > admg consulting > > > > edumaker limited > > > > · Project management > > · Operations & Process improvement > > · 3D Printing > > > > *From:* Discuss [mailto:discuss-bounces@lists.openscad.org] *On Behalf Of > *Roel Vanhout > *Sent:* 23 February 2021 10:04 > *To:* OpenSCAD general discussion > *Subject:* [OpenSCAD] Pattern to call a module depending on variable > value? > > > > Hi, > > > > As I am learning more about OpenSCAD, I found that building new designs by > putting each 'part' into a separate module so that I can export separate > STL's for each part is a much more convenient workflow than putting > everything into one big design and trying to extract parts later on. I do > basically this: > > > > build_config = "clip"; > echo("Using build config ", build_config); > > if (build_config == "all") { > all(); > } else if (build_config == "body") { > body(); > } else if (build_config == "lid") { > lid(); > } else if (build_config == "screw") { > screw(); > } else if (build_config == "clip") { > clip(); > } > > > > I then have a batch file where I basically pass a value for build_config > using -D in a loop, so that all parts are exported. The 'all' module > positions the parts in relation to each other, so that it renders an > overview of how the parts fit together (and I add some details like screws > etc that I don't need to 3d print separately). When in 'development mode' > (with the file open in a text editor), I can manually adjust the > build_config variable to see a specific component. > > > > As I get more parts in my designs, it becomes more annoying to update this > if structure, and sync it with the list of part module names in the batch > file. So I'm wondering if there is a way to call modules based on a string > value, so that I can do the equivalent of 'build_config();' ? > > > > Ideally, I also want to get rid of the list of parts in the batch file, > but I'm not sure how I would go about that as it seems there is no way to > iterate and export from within a loop in OpenSCAD. > > > > I would think that this would be a common problem, and maybe I'm barking > up the wrong tree completely. How do you all deal with this, writing > modular designs but still have a convenient way to export the STLs for the > parts separately? > > > > cheers, > > > > Roel > > > > > > > > > <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> > > Virus-free. www.avg.com > <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient> > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
T
Troberg
Tue, Feb 23, 2021 2:08 PM

I use these handy little modules:

module hide(dohide=true){
if(!dohide){
children();
}
}

module show(doshow=true){
if(doshow){
children();
}
}

They allow me to do this simply like this (works excellently with
customization as well):

show(showlid)
lid();

show(showbox)
box();

hide(hidesamplecontents)
samplecontents();

Neat, simple, practical. Hide & show are also practical for debugging, as
they are simple to use in combination with a debugmode-variable which you
can define at the top of your script (and through customizer).

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

I use these handy little modules: module hide(dohide=true){ if(!dohide){ children(); } } module show(doshow=true){ if(doshow){ children(); } } They allow me to do this simply like this (works excellently with customization as well): show(showlid) lid(); show(showbox) box(); hide(hidesamplecontents) samplecontents(); Neat, simple, practical. Hide & show are also practical for debugging, as they are simple to use in combination with a debugmode-variable which you can define at the top of your script (and through customizer). -- Sent from: http://forum.openscad.org/
TP
Torsten Paul
Tue, Feb 23, 2021 2:18 PM

On 23.02.21 14:28, nop head wrote:

If you use the command line you can take advantage
of the fact that -D passes a statement. E.g.

While noting this is not how it's documented.

-D [ --D ] arg    var=val -pre-define variables

ciao,
Torsten.

On 23.02.21 14:28, nop head wrote: > If you use the command line you can take advantage > of the fact that -D passes a statement. E.g. While noting this is not how it's documented. -D [ --D ] arg var=val -pre-define variables ciao, Torsten.
JB
Jordan Brown
Tue, Feb 23, 2021 3:59 PM

I have a couple of answers to this and related problems, but my basic
one looks like this:

// Pick out a particular component
$content_selected="all";    // [all, vanity, cabinet, toilet, mesa-701a, mesa-807a]

contents() {
    item("vanity") vanity();
    item("cabinet") bathcabinet();
    item("toilet", distance=120, zrot=120, z=10) toilet();
    item("mesa-701a", distance=120, zrot=120, z=10) mesa_701a();
    item("mesa-807a", distance=120, zrot=120, z=10) mesa_807a();
}

contents() is responsible for laying out an array of items.  If
$content_selected is undefined or "all", then it spreads its children
out in an array; if $content_selected is anything else then contents()
just renders its children at the origin (on the assumption that item(),
below, will only render one of them.)

item() does one of three things:

  • if $content_inventory is defined, echoes a line with information
    about the particular item - in particular, its name.  This output is
    used by scripts that generate separate STLs and PNGs for each item. 
    $content_inventory can be set to "all" to dump information about all
    items, or to "stl" or "png" to select only those items that have
    said that they should have STLs or PNGs generated.
  • If $content_selected is undefined, or is "all", or matches the name
    passed, it renders its child.
  • Otherwise, nothing.

Net, with this infrastructure I can:

  • Display everything, spread out in an array.
  • Display a single item, selected either by Customizer or command line
    options.
  • Echo information about the items available in the file.

and with the supporting shell scripts:

  • Generate STLs for all items marked for STLs.  (Default is yes.)
  • Generate PNGs for all items marked for PNGs.  (Default is yes.) 
    Optionally control camera position.

Why the selectivity for STLs and PNGs?  I don't generate PNGs for
individual parts of a multi-print assembly.  I don't generate STLs where
I want to present a picture of several items together, that wouldn't be
printed together.

Here's the implementation:

function default(val, def) = is_undef(val) ? def : val;

module contents(d=100) {
nx = ceil(sqrt($children));
ny = ceil($children/nx);
for (xi=[0:nx-1], yi=[0:ny-1]) {
i = xi + yinx;
if (i < $children) {
if (is_undef($content_selected)
|| $content_selected == "all") {
translate([xi
d, yi*d, 0]) children(i);
} else {
children(i);
}
}
}
}

module item(name, png=true, stl=true, distance, xrot, zrot, z) {
if (is_undef($content_inventory)) {
if (is_undef($content_selected)
|| $content_selected == "all"
|| $content_selected == name) {
children();
}
} else {
_distance = default(distance, 150);
_zrot = default(zrot, 30);
_xrot = default(xrot, 60);
_z = default(z, 15);
camera = is_undef(distance) && is_undef(zrot) && is_undef(z) && is_undef(xrot)
? "--viewall"
: str("--camera 0,0,", _z, ",", _xrot, ",0,", _zrot, ",", _distance);
if ($content_inventory == "all")
echo("PART", name);
else if ($content_inventory == "png" && png)
echo("PART", name, camera);
else if ($content_inventory == "stl" && stl)
echo("PART", name);
}
}

I have a couple of answers to this and related problems, but my basic one looks like this: // Pick out a particular component $content_selected="all"; // [all, vanity, cabinet, toilet, mesa-701a, mesa-807a] contents() { item("vanity") vanity(); item("cabinet") bathcabinet(); item("toilet", distance=120, zrot=120, z=10) toilet(); item("mesa-701a", distance=120, zrot=120, z=10) mesa_701a(); item("mesa-807a", distance=120, zrot=120, z=10) mesa_807a(); } contents() is responsible for laying out an array of items.  If $content_selected is undefined or "all", then it spreads its children out in an array; if $content_selected is anything else then contents() just renders its children at the origin (on the assumption that item(), below, will only render one of them.) item() does one of three things: * if $content_inventory is defined, echoes a line with information about the particular item - in particular, its name.  This output is used by scripts that generate separate STLs and PNGs for each item.  $content_inventory can be set to "all" to dump information about all items, or to "stl" or "png" to select only those items that have said that they should have STLs or PNGs generated. * If $content_selected is undefined, or is "all", or matches the name passed, it renders its child. * Otherwise, nothing. Net, with this infrastructure I can: * Display everything, spread out in an array. * Display a single item, selected either by Customizer or command line options. * Echo information about the items available in the file. and with the supporting shell scripts: * Generate STLs for all items marked for STLs.  (Default is yes.) * Generate PNGs for all items marked for PNGs.  (Default is yes.)  Optionally control camera position. Why the selectivity for STLs and PNGs?  I don't generate PNGs for individual parts of a multi-print assembly.  I don't generate STLs where I want to present a picture of several items together, that wouldn't be printed together. Here's the implementation: function default(val, def) = is_undef(val) ? def : val; module contents(d=100) { nx = ceil(sqrt($children)); ny = ceil($children/nx); for (xi=[0:nx-1], yi=[0:ny-1]) { i = xi + yi*nx; if (i < $children) { if (is_undef($content_selected) || $content_selected == "all") { translate([xi*d, yi*d, 0]) children(i); } else { children(i); } } } } module item(name, png=true, stl=true, distance, xrot, zrot, z) { if (is_undef($content_inventory)) { if (is_undef($content_selected) || $content_selected == "all" || $content_selected == name) { children(); } } else { _distance = default(distance, 150); _zrot = default(zrot, 30); _xrot = default(xrot, 60); _z = default(z, 15); camera = is_undef(distance) && is_undef(zrot) && is_undef(z) && is_undef(xrot) ? "--viewall" : str("--camera 0,0,", _z, ",", _xrot, ",0,", _zrot, ",", _distance); if ($content_inventory == "all") echo("PART", name); else if ($content_inventory == "png" && png) echo("PART", name, camera); else if ($content_inventory == "stl" && stl) echo("PART", name); } }
RV
Roel Vanhout
Wed, Feb 24, 2021 12:58 PM

This is most excellent, thanks, just what I was looking for.

regards

On Tue, Feb 23, 2021 at 4:59 PM Jordan Brown openscad@jordan.maileater.net
wrote:

I have a couple of answers to this and related problems, but my basic one
looks like this:

// Pick out a particular component
$content_selected="all";    // [all, vanity, cabinet, toilet, mesa-701a, mesa-807a]

contents() {
item("vanity") vanity();
item("cabinet") bathcabinet();
item("toilet", distance=120, zrot=120, z=10) toilet();
item("mesa-701a", distance=120, zrot=120, z=10) mesa_701a();
item("mesa-807a", distance=120, zrot=120, z=10) mesa_807a();
}

contents() is responsible for laying out an array of items.  If
$content_selected is undefined or "all", then it spreads its children out
in an array; if $content_selected is anything else then contents() just
renders its children at the origin (on the assumption that item(), below,
will only render one of them.)

item() does one of three things:

- if $content_inventory is defined, echoes a line with information
about the particular item - in particular, its name.  This output is used
by scripts that generate separate STLs and PNGs for each item.
$content_inventory can be set to "all" to dump information about all items,
or to "stl" or "png" to select only those items that have said that they
should have STLs or PNGs generated.
- If $content_selected is undefined, or is "all", or matches the name
passed, it renders its child.
- Otherwise, nothing.

Net, with this infrastructure I can:

- Display everything, spread out in an array.
- Display a single item, selected either by Customizer or command line
options.
- Echo information about the items available in the file.

and with the supporting shell scripts:

- Generate STLs for all items marked for STLs.  (Default is yes.)
- Generate PNGs for all items marked for PNGs.  (Default is yes.)
Optionally control camera position.

Why the selectivity for STLs and PNGs?  I don't generate PNGs for
individual parts of a multi-print assembly.  I don't generate STLs where I
want to present a picture of several items together, that wouldn't be
printed together.

Here's the implementation:

function default(val, def) = is_undef(val) ? def : val;

module contents(d=100) {
nx = ceil(sqrt($children));
ny = ceil($children/nx);
for (xi=[0:nx-1], yi=[0:ny-1]) {
i = xi + yinx;
if (i < $children) {
if (is_undef($content_selected)
|| $content_selected == "all") {
translate([xi
d, yi*d, 0]) children(i);
} else {
children(i);
}
}
}
}

module item(name, png=true, stl=true, distance, xrot, zrot, z) {
if (is_undef($content_inventory)) {
if (is_undef($content_selected)
|| $content_selected == "all"
|| $content_selected == name) {
children();
}
} else {
_distance = default(distance, 150);
_zrot = default(zrot, 30);
_xrot = default(xrot, 60);
_z = default(z, 15);
camera = is_undef(distance) && is_undef(zrot) && is_undef(z) && is_undef(xrot)
? "--viewall"
: str("--camera 0,0,", _z, ",", _xrot, ",0,", _zrot, ",", _distance);
if ($content_inventory == "all")
echo("PART", name);
else if ($content_inventory == "png" && png)
echo("PART", name, camera);
else if ($content_inventory == "stl" && stl)
echo("PART", name);
}
}

This is most excellent, thanks, just what I was looking for. regards On Tue, Feb 23, 2021 at 4:59 PM Jordan Brown <openscad@jordan.maileater.net> wrote: > I have a couple of answers to this and related problems, but my basic one > looks like this: > > // Pick out a particular component > $content_selected="all"; // [all, vanity, cabinet, toilet, mesa-701a, mesa-807a] > > contents() { > item("vanity") vanity(); > item("cabinet") bathcabinet(); > item("toilet", distance=120, zrot=120, z=10) toilet(); > item("mesa-701a", distance=120, zrot=120, z=10) mesa_701a(); > item("mesa-807a", distance=120, zrot=120, z=10) mesa_807a(); > } > > contents() is responsible for laying out an array of items. If > $content_selected is undefined or "all", then it spreads its children out > in an array; if $content_selected is anything else then contents() just > renders its children at the origin (on the assumption that item(), below, > will only render one of them.) > > item() does one of three things: > > - if $content_inventory is defined, echoes a line with information > about the particular item - in particular, its name. This output is used > by scripts that generate separate STLs and PNGs for each item. > $content_inventory can be set to "all" to dump information about all items, > or to "stl" or "png" to select only those items that have said that they > should have STLs or PNGs generated. > - If $content_selected is undefined, or is "all", or matches the name > passed, it renders its child. > - Otherwise, nothing. > > Net, with this infrastructure I can: > > - Display everything, spread out in an array. > - Display a single item, selected either by Customizer or command line > options. > - Echo information about the items available in the file. > > and with the supporting shell scripts: > > - Generate STLs for all items marked for STLs. (Default is yes.) > - Generate PNGs for all items marked for PNGs. (Default is yes.) > Optionally control camera position. > > Why the selectivity for STLs and PNGs? I don't generate PNGs for > individual parts of a multi-print assembly. I don't generate STLs where I > want to present a picture of several items together, that wouldn't be > printed together. > > Here's the implementation: > > function default(val, def) = is_undef(val) ? def : val; > > module contents(d=100) { > nx = ceil(sqrt($children)); > ny = ceil($children/nx); > for (xi=[0:nx-1], yi=[0:ny-1]) { > i = xi + yi*nx; > if (i < $children) { > if (is_undef($content_selected) > || $content_selected == "all") { > translate([xi*d, yi*d, 0]) children(i); > } else { > children(i); > } > } > } > } > > module item(name, png=true, stl=true, distance, xrot, zrot, z) { > if (is_undef($content_inventory)) { > if (is_undef($content_selected) > || $content_selected == "all" > || $content_selected == name) { > children(); > } > } else { > _distance = default(distance, 150); > _zrot = default(zrot, 30); > _xrot = default(xrot, 60); > _z = default(z, 15); > camera = is_undef(distance) && is_undef(zrot) && is_undef(z) && is_undef(xrot) > ? "--viewall" > : str("--camera 0,0,", _z, ",", _xrot, ",0,", _zrot, ",", _distance); > if ($content_inventory == "all") > echo("PART", name); > else if ($content_inventory == "png" && png) > echo("PART", name, camera); > else if ($content_inventory == "stl" && stl) > echo("PART", name); > } > } > > >