#ifdef ENABLE_CGAL #include "cgalutils.h" #include "polyset.h" #include "printutils.h" #include "cgal.h" #include PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p) { PolySet *ps = new PolySet(); typedef CGAL_Polyhedron::Vertex Vertex; typedef CGAL_Polyhedron::Vertex_const_iterator VCI; typedef CGAL_Polyhedron::Facet_const_iterator FCI; typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; for (FCI fi = p.facets_begin(); fi != p.facets_end(); ++fi) { HFCC hc = fi->facet_begin(); HFCC hc_end = hc; Vertex v1, v2, v3; v1 = *VCI((hc++)->vertex()); v3 = *VCI((hc++)->vertex()); do { v2 = v3; v3 = *VCI((hc++)->vertex()); double x1 = CGAL::to_double(v1.point().x()); double y1 = CGAL::to_double(v1.point().y()); double z1 = CGAL::to_double(v1.point().z()); double x2 = CGAL::to_double(v2.point().x()); double y2 = CGAL::to_double(v2.point().y()); double z2 = CGAL::to_double(v2.point().z()); double x3 = CGAL::to_double(v3.point().x()); double y3 = CGAL::to_double(v3.point().y()); double z3 = CGAL::to_double(v3.point().z()); ps->append_poly(); ps->append_vertex(x1, y1, z1); ps->append_vertex(x2, y2, z2); ps->append_vertex(x3, y3, z3); } while (hc != hc_end); } return ps; } #undef GEN_SURFACE_DEBUG class CGAL_Build_PolySet : public CGAL::Modifier_base { public: typedef CGAL_HDS::Vertex::Point CGALPoint; const PolySet &ps; CGAL_Build_PolySet(const PolySet &ps) : ps(ps) { } void operator()(CGAL_HDS& hds) { CGAL_Polybuilder B(hds, true); std::vector vertices; Grid3d vertices_idx(GRID_FINE); for (size_t i = 0; i < ps.polygons.size(); i++) { const PolySet::Polygon *poly = &ps.polygons[i]; for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); if (!vertices_idx.has(p[0], p[1], p[2])) { vertices_idx.data(p[0], p[1], p[2]) = vertices.size(); vertices.push_back(CGALPoint(p[0], p[1], p[2])); } } } B.begin_surface(vertices.size(), ps.polygons.size()); #ifdef GEN_SURFACE_DEBUG printf("=== CGAL Surface ===\n"); #endif for (size_t i = 0; i < vertices.size(); i++) { const CGALPoint &p = vertices[i]; B.add_vertex(p); #ifdef GEN_SURFACE_DEBUG printf("%d: %f %f %f\n", i, p[0], p[1], p[2]); #endif } for (size_t i = 0; i < ps.polygons.size(); i++) { const PolySet::Polygon *poly = &ps.polygons[i]; std::map fc; bool facet_is_degenerated = false; for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); int v = vertices_idx.data(p[0], p[1], p[2]); if (fc[v]++ > 0) facet_is_degenerated = true; } if (!facet_is_degenerated) B.begin_facet(); #ifdef GEN_SURFACE_DEBUG printf("F:"); #endif for (size_t j = 0; j < poly->size(); j++) { const Vector3d &p = poly->at(j); #ifdef GEN_SURFACE_DEBUG printf(" %d (%f,%f,%f)", vertices_idx.data(p[0], p[1], p[2]), p[0], p[1], p[2]); #endif if (!facet_is_degenerated) B.add_vertex_to_facet(vertices_idx.data(p[0], p[1], p[2])); } #ifdef GEN_SURFACE_DEBUG if (facet_is_degenerated) printf(" (degenerated)"); printf("\n"); #endif if (!facet_is_degenerated) B.end_facet(); } #ifdef GEN_SURFACE_DEBUG printf("====================\n"); #endif B.end_surface(); #undef PointKey } }; CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps) { CGAL_Polyhedron *P = NULL; CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); try { P = new CGAL_Polyhedron; CGAL_Build_PolySet builder(ps); P->delegate(builder); } catch (CGAL::Assertion_exception e) { PRINTF("CGAL error in CGAL_Build_PolySet: %s", e.what()); delete P; P = NULL; } CGAL::set_error_behaviour(old_behaviour); return P; } #endif /* ENABLE_CGAL */