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.63k stars 512 forks source link

Spurious CAG "area is not closed!" error #185

Closed fischman closed 7 years ago

fischman commented 7 years ago

The code below generates a DXF just fine if the final statement returns either of the two CAGs, but when both are returned the DXF generation dies with: Uncaught Error: Area is not closed!

function main() {
    const c = CAG.fromSides([
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-45.82118740347841168159, -16.85726810555620147625)), new CAG.Vertex(new CSG.Vector2D(-49.30331715865012398581, -14.68093629710870118288))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.10586702080816223770, -15.27604177352110781385)), new CAG.Vertex(new CSG.Vector2D(-48.16645938811709015681, -15.86317173589183227023))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.60419521731581937729, -14.89550781504266296906)), new CAG.Vertex(new CSG.Vector2D(-49.42407001323204696064, -15.67605088949303393520))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.05727291218684626983, -15.48661638542171203881)), new CAG.Vertex(new CSG.Vector2D(-49.10586702080816223770, -15.27604177352110781385))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.30706235399220815907, -15.81529674600091794900)), new CAG.Vertex(new CSG.Vector2D(-46.00505780290426827150, -17.21108547999804727624))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-46.00505780290426827150, -17.21108547999804727624)), new CAG.Vertex(new CSG.Vector2D(-45.85939703723252591772, -17.21502856394236857795))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-45.85939703723252591772, -17.21502856394236857795)), new CAG.Vertex(new CSG.Vector2D(-45.74972032664388166268, -17.11909303495791334626))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-45.74972032664388166268, -17.11909303495791334626)), new CAG.Vertex(new CSG.Vector2D(-45.73424573227583067592, -16.97420292661295349035))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-45.73424573227583067592, -16.97420292661295349035)), new CAG.Vertex(new CSG.Vector2D(-45.82118740347841168159, -16.85726810555620147625))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.30331715865012398581, -14.68093629710870118288)), new CAG.Vertex(new CSG.Vector2D(-49.45428884427643367871, -14.65565769658912387285))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.45428884427643367871, -14.65565769658912387285)), new CAG.Vertex(new CSG.Vector2D(-49.57891661679624917269, -14.74453612941635327616))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.57891661679624917269, -14.74453612941635327616)), new CAG.Vertex(new CSG.Vector2D(-49.60419521731581937729, -14.89550781504266296906))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.42407001323204696064, -15.67605088949303393520)), new CAG.Vertex(new CSG.Vector2D(-49.30706235399220815907, -15.81529674600091794900))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-48.16645938811709015681, -15.86317173589183227023)), new CAG.Vertex(new CSG.Vector2D(-49.05727291218684626983, -15.48661638542171203881))),
    ]);

    const d = CAG.fromSides([
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.03431352173912216585, -15.58610714407888764299)), new CAG.Vertex(new CSG.Vector2D(-49.21443872582289458251, -14.80556406962851667686))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-68.31614651314507113966, -3.10790373951434872879)), new CAG.Vertex(new CSG.Vector2D(-49.34036769611472550423, -15.79733157434056778357))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.58572929483430868913, -14.97552686612213790340)), new CAG.Vertex(new CSG.Vector2D(-49.53755741140093959984, -15.18427183431472826669))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.53755741140093959984, -15.18427183431472826669)), new CAG.Vertex(new CSG.Vector2D(-54.61235529924312714911, -11.79066769321313756791))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.30227466841120076424, -14.68159232649114187552)), new CAG.Vertex(new CSG.Vector2D(-68.09792828135776687759, -2.77270756611528668145))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.21443872582289458251, -14.80556406962851667686)), new CAG.Vertex(new CSG.Vector2D(-49.30227466841120076424, -14.68159232649114187552))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.34036769611472550423, -15.79733157434056778357)), new CAG.Vertex(new CSG.Vector2D(-49.18823337756091262918, -15.82684012194931710837))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.18823337756091262918, -15.82684012194931710837)), new CAG.Vertex(new CSG.Vector2D(-49.06069007212390431505, -15.73881563386780157998))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-49.06069007212390431505, -15.73881563386780157998)), new CAG.Vertex(new CSG.Vector2D(-49.03431352173912216585, -15.58610714407888764299))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-68.09792828135776687759, -2.77270756611528668145)), new CAG.Vertex(new CSG.Vector2D(-68.24753735887460948106, -2.74623350179570024920))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-68.24753735887460948106, -2.74623350179570024920)), new CAG.Vertex(new CSG.Vector2D(-68.37258141465594007968, -2.83253376987636329432))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-68.37258141465594007968, -2.83253376987636329432)), new CAG.Vertex(new CSG.Vector2D(-68.40089829889257089235, -2.98180502037078554167))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-68.40089829889257089235, -2.98180502037078554167)), new CAG.Vertex(new CSG.Vector2D(-68.31614651314507113966, -3.10790373951434872879))),
        new CAG.Side(new CAG.Vertex(new CSG.Vector2D(-54.61235529924312714911, -11.79066769321313756791)), new CAG.Vertex(new CSG.Vector2D(-49.58572929483430868913, -14.97552686612213790340))),
    ]);

    return [c];  // "Generate DXF" works.
    return [d];  // "Generate DXF" works
    return [c, d];  // "Generate DXF" doesn't work.
}
z3dev commented 7 years ago

@fischman thanks I think there was a small bug introduced last release for 2D format exports. I think this is fixed in the pending 0.5.2 release, and will try.

fischman commented 7 years ago

FWIW I get the same failure on openjscad.org and locally on e16c68a141437321d75b7401d48a851de2b48929

z3dev commented 7 years ago

@fischman Sadly, it looks to be a issue with the CSG.js library. I'm just starting to work with this library, and will log this as a bug against CSG.js.

z3dev commented 7 years ago

@fischman So, I took a look at this today.

Internally, the CAG sides are converted into CSG walls, and then CSG.unionSub() is called to do the work. The resulting CSG is then converted back to CSG sides. Deep inside CSG.unionSub() there's a problem, as the returned CSG (and therefore the CAG) are not properly closed, i.e. polygons are not clean.

This is going to take some time give that I'm now dealing with 3D math.

z3dev commented 7 years ago

This issue was moved to z3dev/hello-world#3

z3dev commented 7 years ago

Ooops! The tools automatically closed this. Reopening.

z3dev commented 7 years ago

This issue was moved to jscad/csg.js#15