diff options
author | Marius Kintel <marius@kintel.net> | 2011-09-07 20:04:59 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2011-09-07 20:04:59 (GMT) |
commit | 27a99044d8388ff30080bd0298eb936b8dd1341a (patch) | |
tree | ddc03a541c8a9708ac76581706188700f445abbc /src/cgalutils.cc | |
parent | 75784844eaad1aa77757eb7640547146e0a96209 (diff) |
Implemented OFF import, refactored PolySet/Polyhedron conversion
Diffstat (limited to 'src/cgalutils.cc')
-rw-r--r-- | src/cgalutils.cc | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/cgalutils.cc b/src/cgalutils.cc new file mode 100644 index 0000000..79e9f1f --- /dev/null +++ b/src/cgalutils.cc @@ -0,0 +1,147 @@ +#ifdef ENABLE_CGAL + +#include "cgalutils.h" +#include "polyset.h" +#include "printutils.h" + +#include "cgal.h" +#include <CGAL/assertions_behaviour.h> +#include <CGAL/exceptions.h> + +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<CGAL_HDS> +{ +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<CGALPoint> vertices; + Grid3d<int> 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]; + QHash<int,int> 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: %s", e.what()); + CGAL::set_error_behaviour(old_behaviour); + } + return P; +} + +#endif /* ENABLE_CGAL */ + |