summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2013-01-08 18:26:25 (GMT)
committerMarius Kintel <marius@kintel.net>2013-01-08 18:26:25 (GMT)
commit810f1a86189555023240507848ff9eebb161b8de (patch)
tree287007ba314d94a551d2ef721dfc796598fede6c
parent8cea6834f68cbbfb85c2568d388bf3b2e707cca5 (diff)
Don't just ignore geometric nodes having zero volume/area - when doing difference/intersection, they tend to turn negative objects into positive ones. Fixes #221
-rw-r--r--src/CGALEvaluator.cc98
-rw-r--r--src/CGALRenderer.cc11
-rw-r--r--src/CGAL_Nef_polyhedron.cc5
-rw-r--r--src/CGAL_Nef_polyhedron.h7
-rw-r--r--src/PolySetCGALEvaluator.cc28
-rw-r--r--src/mainwin.cc48
-rw-r--r--testdata/scad/features/difference-tests.scad1
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/cgalpngtest.cc16
-rw-r--r--tests/cgalstlsanitytest.cc2
-rw-r--r--tests/cgaltest.cc2
11 files changed, 113 insertions, 106 deletions
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc
index a4744c2..4deb3b3 100644
--- a/src/CGALEvaluator.cc
+++ b/src/CGALEvaluator.cc
@@ -61,14 +61,16 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr
if (target.dim != 2 && target.dim != 3) {
assert(false && "Dimension of Nef polyhedron must be 2 or 3");
}
- if (src.empty()) return; // Empty polyhedron. This can happen for e.g. square([0,0])
+ if (src.isEmpty()) return; // Empty polyhedron. This can happen for e.g. square([0,0])
+ if (target.isEmpty() && op != CGE_UNION) return; // empty op <something> => empty
if (target.dim != src.dim) return; // If someone tries to e.g. union 2d and 3d objects
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
try {
switch (op) {
case CGE_UNION:
- target += src;
+ if (target.isEmpty()) target = src.copy();
+ else target += src;
break;
case CGE_INTERSECTION:
target *= src;
@@ -110,7 +112,8 @@ CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGA
if (!isCached(*chnode)) {
CGALCache::instance()->insert(this->tree.getIdString(*chnode), chN);
}
- if (N.empty()) N = chN.copy();
+ // Initialize N on first iteration with first expected geometric object
+ if (N.isNull() && !N.isEmpty()) N = chN.copy();
else process(N, chN, op);
chnode->progress_report();
@@ -245,7 +248,6 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node)
if (!isCached(node)) {
// First union all children
N = applyToChildren(node, CGE_UNION);
-
if ( matrix_contains_infinity( node.matrix ) || matrix_contains_nan( node.matrix ) ) {
// due to the way parse/eval works we can't currently distinguish between NaN and Inf
PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object.");
@@ -253,51 +255,53 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node)
}
// Then apply transform
- // If there is no geometry under the transform, N will be empty and of dim 0,
- // just just silently ignore such nodes
- if (N.dim == 2) {
- // Unfortunately CGAL provides no transform method for CGAL_Nef_polyhedron2
- // objects. So we convert in to our internal 2d data format, transform it,
- // tesselate it and create a new CGAL_Nef_polyhedron2 from it.. What a hack!
-
- Eigen::Matrix2f testmat;
- testmat << node.matrix(0,0), node.matrix(0,1), node.matrix(1,0), node.matrix(1,1);
- if (testmat.determinant() == 0) {
- PRINT("Warning: Scaling a 2D object with 0 - removing object");
- N.reset();
- }
- else {
- CGAL_Aff_transformation2 t(
- node.matrix(0,0), node.matrix(0,1), node.matrix(0,3),
- node.matrix(1,0), node.matrix(1,1), node.matrix(1,3), node.matrix(3,3));
+ // If there is no geometry under the transform, N will be empty
+ // just silently ignore such nodes
+ if (!N.isNull()) {
+ if (N.dim == 2) {
+ // Unfortunately CGAL provides no transform method for CGAL_Nef_polyhedron2
+ // objects. So we convert in to our internal 2d data format, transform it,
+ // tesselate it and create a new CGAL_Nef_polyhedron2 from it.. What a hack!
- DxfData *dd = N.convertToDxfData();
- for (size_t i=0; i < dd->points.size(); i++) {
- CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd->points[i][0], dd->points[i][1]);
- p = t.transform(p);
- dd->points[i][0] = to_double(p.x());
- dd->points[i][1] = to_double(p.y());
+ Eigen::Matrix2f testmat;
+ testmat << node.matrix(0,0), node.matrix(0,1), node.matrix(1,0), node.matrix(1,1);
+ if (testmat.determinant() == 0) {
+ PRINT("Warning: Scaling a 2D object with 0 - removing object");
+ N.reset();
+ }
+ else {
+ CGAL_Aff_transformation2 t(
+ node.matrix(0,0), node.matrix(0,1), node.matrix(0,3),
+ node.matrix(1,0), node.matrix(1,1), node.matrix(1,3), node.matrix(3,3));
+
+ DxfData *dd = N.convertToDxfData();
+ for (size_t i=0; i < dd->points.size(); i++) {
+ CGAL_Kernel2::Point_2 p = CGAL_Kernel2::Point_2(dd->points[i][0], dd->points[i][1]);
+ p = t.transform(p);
+ dd->points[i][0] = to_double(p.x());
+ dd->points[i][1] = to_double(p.y());
+ }
+
+ PolySet ps;
+ ps.is2d = true;
+ dxf_tesselate(&ps, *dd, 0, true, false, 0);
+
+ N = evaluateCGALMesh(ps);
+ delete dd;
}
-
- PolySet ps;
- ps.is2d = true;
- dxf_tesselate(&ps, *dd, 0, true, false, 0);
-
- N = evaluateCGALMesh(ps);
- delete dd;
- }
- }
- else if (N.dim == 3) {
- if (node.matrix.matrix().determinant() == 0) {
- PRINT("Warning: Scaling a 3D object with 0 - removing object");
- N.reset();
}
- else {
- CGAL_Aff_transformation t(
- node.matrix(0,0), node.matrix(0,1), node.matrix(0,2), node.matrix(0,3),
- node.matrix(1,0), node.matrix(1,1), node.matrix(1,2), node.matrix(1,3),
- node.matrix(2,0), node.matrix(2,1), node.matrix(2,2), node.matrix(2,3), node.matrix(3,3));
- N.p3->transform(t);
+ else if (N.dim == 3) {
+ if (node.matrix.matrix().determinant() == 0) {
+ PRINT("Warning: Scaling a 3D object with 0 - removing object");
+ N.reset();
+ }
+ else {
+ CGAL_Aff_transformation t(
+ node.matrix(0,0), node.matrix(0,1), node.matrix(0,2), node.matrix(0,3),
+ node.matrix(1,0), node.matrix(1,1), node.matrix(1,2), node.matrix(1,3),
+ node.matrix(2,0), node.matrix(2,1), node.matrix(2,2), node.matrix(2,3), node.matrix(3,3));
+ N.p3->transform(t);
+ }
}
}
}
@@ -388,7 +392,7 @@ void CGALEvaluator::addToParent(const State &state, const AbstractNode &node, co
CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps)
{
- if (ps.empty()) return CGAL_Nef_polyhedron();
+ if (ps.empty()) return CGAL_Nef_polyhedron(ps.is2d ? 2 : 3);
if (ps.is2d)
{
diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc
index adf1217..4357e44 100644
--- a/src/CGALRenderer.cc
+++ b/src/CGALRenderer.cc
@@ -43,7 +43,11 @@
CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root)
{
- if (root.dim == 2) {
+ if (this->root.isNull()) {
+ this->polyhedron = NULL;
+ this->polyset = NULL;
+ }
+ else if (root.dim == 2) {
DxfData *dd = root.convertToDxfData();
this->polyhedron = NULL;
this->polyset = new PolySet();
@@ -67,10 +71,6 @@ CGALRenderer::CGALRenderer(const CGAL_Nef_polyhedron &root) : root(root)
CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(*this->root.p3, this->polyhedron);
this->polyhedron->init();
}
- else {
- this->polyhedron = NULL;
- this->polyset = NULL;
- }
}
CGALRenderer::~CGALRenderer()
@@ -81,6 +81,7 @@ CGALRenderer::~CGALRenderer()
void CGALRenderer::draw(bool showfaces, bool showedges) const
{
+ if (this->root.isNull()) return;
if (this->root.dim == 2) {
// Draw 2D polygons
glDisable(GL_LIGHTING);
diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc
index ad2e4e2..8906595 100644
--- a/src/CGAL_Nef_polyhedron.cc
+++ b/src/CGAL_Nef_polyhedron.cc
@@ -61,7 +61,7 @@ CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &o
int CGAL_Nef_polyhedron::weight() const
{
- if (this->empty()) return 0;
+ if (this->isNull()) return 0;
size_t memsize = sizeof(CGAL_Nef_polyhedron);
if (this->dim == 2) {
@@ -84,8 +84,7 @@ int CGAL_Nef_polyhedron::weight() const
*/
PolySet *CGAL_Nef_polyhedron::convertToPolyset()
{
- if (this->empty())
- return new PolySet();
+ if (this->isNull()) return new PolySet();
PolySet *ps = NULL;
if (this->dim == 2) {
ps = new PolySet();
diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h
index e8c505b..d949a2a 100644
--- a/src/CGAL_Nef_polyhedron.h
+++ b/src/CGAL_Nef_polyhedron.h
@@ -8,12 +8,15 @@
class CGAL_Nef_polyhedron
{
public:
- CGAL_Nef_polyhedron() : dim(0) {}
+ CGAL_Nef_polyhedron(int dim = 0) : dim(dim) {}
CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p);
CGAL_Nef_polyhedron(CGAL_Nef_polyhedron3 *p);
~CGAL_Nef_polyhedron() {}
- bool empty() const { return (dim == 0 || (!p2 && !p3)); }
+ // Empty means it is a geometric node which has zero area/volume
+ bool isEmpty() const { return (dim > 0 && !p2 && !p3); }
+ // Null means the node doesn't contain any geometry (for whatever reason)
+ bool isNull() const { return !p2 && !p3; }
void reset() { dim=0; p2.reset(); p3.reset(); }
CGAL_Nef_polyhedron &operator+=(const CGAL_Nef_polyhedron &other);
CGAL_Nef_polyhedron &operator*=(const CGAL_Nef_polyhedron &other);
diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc
index 8e08e19..224e657 100644
--- a/src/PolySetCGALEvaluator.cc
+++ b/src/PolySetCGALEvaluator.cc
@@ -134,11 +134,11 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
if (N.dim == 3) {
- if (sum.empty()) sum = N.copy();
+ if (sum.isNull()) sum = N.copy();
else sum += N;
}
}
- if (sum.empty()) return NULL;
+ if (sum.isNull()) return NULL;
if (!sum.p3->is_simple()) {
if (!node.cut_mode) {
PRINT("WARNING: Body of projection(cut = false) isn't valid 2-manifold! Modify your design..");
@@ -149,7 +149,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
//std::cout << sum.dump();
//std::cout.flush();
- CGAL_Nef_polyhedron nef_poly;
+ CGAL_Nef_polyhedron nef_poly(2);
if (node.cut_mode) {
CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
@@ -180,7 +180,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
}
}
- if ( sum.p3->is_empty() ) {
+ if (sum.p3->is_empty()) {
CGAL::set_error_behaviour(old_behaviour);
PRINT("WARNING: projection() failed.");
return NULL;
@@ -204,7 +204,6 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
log << "<!-- volume end. -->\n";
}
nef_poly.p2 = zremover.output_nefpoly2d;
- nef_poly.dim = 2;
} catch (const CGAL::Failure_exception &e) {
PRINTB("CGAL error in projection node while flattening: %s", e.what());
}
@@ -284,8 +283,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
plist.push_back(p);
}
// FIXME: Should the CGAL_Nef_polyhedron2 be cached?
- if (nef_poly.empty()) {
- nef_poly.dim = 2;
+ if (nef_poly.isEmpty()) {
nef_poly.p2.reset(new CGAL_Nef_polyhedron2(plist.begin(), plist.end(), CGAL_Nef_polyhedron2::INCLUDED));
}
else {
@@ -385,18 +383,18 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const LinearExtrudeNode &node)
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
- if (!N.empty()) {
+ if (!N.isNull()) {
if (N.dim != 2) {
PRINT("ERROR: linear_extrude() is not defined for 3D child objects!");
}
else {
- if (sum.empty()) sum = N.copy();
+ if (sum.isNull()) sum = N.copy();
else sum += N;
}
}
}
- if (sum.empty()) return NULL;
+ if (sum.isNull()) return NULL;
dxf = sum.convertToDxfData();;
} else {
dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
@@ -485,18 +483,18 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RotateExtrudeNode &node)
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
- if (!N.empty()) {
+ if (!N.isNull()) {
if (N.dim != 2) {
PRINT("ERROR: rotate_extrude() is not defined for 3D child objects!");
}
else {
- if (sum.empty()) sum = N.copy();
+ if (sum.isNull()) sum = N.copy();
else sum += N;
}
}
}
- if (sum.empty()) return NULL;
+ if (sum.isNull()) return NULL;
dxf = sum.convertToDxfData();
} else {
dxf = new DxfData(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
@@ -511,7 +509,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const CgaladvNode &node)
{
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
- if (!N.empty()) {
+ if (!N.isNull()) {
ps = N.convertToPolyset();
if (ps) ps->convexity = node.convexity;
}
@@ -523,7 +521,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RenderNode &node)
{
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(node);
PolySet *ps = NULL;
- if (!N.empty()) {
+ if (!N.isNull()) {
if (N.dim == 3 && !N.p3->is_simple()) {
PRINT("WARNING: Body of render() isn't valid 2-manifold!");
}
diff --git a/src/mainwin.cc b/src/mainwin.cc
index dc5b79b..dde6761 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -1236,35 +1236,37 @@ void MainWindow::actionRenderCGALDone(CGAL_Nef_polyhedron *root_N)
PolySetCache::instance()->print();
CGALCache::instance()->print();
- if (root_N->dim == 2) {
- PRINT(" Top level object is a 2D object:");
- PRINTB(" Empty: %6s", (root_N->p2->is_empty() ? "yes" : "no"));
- PRINTB(" Plane: %6s", (root_N->p2->is_plane() ? "yes" : "no"));
- PRINTB(" Vertices: %6d", root_N->p2->explorer().number_of_vertices());
- PRINTB(" Halfedges: %6d", root_N->p2->explorer().number_of_halfedges());
- PRINTB(" Edges: %6d", root_N->p2->explorer().number_of_edges());
- PRINTB(" Faces: %6d", root_N->p2->explorer().number_of_faces());
- PRINTB(" FaceCycles: %6d", root_N->p2->explorer().number_of_face_cycles());
- PRINTB(" ConnComp: %6d", root_N->p2->explorer().number_of_connected_components());
- }
-
- if (root_N->dim == 3) {
- PRINT(" Top level object is a 3D object:");
- PRINTB(" Simple: %6s", (root_N->p3->is_simple() ? "yes" : "no"));
- PRINTB(" Valid: %6s", (root_N->p3->is_valid() ? "yes" : "no"));
- PRINTB(" Vertices: %6d", root_N->p3->number_of_vertices());
- PRINTB(" Halfedges: %6d", root_N->p3->number_of_halfedges());
- PRINTB(" Edges: %6d", root_N->p3->number_of_edges());
- PRINTB(" Halffacets: %6d", root_N->p3->number_of_halffacets());
- PRINTB(" Facets: %6d", root_N->p3->number_of_facets());
- PRINTB(" Volumes: %6d", root_N->p3->number_of_volumes());
+ if (!root_N->isNull()) {
+ if (root_N->dim == 2) {
+ PRINT(" Top level object is a 2D object:");
+ PRINTB(" Empty: %6s", (root_N->p2->is_empty() ? "yes" : "no"));
+ PRINTB(" Plane: %6s", (root_N->p2->is_plane() ? "yes" : "no"));
+ PRINTB(" Vertices: %6d", root_N->p2->explorer().number_of_vertices());
+ PRINTB(" Halfedges: %6d", root_N->p2->explorer().number_of_halfedges());
+ PRINTB(" Edges: %6d", root_N->p2->explorer().number_of_edges());
+ PRINTB(" Faces: %6d", root_N->p2->explorer().number_of_faces());
+ PRINTB(" FaceCycles: %6d", root_N->p2->explorer().number_of_face_cycles());
+ PRINTB(" ConnComp: %6d", root_N->p2->explorer().number_of_connected_components());
+ }
+
+ if (root_N->dim == 3) {
+ PRINT(" Top level object is a 3D object:");
+ PRINTB(" Simple: %6s", (root_N->p3->is_simple() ? "yes" : "no"));
+ PRINTB(" Valid: %6s", (root_N->p3->is_valid() ? "yes" : "no"));
+ PRINTB(" Vertices: %6d", root_N->p3->number_of_vertices());
+ PRINTB(" Halfedges: %6d", root_N->p3->number_of_halfedges());
+ PRINTB(" Edges: %6d", root_N->p3->number_of_edges());
+ PRINTB(" Halffacets: %6d", root_N->p3->number_of_halffacets());
+ PRINTB(" Facets: %6d", root_N->p3->number_of_facets());
+ PRINTB(" Volumes: %6d", root_N->p3->number_of_volumes());
+ }
}
int s = this->progresswidget->elapsedTime() / 1000;
PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60));
this->root_N = root_N;
- if (!this->root_N->empty()) {
+ if (!this->root_N->isNull()) {
this->cgalRenderer = new CGALRenderer(*this->root_N);
// Go to CGAL view mode
if (viewActionCGALGrid->isChecked()) {
diff --git a/testdata/scad/features/difference-tests.scad b/testdata/scad/features/difference-tests.scad
index 186772f..b770764 100644
--- a/testdata/scad/features/difference-tests.scad
+++ b/testdata/scad/features/difference-tests.scad
@@ -29,6 +29,7 @@ translate([24,0,0]) difference() {
translate([0,0,6.99]) cylinder(r=4, h=4, center=true);
}
+// Subtracting something from nothing
translate([24,12,0]) difference() {
cube([0,10,10], center=true);
# cylinder(r=4, h=20, center=true);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 18f4469..87e5319 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -773,7 +773,6 @@ set_test_config(Heavy opencsgtest_minkowski3-tests
cgalpngtest_minkowski3-tests
cgalpngtest_for-tests
cgalpngtest_for-nested-tests
- cgalpngtest_difference-tests
cgalpngtest_intersection-tests)
foreach(FILE ${EXAMPLE_FILES})
diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc
index 08e539e..56861c6 100644
--- a/tests/cgalpngtest.cc
+++ b/tests/cgalpngtest.cc
@@ -153,30 +153,30 @@ int main(int argc, char **argv)
exit(1);
}
- CGALRenderer cgalRenderer(N);
-
+ CGALRenderer cgalRenderer(N);
+
BoundingBox bbox;
if (cgalRenderer.polyhedron) {
CGAL::Bbox_3 cgalbbox = cgalRenderer.polyhedron->bbox();
bbox = BoundingBox(Vector3d(cgalbbox.xmin(), cgalbbox.ymin(), cgalbbox.zmin()),
- Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()));
+ Vector3d(cgalbbox.xmax(), cgalbbox.ymax(), cgalbbox.zmax()));
}
else if (cgalRenderer.polyset) {
bbox = cgalRenderer.polyset->getBoundingBox();
}
-
+
Vector3d center = getBoundingCenter(bbox);
double radius = getBoundingRadius(bbox);
-
+
Vector3d cameradir(1, 1, -0.5);
Vector3d camerapos = center - radius*2*cameradir;
csgInfo.glview->setCamera(camerapos, center);
-
-
+
+
csgInfo.glview->setRenderer(&cgalRenderer);
csgInfo.glview->paintGL();
csgInfo.glview->save(outfile);
-
+
delete root_node;
delete root_module;
diff --git a/tests/cgalstlsanitytest.cc b/tests/cgalstlsanitytest.cc
index 137f626..52cfb41 100644
--- a/tests/cgalstlsanitytest.cc
+++ b/tests/cgalstlsanitytest.cc
@@ -129,7 +129,7 @@ int main(int argc, char **argv)
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
current_path(original_path);
- if (!N.empty()) {
+ if (!N.isNull()) {
std::ofstream outfile;
outfile.open(outfilename);
diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc
index e4761db..b546286 100644
--- a/tests/cgaltest.cc
+++ b/tests/cgaltest.cc
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
current_path(original_path);
- if (!N.empty()) {
+ if (!N.isNull()) {
export_stl(&N, std::cout);
}
contact: Jan Huwald // Impressum