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 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
Virus-free. http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient www.avg.com
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
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
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/
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.
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:
Net, with this infrastructure I can:
and with the supporting shell scripts:
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([xid, 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 + yinx;
if (i < $children) {
if (is_undef($content_selected)
|| $content_selected == "all") {
translate([xid, 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);
}
}