discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Conditional rendering without code duplication

K
korpx
Fri, Jun 14, 2019 9:06 AM

Is it possible to conditionally enable/disable operations without duplicating
the code? For example render some 3d objects while previewing others within
the same OpenSCAD file if a variable is set, something like this;

$renderit=1
color("Green")
if($renderit ? render() )
cube([5,5,5]); //Render this if $renderit=1
color("Blue")
cube([3,3,3]); //Always preview this unless F6 is used

instead of what I end up doing;

$renderit=1
if($renderit) {
color("Green")
render()
cube([5,5,5]); //Render this if $renderit=1
} else {
color("Green")
cube([5,5,5]);
}
color("Blue")
cube([3,3,3]); //Always preview this unless F6 is used

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

Is it possible to conditionally enable/disable operations without duplicating the code? For example render some 3d objects while previewing others within the same OpenSCAD file if a variable is set, something like this; *$renderit=1 color("Green") if($renderit ? render() ) cube([5,5,5]); //Render this if $renderit=1 color("Blue") cube([3,3,3]); //Always preview this unless F6 is used* instead of what I end up doing; *$renderit=1 if($renderit) { color("Green") render() cube([5,5,5]); //Render this if $renderit=1 } else { color("Green") cube([5,5,5]); } color("Blue") cube([3,3,3]); //Always preview this unless F6 is used* -- Sent from: http://forum.openscad.org/
K
korpx
Fri, Jun 14, 2019 9:23 AM

I guess I could make a "proxy" module and go through that. Any other ideas?

$renderit=1;

module renderfunc() {
if ($renderit) {
color("Green")
render()
children();
} else {
color("Blue")
children();
}
}

renderfunc() cube([5,5,5]);  //Render this if $renderit=1
cube([3,3,3]); //Always preview this unless F6 is used

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

I guess I could make a "proxy" module and go through that. Any other ideas? $renderit=1; module renderfunc() { if ($renderit) { color("Green") render() children(); } else { color("Blue") children(); } } renderfunc() cube([5,5,5]); //Render this if $renderit=1 cube([3,3,3]); //Always preview this unless F6 is used -- Sent from: http://forum.openscad.org/
NH
nop head
Fri, Jun 14, 2019 10:47 AM

Yes that is the way I would would apply conditional operations without
duplication. Example here:
https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/utils/core/bom.scad#L54

The other way is to wrap the duplicated code in a module so it can be used
in both paths of the if. The module can be nested inside another. An
example here:
https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/vitamins/toggle.scad#L150

On Fri, 14 Jun 2019 at 10:23, korpx andreas.thorn@gmail.com wrote:

I guess I could make a "proxy" module and go through that. Any other ideas?

$renderit=1;

module renderfunc() {
if ($renderit) {
color("Green")
render()
children();
} else {
color("Blue")
children();
}
}

renderfunc() cube([5,5,5]);  //Render this if $renderit=1
cube([3,3,3]); //Always preview this unless F6 is used

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


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

Yes that is the way I would would apply conditional operations without duplication. Example here: https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/utils/core/bom.scad#L54 The other way is to wrap the duplicated code in a module so it can be used in both paths of the if. The module can be nested inside another. An example here: https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/vitamins/toggle.scad#L150 On Fri, 14 Jun 2019 at 10:23, korpx <andreas.thorn@gmail.com> wrote: > I guess I could make a "proxy" module and go through that. Any other ideas? > > > $renderit=1; > > module renderfunc() { > if ($renderit) { > color("Green") > render() > children(); > } else { > color("Blue") > children(); > } > } > > renderfunc() cube([5,5,5]); //Render this if $renderit=1 > cube([3,3,3]); //Always preview this unless F6 is used > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
AC
A. Craig West
Fri, Jun 14, 2019 11:53 AM

I went for this approach as well. My proxy module does pretty much
everything, conditionally...:
The hull case is particularly ugly. It is possible there is a better
way to do this in general now, I ran into the same problem
intersection_for solves, which is that for iterations are implicitly
grouped, which makes it difficult to handle things like intersection
and hull. Openscad could use some sort of ungrouped for loop
(intersection_for wouldn't be necessary then, I don't think).
Something like Bash's "$@" expansion, which solves a similar problem

module draw(hide = false, shadow = false, highlight = false, singular
= false, render = false, difference = false, intersection = false,
hull = false, minkowski = false, union = true, color, alpha,
convexity) {
if (!hide) {
if (!is_undef(color) || !is_undef(alpha)) {
color(color, alpha = alpha) {
draw(shadow = shadow, highlight = highlight, singular =
singular, render = render, difference = difference, intersection =
intersection, hull = hull, minkowski = minkowski, union = union,
convexity = convexity) {
if ($children > 0) {
children(0);
}
if ($children > 1) {
if (intersection) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
} else {
for (i = [1 : $children - 1]) {
children(i);
}
}
}
}
}
} else if (singular) {
!draw(shadow = shadow, highlight = highlight, render = render,
difference = difference, intersection = intersection, hull = hull,
minkowski = minkowski, union = union, convexity = convexity) {
if ($children > 0) {
children(0);
}
if ($children > 1) {
if (intersection) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
} else {
for (i = [1 : $children - 1]) {
children(i);
}
}
}
}
} else if (shadow) {
%draw(render = render, difference = difference, intersection =
intersection, hull = hull, minkowski = minkowski, union = union,
convexity = convexity) {
if ($children > 0) {
children(0);
}
if ($children > 1) {
if (intersection) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
} else {
for (i = [1 : $children - 1]) {
children(i);
}
}
}
}
} else if (highlight) {
#draw(render = render, difference = difference, intersection =
intersection, hull = hull, minkowski = minkowski, union = union,
convexity = convexity) {
if ($children > 0) {
children(0);
}
if ($children > 1) {
if (intersection) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
} else {
for (i = [1 : $children - 1]) {
children(i);
}
}
}
}
} else if (render) {
render(convexity = convexity) {
draw(difference = difference, intersection = intersection,
hull = hull, minkowski = minkowski, union = union) {
if ($children > 0) {
children(0);
}
if ($children > 1) {
if (intersection) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
} else {
for (i = [1 : $children - 1]) {
children(i);
}
}
}
}
}
} else if (difference) {
difference() {
if ($children > 0) {
children(0);
}
for (i = [1 : $children - 1]) {
children(i);
}
}
} else if (minkowski) {
minkowski() {
if ($children > 0) {
children(0);
}
for (i = [1 : $children - 1]) {
children(i);
}
}
} else if (intersection) {
intersection() {
if ($children > 0) {
children(0);
}
if ($children > 1) {
intersection_for (i = [1 : $children - 1]) {
children(i);
}
}
}
} else if (hull) {
hull() {
if ($children > 0) {
children(0);
}
if ($children > 1) {
children(1);
}
if ($children > 2) {
children(2);
}
if ($children > 3) {
children(3);
}
if ($children > 4) {
children(4);
}
if ($children > 5) {
children(5);
}
if ($children > 6) {
children(6);
}
if ($children > 7) {
children(7);
}
if ($children > 8) {
children(8);
}
if ($children > 9) {
children(9);
}
if ($children > 10) {
children(10);
}
if ($children > 11) {
children(11);
}
if ($children > 12) {
for (i = [12 : $children - 1]) {
children(i);
}
}
}
} else if (union) {
union() {
if ($children > 0) {
for (i = [0 : $children - 1]) {
children(i);
}
}
}
} else {
if ($children > 0) {
for (i = [0 : $children - 1]) {
children(i);
}
}
}
}
}

On Fri, Jun 14, 2019 at 6:48 AM nop head nop.head@gmail.com wrote:

Yes that is the way I would would apply conditional operations without duplication. Example here:  https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/utils/core/bom.scad#L54

The other way is to wrap the duplicated code in a module so it can be used in both paths of the if. The module can be nested inside another. An example here: https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/vitamins/toggle.scad#L150

On Fri, 14 Jun 2019 at 10:23, korpx andreas.thorn@gmail.com wrote:

I guess I could make a "proxy" module and go through that. Any other ideas?

$renderit=1;

module renderfunc() {
if ($renderit) {
color("Green")
render()
children();
} else {
color("Blue")
children();
}
}

renderfunc() cube([5,5,5]);  //Render this if $renderit=1
cube([3,3,3]); //Always preview this unless F6 is used

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


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

I went for this approach as well. My proxy module does pretty much everything, conditionally...: The hull case is particularly ugly. It is possible there is a better way to do this in general now, I ran into the same problem intersection_for solves, which is that for iterations are implicitly grouped, which makes it difficult to handle things like intersection and hull. Openscad could use some sort of ungrouped for loop (intersection_for wouldn't be necessary then, I don't think). Something like Bash's "$@" expansion, which solves a similar problem module draw(hide = false, shadow = false, highlight = false, singular = false, render = false, difference = false, intersection = false, hull = false, minkowski = false, union = true, color, alpha, convexity) { if (!hide) { if (!is_undef(color) || !is_undef(alpha)) { color(color, alpha = alpha) { draw(shadow = shadow, highlight = highlight, singular = singular, render = render, difference = difference, intersection = intersection, hull = hull, minkowski = minkowski, union = union, convexity = convexity) { if ($children > 0) { children(0); } if ($children > 1) { if (intersection) { intersection_for (i = [1 : $children - 1]) { children(i); } } else { for (i = [1 : $children - 1]) { children(i); } } } } } } else if (singular) { !draw(shadow = shadow, highlight = highlight, render = render, difference = difference, intersection = intersection, hull = hull, minkowski = minkowski, union = union, convexity = convexity) { if ($children > 0) { children(0); } if ($children > 1) { if (intersection) { intersection_for (i = [1 : $children - 1]) { children(i); } } else { for (i = [1 : $children - 1]) { children(i); } } } } } else if (shadow) { %draw(render = render, difference = difference, intersection = intersection, hull = hull, minkowski = minkowski, union = union, convexity = convexity) { if ($children > 0) { children(0); } if ($children > 1) { if (intersection) { intersection_for (i = [1 : $children - 1]) { children(i); } } else { for (i = [1 : $children - 1]) { children(i); } } } } } else if (highlight) { #draw(render = render, difference = difference, intersection = intersection, hull = hull, minkowski = minkowski, union = union, convexity = convexity) { if ($children > 0) { children(0); } if ($children > 1) { if (intersection) { intersection_for (i = [1 : $children - 1]) { children(i); } } else { for (i = [1 : $children - 1]) { children(i); } } } } } else if (render) { render(convexity = convexity) { draw(difference = difference, intersection = intersection, hull = hull, minkowski = minkowski, union = union) { if ($children > 0) { children(0); } if ($children > 1) { if (intersection) { intersection_for (i = [1 : $children - 1]) { children(i); } } else { for (i = [1 : $children - 1]) { children(i); } } } } } } else if (difference) { difference() { if ($children > 0) { children(0); } for (i = [1 : $children - 1]) { children(i); } } } else if (minkowski) { minkowski() { if ($children > 0) { children(0); } for (i = [1 : $children - 1]) { children(i); } } } else if (intersection) { intersection() { if ($children > 0) { children(0); } if ($children > 1) { intersection_for (i = [1 : $children - 1]) { children(i); } } } } else if (hull) { hull() { if ($children > 0) { children(0); } if ($children > 1) { children(1); } if ($children > 2) { children(2); } if ($children > 3) { children(3); } if ($children > 4) { children(4); } if ($children > 5) { children(5); } if ($children > 6) { children(6); } if ($children > 7) { children(7); } if ($children > 8) { children(8); } if ($children > 9) { children(9); } if ($children > 10) { children(10); } if ($children > 11) { children(11); } if ($children > 12) { for (i = [12 : $children - 1]) { children(i); } } } } else if (union) { union() { if ($children > 0) { for (i = [0 : $children - 1]) { children(i); } } } } else { if ($children > 0) { for (i = [0 : $children - 1]) { children(i); } } } } } On Fri, Jun 14, 2019 at 6:48 AM nop head <nop.head@gmail.com> wrote: > > Yes that is the way I would would apply conditional operations without duplication. Example here: https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/utils/core/bom.scad#L54 > > The other way is to wrap the duplicated code in a module so it can be used in both paths of the if. The module can be nested inside another. An example here: https://github.com/nophead/NopSCADlib/blob/34a9b0e87bd5bc7fb301c2f409381d120799a77e/vitamins/toggle.scad#L150 > > On Fri, 14 Jun 2019 at 10:23, korpx <andreas.thorn@gmail.com> wrote: >> >> I guess I could make a "proxy" module and go through that. Any other ideas? >> >> >> $renderit=1; >> >> module renderfunc() { >> if ($renderit) { >> color("Green") >> render() >> children(); >> } else { >> color("Blue") >> children(); >> } >> } >> >> renderfunc() cube([5,5,5]); //Render this if $renderit=1 >> cube([3,3,3]); //Always preview this unless F6 is used >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
JB
Jordan Brown
Fri, Jun 14, 2019 4:07 PM

Why is
    hull() { ... }
different from
    hull() { union { ... } }
?

Hull just stretches shrink plastic over its children; why does it matter
whether they are one object or many?

Why is     hull() { ... } different from     hull() { union { ... } } ? Hull just stretches shrink plastic over its children; why does it matter whether they are one object or many?
NH
nop head
Fri, Jun 14, 2019 4:19 PM

Because hull is fast but union is very slow, so you have to avoid any
implicit unions in hull's children.

On Fri, 14 Jun 2019 at 17:08, Jordan Brown openscad@jordan.maileater.net
wrote:

Why is
hull() { ... }
different from
hull() { union { ... } }
?

Hull just stretches shrink plastic over its children; why does it matter
whether they are one object or many?


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

Because hull is fast but union is very slow, so you have to avoid any implicit unions in hull's children. On Fri, 14 Jun 2019 at 17:08, Jordan Brown <openscad@jordan.maileater.net> wrote: > Why is > hull() { ... } > different from > hull() { union { ... } } > ? > > Hull just stretches shrink plastic over its children; why does it matter > whether they are one object or many? > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
AC
A. Craig West
Fri, Jun 14, 2019 4:56 PM

That may well have been the problem

On Fri, Jun 14, 2019 at 12:20 PM nop head nop.head@gmail.com wrote:

Because hull is fast but union is very slow, so you have to avoid any implicit unions in hull's children.

On Fri, 14 Jun 2019 at 17:08, Jordan Brown openscad@jordan.maileater.net wrote:

Why is
hull() { ... }
different from
hull() { union { ... } }
?

Hull just stretches shrink plastic over its children; why does it matter whether they are one object or many?


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

That may well have been the problem On Fri, Jun 14, 2019 at 12:20 PM nop head <nop.head@gmail.com> wrote: > > Because hull is fast but union is very slow, so you have to avoid any implicit unions in hull's children. > > On Fri, 14 Jun 2019 at 17:08, Jordan Brown <openscad@jordan.maileater.net> wrote: >> >> Why is >> hull() { ... } >> different from >> hull() { union { ... } } >> ? >> >> Hull just stretches shrink plastic over its children; why does it matter whether they are one object or many? >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org