summaryrefslogtreecommitdiff
path: root/src/CGALEvaluator.cc
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 /src/CGALEvaluator.cc
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
Diffstat (limited to 'src/CGALEvaluator.cc')
-rw-r--r--src/CGALEvaluator.cc98
1 files changed, 51 insertions, 47 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)
{
contact: Jan Huwald // Impressum