summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDon Bright <hugh.m.bright@gmail.com>2013-12-15 14:28:36 (GMT)
committerDon Bright <hugh.m.bright@gmail.com>2013-12-15 14:28:36 (GMT)
commitf570b7fd2558d73f8446681be10bc82fa1c283e6 (patch)
tree4cbff6cd9ab60616372158ebc95f724099d32651 /src
parent851ce360b42e8f3efdf65227ef6dbc637563b222 (diff)
add some error checking
Diffstat (limited to 'src')
-rw-r--r--src/dxftess-cgal.cc50
1 files changed, 33 insertions, 17 deletions
diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc
index 85c038f..9c4e6fe 100644
--- a/src/dxftess-cgal.cc
+++ b/src/dxftess-cgal.cc
@@ -353,7 +353,7 @@ because the algorithm we are using doesn't create any new points, and we can
just use a 'map' to associate 3d points with 2d points).
The code assumes the input polygons are simple, non-intersecting, without
-holes, and without duplicate input points.
+holes, without duplicate input points, and with proper orientation.
The purpose of this code is originally to fix github issue 349. Our CGAL
kernel does not accept polygons for Nef_Polyhedron_3 if each of the
@@ -406,26 +406,29 @@ projection_t find_good_projection( PolySet::Polygon pgon ) {
// plane. 'quadrance' (distance squared) can tell this w/o using sqrt.
CGAL::Plane_3<CGAL_Kernel3> pl( cgp(v1), cgp(v2), cgp(v3) );
NT3 qxy = pl.a()*pl.a()+pl.b()*pl.b();
- NT3 qyz = pl.b()*pl.b()+pl.c()*pl.c();
- NT3 qxz = pl.c()*pl.c()+pl.a()*pl.a();
+ NT3 qyz = pl.b()*pl.b()+pl.c()*pl.c();
+ NT3 qxz = pl.c()*pl.c()+pl.a()*pl.a();
NT3 min = std::min(qxy,std::min(qyz,qxz));
if (min==qxy) return XYPLANE;
else if (min==qyz) return YZPLANE;
return XZPLANE;
}
-/* triangulate the given polygon using CGAL's Constrained Delaunay
-algorithm. project the polygon's points using the given projection
-before performing the triangulation. this code assumes input polygon is
-simple, no holes, no self-intersections, no duplicate points, and
+/* triangulate the given polygon using CGAL's 2d Constrained Delaunay
+algorithm. Project the polygon's points into 2d using the given projection
+before performing the triangulation. This code assumes input polygon is
+simple, no holes, no self-intersections, no duplicate points, and is
properly oriented. */
-void triangulate_polygon( const PolySet::Polygon &pgon, std::vector<PolySet::Polygon> &triangles, projection_t projection )
+bool triangulate_polygon( const PolySet::Polygon &pgon, std::vector<PolySet::Polygon> &triangles, projection_t projection )
{
+ bool err = false;
+ CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
+ try {
CDT cdt;
std::vector<Vertex_handle> vhandles;
std::map<CDTPoint,Vector3d> vertmap;
CGAL::Orientation original_orientation;
- std::vector<CDTPoint> orpgon;
+ std::vector<CDTPoint> orienpgon;
for (size_t i = 0; i < pgon.size(); i++) {
Vector3d v3 = pgon.at(i);
Vector2d v2 = get_projected_point( v3, projection );
@@ -433,9 +436,9 @@ void triangulate_polygon( const PolySet::Polygon &pgon, std::vector<PolySet::Pol
vertmap[ cdtpoint ] = v3;
Vertex_handle vh = cdt.insert( cdtpoint );
vhandles.push_back(vh);
- orpgon.push_back( cdtpoint );
+ orienpgon.push_back( cdtpoint );
}
- original_orientation = CGAL::orientation_2( orpgon.begin(),orpgon.end() );
+ original_orientation = CGAL::orientation_2( orienpgon.begin(),orienpgon.end() );
for (size_t i = 0; i < vhandles.size(); i++ ) {
int vindex1 = (i+0);
int vindex2 = (i+1)%vhandles.size();
@@ -468,21 +471,34 @@ void triangulate_polygon( const PolySet::Polygon &pgon, std::vector<PolySet::Pol
triangles.push_back( pgon );
}
}
+ catch (const CGAL::Assertion_exception &e) {
+ PRINTB("CGAL error in dxftess triangulate_polygon: %s", e.what());
+ err = true;
+ }
+ CGAL::set_error_behaviour(old_behaviour);
+ return err;
}
/* Given a 3d PolySet with 'near planar' polygonal faces, Tessellate the
faces. As of writing, our only tessellation method is Triangulation
using CGAL's Constrained Delaunay algorithm. This code assumes the input
-polyset has simple polygon faces with no holes, no self intersections, and no
-duplicate points. */
+polyset has simple polygon faces with no holes, no self intersections, no
+duplicate points, and proper orientation. */
void tessellate_3d_faces( const PolySet &inps, PolySet &outps ) {
for (size_t i = 0; i < inps.polygons.size(); i++) {
const PolySet::Polygon pgon = inps.polygons[i];
- if (pgon.size()<3) continue;
+ if (pgon.size()<3) {
+ PRINT("WARNING: PolySet has polygon with <3 points");
+ continue;
+ }
std::vector<PolySet::Polygon> triangles;
- projection_t projection = find_good_projection( pgon );
- triangulate_polygon( pgon, triangles, projection );
- for (size_t j=0;j<triangles.size();j++) {
+ projection_t goodproj = find_good_projection( pgon );
+ if (goodproj==NONE) {
+ PRINT("WARNING: PolySet has degenerate polygon");
+ continue;
+ }
+ bool err = triangulate_polygon( pgon, triangles, goodproj );
+ if (!err) for (size_t j=0;j<triangles.size();j++) {
PolySet::Polygon t = triangles[j];
outps.append_poly();
outps.append_vertex(t[0].x(),t[0].y(),t[0].z());
contact: Jan Huwald // Impressum