Clifford Wolf:

Added CGAL Nef Polyhedron 2D/3D abstraction



git-svn-id: http://svn.clifford.at/openscad/trunk@187 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-12-27 23:49:27 +00:00
parent 612f04dfdf
commit f7799a8e4e
8 changed files with 175 additions and 85 deletions

View File

@ -77,16 +77,26 @@ CGAL_Nef_polyhedron CsgNode::render_cgal_nef_polyhedron() const
if (first) { if (first) {
N = v->render_cgal_nef_polyhedron(); N = v->render_cgal_nef_polyhedron();
first = false; first = false;
} else if (type == CSG_TYPE_UNION) { } else if (N.dim == 2) {
N += v->render_cgal_nef_polyhedron(); if (type == CSG_TYPE_UNION) {
} else if (type == CSG_TYPE_DIFFERENCE) { N.p2 += v->render_cgal_nef_polyhedron().p2;
N -= v->render_cgal_nef_polyhedron(); } else if (type == CSG_TYPE_DIFFERENCE) {
} else if (type == CSG_TYPE_INTERSECTION) { N.p2 -= v->render_cgal_nef_polyhedron().p2;
N *= v->render_cgal_nef_polyhedron(); } else if (type == CSG_TYPE_INTERSECTION) {
N.p2 *= v->render_cgal_nef_polyhedron().p2;
}
} else if (N.dim == 3) {
if (type == CSG_TYPE_UNION) {
N.p3 += v->render_cgal_nef_polyhedron().p3;
} else if (type == CSG_TYPE_DIFFERENCE) {
N.p3 -= v->render_cgal_nef_polyhedron().p3;
} else if (type == CSG_TYPE_INTERSECTION) {
N.p3 *= v->render_cgal_nef_polyhedron().p3;
}
} }
} }
cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.weight());
progress_report(); progress_report();
return N; return N;
} }

View File

@ -31,7 +31,7 @@
void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd) void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd)
{ {
CGAL_Polyhedron P; CGAL_Polyhedron P;
root_N->convert_to_Polyhedron(P); root_N->p3.convert_to_Polyhedron(P);
typedef CGAL_Polyhedron::Vertex Vertex; typedef CGAL_Polyhedron::Vertex Vertex;
typedef CGAL_Polyhedron::Vertex_const_iterator VCI; typedef CGAL_Polyhedron::Vertex_const_iterator VCI;

View File

@ -909,22 +909,28 @@ void MainWindow::actionRenderCGAL()
PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size()); PRINTF("Number of objects currently in CGAL cache: %d", AbstractNode::cgal_nef_cache.size());
QApplication::processEvents(); QApplication::processEvents();
PRINTF(" Simple: %6s", root_N->is_simple() ? "yes" : "no"); if (root_N->dim == 2) {
QApplication::processEvents(); // FIXME
PRINTF(" Valid: %6s", root_N->is_valid() ? "yes" : "no"); }
QApplication::processEvents();
PRINTF(" Vertices: %6d", (int)root_N->number_of_vertices()); if (root_N->dim == 3) {
QApplication::processEvents(); PRINTF(" Simple: %6s", root_N->p3.is_simple() ? "yes" : "no");
PRINTF(" Halfedges: %6d", (int)root_N->number_of_halfedges()); QApplication::processEvents();
QApplication::processEvents(); PRINTF(" Valid: %6s", root_N->p3.is_valid() ? "yes" : "no");
PRINTF(" Edges: %6d", (int)root_N->number_of_edges()); QApplication::processEvents();
QApplication::processEvents(); PRINTF(" Vertices: %6d", (int)root_N->p3.number_of_vertices());
PRINTF(" Halffacets: %6d", (int)root_N->number_of_halffacets()); QApplication::processEvents();
QApplication::processEvents(); PRINTF(" Halfedges: %6d", (int)root_N->p3.number_of_halfedges());
PRINTF(" Facets: %6d", (int)root_N->number_of_facets()); QApplication::processEvents();
QApplication::processEvents(); PRINTF(" Edges: %6d", (int)root_N->p3.number_of_edges());
PRINTF(" Volumes: %6d", (int)root_N->number_of_volumes()); QApplication::processEvents();
QApplication::processEvents(); PRINTF(" Halffacets: %6d", (int)root_N->p3.number_of_halffacets());
QApplication::processEvents();
PRINTF(" Facets: %6d", (int)root_N->p3.number_of_facets());
QApplication::processEvents();
PRINTF(" Volumes: %6d", (int)root_N->p3.number_of_volumes());
QApplication::processEvents();
}
int s = t.elapsed() / 1000; int s = t.elapsed() / 1000;
PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); PRINTF("Total rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
@ -1003,7 +1009,13 @@ void MainWindow::actionExportSTLorOFF(bool)
return; return;
} }
if (!root_N->is_simple()) { if (root_N->dim != 3) {
PRINT("Current top level object is not a 3D object.");
current_win = NULL;
return;
}
if (root_N->p3.is_simple()) {
PRINT("Object isn't a valid 2-manifold! Modify your design.."); PRINT("Object isn't a valid 2-manifold! Modify your design..");
current_win = NULL; current_win = NULL;
return; return;
@ -1020,7 +1032,7 @@ void MainWindow::actionExportSTLorOFF(bool)
QProgressDialog *pd = new QProgressDialog( QProgressDialog *pd = new QProgressDialog(
stl_mode ? "Exporting object to STL file..." : "Exporting object to OFF file...", stl_mode ? "Exporting object to STL file..." : "Exporting object to OFF file...",
QString(), 0, root_N->number_of_facets() + 1); QString(), 0, root_N->p3.number_of_facets() + 1);
pd->setValue(0); pd->setValue(0);
pd->setAutoClose(false); pd->setAutoClose(false);
pd->show(); pd->show();
@ -1180,11 +1192,11 @@ static void renderGLviaCGAL(void *vp)
delete p; delete p;
m->cgal_ogl_p = NULL; m->cgal_ogl_p = NULL;
} }
if (m->root_N) { if (m->root_N && m->root_N->dim == 3) {
CGAL::OGL::Polyhedron *p = (CGAL::OGL::Polyhedron*)m->cgal_ogl_p; CGAL::OGL::Polyhedron *p = (CGAL::OGL::Polyhedron*)m->cgal_ogl_p;
if (!p) { if (!p) {
m->cgal_ogl_p = p = new CGAL::OGL::Polyhedron(); m->cgal_ogl_p = p = new CGAL::OGL::Polyhedron();
CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron>::convert_to_OGLPolyhedron(*m->root_N, p); CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron3>::convert_to_OGLPolyhedron(m->root_N->p3, p);
p->init(); p->init();
} }
if (m->viewActionCGALSurfaces->isChecked()) if (m->viewActionCGALSurfaces->isChecked())

View File

@ -248,14 +248,21 @@ static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode
continue; continue;
if (is_first) if (is_first)
N = v->render_cgal_nef_polyhedron(); N = v->render_cgal_nef_polyhedron();
else if (intersect) else if (N.dim == 2) {
N *= v->render_cgal_nef_polyhedron(); if (intersect)
else N.p2 *= v->render_cgal_nef_polyhedron().p2;
N += v->render_cgal_nef_polyhedron(); else
N.p2 += v->render_cgal_nef_polyhedron().p2;
} else {
if (intersect)
N.p3 *= v->render_cgal_nef_polyhedron().p3;
else
N.p3 += v->render_cgal_nef_polyhedron().p3;
}
is_first = false; is_first = false;
} }
that->cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); that->cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.weight());
that->progress_report(); that->progress_report();
return N; return N;
} }

View File

@ -459,20 +459,54 @@ public:
#ifdef ENABLE_CGAL #ifdef ENABLE_CGAL
#include <CGAL/Gmpq.h> #include <CGAL/Gmpq.h>
#include <CGAL/Extended_cartesian.h>
#include <CGAL/Nef_polyhedron_2.h>
#include <CGAL/Cartesian.h> #include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h> #include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h> #include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h> #include <CGAL/IO/Polyhedron_iostream.h>
typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel; typedef CGAL::Extended_cartesian<CGAL::Gmpq> CGAL_Kernel2;
typedef CGAL::Polyhedron_3<CGAL_Kernel> CGAL_Polyhedron; typedef CGAL::Nef_polyhedron_2<CGAL_Kernel2> CGAL_Nef_polyhedron2;
typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel3;
typedef CGAL::Polyhedron_3<CGAL_Kernel3> CGAL_Polyhedron;
typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS;
typedef CGAL::Polyhedron_incremental_builder_3<CGAL_HDS> CGAL_Polybuilder; typedef CGAL::Polyhedron_incremental_builder_3<CGAL_HDS> CGAL_Polybuilder;
typedef CGAL::Nef_polyhedron_3<CGAL_Kernel> CGAL_Nef_polyhedron; typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3> CGAL_Nef_polyhedron3;
typedef CGAL_Nef_polyhedron::Aff_transformation_3 CGAL_Aff_transformation; typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation;
typedef CGAL_Nef_polyhedron::Vector_3 CGAL_Vector; typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector;
typedef CGAL_Nef_polyhedron::Plane_3 CGAL_Plane; typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane;
typedef CGAL_Nef_polyhedron::Point_3 CGAL_Point; typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point;
struct CGAL_Nef_polyhedron
{
int dim;
CGAL_Nef_polyhedron2 p2;
CGAL_Nef_polyhedron3 p3;
CGAL_Nef_polyhedron() {
dim = 0;
}
CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) {
dim = 2;
p2 = p;
}
CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) {
dim = 3;
p3 = p;
}
int weight() {
if (dim == 2)
return 100;
if (dim == 3)
return p3.number_of_vertices();
return 0;
}
};
#endif /* ENABLE_CGAL */ #endif /* ENABLE_CGAL */

View File

@ -290,8 +290,8 @@ CGAL_Nef_polyhedron PolySet::render_cgal_nef_polyhedron() const
#if 0 #if 0
std::cout << P; std::cout << P;
#endif #endif
CGAL_Nef_polyhedron N(P); CGAL_Nef_polyhedron3 N(P);
return N; return CGAL_Nef_polyhedron(N);
} }
#endif /* ENABLE_CGAL */ #endif /* ENABLE_CGAL */
@ -314,7 +314,7 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
PolySet *ps = render_polyset(RENDER_CGAL); PolySet *ps = render_polyset(RENDER_CGAL);
CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron(); CGAL_Nef_polyhedron N = ps->render_cgal_nef_polyhedron();
cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.weight());
progress_report(); progress_report();
ps->unlink(); ps->unlink();
return N; return N;

View File

@ -93,12 +93,14 @@ CGAL_Nef_polyhedron RenderNode::render_cgal_nef_polyhedron() const
if (first) { if (first) {
N = v->render_cgal_nef_polyhedron(); N = v->render_cgal_nef_polyhedron();
first = false; first = false;
} else { } else if (N.dim == 2) {
N += v->render_cgal_nef_polyhedron(); N.p2 += v->render_cgal_nef_polyhedron().p2;
} else if (N.dim == 3) {
N.p3 += v->render_cgal_nef_polyhedron().p3;
} }
} }
cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.weight());
progress_report(); progress_report();
return N; return N;
} }
@ -153,45 +155,56 @@ CSGTerm *RenderNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights
delete pd; delete pd;
} }
if (!N.is_simple()) { if (N.dim == 2)
PRINTF("WARNING: Result of render() isn't valid 2-manifold! Modify your design.."); {
// FIXME
return NULL; return NULL;
} }
PolySet *ps = new PolySet(); if (N.dim == 3)
ps->convexity = convexity; {
if (!N.p3.is_simple()) {
CGAL_Polyhedron P; PRINTF("WARNING: Result of render() isn't valid 2-manifold! Modify your design..");
N.convert_to_Polyhedron(P); return NULL;
}
typedef CGAL_Polyhedron::Vertex Vertex; PolySet *ps = new PolySet();
typedef CGAL_Polyhedron::Vertex_const_iterator VCI; ps->convexity = convexity;
typedef CGAL_Polyhedron::Facet_const_iterator FCI;
typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC; CGAL_Polyhedron P;
N.p3.convert_to_Polyhedron(P);
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) { typedef CGAL_Polyhedron::Vertex Vertex;
HFCC hc = fi->facet_begin(); typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
HFCC hc_end = hc; typedef CGAL_Polyhedron::Facet_const_iterator FCI;
ps->append_poly(); typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
do {
Vertex v = *VCI((hc++)->vertex()); for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
double x = CGAL::to_double(v.point().x()); HFCC hc = fi->facet_begin();
double y = CGAL::to_double(v.point().y()); HFCC hc_end = hc;
double z = CGAL::to_double(v.point().z()); ps->append_poly();
ps->append_vertex(x, y, z); do {
} while (hc != hc_end); Vertex v = *VCI((hc++)->vertex());
double x = CGAL::to_double(v.point().x());
double y = CGAL::to_double(v.point().y());
double z = CGAL::to_double(v.point().z());
ps->append_vertex(x, y, z);
} while (hc != hc_end);
}
PolySet::ps_cache.insert(key, new PolySetPtr(ps->link()));
CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
if (modinst->tag_highlight && highlights)
highlights->append(term->link());
if (modinst->tag_background && background) {
background->append(term);
return NULL;
}
return term;
} }
PolySet::ps_cache.insert(key, new PolySetPtr(ps->link())); return NULL;
CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
if (modinst->tag_highlight && highlights)
highlights->append(term->link());
if (modinst->tag_background && background) {
background->append(term);
return NULL;
}
return term;
} }
#else #else

View File

@ -190,20 +190,34 @@ CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const
return *cgal_nef_cache[cache_id]; return *cgal_nef_cache[cache_id];
} }
bool first = true;
CGAL_Nef_polyhedron N; CGAL_Nef_polyhedron N;
foreach (AbstractNode *v, children) { foreach (AbstractNode *v, children) {
if (v->modinst->tag_background) if (v->modinst->tag_background)
continue; continue;
N += v->render_cgal_nef_polyhedron(); if (first) {
N = v->render_cgal_nef_polyhedron();
first = false;
} else if (N.dim == 2) {
N.p2 += v->render_cgal_nef_polyhedron().p2;
} else if (N.dim == 3) {
N.p3 += v->render_cgal_nef_polyhedron().p3;
}
} }
CGAL_Aff_transformation t( if (N.dim == 2) {
m[0], m[4], m[ 8], m[12], // FIXME
m[1], m[5], m[ 9], m[13], }
m[2], m[6], m[10], m[14], m[15]); if (N.dim == 3) {
N.transform(t); CGAL_Aff_transformation t(
m[0], m[4], m[ 8], m[12],
m[1], m[5], m[ 9], m[13],
m[2], m[6], m[10], m[14], m[15]);
N.p3.transform(t);
}
cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.weight());
progress_report(); progress_report();
return N; return N;
} }