summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Bright <hugh.m.bright@gmail.com>2012-02-11 02:15:16 (GMT)
committerDon Bright <hugh.m.bright@gmail.com>2012-02-11 02:15:16 (GMT)
commita76d5b02bdb8cd7a9d32c2e204c86726d1384c63 (patch)
treecb4d936cf0cfede1d7f07f18ab3edfc0b35f6233
parenta83fda0c3d9e92a6e47622cd1c2fdeebdfbb8c1a (diff)
use Nef_polyhedron3 intersection to do projection(cut).
-rw-r--r--src/CGAL_Nef_polyhedron.cc1
-rw-r--r--src/CGAL_Nef_polyhedron.h2
-rw-r--r--src/CGAL_Nef_polyhedron_DxfData.cc25
-rw-r--r--src/PolySetCGALEvaluator.cc155
-rw-r--r--src/dxftess-cgal.cc1
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;
}
contact: Jan Huwald // Impressum