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) {
N = v->render_cgal_nef_polyhedron();
first = false;
} else if (type == CSG_TYPE_UNION) {
N += v->render_cgal_nef_polyhedron();
} else if (type == CSG_TYPE_DIFFERENCE) {
N -= v->render_cgal_nef_polyhedron();
} else if (type == CSG_TYPE_INTERSECTION) {
N *= v->render_cgal_nef_polyhedron();
} else if (N.dim == 2) {
if (type == CSG_TYPE_UNION) {
N.p2 += v->render_cgal_nef_polyhedron().p2;
} else if (type == CSG_TYPE_DIFFERENCE) {
N.p2 -= v->render_cgal_nef_polyhedron().p2;
} 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();
return N;
}

View File

@ -31,7 +31,7 @@
void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd)
{
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_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());
QApplication::processEvents();
PRINTF(" Simple: %6s", root_N->is_simple() ? "yes" : "no");
QApplication::processEvents();
PRINTF(" Valid: %6s", root_N->is_valid() ? "yes" : "no");
QApplication::processEvents();
PRINTF(" Vertices: %6d", (int)root_N->number_of_vertices());
QApplication::processEvents();
PRINTF(" Halfedges: %6d", (int)root_N->number_of_halfedges());
QApplication::processEvents();
PRINTF(" Edges: %6d", (int)root_N->number_of_edges());
QApplication::processEvents();
PRINTF(" Halffacets: %6d", (int)root_N->number_of_halffacets());
QApplication::processEvents();
PRINTF(" Facets: %6d", (int)root_N->number_of_facets());
QApplication::processEvents();
PRINTF(" Volumes: %6d", (int)root_N->number_of_volumes());
QApplication::processEvents();
if (root_N->dim == 2) {
// FIXME
}
if (root_N->dim == 3) {
PRINTF(" Simple: %6s", root_N->p3.is_simple() ? "yes" : "no");
QApplication::processEvents();
PRINTF(" Valid: %6s", root_N->p3.is_valid() ? "yes" : "no");
QApplication::processEvents();
PRINTF(" Vertices: %6d", (int)root_N->p3.number_of_vertices());
QApplication::processEvents();
PRINTF(" Halfedges: %6d", (int)root_N->p3.number_of_halfedges());
QApplication::processEvents();
PRINTF(" Edges: %6d", (int)root_N->p3.number_of_edges());
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;
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;
}
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..");
current_win = NULL;
return;
@ -1020,7 +1032,7 @@ void MainWindow::actionExportSTLorOFF(bool)
QProgressDialog *pd = new QProgressDialog(
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->setAutoClose(false);
pd->show();
@ -1180,11 +1192,11 @@ static void renderGLviaCGAL(void *vp)
delete p;
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;
if (!p) {
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();
}
if (m->viewActionCGALSurfaces->isChecked())

View File

@ -248,14 +248,21 @@ static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode
continue;
if (is_first)
N = v->render_cgal_nef_polyhedron();
else if (intersect)
N *= v->render_cgal_nef_polyhedron();
else
N += v->render_cgal_nef_polyhedron();
else if (N.dim == 2) {
if (intersect)
N.p2 *= v->render_cgal_nef_polyhedron().p2;
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;
}
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();
return N;
}

View File

@ -459,20 +459,54 @@ public:
#ifdef ENABLE_CGAL
#include <CGAL/Gmpq.h>
#include <CGAL/Extended_cartesian.h>
#include <CGAL/Nef_polyhedron_2.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel;
typedef CGAL::Polyhedron_3<CGAL_Kernel> CGAL_Polyhedron;
typedef CGAL::Extended_cartesian<CGAL::Gmpq> CGAL_Kernel2;
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_incremental_builder_3<CGAL_HDS> CGAL_Polybuilder;
typedef CGAL::Nef_polyhedron_3<CGAL_Kernel> CGAL_Nef_polyhedron;
typedef CGAL_Nef_polyhedron::Aff_transformation_3 CGAL_Aff_transformation;
typedef CGAL_Nef_polyhedron::Vector_3 CGAL_Vector;
typedef CGAL_Nef_polyhedron::Plane_3 CGAL_Plane;
typedef CGAL_Nef_polyhedron::Point_3 CGAL_Point;
typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3> CGAL_Nef_polyhedron3;
typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation;
typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector;
typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane;
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 */

View File

@ -290,8 +290,8 @@ CGAL_Nef_polyhedron PolySet::render_cgal_nef_polyhedron() const
#if 0
std::cout << P;
#endif
CGAL_Nef_polyhedron N(P);
return N;
CGAL_Nef_polyhedron3 N(P);
return CGAL_Nef_polyhedron(N);
}
#endif /* ENABLE_CGAL */
@ -314,7 +314,7 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
PolySet *ps = render_polyset(RENDER_CGAL);
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();
ps->unlink();
return N;

View File

@ -93,12 +93,14 @@ CGAL_Nef_polyhedron RenderNode::render_cgal_nef_polyhedron() const
if (first) {
N = v->render_cgal_nef_polyhedron();
first = false;
} else {
N += v->render_cgal_nef_polyhedron();
} 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_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();
return N;
}
@ -153,45 +155,56 @@ CSGTerm *RenderNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights
delete pd;
}
if (!N.is_simple()) {
PRINTF("WARNING: Result of render() isn't valid 2-manifold! Modify your design..");
if (N.dim == 2)
{
// FIXME
return NULL;
}
PolySet *ps = new PolySet();
ps->convexity = convexity;
CGAL_Polyhedron P;
N.convert_to_Polyhedron(P);
if (N.dim == 3)
{
if (!N.p3.is_simple()) {
PRINTF("WARNING: Result of render() isn't valid 2-manifold! Modify your design..");
return NULL;
}
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;
PolySet *ps = new PolySet();
ps->convexity = convexity;
CGAL_Polyhedron P;
N.p3.convert_to_Polyhedron(P);
for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
HFCC hc = fi->facet_begin();
HFCC hc_end = hc;
ps->append_poly();
do {
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);
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;
ps->append_poly();
do {
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()));
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;
return NULL;
}
#else

View File

@ -190,20 +190,34 @@ CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const
return *cgal_nef_cache[cache_id];
}
bool first = true;
CGAL_Nef_polyhedron N;
foreach (AbstractNode *v, children) {
if (v->modinst->tag_background)
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(
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.transform(t);
if (N.dim == 2) {
// FIXME
}
if (N.dim == 3) {
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();
return N;
}