diff --git a/csgops.cc b/csgops.cc index a266ab15..90873460 100644 --- a/csgops.cc +++ b/csgops.cc @@ -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; } diff --git a/export.cc b/export.cc index 4d5e7daa..9154f496 100644 --- a/export.cc +++ b/export.cc @@ -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; diff --git a/mainwin.cc b/mainwin.cc index f024221e..4fe8724c 100644 --- a/mainwin.cc +++ b/mainwin.cc @@ -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::convert_to_OGLPolyhedron(*m->root_N, p); + CGAL::OGL::Nef3_Converter::convert_to_OGLPolyhedron(m->root_N->p3, p); p->init(); } if (m->viewActionCGALSurfaces->isChecked()) diff --git a/module.cc b/module.cc index 6e89e187..4a0b7039 100644 --- a/module.cc +++ b/module.cc @@ -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; } diff --git a/openscad.h b/openscad.h index beb3628f..b765bd29 100644 --- a/openscad.h +++ b/openscad.h @@ -459,20 +459,54 @@ public: #ifdef ENABLE_CGAL #include +#include +#include #include #include #include #include -typedef CGAL::Cartesian CGAL_Kernel; -typedef CGAL::Polyhedron_3 CGAL_Polyhedron; +typedef CGAL::Extended_cartesian CGAL_Kernel2; +typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; + +typedef CGAL::Cartesian CGAL_Kernel3; +typedef CGAL::Polyhedron_3 CGAL_Polyhedron; typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; -typedef CGAL::Nef_polyhedron_3 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_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 */ diff --git a/polyset.cc b/polyset.cc index b3bd7c22..467b0966 100644 --- a/polyset.cc +++ b/polyset.cc @@ -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; diff --git a/render.cc b/render.cc index d5478f3e..532c2e94 100644 --- a/render.cc +++ b/render.cc @@ -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 *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 diff --git a/transform.cc b/transform.cc index 51b54dc6..ca9fa20d 100644 --- a/transform.cc +++ b/transform.cc @@ -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; }