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

Uncaught TypeError in reTesselateCoplanarPolygons #1360

Open kirevdokimov opened 1 month ago

kirevdokimov commented 1 month ago

I use .union() to merge geometries, but when I do so, it causes errors.

Expected Behavior

Geometries are merged with no issues

Actual Behavior

.union() throws an exception

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at reTesselateCoplanarPolygons (reTesselateCoplanarPolygons.js:176:40)
    at retessellate.js:25:44
    at Array.forEach (<anonymous>)
    at retessellate (retessellate.js:23:14)
    at union8 (unionGeom3.js:21:17)
    at union8 (union.js:42:35)

Steps to Reproduce the Problem

I assume this basic example works for everyone

const c1 = cylinder({ radius: 3, height: 12, center: [0, 0, 5], segments: 12 })
const c2 = cylinder({ radius: 3, height: 18, center: [0, 0, 5], segments: 12 })

const u = union(c1, c2)

Specifications

kirevdokimov commented 1 month ago

polygonindexKey is equal to "clear" or "remove" while we iterate over startingpolygonindexes, what causes vertices2d to be undefined. image image

If we check for Nan with if (isNaN(polygonindexKey)) continue line, other issue occurs:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '1')
    at interpolateBetween2DPointsForY (interpolateBetween2DPointsForY.js:11:16)
    at reTesselateCoplanarPolygons (reTesselateCoplanarPolygons.js:226:15)
    at retessellate.js:25:44
    at Array.forEach (<anonymous>)
    at retessellate (retessellate.js:23:14)
    at union8 (unionGeom3.js:21:17)
    at union8 (union.js:42:35)
kirevdokimov commented 1 month ago

This is because activepolygonKey is equal to "clear" or "remove" sometimes as well. image Checking for NaN here with if (isNaN(activepolygonKey)) continue line solves the issue

z3dev commented 1 month ago

@kirevdokimov thanks for the excellent example, and the in-depth analysis.

there are lots of tests but not for this specific example. Given the similarity of the two cylinders, there's obviously something about the retellsation. Have you taken a look at the results of the Union before the retessellation? (Sorry for the spelling)

I'll look over the fix.

kirevdokimov commented 4 weeks ago

Responded in a related merge request: #1361

platypii commented 3 weeks ago

I was not able to reproduce this issue with the example you gave. Maybe I'm missing something?

retess