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 | |
parent | 75784844eaad1aa77757eb7640547146e0a96209 (diff) |
Implemented OFF import, refactored PolySet/Polyhedron conversion
-rw-r--r-- | openscad.pro | 4 | ||||
-rw-r--r-- | src/CGALEvaluator.cc | 103 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron.cc | 35 | ||||
-rw-r--r-- | src/cgalfwd.h | 18 | ||||
-rw-r--r-- | src/cgalutils.cc | 147 | ||||
-rw-r--r-- | src/cgalutils.h | 9 | ||||
-rw-r--r-- | src/import.cc | 22 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 6 |
8 files changed, 210 insertions, 134 deletions
diff --git a/openscad.pro b/openscad.pro index a7dd59e..4541eaa 100644 --- a/openscad.pro +++ b/openscad.pro @@ -213,12 +213,14 @@ SOURCES += src/openscad.cc \ cgal { HEADERS += src/cgal.h \ src/cgalfwd.h \ + src/cgalutils.h \ src/CGALEvaluator.h \ src/PolySetCGALEvaluator.h \ src/CGALRenderer.h \ src/CGAL_Nef_polyhedron.h -SOURCES += src/CGALEvaluator.cc \ +SOURCES += src/cgalutils.cc \ + src/CGALEvaluator.cc \ src/PolySetCGALEvaluator.cc \ src/CGALRenderer.cc \ src/CGAL_Nef_polyhedron.cc \ diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 9c5a51e..8e5e222 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -12,6 +12,7 @@ #include "dxftess.h" #include "cgal.h" +#include "cgalutils.h" #include <CGAL/assertions_behaviour.h> #include <CGAL/exceptions.h> @@ -332,93 +333,6 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node } #endif -#ifdef ENABLE_CGAL - -#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 - } -}; - -#endif /* ENABLE_CGAL */ - CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { if (ps.empty()) return CGAL_Nef_polyhedron(); @@ -679,15 +593,12 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const PolySet &ps) { CGAL::Failure_behaviour old_behaviour = CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION); try { - CGAL_Polyhedron P; - CGAL_Build_PolySet builder(ps); - P.delegate(builder); -#if 0 - std::cout << P; -#endif - CGAL_Nef_polyhedron3 *N = new CGAL_Nef_polyhedron3(P); - return CGAL_Nef_polyhedron(N); - } + CGAL_Polyhedron *P = createPolyhedronFromPolySet(ps); + if (P) { + CGAL_Nef_polyhedron3 *N = new CGAL_Nef_polyhedron3(*P); + return CGAL_Nef_polyhedron(N); + } + } catch (CGAL::Assertion_exception e) { PRINTF("CGAL error: %s", e.what()); CGAL::set_error_behaviour(old_behaviour); diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index afe7119..6dcbdea 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -1,5 +1,6 @@ #include "CGAL_Nef_polyhedron.h" #include "cgal.h" +#include "cgalutils.h" #include "polyset.h" #include "dxfdata.h" #include "dxftess.h" @@ -51,8 +52,9 @@ int CGAL_Nef_polyhedron::weight() const PolySet *CGAL_Nef_polyhedron::convertToPolyset() { assert(!this->empty()); - PolySet *ps = new PolySet(); + PolySet *ps = NULL; if (this->dim == 2) { + ps = new PolySet(); DxfData *dd = this->convertToDxfData(); ps->is2d = true; dxf_tesselate(ps, *dd, 0, true, false, 0); @@ -62,36 +64,7 @@ PolySet *CGAL_Nef_polyhedron::convertToPolyset() else if (this->dim == 3) { CGAL_Polyhedron P; this->p3->convert_to_Polyhedron(P); - - 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); - } + ps = createPolySetFromPolyhedron(P); } return ps; } diff --git a/src/cgalfwd.h b/src/cgalfwd.h index df9b9e2..3fad608 100644 --- a/src/cgalfwd.h +++ b/src/cgalfwd.h @@ -1,8 +1,13 @@ #ifndef CGALFWD_H_ #define CGALFWD_H_ +#ifndef CGAL_FORWARD +#include "cgal.h" +#else #ifdef ENABLE_CGAL +#include <memory> + namespace CGAL { class Gmpq; template <class T> class Extended_cartesian; @@ -22,6 +27,19 @@ namespace CGAL { typedef CGAL::Cartesian<NT> CGAL_Kernel3; typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3, CGAL::SNC_indexed_items, bool> CGAL_Nef_polyhedron3; +namespace CGAL { +#ifndef CGAL_ALLOCATOR +# define CGAL_ALLOCATOR(T) std::allocator< T > +#endif + class HalfedgeDS_items_2; + template <class Traits_, class HalfedgeDSItems, class Alloc> class HalfedgeDS_default; + class Polyhedron_items_3; + template <class PolyhedronTraits_3, class PolyhedronItems_3, class T_HDS, class Alloc> class Polyhedron_3; +} +typedef CGAL::Polyhedron_3<CGAL_Kernel3, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_default<CGAL_Kernel3, CGAL::HalfedgeDS_items_2, CGAL_ALLOCATOR(int)>, CGAL_ALLOCATOR(int)> CGAL_Polyhedron; + #endif /* ENABLE_CGAL */ #endif + +#endif 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 */ + diff --git a/src/cgalutils.h b/src/cgalutils.h new file mode 100644 index 0000000..a249697 --- /dev/null +++ b/src/cgalutils.h @@ -0,0 +1,9 @@ +#ifndef CGALUTILS_H_ +#define CGALUTILS_H_ + +#include <cgalfwd.h> + +class PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p); +CGAL_Polyhedron *createPolyhedronFromPolySet(const class PolySet &ps); + +#endif diff --git a/src/import.cc b/src/import.cc index 17ad3f2..8c27832 100644 --- a/src/import.cc +++ b/src/import.cc @@ -35,11 +35,16 @@ #include "printutils.h" #include "handle_dep.h" // handle_dep() +#ifdef ENABLE_CGAL +#include "cgalutils.h" +#endif + #include <QFile> #include <QRegExp> #include <QStringList> #include <sys/types.h> #include <sys/stat.h> +#include <fstream> #include <sstream> #include <assert.h> #include <boost/assign/std/vector.hpp> @@ -108,11 +113,11 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) const { - PolySet *p = new PolySet(); - p->convexity = this->convexity; + PolySet *p = NULL; if (this->type == TYPE_STL) { + p = new PolySet(); handle_dep(this->filename); QFile f(QString::fromStdString(this->filename)); if (!f.open(QIODevice::ReadOnly)) { @@ -190,11 +195,21 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c else if (this->type == TYPE_OFF) { - PRINTF("WARNING: OFF import is not implemented yet."); +#ifdef ENABLE_CGAL + CGAL_Polyhedron poly; + std::ifstream file(this->filename.c_str()); + file >> poly; + file.close(); + + p = createPolySetFromPolyhedron(poly); +#else + PRINTF("WARNING: OFF import requires CGAL."); +#endif } else if (this->type == TYPE_DXF) { + p = new PolySet(); DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale); p->is2d = true; dxf_tesselate(p, dd, 0, true, false, 0); @@ -205,6 +220,7 @@ PolySet *ImportNode::evaluate_polyset(render_mode_e, class PolySetEvaluator *) c PRINTF("ERROR: Unsupported file format while trying to import file '%s'", this->filename.c_str()); } + if (p) p->convexity = this->convexity; return p; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b0aa6ed..2f43273 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -142,7 +142,7 @@ include_directories(${CGAL_INCLUDE_DIRS}) # # cgaltest # -add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/CSGTermEvaluator.cc +add_executable(cgaltest cgaltest.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) @@ -153,7 +153,7 @@ target_link_libraries(cgaltest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_ # cgalpngtest # add_executable(cgalpngtest cgalpngtest.cc OffscreenView.cc OffscreenContext.mm - ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CGALRenderer.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CSGTermEvaluator.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc @@ -166,7 +166,7 @@ target_link_libraries(cgalpngtest ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${ # add_executable(opencsgtest opencsgtest.cc OffscreenView.cc OffscreenContext.mm ../src/OpenCSGRenderer.cc ../src/ThrownTogetherRenderer.cc - ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc + ../src/CSGTermEvaluator.cc ../src/CGAL_Nef_polyhedron.cc ../src/cgalutils.cc ../src/CGALEvaluator.cc ../src/PolySetCGALEvaluator.cc ../src/qhash.cc ../src/CGAL_Nef_polyhedron_DxfData.cc ../src/cgaladv_minkowski2.cc ../src/cgaladv_convexhull2.cc ${COMMON_SOURCES}) |