summaryrefslogtreecommitdiff
path: root/src/cgalutils.cc
diff options
context:
space:
mode:
authordon bright <hugh.m.bright@gmail.com>2012-10-16 01:17:12 (GMT)
committerdon bright <hugh.m.bright@gmail.com>2012-10-16 01:17:12 (GMT)
commit56def4aef228564ea4abcc06d4873c961921cf7d (patch)
tree5374210ab104604af37eae51af1341b5d7792b02 /src/cgalutils.cc
parent65fc1d6b01ade5e76fe712f93e2e108194c3291b (diff)
projection: fallback to 'large thin box' if intersection with plane fails.
also implement SVG debugging output for 2d + 3d Nef Polyhedrons.
Diffstat (limited to 'src/cgalutils.cc')
-rw-r--r--src/cgalutils.cc297
1 files changed, 295 insertions, 2 deletions
diff --git a/src/cgalutils.cc b/src/cgalutils.cc
index e402139..7ae6d7b 100644
--- a/src/cgalutils.cc
+++ b/src/cgalutils.cc
@@ -3,9 +3,11 @@
#include "cgalutils.h"
#include "polyset.h"
#include "printutils.h"
-
#include "cgal.h"
-
+#include <CGAL/bounding_box.h>
+typedef CGAL::Point_3<CGAL_Kernel3> CGAL_Point_3;
+typedef CGAL::Point_2<CGAL_Kernel2> CGAL_Point_2;
+#include <boost/algorithm/string.hpp>
#include <map>
PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p)
@@ -145,5 +147,296 @@ CGAL_Polyhedron *createPolyhedronFromPolySet(const PolySet &ps)
return P;
}
+
+
+
+CGAL::Point project_svg3( CGAL_Point_3 p, CGAL_Iso_cuboid_3 bbox )
+{
+ // do extremely simple fake isometric projection, based on bounding box
+ double x = CGAL::to_double( p.x() );
+ double y = CGAL::to_double( p.y() );
+ double z = CGAL::to_double( p.z() );
+ double screenw = 480;
+ double screenh = 480;
+ double xcenter = screenw / 2;
+ double ycenter = screenh / 2;
+ double xdist = ( 2 * CGAL::to_double( bbox.xmax() - bbox.xmin() ) );
+ double ydist = ( 2 * CGAL::to_double( bbox.ymax() - bbox.ymin() ) );
+ double zdist = ( 2 * CGAL::to_double( bbox.zmax() - bbox.zmin() ) );
+ double xscale = (xdist==0) ? 1 : screenw / (xdist * 1.618);
+ double yscale = (ydist==0) ? 1 : screenh / (ydist * 1.618 * 3);
+ double zscale = (zdist==0) ? 1 : screenh / (zdist * 1.618);
+ double tx = xcenter + x * xscale + y * yscale;
+ double ty = ycenter - z * zscale - y * yscale;
+ return CGAL::Point( tx, ty, 0 );
+}
+
+CGAL::Point project_svg2( CGAL::Point p, CGAL_Iso_cuboid_3 bbox )
+{
+ CGAL_Point_3 pnew( p.x(), 0, p.y() );
+ return project_svg3( pnew, bbox );
+}
+
+// for debugging, not necessarily pretty or useful for users.
+std::string dump_cgal_nef_polyhedron2_face_svg(
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c1,
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c2,
+ CGAL_Nef_polyhedron2::Explorer explorer )
+{
+ std::stringstream out;
+ CGAL_For_all(c1, c2) {
+ if ( explorer.is_standard( explorer.target(c1) ) ) {
+ CGAL_Nef_polyhedron2::Explorer::Point source = explorer.point( explorer.source( c1 ) );
+ CGAL_Nef_polyhedron2::Explorer::Point target = explorer.point( explorer.target( c1 ) );
+ CGAL::Point tp1 = project_svg2( source );
+ CGAL::Point tp2 = project_svg2( target );
+ out << " <line"
+ << " x1='" << CGAL::to_double(tp1.x()) << "'"
+ << " x2='" << CGAL::to_double(tp1.y()) << "'"
+ << " y1='" << CGAL::to_double(tp2.x()) << "'"
+ << " y2='" << CGAL::to_double(tp2.y()) << "'"
+ << " stroke='red' />\n";
+ }
+ }
+ return out.str();
+}
+
+std::string dump_cgal_nef_polyhedron2_svg( const CGAL_Nef_polyhedron2 &N )
+{
+ std::stringstream out;
+ CGAL_Nef_polyhedron2::Explorer explorer = N.explorer();
+ CGAL_Nef_polyhedron2::Explorer::Face_const_iterator i;
+ out << "<svg width='480px' height='480px' xmlns='http://www.w3.org/2000/svg' version='1.1'>\n";
+ out << "<polyline points='0,0 480,0 480,480 0,480' style='fill:none;stroke:black' />\n";
+ out << "<polyline points='10,455 10,475 10,465 18,465 2,465 10,465 14,461 6,469 10,465' style='fill:none;stroke:black;' />";
+ for ( i = explorer.faces_begin(); i!= explorer.faces_end(); ++i ) {
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c1
+ = explorer.face_cycle( i ), c2 ( c1 );
+ out << dump_cgal_nef_polyhedron2_face_svg( c1, c2, explorer );
+
+/*
+ holes not implemented
+ CGAL_Nef_polyhedron2::Explorer::Hole_const_iterator j;
+ for ( j = explorer.holes_begin( i ); j!= explorer.holes_end( i ); ++j ) {
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c3( j ), c4 ( c3 );
+ out << dump_cgal_nef_polyhedron2_face_svg( c3, c4, explorer );
+ }
+*/
+ }
+ out << "</svg>";
+ std::string tmp = out.str();
+ boost::replace_all( tmp, "'", "\"" );
+ return tmp;
+}
+
+
+std::string dump_cgal_nef_polyhedron2_face(
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c1,
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c2,
+ CGAL_Nef_polyhedron2::Explorer explorer )
+{
+ std::stringstream out;
+ CGAL_For_all(c1, c2) {
+ out << " On frame edge:" << explorer.is_frame_edge( c1 );
+ out << " Mark: " << explorer.mark( c1 );
+ if ( explorer.is_standard( explorer.target(c1) ) ) {
+ CGAL_Nef_polyhedron2::Explorer::Point source = explorer.point( explorer.source( c1 ) );
+ CGAL_Nef_polyhedron2::Explorer::Point target = explorer.point( explorer.target( c1 ) );
+ out << " Halfedge x y x2 y2: "
+ << CGAL::to_double(source.x()) << " "
+ << CGAL::to_double(source.y()) << " "
+ << CGAL::to_double(target.x()) << " "
+ << CGAL::to_double(target.y()) << "\n";
+ } else {
+ CGAL_Nef_polyhedron2::Explorer::Ray ray = explorer.ray( explorer.target( c1 ) );
+ out << " Ray x y dx dy: "
+ << CGAL::to_double(ray.point(0).x()) << " "
+ << CGAL::to_double(ray.point(0).y()) << " "
+ << CGAL::to_double(ray.point(1).x()) << " "
+ << CGAL::to_double(ray.point(1).y()) << "\n";
+ }
+ }
+ return out.str();
+}
+
+std::string dump_cgal_nef_polyhedron2( const CGAL_Nef_polyhedron2 &N )
+{
+ std::stringstream out;
+ CGAL_Nef_polyhedron2::Explorer explorer = N.explorer();
+ CGAL_Nef_polyhedron2::Explorer::Face_const_iterator i;
+ out << "CGAL_Nef_polyhedron2 dump begin\n";
+ for ( i = explorer.faces_begin(); i!= explorer.faces_end(); ++i ) {
+ out << " Face body:\n";
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c1
+ = explorer.face_cycle( i ), c2 ( c1 );
+ out << dump_cgal_nef_polyhedron2_face( c1, c2, explorer );
+
+ CGAL_Nef_polyhedron2::Explorer::Hole_const_iterator j;
+ for ( j = explorer.holes_begin( i ); j!= explorer.holes_end( i ); ++j ) {
+ out << " Face hole:\n";
+ CGAL_Nef_polyhedron2::Explorer::Halfedge_around_face_const_circulator c3( j ), c4 ( c3 );
+ out << dump_cgal_nef_polyhedron2_face( c3, c4, explorer );
+ }
+ }
+ out << "CGAL_Nef_polyhedron2 dump end";
+ return out.str();
+}
+
+// This uses the Shell Explorer pattern from the CGAL Manual to dump the 3d Nef Polyhedron information
+// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html#Subsection_29.7.2
+class NefPoly3_dumper_svg {
+public:
+ std::stringstream out;
+ CGAL_Iso_cuboid_3 bbox;
+ NefPoly3_dumper_svg(const CGAL_Nef_polyhedron3& N) {}
+ void setbbox( CGAL_Iso_cuboid_3 bbox ) { this->bbox = bbox; }
+ void visit(CGAL_Nef_polyhedron3::Vertex_const_handle v) {}
+ void visit(CGAL_Nef_polyhedron3::Halfedge_const_handle ) {}
+ void visit(CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {}
+ void visit(CGAL_Nef_polyhedron3::SHalfloop_const_handle shh ){}
+ void visit(CGAL_Nef_polyhedron3::SFace_const_handle ) {}
+ void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet )
+ {
+ int contour_count = 0;
+ out << " <!-- Halffacet. Mark: " << (*hfacet).mark() << " -->\n";
+ CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator i;
+ CGAL_forall_facet_cycles_of( i, hfacet ) {
+ CGAL_Nef_polyhedron3::SHalfloop_const_handle shl_handle;
+ out << " <!-- Halffacet cycle: -->\n";
+ if ( contour_count == 0 ) {
+ out << " <!-- Body contour:--> \n";
+ } else {
+ out << " <!-- Hole contour:--> \n" ;
+ }
+ CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(i), c2(c1);
+ CGAL_For_all( c1, c2 ) {
+ out << " <line";
+ // don't know why we use source()->source(), except thats what CGAL does internally
+ CGAL_Point_3 source = c1->source()->source()->point();
+ CGAL_Point_3 target = c1->source()->target()->point();
+ tp1 = project_svg ( source );
+ tp2 = project_svg ( target );
+ out << " "
+ << "x1='" << CGAL::to_double(tp1.x()) << "' "
+ << "y1='" << CGAL::to_double(tp1.y()) << "' "
+ << "x2='" << CGAL::to_double(tp2.x()) << "' "
+ << "y2='" << CGAL::to_double(tp2.y()) << "' "
+ << "stroke='red' />\n";
+ }
+ contour_count++;
+ } // next facet cycle (i.e. next contour)
+ } // visit()
+
+};
+
+
+std::string dump_cgal_nef_polyhedron3_svg( const CGAL_Nef_polyhedron3 &N )
+{
+ std::stringstream out;
+ out << "<svg width='480px' height='480px' xmlns='http://www.w3.org/2000/svg' version='1.1'>\n";
+ out << "<polyline points='0,0 480,0 480,480 0,480' style='fill:none;stroke:black' />\n";
+ out << "<polyline points='10,455 10,475 10,465 18,465 2,465 10,465 14,461 6,469 10,465' style='fill:none;stroke:black;' />";
+ out << "<!--CGAL_Nef_polyhedron3 dump begin-->\n";
+
+ std::vector<CGAL_Point_3> points;
+ CGAL_Nef_polyhedron3::Vertex_const_iterator vi;
+ for (vi = N.vertices_begin(); vi!=N.vertices_end(); ++vi)
+ points.push_back( vi->point() );
+ CGAL_Iso_cuboid_3 bbox = CGAL::bounding_box( points.begin(), points.end() );
+
+ CGAL_Nef_polyhedron3::Volume_const_iterator c;
+ CGAL_forall_volumes(c,N) {
+ out << " <!--Processing volume...-->\n";
+ out << " <!--Mark: " << (*c).mark() << "-->\n";
+ CGAL_Nef_polyhedron3::Shell_entry_const_iterator it;
+ CGAL_forall_shells_of(it,c) {
+ out << " <!--Processing shell...-->\n";
+ NefPoly3_dumper_svg dumper_svg(N);
+ dumper_svg.setbbox( bbox );
+ N.visit_shell_objects(CGAL_Nef_polyhedron3::SFace_const_handle(it), dumper_svg );
+ out << dumper_svg.out.str();
+ out << " <!--Processing shell end-->\n";
+ }
+ out << " <!--Processing volume end-->\n";
+ }
+ out << "<!--CGAL_Nef_polyhedron3 dump end-->\n";
+ out << "</svg>";
+ std::string tmp = out.str();
+ boost::replace_all( tmp, "'", "\"" );
+ return tmp;
+}
+
+// This uses the Shell Explorer pattern from the CGAL Manual to dump the 3d Nef Polyhedron information
+// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Nef_3/Chapter_main.html#Subsection_29.7.2
+class NefPoly3_dumper {
+public:
+ std::stringstream out;
+ NefPoly3_dumper(const CGAL_Nef_polyhedron3& N) {}
+ void visit(CGAL_Nef_polyhedron3::Vertex_const_handle v) {}
+ void visit(CGAL_Nef_polyhedron3::Halfedge_const_handle ) {}
+ void visit(CGAL_Nef_polyhedron3::SHalfedge_const_handle ) {}
+ void visit(CGAL_Nef_polyhedron3::SHalfloop_const_handle shh )
+ {
+ out << " SHalfloop visit\n";
+ out << " Mark: " << (*shh).mark() << "\n";
+ }
+ void visit(CGAL_Nef_polyhedron3::SFace_const_handle ) {}
+ void visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet )
+ {
+ int contour_count = 0;
+ out << " Halffacet visit\n";
+ out << " Mark: " << (*hfacet).mark() << "\n";
+ CGAL_Nef_polyhedron3::Halffacet_cycle_const_iterator i;
+ CGAL_forall_facet_cycles_of( i, hfacet ) {
+ CGAL_Nef_polyhedron3::SHalfloop_const_handle shl_handle;
+ out << " Halffacet cycle:\n";
+ if ( contour_count == 0 ) {
+ out << " Body contour:\n";
+ } else {
+ out << " Hole contour:\n" ;
+ }
+ CGAL_Nef_polyhedron3::SHalfedge_around_facet_const_circulator c1(i), c2(c1);
+ int count=0;
+ CGAL_For_all( c1, c2 ) {
+ out << " Halfedge vertex:";
+ out << " Mark: " << (*c1).mark();
+ count++;
+ CGAL_Point_3 point3d = c1->source()->source()->point();
+ double x = CGAL::to_double( point3d.x() );
+ double y = CGAL::to_double( point3d.y() );
+ double z = CGAL::to_double( point3d.z() );
+ out << " x:" << x << " y:" << y << " z:" << z <<"\n";
+ }
+ out << " point count: " << count << "\n";
+ contour_count++;
+ } // next facet cycle (i.e. next contour)
+ } // visit()
+
+};
+
+std::string dump_cgal_nef_polyhedron3( const CGAL_Nef_polyhedron3 &N )
+{
+ std::stringstream out;
+ out << "CGAL_Nef_polyhedron3 dump begin\n";
+ CGAL_Nef_polyhedron3::Volume_const_iterator c;
+ CGAL_forall_volumes(c,N) {
+ out << " Processing volume...\n";
+ out << " Mark: " << (*c).mark() << "\n";
+ CGAL_Nef_polyhedron3::Shell_entry_const_iterator it;
+ CGAL_forall_shells_of(it,c) {
+ out << " Processing shell...\n";
+ NefPoly3_dumper dumper(N);
+ N.visit_shell_objects(CGAL_Nef_polyhedron3::SFace_const_handle(it), dumper );
+ out << dumper.out.str();
+ out << " Processing shell end\n";
+ }
+ out << " Processing volume end\n";
+ }
+ out << "CGAL_Nef_polyhedron3 dump end\n";
+ return out.str();
+}
+
+
+
#endif /* ENABLE_CGAL */
contact: Jan Huwald // Impressum