More correct handling of empty geometry. Should fix a few crash bugs

master
Marius Kintel 2014-11-27 20:40:37 -05:00
parent c2775d4541
commit fac2340989
2 changed files with 17 additions and 16 deletions

View File

@ -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<const Polygon2d *> children = collectChildren2D(node);
Polygon2d *geometry = NULL;
Polygon2d *geometry = new Polygon2d();
typedef CGAL::Point_2<CGAL::Cartesian<double> > 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<const Geometry> geom;
if (!isSmartCached(node)) {
const Geometry *geometry = node.createGeometry();
assert(geometry);
if (const Polygon2d *polygon = dynamic_cast<const Polygon2d*>(geometry)) {
if (!polygon->isSanitized()) {
Polygon2d *p = ClipperUtils::sanitize(*polygon);

View File

@ -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<ClipperLib::Paths> &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<const Polygon2d*> &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;
}