On 9/24/26 22:23, Jordan Brown via Discuss wrote:
Gene asked for more of a discussion of the example that I gave as
problematic for Lazy Union.
I had said:
Q. Why did it do that?
A. With LU, the "for" doesn't get implicitly unioned; instead, it
stays separate as two children of the intersection. The
intersection then has three children (sphere, sphere, cube) that
it intersects. (But: if you had to ask, isn't that a problem?)
and Gene said:
It would seem so to me. I see the first render as a possible mistaken
use of "scope". Probably because I don't always understand it
myself. Perhaps some educational conversation is indicated? So far,
everything I have done hasn't used BOSL2 but once.
There's no BOSL2 in this picture, but I'm happy to go through it in
more detail.
Here's the example again:
intersection() {
for(x=[-1,1])
translate([x,0,0]*10)
sphere(15);
cube(25, center=true);
}
what happens if the cube statement is moved to the first argument of the
intersection?
And I've not yet discerned how to "turn on" this LU?
Here's its result in standard OpenSCAD:
Why does it get that result?
The "for" loop generates two spheres, which are implicitly unioned so
that there's one "two spheres mushed into each other" shape:
The intersection then intersects that sort-of-dumbell-shaped shape
with a centered cube, chopping off the top, bottom, front, back, left,
and right sides. Highlighting the cube with #:
Now, to be clear: is this particular model useful for anything real?
Eh, probably not. It's a contrived, simple example. But are there
more complex variants that might well appear in a "real" model? I
think so. For instance, a cross-section might well involve a very
similar construct. Or maybe an artistic intersection of an array of
shapes with another shape. I'll give a couple of examples at the end.
The point of the message was that with Lazy Union enabled, the results
of the "for" are not implicitly unioned, and the result is as if
you'd said
intersection() {
translate([-10,0,0])
sphere(15);
translate([10,0,0])
sphere(15);
cube(25, center=true);
}
Intersecting the two spheres, highlighting one of them, yields this:
and then intersecting with the cube doesn't change anything, because
the cube (highlighted) is larger than that:
I promised a couple of perhaps-more-realistic models. I'm not
explaining them in detail, but I hope that you can see how they relate
to my original simple example.
Mightn't something like this (an intersection of an array of spheres
with a cube) show up in an artistic model?
Or something like this (an intersection of an array of cubes with a
sphere)?
Or, again simplified, this sort of cross-section cut? This particular
example does not use intersection; it demonstrates a related problem
with difference; the LU result is:
Gene
what happens if the cube statement is moved to the first argument of the intersection?
Same. The order of items in an intersection() makes no difference.
And I've not yet discerned how to "turn on" this LU?
In a Nightly, Edit/Preferences/Experimental/Lazy-Union (check-box).
From: maurice e heskett via Discuss [mailto:discuss@lists.openscad.org]
Sent: Friday, September 25, 2026 2:24 PM
To: discuss@lists.openscad.org
Cc: maurice e heskett
Subject: [OpenSCAD] Re: Deeper analysis of my intersection example (was Re: Re: Why LazyUnion cannot survive in its current form)
On 9/24/26 22:23, Jordan Brown via Discuss wrote:
Gene asked for more of a discussion of the example that I gave as problematic for Lazy Union.
I had said:
Q. Why did it do that?
A. With LU, the "for" doesn't get implicitly unioned; instead, it stays separate as two children of the intersection. The intersection then has three children (sphere, sphere, cube) that it intersects. (But: if you had to ask, isn't that a problem?)
and Gene said:
It would seem so to me. I see the first render as a possible mistaken use of "scope". Probably because I don't always understand it myself. Perhaps some educational conversation is indicated? So far, everything I have done hasn't used BOSL2 but once.
There's no BOSL2 in this picture, but I'm happy to go through it in more detail.
Here's the example again:
intersection() {
for(x=[-1,1])
translate([x,0,0]*10)
sphere(15);
cube(25, center=true);
}
what happens if the cube statement is moved to the first argument of the intersection?
And I've not yet discerned how to "turn on" this LU?
Here's its result in standard OpenSCAD:
Why does it get that result?
The "for" loop generates two spheres, which are implicitly unioned so that there's one "two spheres mushed into each other" shape:
The intersection then intersects that sort-of-dumbell-shaped shape with a centered cube, chopping off the top, bottom, front, back, left, and right sides. Highlighting the cube with #:
Now, to be clear: is this particular model useful for anything real? Eh, probably not. It's a contrived, simple example. But are there more complex variants that might well appear in a "real" model? I think so. For instance, a cross-section might well involve a very similar construct. Or maybe an artistic intersection of an array of shapes with another shape. I'll give a couple of examples at the end.
The point of the message was that with Lazy Union enabled, the results of the "for" are not implicitly unioned, and the result is as if you'd said
intersection() {
translate([-10,0,0])
sphere(15);
translate([10,0,0])
sphere(15);
cube(25, center=true);
}
Intersecting the two spheres, highlighting one of them, yields this:
and then intersecting with the cube doesn't change anything, because the cube (highlighted) is larger than that:
I promised a couple of perhaps-more-realistic models. I'm not explaining them in detail, but I hope that you can see how they relate to my original simple example.
Mightn't something like this (an intersection of an array of spheres with a cube) show up in an artistic model?
Or something like this (an intersection of an array of cubes with a sphere)?
Or, again simplified, this sort of cross-section cut? This particular example does not use intersection; it demonstrates a related problem with difference; the LU result is:
Gene
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On 9/24/2026 10:38 PM, Michael Marx (spin) via Discuss wrote:
And I've not yet discerned how to "turn on" this LU?
In a Nightly, Edit/Preferences/Experimental/Lazy-Union (check-box).
In nightlies that are older than Sept 5 or so, it's Preferences/Features.
On 9/24/2026 10:23 PM, maurice e heskett via Discuss wrote:
what happens if the cube statement is moved to the first argument of
the intersection?
To add on to what Michael said...
intersection, union (including implicit union), and (I believe)
Minkowski are all commutative operators. You can rearrange their
children without changing the result.
difference is not commutative; its first child is "positive" and the
rest are "negative".
This is analogous to ordinary arithmetic, where A+B is the same as B+A,
but A-B is not the same as B-A. (And A-B-C is the same as A-C-B.)
I just downloaded latest Nightly 2026.09.23 (zip) and it is still Preferences/Experimental. Your change has got bogged somewhere.
From: Jordan Brown via Discuss [mailto:discuss@lists.openscad.org]
Sent: Friday, September 25, 2026 3:34 PM
To: OpenSCAD general discussion Mailing-list
Cc: Michael Marx (spin); Jordan Brown
Subject: [OpenSCAD] Re: Deeper analysis of my intersection example (was Re: Re: Why LazyUnion cannot survive in its current form)
On 9/24/2026 10:38 PM, Michael Marx (spin) via Discuss wrote:
And I've not yet discerned how to "turn on" this LU?
In a Nightly, Edit/Preferences/Experimental/Lazy-Union (check-box).
In nightlies that are older than Sept 5 or so, it's Preferences/Features.
On 9/24/26 6:45 PM, Jordan Brown via Discuss wrote:
Preserving LU at the top level only would of course be incompatible
with its existing behavior.
If you did as I said (export options) and it was possible (caveat what
you pointed out), it would be backward-compatible. All existing
non-LU-code would render and export the exact same STL. OBJ/3MF would
depend on export option. But doesn't matter, as I changed my mind (see
below).
You'd have to pick them off the the preview or just know what order
they will be in; you couldn't safely statically tie slicer settings to
them. There's no way to add metadata to a part, and so no hope that
you can say "red" and have the slicer automatically pick the extruder
that it's been told has red loaded.
If you're going to be having the model encode this amount of metadata,
I'm thinking you're also going to want to encode modifiers as well,
which means having non-unioned objects taking up the same volume. I
guess you're right, it makes more sense to have an explicit label
("group(part=...)") rather than magically have the top level do this.
Maybe however LU is implemented has some reusable code, or maybe this is
so trivial it doesn't matter.
I can't speak for the maintainers, but I would be surprised if
someone put this in as a new experimental feature and it didn't get
accepted.
I'm not 100% clear on which "this" you're talking about, but if you
mean LU as it exists today... my understanding is that it wasn't
intended as an important-to-users feature.
I meant "don't union the top level" but I guess I disagree now. Haven't
really thought about it in depth for a while.
It was intended as an optimization, reducing render time by skipping
the (usually-expensive) final union and emitting a model that most
slicers could still handle.
Additionally the backward-incompatibility of removing intersection_for
was seen as a positive change to the language and the speed gains were
hoped to make that change more palatable. However, with Manifold
eliminating any speedup and basically no breaking changes (except for
use<>) are deemed acceptable to merge by the BDFL, it's not going to
ever leave experimental.
Manifold has mostly addressed the optimization need, and its other
warts make it undesirable. (Or at least that's my understanding of
the feeling.)
I'm not saying that LU will go away any time soon. People are known
to be (ab)using it for multicolor/multimaterial design. Even if a new
first-class-citizen scheme is introduced, my bet is that LU won't go
away immediately. However, it's pretty clear to me that it won't be
the basis for a new first-class-citizen multicolor/multimaterial scheme.
I think colorscad approach except using "group(part=...)" makes it so
you only need to evaluate once is the simplest way forward. Either
you'll need to ban STL export or union things for export; you'll still
need to address the point you made about render vs export.
I think the easiest fix for OpenSCAD would be the formerly proposed
group("name_of_part") approach.
This would prevent top level parts from being unioned on the toplevel and
several parts including their name would be available for export to 3mf.
Unless OpenSCAD some time in the future makes solids 1st class object,
Then you could write:
export(
{
"case": case1_model,
"lid": lid_model } ,
"properly_annotated_model.3mf")
Cheers
On Fri, Sep 25, 2026 at 8:49 AM Cory Cross via Discuss <
discuss@lists.openscad.org> wrote:
On 9/24/26 6:45 PM, Jordan Brown via Discuss wrote:
Preserving LU at the top level only would of course be incompatible
with its existing behavior.
If you did as I said (export options) and it was possible (caveat what
you pointed out), it would be backward-compatible. All existing
non-LU-code would render and export the exact same STL. OBJ/3MF would
depend on export option. But doesn't matter, as I changed my mind (see
below).
You'd have to pick them off the the preview or just know what order
they will be in; you couldn't safely statically tie slicer settings to
them. There's no way to add metadata to a part, and so no hope that
you can say "red" and have the slicer automatically pick the extruder
that it's been told has red loaded.
If you're going to be having the model encode this amount of metadata,
I'm thinking you're also going to want to encode modifiers as well,
which means having non-unioned objects taking up the same volume. I
guess you're right, it makes more sense to have an explicit label
("group(part=...)") rather than magically have the top level do this.
Maybe however LU is implemented has some reusable code, or maybe this is
so trivial it doesn't matter.
I can't speak for the maintainers, but I would be surprised if
someone put this in as a new experimental feature and it didn't get
accepted.
I'm not 100% clear on which "this" you're talking about, but if you
mean LU as it exists today... my understanding is that it wasn't
intended as an important-to-users feature.
I meant "don't union the top level" but I guess I disagree now. Haven't
really thought about it in depth for a while.
It was intended as an optimization, reducing render time by skipping
the (usually-expensive) final union and emitting a model that most
slicers could still handle.
Additionally the backward-incompatibility of removing intersection_for
was seen as a positive change to the language and the speed gains were
hoped to make that change more palatable. However, with Manifold
eliminating any speedup and basically no breaking changes (except for
use<>) are deemed acceptable to merge by the BDFL, it's not going to
ever leave experimental.
Manifold has mostly addressed the optimization need, and its other
warts make it undesirable. (Or at least that's my understanding of
the feeling.)
I'm not saying that LU will go away any time soon. People are known
to be (ab)using it for multicolor/multimaterial design. Even if a new
first-class-citizen scheme is introduced, my bet is that LU won't go
away immediately. However, it's pretty clear to me that it won't be
the basis for a new first-class-citizen multicolor/multimaterial scheme.
I think colorscad approach except using "group(part=...)" makes it so
you only need to evaluate once is the simplest way forward. Either
you'll need to ban STL export or union things for export; you'll still
need to address the point you made about render vs export.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
On 9/25/26 01:34, Jordan Brown via Discuss wrote:
On 9/24/2026 10:38 PM, Michael Marx (spin) via Discuss wrote:
And I've not yet discerned how to "turn on" this LU?
In a Nightly, Edit/Preferences/Experimental/Lazy-Union (check-box).
In nightlies that are older than Sept 5 or so, it's Preferences/Features.
This version, on this N95 powered toy, is from the repo's, much newer
than 2101 but not a nightly. And it has perms prolems I haven't run
down and swatted yet. I'll need to kill the screen blanker among a long
list of must do's and figure out how to connect to my sons printer which
is by wifi from his windows tablet. Thats probably an OrcaSlicer problem.
This uses xwayland, xset has no effect. :-\
On 9/25/26 01:50, Jordan Brown via Discuss wrote:
On 9/24/2026 10:23 PM, maurice e heskett via Discuss wrote:
what happens if the cube statement is moved to the first argument of
the intersection?
To add on to what Michael said...
intersection, union (including implicit union), and (I believe)
Minkowski are all commutative operators. You can rearrange their
children without changing the result.
difference is not commutative; its first child is "positive" and the
rest are "negative".
Hmmm I was thinking they all worked like difference. My bad. Thanks.
This is analogous to ordinary arithmetic, where A+B is the same as
B+A, but A-B is not the same as B-A. (And A-B-C is the same as A-C-B.)
Gene.
On 9/25/2026 12:24 AM, Michael Marx (spin) via Discuss wrote:
I just downloaded latest Nightly 2026.09.23 (zip) and it is still
Preferences/Experimental. Your change has got bogged somewhere.
Builds older than Sept 5 call it "Features". Builds newer than Sept 5
call it "Experimental".
You talked about "Experimental". I figured that Sept 5 was not so long
ago that we could assume that everybody had picked up a newer build that
includes the Features -> Experimental change.