jscad / OpenJSCAD.org

JSCAD is an open source set of modular, browser and command line tools for creating parametric 2D and 3D designs with JavaScript code. It provides a quick, precise and reproducible method for generating 3D models, and is especially useful for 3D printing applications.
https://openjscad.xyz/
MIT License
2.65k stars 514 forks source link

V2 - extrudeLinear mutates the input 2d shape #1251

Open tsuckow opened 1 year ago

tsuckow commented 1 year ago

Expected Behavior

The original input 2d shape's translation to be preserved

image Note: Image generate with workaround noted below

Actual Behavior

The z translation of the shape is 0'd

image

Steps to Reproduce the Problem

https://gist.github.com/tsuckow/b8569b1e061dc0286cb95517ca4add2b

  1. Create a 2d shape "h1"
  2. Translate it in the Z axis "h2"
  3. extrudeLinear
  4. Output both "h2" and the extruded shape

Workaround

Wrapping the original 2d shape in an erroneous translate([0,0,0], orig) creates a clone to be mutated

Then "retranslate" the extruded shape

Specifications

z3dev commented 1 year ago

@tsuckow translating a 2D shape to another dimension doesn't really work. So, don't do it.

In other words, there's no way to know what will happen.

by the way, the viewer presents whatever is possible. What actually happens to the 2D shape upon export is unknown.

tsuckow commented 1 year ago

In that case it may be fine that the output of extrude linear is "0'd" but I would still claim it should not mutate the object passed to it. If V2 is supposed to be a pure functional paradigm then that side effect violates the pureness.

If changing behavior is a concern in V2, consider it a v3 request to consider inputs immutable.

z3dev commented 9 months ago

Actually, the 2D geometry contains both matrix and set of points. After the translate(), the matrix is adjusted Z+ 10. The rendering shows the 2D object laying above the XY plane, but the 2D geometry is not really.

When the 2D geometry is used in other functions, the set of points is retrieved, i.e. geom2.getPoints(). Its here that the points are adjusted, and the matrix reset. This is the expected behavior as this boosts the performance of operations on geometry.

The bug actually resides in the rendering, which does not call geom2.getPoints(). 2D objects should always be rendered on the XY axis.