diff --git a/Point_set_processing_3/examples/Point_set_processing_3/include/compute_normal.h b/Point_set_processing_3/examples/Point_set_processing_3/include/compute_normal.h new file mode 100644 index 00000000000..3437332ab75 --- /dev/null +++ b/Point_set_processing_3/examples/Point_set_processing_3/include/compute_normal.h @@ -0,0 +1,45 @@ +#ifndef _COMPUTE_NORMAL_ +#define _COMPUTE_NORMAL_ + +template +typename Kernel::Vector_3 compute_facet_normal(const Facet& f) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; + Vector normal = CGAL::NULL_VECTOR; + HF_circulator he = f.facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + const Point& prev = he->prev()->vertex()->point(); + const Point& curr = he->vertex()->point(); + const Point& next = he->next()->vertex()->point(); + Vector n = CGAL::cross_product(next-curr,prev-curr); + normal = normal + (n / std::sqrt(n*n)); + } + return normal / std::sqrt(normal * normal); +} + +template +typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; + typedef typename Vertex::Facet Facet; + Vector normal = CGAL::NULL_VECTOR; + HV_circulator he = v.vertex_begin(); + HV_circulator end = he; + CGAL_For_all(he,end) + { + if(!he->is_border()) + { + Vector n = compute_facet_normal(*he->facet()); + normal = normal + (n / std::sqrt(n*n)); + } + } + return normal / std::sqrt(normal * normal); +} + +#endif // _COMPUTE_NORMAL_ diff --git a/Point_set_processing_3/examples/Point_set_processing_3/include/enriched_polyhedron.h b/Point_set_processing_3/examples/Point_set_processing_3/include/enriched_polyhedron.h deleted file mode 100644 index feab694e237..00000000000 --- a/Point_set_processing_3/examples/Point_set_processing_3/include/enriched_polyhedron.h +++ /dev/null @@ -1,247 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// // -// Class: Enriched_polyhedron // -// // -/////////////////////////////////////////////////////////////////////////// - -#ifndef _POLYGON_MESH_ -#define _POLYGON_MESH_ - -// CGAL -#include -#include - -#include - -// Forward declarations -struct Vertex_normal; -struct Facet_normal; - - -// a refined facet with a normal -template -class Enriched_facet : public CGAL::HalfedgeDS_face_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_facet() - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - - -// a refined halfedge with a general tag -template -class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base -{ -private: - -public: - - // life cycle - Enriched_halfedge() - { - } -}; - - -// a refined vertex with a normal, tag and camera -template -class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_vertex() {} - // repeat mandatory constructors - Enriched_vertex(const Point_3_& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - -// A redefined items class for the Polyhedron_3 -// with a refined vertex class that contains a -// member for the normal vector and a refined -// facet with a normal vector instead of the -// plane equation (this is an alternative -// solution instead of using -// Polyhedron_traits_with_normals_3). - -struct Enriched_items : public CGAL::Polyhedron_items_3 -{ - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_vertex Vertex; - }; - - // wrap face - template - struct Face_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef typename Traits::Vector_3 Normal; - typedef Enriched_halfedge Halfedge; - }; -}; - - -// Enriched polyhedron -template -class Enriched_polyhedron - : public CGAL::Polyhedron_3 -{ - // Private types -private: - - typedef CGAL::Polyhedron_3 Base; - - // Public types -public: - - typedef typename PolyhedronTraits_3::FT FT; - typedef typename PolyhedronTraits_3::Point_3 Point; - - // Repeat Polyhedron_3 public types - typedef typename Base::HalfedgeDS HalfedgeDS; - typedef typename Base::Vertex Vertex; - typedef typename Base::Halfedge Halfedge; - typedef typename Base::Facet Facet; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Vertex_const_handle Vertex_const_handle; - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Halfedge_const_handle Halfedge_const_handle; - typedef typename Base::Facet_handle Facet_handle; - typedef typename Base::Facet_const_handle Facet_const_handle; - typedef typename Base::Vertex_iterator Vertex_iterator; - typedef typename Base::Vertex_const_iterator Vertex_const_iterator; - typedef typename Base::Halfedge_iterator Halfedge_iterator; - typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Base::Facet_iterator Facet_iterator; - typedef typename Base::Facet_const_iterator Facet_const_iterator; - typedef typename Base::Point_iterator Point_iterator; - typedef typename Base::Point_const_iterator Point_const_iterator; - typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; - typedef typename Base::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator; - typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Base::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - -public : - - // Default constructor, copy constructor and operator =() are fine. - - // Repeat Delaunay_triangulation_3 public methods - Base::halfedges_begin; - Base::halfedges_end; - Base::facets_begin; - Base::facets_end; - Base::vertices_begin; - Base::vertices_end; - - // Compute normals using mesh connectivity (per facet, then per vertex) - void compute_normals_per_facet() - { - std::for_each(facets_begin(),facets_end(),Facet_normal()); - } - void compute_normals_per_vertex() - { - std::for_each(vertices_begin(),vertices_end(),Vertex_normal()); - } - void compute_normals() - { - compute_normals_per_facet(); - compute_normals_per_vertex(); - } -}; - -// compute facet normal (functor) -struct Facet_normal -{ - template - void operator()(Facet& f) - { - typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; - typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); - do - { - typename Facet::Normal_3 normal = CGAL::cross_product( - h->next()->vertex()->point() - h->vertex()->point(), - h->next()->next()->vertex()->point() - h->next()->vertex()->point()); - double sqnorm = normal * normal; - if(sqnorm != 0) - normal = normal / (double)std::sqrt(sqnorm); - sum = sum + normal; - } - while(++h != f.facet_begin()); - double sqnorm = sum * sum; - if(sqnorm != 0.0) - f.normal() = sum / std::sqrt(sqnorm); - else - { - f.normal() = CGAL::NULL_VECTOR; - std::cerr << "degenerate face\n"; - } - } -}; - - -// compute vertex normal (functor) -struct Vertex_normal -{ - template - void operator()(Vertex& v) - { - typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; - typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = v.vertex_begin(); - typename Vertex::Halfedge_around_vertex_const_circulator begin = pHalfedge; - CGAL_For_all(pHalfedge,begin) - if(!pHalfedge->is_border()) - normal = normal + pHalfedge->facet()->normal(); - double sqnorm = normal * normal; - if(sqnorm != 0.0f) - v.normal() = normal / (float)std::sqrt(sqnorm); - else - v.normal() = CGAL::NULL_VECTOR; - } -}; - - -#endif // _POLYGON_MESH_ diff --git a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp index 8ee914a725d..5a047c0e1ff 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp +++ b/Point_set_processing_3/examples/Point_set_processing_3/normal_estimation.cpp @@ -12,8 +12,8 @@ // CGAL #include #include -#include #include +#include #include // This package @@ -25,12 +25,11 @@ #include #include -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include #include #include -#include // ---------------------------------------------------------------------------- @@ -222,12 +221,13 @@ int main(int argc, char * argv[]) PointList points; // If OFF file format + std::cerr << "Open " << input_filename << " for reading..." << std::endl; std::string extension = input_filename.substr(input_filename.find_last_of('.')); if (extension == ".off" || extension == ".OFF") { // Read the mesh file in a polyhedron std::ifstream stream(input_filename.c_str()); - typedef Enriched_polyhedron Polyhedron; + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; CGAL::scan_OFF(stream, input_mesh, true /* verbose */); if(!stream || !input_mesh.is_valid() || input_mesh.empty()) @@ -236,15 +236,13 @@ int main(int argc, char * argv[]) return EXIT_FAILURE; } - // Compute vertices' normals from connectivity - input_mesh.compute_normals(); - - // Convert vertices and normals to PointList - Polyhedron::Vertex_iterator v; + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); points.push_back(Point_with_normal(p,n)); } } @@ -269,11 +267,9 @@ int main(int argc, char * argv[]) } // Print status - long memory = CGAL::Memory_sizer().virtual_size(); int nb_vertices = points.size(); std::cerr << "Read file " << input_filename << ": " << nb_vertices << " vertices, " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" << std::endl; task_timer.reset(); diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/Point_set_scene_item.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/Point_set_scene_item.cpp index 095e9dd127a..e9d4b95fc2b 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/Point_set_scene_item.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/Point_set_demo/Point_set_scene_item.cpp @@ -40,7 +40,7 @@ Point_set_scene_item::Point_set_scene_item(const Polyhedron& input_mesh) Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { - Point p = v->point(); + const Point& p = v->point(); Vector n = compute_vertex_normal(*v); m_points->push_back(UI_point(p,n)); } diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/PoissonDoc.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/PoissonDoc.cpp index 187cb35dc4b..0406415b980 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/PoissonDoc.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/PoissonDoc.cpp @@ -6,7 +6,7 @@ #include "Poisson.h" #include "DialogOptions.h" #include "PoissonDoc.h" -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include "read_pwc_point_set.h" #include "read_g23_point_set.h" #include "outlier_removal_wrt_camera_cone_angle_3.h" @@ -15,6 +15,7 @@ // CGAL #include #include +#include #include #include #include @@ -242,28 +243,24 @@ BOOL CPoissonDoc::OnOpenDocument(LPCTSTR lpszPathName) // Read OFF file as a mesh and compute normals from connectivity if (is_mesh) { - // read file in polyhedron - typedef Enriched_polyhedron Polyhedron; + // Read the mesh file in a polyhedron + std::ifstream stream(lpszPathName); + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; - std::ifstream file_stream(lpszPathName); - CGAL::scan_OFF(file_stream, input_mesh, true /* verbose */); - if(!file_stream || !input_mesh.is_valid() || input_mesh.empty()) + CGAL::scan_OFF(stream, input_mesh, true /* verbose */); + if(!stream || !input_mesh.is_valid() || input_mesh.empty()) { prompt_message("Unable to read file"); return FALSE; } - // Compute normals using mesh connectivity - input_mesh.compute_normals(); - - // Copy points to m_points - Polyhedron::Vertex_iterator v; - for(v = input_mesh.vertices_begin(); - v != input_mesh.vertices_end(); - v++) + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; + for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); m_points.push_back(Point_with_normal(p,n)); } } diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/compute_normal.h b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/compute_normal.h new file mode 100644 index 00000000000..3437332ab75 --- /dev/null +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/compute_normal.h @@ -0,0 +1,45 @@ +#ifndef _COMPUTE_NORMAL_ +#define _COMPUTE_NORMAL_ + +template +typename Kernel::Vector_3 compute_facet_normal(const Facet& f) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; + Vector normal = CGAL::NULL_VECTOR; + HF_circulator he = f.facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + const Point& prev = he->prev()->vertex()->point(); + const Point& curr = he->vertex()->point(); + const Point& next = he->next()->vertex()->point(); + Vector n = CGAL::cross_product(next-curr,prev-curr); + normal = normal + (n / std::sqrt(n*n)); + } + return normal / std::sqrt(normal * normal); +} + +template +typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; + typedef typename Vertex::Facet Facet; + Vector normal = CGAL::NULL_VECTOR; + HV_circulator he = v.vertex_begin(); + HV_circulator end = he; + CGAL_For_all(he,end) + { + if(!he->is_border()) + { + Vector n = compute_facet_normal(*he->facet()); + normal = normal + (n / std::sqrt(n*n)); + } + } + return normal / std::sqrt(normal * normal); +} + +#endif // _COMPUTE_NORMAL_ diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/enriched_polyhedron.h b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/enriched_polyhedron.h deleted file mode 100644 index 9a660bb35ee..00000000000 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/poisson/include/enriched_polyhedron.h +++ /dev/null @@ -1,272 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// // -// Class: Enriched_polyhedron // -// // -/////////////////////////////////////////////////////////////////////////// - -#ifndef _POLYGON_MESH_ -#define _POLYGON_MESH_ - -// CGAL -#include -#include - -#include - -// Forward declarations -struct Vertex_normal; -struct Facet_normal; - - -// a refined facet with a normal -template -class Enriched_facet : public CGAL::HalfedgeDS_face_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_facet() - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - - -// a refined halfedge with a general tag -template -class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base -{ -private: - -public: - - // life cycle - Enriched_halfedge() - { - } -}; - - -// a refined vertex with a normal, tag and camera -template -class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_vertex() {} - // repeat mandatory constructors - Enriched_vertex(const Point_3_& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - -// A redefined items class for the Polyhedron_3 -// with a refined vertex class that contains a -// member for the normal vector and a refined -// facet with a normal vector instead of the -// plane equation (this is an alternative -// solution instead of using -// Polyhedron_traits_with_normals_3). - -struct Enriched_items : public CGAL::Polyhedron_items_3 -{ - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_vertex Vertex; - }; - - // wrap face - template - struct Face_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef typename Traits::Vector_3 Normal; - typedef Enriched_halfedge Halfedge; - }; -}; - - -// Enriched polyhedron -template -class Enriched_polyhedron - : public CGAL::Polyhedron_3 -{ - // Private types -private: - - typedef CGAL::Polyhedron_3 Base; - - // Auxiliary class to build a triangles iterator - template // Node is Facet - struct Project_triangle { - typedef Node argument_type; - typedef typename PolyhedronTraits_3::Triangle_3 Triangle; - typedef Triangle result_type; - typedef typename PolyhedronTraits_3::Point_3 Point; - - Triangle operator()(const Node& f) const { - Halfedge_const_handle he = f.halfedge(); - const Point& a = he->vertex()->point(); - const Point& b = he->next()->vertex()->point(); - const Point& c = he->next()->next()->vertex()->point(); - return Triangle(a,b,c); - } - }; - - // Public types -public: - - typedef typename PolyhedronTraits_3::FT FT; - typedef typename PolyhedronTraits_3::Point_3 Point; - - // Repeat Polyhedron_3 public types - typedef typename Base::HalfedgeDS HalfedgeDS; - typedef typename Base::Vertex Vertex; - typedef typename Base::Halfedge Halfedge; - typedef typename Base::Facet Facet; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Vertex_const_handle Vertex_const_handle; - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Halfedge_const_handle Halfedge_const_handle; - typedef typename Base::Facet_handle Facet_handle; - typedef typename Base::Facet_const_handle Facet_const_handle; - typedef typename Base::Vertex_iterator Vertex_iterator; - typedef typename Base::Vertex_const_iterator Vertex_const_iterator; - typedef typename Base::Halfedge_iterator Halfedge_iterator; - typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Base::Facet_iterator Facet_iterator; - typedef typename Base::Facet_const_iterator Facet_const_iterator; - typedef typename Base::Point_iterator Point_iterator; - typedef typename Base::Point_const_iterator Point_const_iterator; - typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; - typedef typename Base::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator; - typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Base::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - - // Iterator over triangles - typedef CGAL::Iterator_project > - Triangle_const_iterator; - -public : - - // Default constructor, copy constructor and operator =() are fine. - - // Repeat Delaunay_triangulation_3 public methods - Base::halfedges_begin; - Base::halfedges_end; - Base::facets_begin; - Base::facets_end; - Base::vertices_begin; - Base::vertices_end; - - // Get first/last iterators over triangles. - Triangle_const_iterator triangles_begin() const { return Triangle_const_iterator(facets_begin()); } - Triangle_const_iterator triangles_end() const { return Triangle_const_iterator(facets_end()); } - - // Compute normals using mesh connectivity (per facet, then per vertex) - void compute_normals_per_facet() - { - std::for_each(facets_begin(),facets_end(),Facet_normal()); - } - void compute_normals_per_vertex() - { - std::for_each(vertices_begin(),vertices_end(),Vertex_normal()); - } - void compute_normals() - { - compute_normals_per_facet(); - compute_normals_per_vertex(); - } -}; - -// compute facet normal (functor) -struct Facet_normal -{ - template - void operator()(Facet& f) - { - typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; - typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); - do - { - typename Facet::Normal_3 normal = CGAL::cross_product( - h->next()->vertex()->point() - h->vertex()->point(), - h->next()->next()->vertex()->point() - h->next()->vertex()->point()); - double sqnorm = normal * normal; - if(sqnorm != 0) - normal = normal / (double)std::sqrt(sqnorm); - sum = sum + normal; - } - while(++h != f.facet_begin()); - double sqnorm = sum * sum; - if(sqnorm != 0.0) - f.normal() = sum / std::sqrt(sqnorm); - else - { - f.normal() = CGAL::NULL_VECTOR; - std::cerr << "degenerate face\n"; - } - } -}; - - -// compute vertex normal (functor) -struct Vertex_normal -{ - template - void operator()(Vertex& v) - { - typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; - typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = v.vertex_begin(); - typename Vertex::Halfedge_around_vertex_const_circulator begin = pHalfedge; - CGAL_For_all(pHalfedge,begin) - if(!pHalfedge->is_border()) - normal = normal + pHalfedge->facet()->normal(); - double sqnorm = normal * normal; - if(sqnorm != 0.0f) - v.normal() = normal / (float)std::sqrt(sqnorm); - else - v.normal() = CGAL::NULL_VECTOR; - } -}; - - -#endif // _POLYGON_MESH_ diff --git a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/APSS_reconstruction.cpp b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/APSS_reconstruction.cpp index 2c658fcf015..4a534221f71 100644 --- a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/APSS_reconstruction.cpp +++ b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/APSS_reconstruction.cpp @@ -11,6 +11,7 @@ // CGAL #include #include +#include #include #include #include @@ -23,7 +24,7 @@ #include #include -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include #include @@ -114,12 +115,13 @@ int main(int argc, char * argv[]) PointList points; // If OFF file format + std::cerr << "Open " << input_filename << " for reading..." << std::endl; std::string extension = input_filename.substr(input_filename.find_last_of('.')); if (extension == ".off" || extension == ".OFF") { // Read the mesh file in a polyhedron std::ifstream stream(input_filename.c_str()); - typedef Enriched_polyhedron Polyhedron; + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; CGAL::scan_OFF(stream, input_mesh, true /* verbose */); if(!stream || !input_mesh.is_valid() || input_mesh.empty()) @@ -128,15 +130,13 @@ int main(int argc, char * argv[]) return EXIT_FAILURE; } - // Compute vertices' normals from connectivity - input_mesh.compute_normals(); - - // Convert vertices and normals to PointList - Polyhedron::Vertex_iterator v; + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); points.push_back(Point_with_normal(p,n)); } } diff --git a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/compute_normal.h b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/compute_normal.h new file mode 100644 index 00000000000..3437332ab75 --- /dev/null +++ b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/compute_normal.h @@ -0,0 +1,45 @@ +#ifndef _COMPUTE_NORMAL_ +#define _COMPUTE_NORMAL_ + +template +typename Kernel::Vector_3 compute_facet_normal(const Facet& f) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; + Vector normal = CGAL::NULL_VECTOR; + HF_circulator he = f.facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + const Point& prev = he->prev()->vertex()->point(); + const Point& curr = he->vertex()->point(); + const Point& next = he->next()->vertex()->point(); + Vector n = CGAL::cross_product(next-curr,prev-curr); + normal = normal + (n / std::sqrt(n*n)); + } + return normal / std::sqrt(normal * normal); +} + +template +typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; + typedef typename Vertex::Facet Facet; + Vector normal = CGAL::NULL_VECTOR; + HV_circulator he = v.vertex_begin(); + HV_circulator end = he; + CGAL_For_all(he,end) + { + if(!he->is_border()) + { + Vector n = compute_facet_normal(*he->facet()); + normal = normal + (n / std::sqrt(n*n)); + } + } + return normal / std::sqrt(normal * normal); +} + +#endif // _COMPUTE_NORMAL_ diff --git a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/enriched_polyhedron.h b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/enriched_polyhedron.h deleted file mode 100644 index feab694e237..00000000000 --- a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/include/enriched_polyhedron.h +++ /dev/null @@ -1,247 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// // -// Class: Enriched_polyhedron // -// // -/////////////////////////////////////////////////////////////////////////// - -#ifndef _POLYGON_MESH_ -#define _POLYGON_MESH_ - -// CGAL -#include -#include - -#include - -// Forward declarations -struct Vertex_normal; -struct Facet_normal; - - -// a refined facet with a normal -template -class Enriched_facet : public CGAL::HalfedgeDS_face_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_facet() - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - - -// a refined halfedge with a general tag -template -class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base -{ -private: - -public: - - // life cycle - Enriched_halfedge() - { - } -}; - - -// a refined vertex with a normal, tag and camera -template -class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_vertex() {} - // repeat mandatory constructors - Enriched_vertex(const Point_3_& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - -// A redefined items class for the Polyhedron_3 -// with a refined vertex class that contains a -// member for the normal vector and a refined -// facet with a normal vector instead of the -// plane equation (this is an alternative -// solution instead of using -// Polyhedron_traits_with_normals_3). - -struct Enriched_items : public CGAL::Polyhedron_items_3 -{ - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_vertex Vertex; - }; - - // wrap face - template - struct Face_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef typename Traits::Vector_3 Normal; - typedef Enriched_halfedge Halfedge; - }; -}; - - -// Enriched polyhedron -template -class Enriched_polyhedron - : public CGAL::Polyhedron_3 -{ - // Private types -private: - - typedef CGAL::Polyhedron_3 Base; - - // Public types -public: - - typedef typename PolyhedronTraits_3::FT FT; - typedef typename PolyhedronTraits_3::Point_3 Point; - - // Repeat Polyhedron_3 public types - typedef typename Base::HalfedgeDS HalfedgeDS; - typedef typename Base::Vertex Vertex; - typedef typename Base::Halfedge Halfedge; - typedef typename Base::Facet Facet; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Vertex_const_handle Vertex_const_handle; - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Halfedge_const_handle Halfedge_const_handle; - typedef typename Base::Facet_handle Facet_handle; - typedef typename Base::Facet_const_handle Facet_const_handle; - typedef typename Base::Vertex_iterator Vertex_iterator; - typedef typename Base::Vertex_const_iterator Vertex_const_iterator; - typedef typename Base::Halfedge_iterator Halfedge_iterator; - typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Base::Facet_iterator Facet_iterator; - typedef typename Base::Facet_const_iterator Facet_const_iterator; - typedef typename Base::Point_iterator Point_iterator; - typedef typename Base::Point_const_iterator Point_const_iterator; - typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; - typedef typename Base::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator; - typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Base::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - -public : - - // Default constructor, copy constructor and operator =() are fine. - - // Repeat Delaunay_triangulation_3 public methods - Base::halfedges_begin; - Base::halfedges_end; - Base::facets_begin; - Base::facets_end; - Base::vertices_begin; - Base::vertices_end; - - // Compute normals using mesh connectivity (per facet, then per vertex) - void compute_normals_per_facet() - { - std::for_each(facets_begin(),facets_end(),Facet_normal()); - } - void compute_normals_per_vertex() - { - std::for_each(vertices_begin(),vertices_end(),Vertex_normal()); - } - void compute_normals() - { - compute_normals_per_facet(); - compute_normals_per_vertex(); - } -}; - -// compute facet normal (functor) -struct Facet_normal -{ - template - void operator()(Facet& f) - { - typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; - typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); - do - { - typename Facet::Normal_3 normal = CGAL::cross_product( - h->next()->vertex()->point() - h->vertex()->point(), - h->next()->next()->vertex()->point() - h->next()->vertex()->point()); - double sqnorm = normal * normal; - if(sqnorm != 0) - normal = normal / (double)std::sqrt(sqnorm); - sum = sum + normal; - } - while(++h != f.facet_begin()); - double sqnorm = sum * sum; - if(sqnorm != 0.0) - f.normal() = sum / std::sqrt(sqnorm); - else - { - f.normal() = CGAL::NULL_VECTOR; - std::cerr << "degenerate face\n"; - } - } -}; - - -// compute vertex normal (functor) -struct Vertex_normal -{ - template - void operator()(Vertex& v) - { - typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; - typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = v.vertex_begin(); - typename Vertex::Halfedge_around_vertex_const_circulator begin = pHalfedge; - CGAL_For_all(pHalfedge,begin) - if(!pHalfedge->is_border()) - normal = normal + pHalfedge->facet()->normal(); - double sqnorm = normal * normal; - if(sqnorm != 0.0f) - v.normal() = normal / (float)std::sqrt(sqnorm); - else - v.normal() = CGAL::NULL_VECTOR; - } -}; - - -#endif // _POLYGON_MESH_ diff --git a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp index fe340ee0ceb..41e577eb38f 100644 --- a/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp +++ b/Surface_reconstruction_points_3/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp @@ -11,6 +11,7 @@ // CGAL #include #include +#include #include #include #include @@ -23,7 +24,7 @@ #include #include -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include #include @@ -109,12 +110,13 @@ int main(int argc, char * argv[]) PointList points; // If OFF file format + std::cerr << "Open " << input_filename << " for reading..." << std::endl; std::string extension = input_filename.substr(input_filename.find_last_of('.')); if (extension == ".off" || extension == ".OFF") { // Read the mesh file in a polyhedron std::ifstream stream(input_filename.c_str()); - typedef Enriched_polyhedron Polyhedron; + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; CGAL::scan_OFF(stream, input_mesh, true /* verbose */); if(!stream || !input_mesh.is_valid() || input_mesh.empty()) @@ -123,15 +125,13 @@ int main(int argc, char * argv[]) return EXIT_FAILURE; } - // Compute vertices' normals from connectivity - input_mesh.compute_normals(); - - // Convert vertices and normals to PointList - Polyhedron::Vertex_iterator v; + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); points.push_back(Point_with_normal(p,n)); } } diff --git a/Surface_reconstruction_points_3/include/CGAL/polyhedron_connected_components.h b/Surface_reconstruction_points_3/include/CGAL/polyhedron_connected_components.h new file mode 100644 index 00000000000..4c013bafde5 --- /dev/null +++ b/Surface_reconstruction_points_3/include/CGAL/polyhedron_connected_components.h @@ -0,0 +1,177 @@ +// Copyright (c) 2005-2009 INRIA (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Saboret, Pierre Alliez + +#ifndef CGAL_POLYHEDRON_CONNECTED_COMPONENTS_H +#define CGAL_POLYHEDRON_CONNECTED_COMPONENTS_H + +#include + +#include +#include + +CGAL_BEGIN_NAMESPACE + + +// ---------------------------------------------------------------------------- +// Private section +// ---------------------------------------------------------------------------- +namespace CGALi { + + +/// Get any vertex with tag == tag_value. +/// +/// @commentheading Template Parameters: +/// @param Polyhedron an instance of CGAL::Polyhedron_3<>. +/// +/// @return a list of pairs (component size, a vertex of the component), +/// ordered by size. + +template +typename Polyhedron::Vertex_handle +get_any_vertex_tag(Polyhedron& polyhedron, + std::map& tags, + const int tag_value) +{ + typedef typename Polyhedron::Vertex_handle Vertex_handle; + typedef typename Polyhedron::Vertex_iterator Vertex_iterator; + + for (Vertex_iterator it = polyhedron.vertices_begin(); + it != polyhedron.vertices_end(); + it++) + { + if (tags[&*it] == tag_value) + return it; + } + + return NULL; +} + +/// Tag a "free" connected component as "done". +/// +/// @commentheading Template Parameters: +/// @param Polyhedron an instance of CGAL::Polyhedron_3<>. +/// +/// @return the size (number of vertices) of the component. +template +unsigned int tag_component(Polyhedron& polyhedron, + typename Polyhedron::Vertex_handle pSeedVertex, + std::map& tags, + const int tag_free, + const int tag_done) +{ + typedef typename Polyhedron::Vertex_handle Vertex_handle; + typedef typename Polyhedron::Vertex_iterator Vertex_iterator; + typedef typename Polyhedron::Halfedge_around_vertex_circulator + Halfedge_around_vertex_circulator; + + unsigned int number_of_vertices = 0; // size (number of vertices) of the component + + std::list vertices; + vertices.push_front(pSeedVertex); + while (!vertices.empty()) + { + Vertex_handle pVertex = vertices.front(); + vertices.pop_front(); + + // Skip vertex if already done + if (tags[&*pVertex] == tag_done) + continue; + + // Mark vertex done + tags[&*pVertex] = tag_done; + number_of_vertices++; + + // Add free neighbors to the list + Halfedge_around_vertex_circulator cir, cir_end; + cir = pVertex->vertex_begin(); + cir_end = cir; + CGAL_For_all(cir,cir_end) + { + Vertex_handle neighbor = cir->opposite()->vertex(); + if (tags[&*neighbor] == tag_free) + vertices.push_front(neighbor); + } + } + + return number_of_vertices; +} + + +} /* namespace CGALi */ + + +// ---------------------------------------------------------------------------- +// Public section +// ---------------------------------------------------------------------------- + + +/// Compute the list of all connected components of a polyhedron. +/// +/// @commentheading Template Parameters: +/// @param Polyhedron an instance of CGAL::Polyhedron_3<> that supports positions. +/// +/// @return a list of pairs (component size, a halfedge of the component), +/// ordered by size. + +template +std::multimap +get_polyhedron_connected_components(Polyhedron& polyhedron) +{ + // Implementation note: + // We tag vertices instead of halfedges to save a factor 6. + // The drawback is that we require the Polyhedron_3<> to support positions. + // TODO: replace std::map to tag vertices by a property map. + Assert_compile_time_tag(Polyhedron::Supports_halfedge_vertex(), Tag_true()); + std::map tags; + + typedef typename Polyhedron::Halfedge_handle Halfedge_handle; + typedef typename Polyhedron::Vertex_handle Vertex_handle; + typedef typename Polyhedron::Vertex_iterator Vertex_iterator; + + /// list of all connected components of a polyhedron, ordered by size. + std::multimap components; + + // Tag all mesh vertices as "free". + const int tag_free = 0; + const int tag_done = 1; + for (Vertex_iterator it = polyhedron.vertices_begin(); + it != polyhedron.vertices_end(); + it++) + { + tags[&*it] = tag_free; + } + + // For each component + Vertex_handle seed_vertex = NULL; + while((seed_vertex = CGALi::get_any_vertex_tag(polyhedron, tags, tag_free)) != NULL) + { + // Tag it as "done" and compute its size + unsigned int component_size = CGALi::tag_component(polyhedron, seed_vertex, tags, tag_free, tag_done); + + // Add component to list, ordered by size + components.insert(std::make_pair(component_size, seed_vertex->halfedge())); + } + + return components; +} + + +CGAL_END_NAMESPACE + +#endif // CGAL_POLYHEDRON_CONNECTED_COMPONENTS_H diff --git a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/APSS_reconstruction_test.cpp b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/APSS_reconstruction_test.cpp index 5f3e16287df..e0f89e6fda5 100644 --- a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/APSS_reconstruction_test.cpp +++ b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/APSS_reconstruction_test.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ #include #include -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include #include @@ -102,12 +103,13 @@ int main(int argc, char * argv[]) PointList points; // If OFF file format + std::cerr << "Open " << input_filename << " for reading..." << std::endl; std::string extension = input_filename.substr(input_filename.find_last_of('.')); if (extension == ".off" || extension == ".OFF") { // Read the mesh file in a polyhedron std::ifstream stream(input_filename.c_str()); - typedef Enriched_polyhedron Polyhedron; + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; CGAL::scan_OFF(stream, input_mesh, true /* verbose */); if(!stream || !input_mesh.is_valid() || input_mesh.empty()) @@ -117,15 +119,13 @@ int main(int argc, char * argv[]) continue; } - // Compute vertices' normals from connectivity - input_mesh.compute_normals(); - - // Convert vertices and normals to PointList - Polyhedron::Vertex_iterator v; + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); points.push_back(Point_with_normal(p,n)); } } diff --git a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/compute_normal.h b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/compute_normal.h new file mode 100644 index 00000000000..3437332ab75 --- /dev/null +++ b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/compute_normal.h @@ -0,0 +1,45 @@ +#ifndef _COMPUTE_NORMAL_ +#define _COMPUTE_NORMAL_ + +template +typename Kernel::Vector_3 compute_facet_normal(const Facet& f) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; + Vector normal = CGAL::NULL_VECTOR; + HF_circulator he = f.facet_begin(); + HF_circulator end = he; + CGAL_For_all(he,end) + { + const Point& prev = he->prev()->vertex()->point(); + const Point& curr = he->vertex()->point(); + const Point& next = he->next()->vertex()->point(); + Vector n = CGAL::cross_product(next-curr,prev-curr); + normal = normal + (n / std::sqrt(n*n)); + } + return normal / std::sqrt(normal * normal); +} + +template +typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) +{ + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; + typedef typename Vertex::Facet Facet; + Vector normal = CGAL::NULL_VECTOR; + HV_circulator he = v.vertex_begin(); + HV_circulator end = he; + CGAL_For_all(he,end) + { + if(!he->is_border()) + { + Vector n = compute_facet_normal(*he->facet()); + normal = normal + (n / std::sqrt(n*n)); + } + } + return normal / std::sqrt(normal * normal); +} + +#endif // _COMPUTE_NORMAL_ diff --git a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/enriched_polyhedron.h b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/enriched_polyhedron.h deleted file mode 100644 index feab694e237..00000000000 --- a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/include/enriched_polyhedron.h +++ /dev/null @@ -1,247 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// // -// Class: Enriched_polyhedron // -// // -/////////////////////////////////////////////////////////////////////////// - -#ifndef _POLYGON_MESH_ -#define _POLYGON_MESH_ - -// CGAL -#include -#include - -#include - -// Forward declarations -struct Vertex_normal; -struct Facet_normal; - - -// a refined facet with a normal -template -class Enriched_facet : public CGAL::HalfedgeDS_face_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_facet() - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - - -// a refined halfedge with a general tag -template -class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base -{ -private: - -public: - - // life cycle - Enriched_halfedge() - { - } -}; - - -// a refined vertex with a normal, tag and camera -template -class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base -{ - // normal - Norm m_normal; - -public: - // life cycle - Enriched_vertex() {} - // repeat mandatory constructors - Enriched_vertex(const Point_3_& pt) - : CGAL::HalfedgeDS_vertex_base(pt) - { - } - - // normal - typedef Norm Normal_3; - Normal_3& normal() { return m_normal; } - const Normal_3& normal() const { return m_normal; } -}; - -// A redefined items class for the Polyhedron_3 -// with a refined vertex class that contains a -// member for the normal vector and a refined -// facet with a normal vector instead of the -// plane equation (this is an alternative -// solution instead of using -// Polyhedron_traits_with_normals_3). - -struct Enriched_items : public CGAL::Polyhedron_items_3 -{ - // wrap vertex - template - struct Vertex_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_vertex Vertex; - }; - - // wrap face - template - struct Face_wrapper - { - typedef typename Traits::Point_3 Point; - typedef typename Traits::Vector_3 Normal; - typedef Enriched_facet Face; - }; - - // wrap halfedge - template - struct Halfedge_wrapper - { - typedef typename Traits::Vector_3 Normal; - typedef Enriched_halfedge Halfedge; - }; -}; - - -// Enriched polyhedron -template -class Enriched_polyhedron - : public CGAL::Polyhedron_3 -{ - // Private types -private: - - typedef CGAL::Polyhedron_3 Base; - - // Public types -public: - - typedef typename PolyhedronTraits_3::FT FT; - typedef typename PolyhedronTraits_3::Point_3 Point; - - // Repeat Polyhedron_3 public types - typedef typename Base::HalfedgeDS HalfedgeDS; - typedef typename Base::Vertex Vertex; - typedef typename Base::Halfedge Halfedge; - typedef typename Base::Facet Facet; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Vertex_const_handle Vertex_const_handle; - typedef typename Base::Halfedge_handle Halfedge_handle; - typedef typename Base::Halfedge_const_handle Halfedge_const_handle; - typedef typename Base::Facet_handle Facet_handle; - typedef typename Base::Facet_const_handle Facet_const_handle; - typedef typename Base::Vertex_iterator Vertex_iterator; - typedef typename Base::Vertex_const_iterator Vertex_const_iterator; - typedef typename Base::Halfedge_iterator Halfedge_iterator; - typedef typename Base::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Base::Facet_iterator Facet_iterator; - typedef typename Base::Facet_const_iterator Facet_const_iterator; - typedef typename Base::Point_iterator Point_iterator; - typedef typename Base::Point_const_iterator Point_const_iterator; - typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; - typedef typename Base::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator; - typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; - typedef typename Base::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - -public : - - // Default constructor, copy constructor and operator =() are fine. - - // Repeat Delaunay_triangulation_3 public methods - Base::halfedges_begin; - Base::halfedges_end; - Base::facets_begin; - Base::facets_end; - Base::vertices_begin; - Base::vertices_end; - - // Compute normals using mesh connectivity (per facet, then per vertex) - void compute_normals_per_facet() - { - std::for_each(facets_begin(),facets_end(),Facet_normal()); - } - void compute_normals_per_vertex() - { - std::for_each(vertices_begin(),vertices_end(),Vertex_normal()); - } - void compute_normals() - { - compute_normals_per_facet(); - compute_normals_per_vertex(); - } -}; - -// compute facet normal (functor) -struct Facet_normal -{ - template - void operator()(Facet& f) - { - typename Facet::Normal_3 sum = CGAL::NULL_VECTOR; - typename Facet::Halfedge_around_facet_circulator h = f.facet_begin(); - do - { - typename Facet::Normal_3 normal = CGAL::cross_product( - h->next()->vertex()->point() - h->vertex()->point(), - h->next()->next()->vertex()->point() - h->next()->vertex()->point()); - double sqnorm = normal * normal; - if(sqnorm != 0) - normal = normal / (double)std::sqrt(sqnorm); - sum = sum + normal; - } - while(++h != f.facet_begin()); - double sqnorm = sum * sum; - if(sqnorm != 0.0) - f.normal() = sum / std::sqrt(sqnorm); - else - { - f.normal() = CGAL::NULL_VECTOR; - std::cerr << "degenerate face\n"; - } - } -}; - - -// compute vertex normal (functor) -struct Vertex_normal -{ - template - void operator()(Vertex& v) - { - typename Vertex::Normal_3 normal = CGAL::NULL_VECTOR; - typename Vertex::Halfedge_around_vertex_const_circulator pHalfedge = v.vertex_begin(); - typename Vertex::Halfedge_around_vertex_const_circulator begin = pHalfedge; - CGAL_For_all(pHalfedge,begin) - if(!pHalfedge->is_border()) - normal = normal + pHalfedge->facet()->normal(); - double sqnorm = normal * normal; - if(sqnorm != 0.0f) - v.normal() = normal / (float)std::sqrt(sqnorm); - else - v.normal() = CGAL::NULL_VECTOR; - } -}; - - -#endif // _POLYGON_MESH_ diff --git a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/poisson_reconstruction_test.cpp b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/poisson_reconstruction_test.cpp index d3c8cf833ad..5adac1f9588 100644 --- a/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/poisson_reconstruction_test.cpp +++ b/Surface_reconstruction_points_3/test/Surface_reconstruction_points_3/poisson_reconstruction_test.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ #include #include -#include "enriched_polyhedron.h" +#include "compute_normal.h" #include #include @@ -101,12 +102,13 @@ int main(int argc, char * argv[]) PointList points; // If OFF file format + std::cerr << "Open " << input_filename << " for reading..." << std::endl; std::string extension = input_filename.substr(input_filename.find_last_of('.')); if (extension == ".off" || extension == ".OFF") { // Read the mesh file in a polyhedron std::ifstream stream(input_filename.c_str()); - typedef Enriched_polyhedron Polyhedron; + typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron input_mesh; CGAL::scan_OFF(stream, input_mesh, true /* verbose */); if(!stream || !input_mesh.is_valid() || input_mesh.empty()) @@ -116,15 +118,13 @@ int main(int argc, char * argv[]) continue; } - // Compute vertices' normals from connectivity - input_mesh.compute_normals(); - - // Convert vertices and normals to PointList - Polyhedron::Vertex_iterator v; + // Convert Polyhedron vertices to point set. + // Compute vertices' normals from connectivity. + Polyhedron::Vertex_const_iterator v; for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) { const Point& p = v->point(); - const Vector& n = v->normal(); + Vector n = compute_vertex_normal(*v); points.push_back(Point_with_normal(p,n)); } }