openscad icon indicating copy to clipboard operation
openscad copied to clipboard

internal breaking change 2021.01 vs 2019.05

Open mjk-at-sag opened this issue 3 years ago • 6 comments

module print (emboss=$preview)
    if (emboss) { children(); }
    else { difference() { children(0); children([1:$children-1]); } }

module background ()
    if (false) cube([75, 20, 10], true);

print($preview) {
    background();
    color("black")
        translate([0, 0, 4.5]) linear_extrude(1)
        text(str(version()), valign="center", halign="center");
  }
  1. open with 2021.05

  2. F6 - render

  3. read "WARNING: No top level geometry to render"

  4. F7 - export

  5. read "ERROR: Nothing to export! ..."

  6. open with 2019.05

  7. F6

  8. F7

  9. success


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

mjk-at-sag avatar Mar 09 '21 22:03 mjk-at-sag

@mjk-at-sag This is a consequence of changes from #3342 and how empty geometries are now handled. The bug was in 2019 version, and is now fixed. You are subtracting your text from an empty child background(); so the result is empty geometry.

thehans avatar Mar 11 '21 19:03 thehans

@thehans Very well, I accept that. Now I don't understand why the following two designs produce the same results when previewed (F5) and different results when rendered (F6).

This produces the now correct result:

module print (emboss=$preview)
    if (emboss) { children(); }
    else { difference() { children(0); children([1:$children-1]); } }

module background ()
    if (false) cube([75, 20, 10], true);

print($preview) {
    //////// background();       //////////////// <========
    color("black")
        translate([0, 0, 4.5]) linear_extrude(1)
        text(str(version()), valign="center", halign="center");
    color("red")
        translate([0, 0, -0.5]) linear_extrude(1)
        text(str(version()), valign="center", halign="center");
}

This produces the old incorrect result:

module print (emboss=$preview)
    if (emboss) { children(); }
    else { difference() { children(0); children([1:$children-1]); } }

module background ()
    if (false) cube([75, 20, 10], true);

print($preview) {
    if (false) background();     ////////////////// <=======
    color("black")
        translate([0, 0, 4.5]) linear_extrude(1)
        text(str(version()), valign="center", halign="center");
    color("red")
        translate([0, 0, -0.5]) linear_extrude(1)
        text(str(version()), valign="center", halign="center");
}

mjk-at-sag avatar Mar 12 '21 08:03 mjk-at-sag

OK, I see. The second example does appear to be a bug when rendered with F6.

thehans avatar Mar 13 '21 22:03 thehans

Looking at this, it looks correct: The designs happen to produce the same results when previewed (F5) and different results when rendered (F6) because the design is written to handle previews differently from render.

kintel avatar Mar 31 '24 16:03 kintel

The preview/render difference is presumably related to the $preview.

But the 2019-vs-later difference is, as @thehans described above, based on a change in the behavior of empty geometries.

Here's a test case:

module dummy() {
}

difference() {
    dummy();
    cube(10);
    cube(10, center=true);
}

2019.05 ignores the dummy child, for at least some purposes, and yields a cube with the corner cut out. 2021.01 and later subtract two cubes from nothing, and yield nothing.

Note: in all three, an "if" is counted as a child, but if it fails it yields no geometry. Or something like that. If you change the dummy(); to if (false) dummy();, all three yield the cube with corner cut off; the failing "if" does not count as the first child of the difference.

module dummy() {
}

difference() {
    if (false) dummy();
    cube(10);
    cube(10, center=true);
}

Similarly, if the first child of the difference() is an echo(), it is ignored for geometry purposes and yields the cube-with-cut-corner. However, if the first child of the difference is a module that calls echo() and does nothing else, in 2019.05 it's ignored and in 2021.01 and later that does count for geometry purposes, and you end up with nothing.


My humble opinion is that they are all wrong, though 2021.01 and later are better. Every module invocation, including echo, failing if, and for-that-executes-zero-times, should yield geometry, perhaps empty. Nothing should peek at the resulting geometry, in any way, to handle it specially if it is empty.

jordanbrown0 avatar Mar 31 '24 17:03 jordanbrown0

Further clarification: they should all yield exactly one child, which might be empty geometry.

jordanbrown0 avatar Mar 31 '24 17:03 jordanbrown0