summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2012-02-03 22:10:43 (GMT)
committerMarius Kintel <marius@kintel.net>2012-02-03 22:10:43 (GMT)
commit6dde0695f1f4edbae6980fb62ca207630f560095 (patch)
tree2960b49bc570116a7356cc015d5bcb3a3d3b0c5c
parentd7ee4e4f3c17667c0a5bdb3b68d4485ce79869dd (diff)
parentc2c67f2eacd74b560c5c5a428e8a0a7bae4fd55a (diff)
Merge branch 'master' of github.com:openscad/openscad
-rw-r--r--src/PolySetCGALEvaluator.cc20
-rw-r--r--src/export.cc18
-rw-r--r--src/export.h9
-rw-r--r--testdata/scad/bugs/projectioncrash.scad5
-rw-r--r--testdata/scad/features/projection-tests.scad3
5 files changed, 51 insertions, 4 deletions
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<int> 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/src/export.cc b/src/export.cc
index 6dce699..40ce6cb 100644
--- a/src/export.cc
+++ b/src/export.cc
@@ -53,7 +53,6 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output)
output << "solid OpenSCAD_Model\n";
- int facet_count = 0;
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
HFCC hc = fi->facet_begin();
HFCC hc_end = hc;
@@ -198,3 +197,20 @@ void export_dxf(CGAL_Nef_polyhedron *root_N, std::ostream &output)
#endif
+#ifdef DEBUG
+#include <boost/foreach.hpp>
+void export_stl(const PolySet &ps, std::ostream &output)
+{
+ output << "solid OpenSCAD_PolySet\n";
+ BOOST_FOREACH(const PolySet::Polygon &p, ps.polygons) {
+ output << "facet\n";
+ output << "outer loop\n";
+ BOOST_FOREACH(const Vector3d &v, p) {
+ output << "vertex " << v[0] << " " << v[1] << " " << v[2] << "\n";
+ }
+ output << "endloop\n";
+ output << "endfacet\n";
+ }
+ output << "endsolid OpenSCAD_PolySet\n";
+}
+#endif
diff --git a/src/export.h b/src/export.h
index 9750c30..3897be0 100644
--- a/src/export.h
+++ b/src/export.h
@@ -1,13 +1,18 @@
#ifndef EXPORT_H_
#define EXPORT_H_
-#ifdef ENABLE_CGAL
-
#include <iostream>
+#ifdef ENABLE_CGAL
+
void export_stl(class CGAL_Nef_polyhedron *root_N, std::ostream &output);
void export_off(CGAL_Nef_polyhedron *root_N, std::ostream &output);
void export_dxf(CGAL_Nef_polyhedron *root_N, std::ostream &output);
+
+#endif
+
+#ifdef DEBUG
+void export_stl(const class PolySet &ps, std::ostream &output);
#endif
#endif
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);
contact: Jan Huwald // Impressum