diff options
author | Don Bright <hugh.m.bright@gmail.com> | 2012-02-11 02:15:16 (GMT) |
---|---|---|
committer | Don Bright <hugh.m.bright@gmail.com> | 2012-02-11 02:15:16 (GMT) |
commit | a76d5b02bdb8cd7a9d32c2e204c86726d1384c63 (patch) | |
tree | cb4d936cf0cfede1d7f07f18ab3edfc0b35f6233 /src | |
parent | a83fda0c3d9e92a6e47622cd1c2fdeebdfbb8c1a (diff) |
use Nef_polyhedron3 intersection to do projection(cut).
Diffstat (limited to 'src')
-rw-r--r-- | src/CGAL_Nef_polyhedron.cc | 1 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron.h | 2 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron_DxfData.cc | 25 | ||||
-rw-r--r-- | src/PolySetCGALEvaluator.cc | 155 | ||||
-rw-r--r-- | src/dxftess-cgal.cc | 1 |
5 files changed, 129 insertions, 55 deletions
diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 04783e5..54c02e7 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -5,6 +5,7 @@ #include "polyset.h" #include "dxfdata.h" #include "dxftess.h" +#include <sstream> CGAL_Nef_polyhedron::CGAL_Nef_polyhedron(CGAL_Nef_polyhedron2 *p) { diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h index f93905f..0b0784e 100644 --- a/src/CGAL_Nef_polyhedron.h +++ b/src/CGAL_Nef_polyhedron.h @@ -3,6 +3,7 @@ #include "cgalfwd.h" #include "memory.h" +#include <string> class CGAL_Nef_polyhedron { @@ -18,6 +19,7 @@ public: CGAL_Nef_polyhedron &operator-=(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron &minkowski(const CGAL_Nef_polyhedron &other); CGAL_Nef_polyhedron copy() const; + std::string dump_p2() const; int weight() const; class PolySet *convertToPolyset(); class DxfData *convertToDxfData() const; diff --git a/src/CGAL_Nef_polyhedron_DxfData.cc b/src/CGAL_Nef_polyhedron_DxfData.cc index fe58636..d5f774d 100644 --- a/src/CGAL_Nef_polyhedron_DxfData.cc +++ b/src/CGAL_Nef_polyhedron_DxfData.cc @@ -77,4 +77,29 @@ DxfData *CGAL_Nef_polyhedron::convertToDxfData() const return dxfdata; } +// moved here to reduce compile size/time of CGAL_Nef_polyhedron.cc +std::string CGAL_Nef_polyhedron::dump_p2() const +{ + std::stringstream out; + CGAL_Nef_polyhedron2::Explorer explorer = this->p2->explorer(); + CGAL_Nef_polyhedron2::Explorer::Vertex_const_iterator i; + out << "CGAL_Nef_polyhedron::p2 vertices"; + for (i = explorer.vertices_begin(); i != explorer.vertices_end(); ++i) { + if ( explorer.is_standard( i ) ) { + CGAL_Nef_polyhedron2::Explorer::Point point = explorer.point( i ); + out << "\n Standard vertex x y: " + << CGAL::to_double(point.x()) << " " + << CGAL::to_double(point.y()); + } else { + CGAL_Nef_polyhedron2::Explorer::Ray ray = explorer.ray( i ); + CGAL_Nef_polyhedron2::Explorer::Point point = ray.point( 0 ); + out << "\n Ray x y dx dy: " + << CGAL::to_double(point.x()) << " " << CGAL::to_double(point.y()) + << CGAL::to_double(ray.direction().dx()) << " " << CGAL::to_double(ray.direction().dy()) << "\n"; + } + } + out << "\nCGAL_Nef_polyhedron::p2 vertices end"; + return out.str(); +} + #endif // ENABLE_CGAL diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index c1bdea4..d6d0f87 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -16,11 +16,87 @@ #include "openscad.h" // get_fragments_from_r() #include <boost/foreach.hpp> +// This object 'visits' the Nef Polyhedron 3d, extracting 2d information +// from it for the projection( cut = true ) command. +// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html +class NefShellVisitor_for_cut { +public: + std::stringstream out; + CGAL_Nef_polyhedron2 tmpnef; + CGAL_Nef_polyhedron2 nefpoly2d; + CGAL_Nef_polyhedron2::Boundary boundary; + NefShellVisitor_for_cut() + { boundary = CGAL_Nef_polyhedron2::INCLUDED; } + std::string dump() + { return out.str(); } + void visit( CGAL_Nef_polyhedron3::Vertex_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::Halfedge_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SHalfloop_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::SFace_const_handle ) {} + void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet ) { + // this method is fed each 'facet' of the Nef_polyhedron3 that's been intersected + // with the flat x-y plane. + // + // So, we assume that all z coordinates are 0. + // + // Now. CGAL_Nef_poly3d objects have two 'half facets' for every flat shape. + // i.e. on a cube, there are 12 'half facets', 6 pointing 'in' and 6 'out'. + // On a flat square in 3d space, there are 2 half-facets, one pointing 'up' and one 'down'. + // We only use the 'down' facets here. Why? Because otherwise you get a double-set of vertices! + // + // Also note, 'up' facets list vertexs in CounterClockwise Order, and 'down' facets list vertexs + // in Clockwise order. (or is it the other way round?). + + CGAL::Direction_3<CGAL_Kernel3> up(0,0,1); + CGAL::Plane_3<CGAL_Kernel3> plane = hfacet->plane(); + out << " direction == up? " << ( plane.orthogonal_direction() == up ) << "\n"; + if ( plane.orthogonal_direction() != up ) { + out << "direction == down. skipping\n"; + return; + } + + int numcontours = 0; + CGAL_Nef_polyhedron2::Point point; + CGAL_Nef_polyhedron3::Vertex_const_handle vertex; + CGAL_Nef_polyhedron3::Halfedge_const_handle halfedge; + CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator i; + CGAL_Nef_polyhedron3::SHalfedge_const_handle first_halfedge, j; + for ( i = hfacet->facet_cycles_begin(); i != hfacet->facet_cycles_end(); ++i ) { + j = CGAL_Nef_polyhedron3::SHalfedge_const_handle( i ); + first_halfedge = j; + std::list<CGAL_Nef_polyhedron2::Point> contour; + do { + // j->source() is a CGAL_Nef_polyhedron3::Nef_polyhedron_S2::SVertex, + // but SVertex is the same thing as CGAL_Nef_polyhedron3::Halfedge + // and Halfedge can give us an actual point. + halfedge = CGAL_Nef_polyhedron3::Halfedge_const_handle( j->source() ); + vertex = CGAL_Nef_polyhedron3::Vertex_const_handle( halfedge->source() ); + point = CGAL_Nef_polyhedron2::Point( vertex->point().x(), vertex->point().y() ); + contour.push_back( point ); + //out << " add xyz " << x << " "<< y << " " <<z << endl; + j = j->next(); + } while ( j != first_halfedge ); + tmpnef = CGAL_Nef_polyhedron2( contour.begin(), contour.end(), boundary ); + if ( numcontours == 0 ) { + out << " contour is a body. joining." << contour.size() << " points.\n" ; + nefpoly2d = nefpoly2d.join( tmpnef ); + } else { + out << " contour is a hole. intersecting." << contour.size() << "points.\n"; + nefpoly2d = nefpoly2d.intersection( tmpnef ); + } + numcontours++; + } // next facet cycle + } // visit() +}; + PolySetCGALEvaluator::PolySetCGALEvaluator(CGALEvaluator &cgalevaluator) : PolySetEvaluator(cgalevaluator.getTree()), cgalevaluator(cgalevaluator) { } +#include <iostream> + PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) { // Before projecting, union all children @@ -43,64 +119,33 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node) // XY plane. if (node.cut_mode) { - PolySet cube; - double infval = 1e8, eps = 0.1; - double x1 = -infval, x2 = +infval, y1 = -infval, y2 = +infval, z1 = 0, z2 = eps; - - cube.append_poly(); // top - cube.append_vertex(x1, y1, z2); - cube.append_vertex(x2, y1, z2); - cube.append_vertex(x2, y2, z2); - cube.append_vertex(x1, y2, z2); - - cube.append_poly(); // bottom - cube.append_vertex(x1, y2, z1); - cube.append_vertex(x2, y2, z1); - cube.append_vertex(x2, y1, z1); - cube.append_vertex(x1, y1, z1); - - cube.append_poly(); // side1 - cube.append_vertex(x1, y1, z1); - cube.append_vertex(x2, y1, z1); - cube.append_vertex(x2, y1, z2); - cube.append_vertex(x1, y1, z2); - - cube.append_poly(); // side2 - cube.append_vertex(x2, y1, z1); - cube.append_vertex(x2, y2, z1); - cube.append_vertex(x2, y2, z2); - cube.append_vertex(x2, y1, z2); - - cube.append_poly(); // side3 - cube.append_vertex(x2, y2, z1); - cube.append_vertex(x1, y2, z1); - cube.append_vertex(x1, y2, z2); - cube.append_vertex(x2, y2, z2); - - cube.append_poly(); // side4 - cube.append_vertex(x1, y2, z1); - cube.append_vertex(x1, y1, z1); - cube.append_vertex(x1, y1, z2); - cube.append_vertex(x1, y2, z2); - CGAL_Nef_polyhedron Ncube = this->cgalevaluator.evaluateCGALMesh(cube); - - sum *= Ncube; - - // FIXME: Instead of intersecting with a thin volume, we could intersect - // with a plane. This feels like a better solution. However, as the result - // of such an intersection isn't simple, we cannot convert the resulting - // Nef polyhedron to a Polyhedron using convertToPolyset() and we need - // another way of extracting the result. kintel 20120203. -// *sum.p3 = sum.p3->intersection(CGAL_Nef_polyhedron3::Plane_3(0, 0, 1, 0), -// CGAL_Nef_polyhedron3::PLANE_ONLY); - - - if (!sum.p3->is_simple()) { +//---------------------------- + CGAL_Nef_polyhedron3::Plane_3 plane = CGAL_Nef_polyhedron3::Plane_3( 0,0,1,0 ); + *sum.p3 = sum.p3->intersection( plane, CGAL_Nef_polyhedron3::PLANE_ONLY); + + NefShellVisitor_for_cut shell_visitor; + CGAL_Nef_polyhedron3::Volume_const_iterator i; + CGAL_Nef_polyhedron3::Shell_entry_const_iterator j; + CGAL_Nef_polyhedron3::SFace_const_handle sface_handle; + for ( i = sum.p3->volumes_begin(); i != sum.p3->volumes_end(); ++i ) { + for ( j = i->shells_begin(); j != i->shells_end(); ++j ) { + sface_handle = CGAL_Nef_polyhedron3::SFace_const_handle( j ); + sum.p3->visit_shell_objects( sface_handle , shell_visitor ); + } + } + + std::cout << "shell visitor\n" << shell_visitor.dump() << "\n"; +//---------------------------- + +/* if (!sum.p3->is_simple()) { PRINT("WARNING: Body of projection(cut = true) isn't valid 2-manifold! Modify your design.."); goto cant_project_non_simple_polyhedron; - } + }*/ - PolySet *ps3 = sum.convertToPolyset(); + CGAL_Nef_polyhedron flat_nef_poly; + *(flat_nef_poly.p2) = shell_visitor.nefpoly2d; + flat_nef_poly.dim = 2; + PolySet *ps3 = flat_nef_poly.convertToPolyset(); if (!ps3) return NULL; // Extract polygons in the XY plane, ignoring all other polygons diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index d1e79ad..15859bd 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -131,6 +131,7 @@ void dxf_tesselate(PolySet *ps, DxfData &dxf, double rot, bool up, bool /* do_tr // ..maybe it would be better to assert here. But this would // break compatibility with the glu tesselator that handled such // cases just fine. + PRINT( "WARNING: Duplicate vertex during Tessellation. Render may be incorrect." ); continue; } |