"Lazy union" is now experimental in snapshots

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

"Lazy union" is now experimental in snapshots

thehans
The code for this was recently merged and should be available in the latest nightly snapshots.  As with other experimental features, it must be enabled in your preferences to make use of it.

The feature removes "implicit union" from the following builtin modules:
  - for 
  - children
  - let
  - if, if/else
  - echo
  - assert
  - (root aka top-level, and root modifier: '!' )

So children of these module types will basically be interpreted as a list of geometries(aka list nodes) that are applied to the next parent up, instead of grouping and performing union every time.
This has potential to vastly speed up rendering of some types of models.

Marius began work on this years ago, and I've recently updated his branch and added + fixed a few things to prepare it for merging.  So big thanks to Marius for doing the brunt of the work so far!

The plan is to eventually support many other modules including: 
  - (user-defined modules)
  - (the various builtin transformations)
  - color
  - render
  - projection
  - (*maybe* offset, linear_extrude, and rotate_extrude) 

Those last 3 operate on groups of 2D geometries for which union is already fast. so those currently have lowest priority unless someone has a case for needing them.

It was decided that rather than waiting for the changes to be implemented on every possible module type, we should do this incrementally so that some progress can be made and this long-awaited feature can begin getting tested by adventurous users.

For anyone wanting to test it out:  
Be aware that there are some situations where these change will affect output geometry.
In the following "for" is used as an example, but the same applies to any of the currently implemented modules:

difference() { for(...) ... }
    This will result in the object from the first iteration being subtracted by all subsequent iterations.  
    (Only relevant when a list node is the *first* term in the difference operation)

intersection() { for(...) ... }
    This will act the same as "intersection_for" which will eventually be deprecated.  
    (Unlike difference, this applies to list nodes as terms in *any* position)

minkowski() { for(...) ... }
    This will perform minkowski sum such that  each iteration counts as a single term in the operation.

Additionally, when exporting multiple modules which are called directly from the top-level (or where all parents of a module up to the top-level are list nodes), these will result in distinct non-unioned geometries added to the exported file.  If such objects actually intersect, this may produce invalid output, and may be dependent on the consuming program(slicer etc) for whether this actually works or not.
On the other hand, intersecting geometries may actually be desirable for some cases such as 2D DXF export to be used in laser engraving tool paths, where lines happen to cross.
It is currently up to the user to decide when union is actually necessary.  if you want to play it safe you can always wrap your top level in one big union to behave same as before.

There should be no change to behavior unless the "lazy-union" feature is enabled in preferences.  If you find any unexpected behavior as a result of the recent changes, please report it.

The original issue and discussion of these changes is tracked here: https://github.com/openscad/openscad/issues/350

- Hans Loeblich

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: "Lazy union" is now experimental in snapshots

RevarBat
I have a request...  Please require something in the language to turn on lazy unions, so that I can use both files that use it, and older files that require the old behavior without having to change the preferences setting each time.

Maybe something at root level like:

    feature_enable("lazy-unions");

- Revar

 

On Nov 20, 2019, at 2:43 PM, Hans L <[hidden email]> wrote:

The code for this was recently merged and should be available in the latest nightly snapshots.  As with other experimental features, it must be enabled in your preferences to make use of it.

The feature removes "implicit union" from the following builtin modules:
  - for 
  - children
  - let
  - if, if/else
  - echo
  - assert
  - (root aka top-level, and root modifier: '!' )

So children of these module types will basically be interpreted as a list of geometries(aka list nodes) that are applied to the next parent up, instead of grouping and performing union every time.
This has potential to vastly speed up rendering of some types of models.

Marius began work on this years ago, and I've recently updated his branch and added + fixed a few things to prepare it for merging.  So big thanks to Marius for doing the brunt of the work so far!

The plan is to eventually support many other modules including: 
  - (user-defined modules)
  - (the various builtin transformations)
  - color
  - render
  - projection
  - (*maybe* offset, linear_extrude, and rotate_extrude) 

Those last 3 operate on groups of 2D geometries for which union is already fast. so those currently have lowest priority unless someone has a case for needing them.

It was decided that rather than waiting for the changes to be implemented on every possible module type, we should do this incrementally so that some progress can be made and this long-awaited feature can begin getting tested by adventurous users.

For anyone wanting to test it out:  
Be aware that there are some situations where these change will affect output geometry.
In the following "for" is used as an example, but the same applies to any of the currently implemented modules:

difference() { for(...) ... }
    This will result in the object from the first iteration being subtracted by all subsequent iterations.  
    (Only relevant when a list node is the *first* term in the difference operation)

intersection() { for(...) ... }
    This will act the same as "intersection_for" which will eventually be deprecated.  
    (Unlike difference, this applies to list nodes as terms in *any* position)

minkowski() { for(...) ... }
    This will perform minkowski sum such that  each iteration counts as a single term in the operation.

Additionally, when exporting multiple modules which are called directly from the top-level (or where all parents of a module up to the top-level are list nodes), these will result in distinct non-unioned geometries added to the exported file.  If such objects actually intersect, this may produce invalid output, and may be dependent on the consuming program(slicer etc) for whether this actually works or not.
On the other hand, intersecting geometries may actually be desirable for some cases such as 2D DXF export to be used in laser engraving tool paths, where lines happen to cross.
It is currently up to the user to decide when union is actually necessary.  if you want to play it safe you can always wrap your top level in one big union to behave same as before.

There should be no change to behavior unless the "lazy-union" feature is enabled in preferences.  If you find any unexpected behavior as a result of the recent changes, please report it.

The original issue and discussion of these changes is tracked here: https://github.com/openscad/openscad/issues/350

- Hans Loeblich
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: "Lazy union" is now experimental in snapshots

Parkinbot
In reply to this post by thehans
This is great news and has the potential to speed up certain OpenSCAD designs
a lot! However it might introduce a bunch of pitfalls for novice users and
lead to indesireable output (mainly misformed STLs), if it gets standard
behavior.  
That's why I expected the implementation to take another path. Mainly in
form of a lazy_union() operator that inhibits implicit union in an on-demand
fashion for its operands or, as proposed by Revar, some kind of pragma
switch, that allows to apply the new semantics only to dedicated code
sections.
A global switch will likely break a big portion of legacy code and more or
less lead to complete revisioning and testing of complex code chunks, while
a situative switch will be an optional tool that allows to speed up things
specifically "on your own risk", where it makes sense.




thehans wrote

> The code for this was recently merged and should be available in the
> latest
> nightly snapshots.  As with other experimental features, it must be
> enabled
> in your preferences to make use of it.
>
> The feature removes "implicit union" from the following builtin modules:
>   - for
>   - children
>   - let
>   - if, if/else
>   - echo
>   - assert
>   - (root aka top-level, and root modifier: '!' )





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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: "Lazy union" is now experimental in snapshots

MichaelAtOz
Administrator
Such methods are being discussed at
https://github.com/openscad/openscad/issues/3142 I believe wider opinions
are needed.



-----
Admin - email* me if you need anything,  or if I've done something stupid...

* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Admin - email* me if you need anything, or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.
Reply | Threaded
Open this post in threaded view
|

Re: "Lazy union" is now experimental in snapshots

Troberg
In reply to this post by thehans
This would be nice!

It won't affect my code, I always do a union() when that's what I mean, as I
prefer clearer code, so for me, it's just a performance gain.



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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org