summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2011-09-07 20:04:59 (GMT)
committerMarius Kintel <marius@kintel.net>2011-09-07 20:04:59 (GMT)
commit27a99044d8388ff30080bd0298eb936b8dd1341a (patch)
treeddc03a541c8a9708ac76581706188700f445abbc
parent75784844eaad1aa77757eb7640547146e0a96209 (diff)
Implemented OFF import, refactored PolySet/Polyhedron conversion
-rw-r--r--openscad.pro4
-rw-r--r--src/CGALEvaluator.cc103
-rw-r--r--src/CGAL_Nef_polyhedron.cc35
-rw-r--r--src/cgalfwd.h18
-rw-r--r--src/cgalutils.cc147
-rw-r--r--src/cgalutils.h9
-rw-r--r--src/import.cc22
-rw-r--r--tests/CMakeLists.txt6
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})
contact: Jan Huwald // Impressum