From fac2340989564cb03ad6688317e7e49ef156b43c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 27 Nov 2014 20:40:37 -0500 Subject: [PATCH] More correct handling of empty geometry. Should fix a few crash bugs --- src/GeometryEvaluator.cc | 20 +++++++++++++------- src/clipper-utils.cc | 13 ++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 0f50141c..71b52a81 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -90,7 +90,7 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren(const Abstrac } if (dim == 2) { Polygon2d *p2d = applyToChildren2D(node, op); - assert(!p2d || !p2d->isEmpty()); + assert(p2d); return ResultObject(p2d); } else if (dim == 3) return applyToChildren3D(node, op); @@ -129,10 +129,16 @@ GeometryEvaluator::ResultObject GeometryEvaluator::applyToChildren3D(const Abstr } + +/*! + Apply 2D hull. + + May return an empty geometry but will not return NULL. +*/ Polygon2d *GeometryEvaluator::applyHull2D(const AbstractNode &node) { std::vector children = collectChildren2D(node); - Polygon2d *geometry = NULL; + Polygon2d *geometry = new Polygon2d(); typedef CGAL::Point_2 > CGALPoint2; // Collect point cloud @@ -154,7 +160,6 @@ Polygon2d *GeometryEvaluator::applyHull2D(const AbstractNode &node) BOOST_FOREACH(const CGALPoint2 &p, result) { outline.vertices.push_back(Vector2d(p[0], p[1])); } - geometry = new Polygon2d(); geometry->addOutline(outline); } return geometry; @@ -275,12 +280,12 @@ Geometry::ChildList GeometryEvaluator::collectChildren3D(const AbstractNode &nod smartCacheInsert(*chnode, chgeom); if (chgeom) { - if (chgeom->isEmpty() || chgeom->getDimension() == 3) { - children.push_back(item); - } - else { + if (chgeom->getDimension() == 2) { PRINT("WARNING: Ignoring 2D child object for 3D operation"); } + else if (chgeom->isEmpty() || chgeom->getDimension() == 3) { + children.push_back(item); + } } } return children; @@ -447,6 +452,7 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node) shared_ptr geom; if (!isSmartCached(node)) { const Geometry *geometry = node.createGeometry(); + assert(geometry); if (const Polygon2d *polygon = dynamic_cast(geometry)) { if (!polygon->isSanitized()) { Polygon2d *p = ClipperUtils::sanitize(*polygon); diff --git a/src/clipper-utils.cc b/src/clipper-utils.cc index 8754f578..7b1c1463 100644 --- a/src/clipper-utils.cc +++ b/src/clipper-utils.cc @@ -84,9 +84,7 @@ namespace ClipperUtils { /*! Apply the clipper operator to the given paths. - Returns a Polygon2d, or NULL if the result is empty. - - NB! Will not return an empty Polygon2d. + May return an empty Polygon2d, but will not return NULL. */ Polygon2d *apply(const std::vector &pathsvector, ClipperLib::ClipType clipType) @@ -106,7 +104,7 @@ namespace ClipperUtils { clipper.Clear(); } } - return (result.Total() == 0) ? NULL : ClipperUtils::toPolygon2d(result); + return ClipperUtils::toPolygon2d(result); } bool first = true; @@ -116,7 +114,6 @@ namespace ClipperUtils { } ClipperLib::PolyTree sumresult; clipper.Execute(clipType, sumresult, ClipperLib::pftNonZero, ClipperLib::pftNonZero); - if (sumresult.Total() == 0) return NULL; // The returned result will have outlines ordered according to whether // they're positive or negative: Positive outlines counter-clockwise and // negative outlines clockwise. @@ -126,9 +123,7 @@ namespace ClipperUtils { /*! Apply the clipper operator to the given polygons. - Returns a Polygon2d, or NULL if the result is empty. - - NB! Will not return an empty Polygon2d. + May return an empty Polygon2d, but will not return NULL. */ Polygon2d *apply(const std::vector &polygons, ClipperLib::ClipType clipType) @@ -140,7 +135,7 @@ namespace ClipperUtils { pathsvector.push_back(polypaths); } Polygon2d *res = apply(pathsvector, clipType); - assert(!res || !res->isEmpty()); + assert(res); return res; }