From cb363df358a70a1f366085773d13a3875a1ceda5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 3 Feb 2012 23:05:42 +0100 Subject: Added test case and source code comments related to issue #80 diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index 22567f2..c1bdea4 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -39,6 +39,8 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) ps->convexity = node.convexity; ps->is2d = true; + // In cut mode, the model is intersected by a large but very thin box living on the + // XY plane. if (node.cut_mode) { PolySet cube; @@ -82,8 +84,17 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) cube.append_vertex(x1, y2, z2); CGAL_Nef_polyhedron Ncube = this->cgalevaluator.evaluateCGALMesh(cube); - // N.p3 *= CGAL_Nef_polyhedron3(CGAL_Plane(0, 0, 1, 0), CGAL_Nef_polyhedron3::INCLUDED); sum *= Ncube; + + // FIXME: Instead of intersecting with a thin volume, we could intersect + // with a plane. This feels like a better solution. However, as the result + // of such an intersection isn't simple, we cannot convert the resulting + // Nef polyhedron to a Polyhedron using convertToPolyset() and we need + // another way of extracting the result. kintel 20120203. +// *sum.p3 = sum.p3->intersection(CGAL_Nef_polyhedron3::Plane_3(0, 0, 1, 0), +// CGAL_Nef_polyhedron3::PLANE_ONLY); + + if (!sum.p3->is_simple()) { PRINT("WARNING: Body of projection(cut = true) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; @@ -91,6 +102,12 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) PolySet *ps3 = sum.convertToPolyset(); if (!ps3) return NULL; + + // Extract polygons in the XY plane, ignoring all other polygons + // FIXME: If the polyhedron is really thin, there might be unwanted polygons + // in the XY plane, causing the resulting 2D polygon to be self-intersection + // and cause a crash in CGALEvaluator::PolyReducer. The right solution is to + // filter these polygons here. kintel 20120203. Grid2d conversion_grid(GRID_COARSE); for (size_t i = 0; i < ps3->polygons.size(); i++) { for (size_t j = 0; j < ps3->polygons[i].size(); j++) { @@ -114,6 +131,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) } delete ps3; } + // In projection mode all the triangles are projected manually into the XY plane else { if (!sum.p3->is_simple()) { diff --git a/testdata/scad/bugs/projectioncrash.scad b/testdata/scad/bugs/projectioncrash.scad new file mode 100644 index 0000000..532ef8d --- /dev/null +++ b/testdata/scad/bugs/projectioncrash.scad @@ -0,0 +1,5 @@ +// This causes OpenSCAD to crash. See source code comments: +// PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) +// Se also https://github.com/openscad/openscad/issues/80 + +projection(cut=true) translate([0,0,-4.999999]) cube(10, center=true); diff --git a/testdata/scad/features/projection-tests.scad b/testdata/scad/features/projection-tests.scad index e1b05c7..edb65ba 100644 --- a/testdata/scad/features/projection-tests.scad +++ b/testdata/scad/features/projection-tests.scad @@ -8,3 +8,6 @@ projection(cut=true) { square(); } linear_extrude(height=20) projection(cut=false) sphere(r=10); translate([22,0,0]) linear_extrude(height=20) projection(cut=true) translate([0,0,9]) sphere(r=10); translate([44,0,0]) linear_extrude(height=20) projection(cut=true) translate([0,0,7]) sphere(r=10); + +// Boundary case: clipping the top of a cube +translate([0,-22,0]) linear_extrude(height=5) projection(cut=true) translate([0,0,-4.999999]) cube(10, center=true); -- cgit v0.10.1