mirror of https://github.com/CGAL/cgal
Replace custom polyhedron class Enriched_polyhedron by a regular Polyhedron_3 + a call to compute_vertex_normal() (borrowed from Polyhedron demo).
The new code is shorter and easier to understand.
This commit is contained in:
parent
5e81b086c8
commit
c6ad02b857
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _COMPUTE_NORMAL_
|
||||
#define _COMPUTE_NORMAL_
|
||||
|
||||
template <class Facet, class Kernel>
|
||||
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 <class Vertex, class Kernel>
|
||||
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<Facet,Kernel>(*he->facet());
|
||||
normal = normal + (n / std::sqrt(n*n));
|
||||
}
|
||||
}
|
||||
return normal / std::sqrt(normal * normal);
|
||||
}
|
||||
|
||||
#endif // _COMPUTE_NORMAL_
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Class: Enriched_polyhedron //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _POLYGON_MESH_
|
||||
#define _POLYGON_MESH_
|
||||
|
||||
// CGAL
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
// Forward declarations
|
||||
struct Vertex_normal;
|
||||
struct Facet_normal;
|
||||
|
||||
|
||||
// a refined facet with a normal
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_facet : public CGAL::HalfedgeDS_face_base<Refs, Tag>
|
||||
{
|
||||
// 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 Refs, class Tprev, class Tvertex, class Tface, class Norm>
|
||||
class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
// life cycle
|
||||
Enriched_halfedge()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// a refined vertex with a normal, tag and camera
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>
|
||||
{
|
||||
// normal
|
||||
Norm m_normal;
|
||||
|
||||
public:
|
||||
// life cycle
|
||||
Enriched_vertex() {}
|
||||
// repeat mandatory constructors
|
||||
Enriched_vertex(const Point_3_& pt)
|
||||
: CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>(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 <class Refs, class Traits>
|
||||
struct Vertex_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_vertex<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Vertex;
|
||||
};
|
||||
|
||||
// wrap face
|
||||
template <class Refs, class Traits>
|
||||
struct Face_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_facet<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Face;
|
||||
};
|
||||
|
||||
// wrap halfedge
|
||||
template <class Refs, class Traits>
|
||||
struct Halfedge_wrapper
|
||||
{
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_halfedge<Refs,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
Normal> Halfedge;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Enriched polyhedron
|
||||
template <class PolyhedronTraits_3,
|
||||
class PolyhedronItems_3 = Enriched_items>
|
||||
class Enriched_polyhedron
|
||||
: public CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3>
|
||||
{
|
||||
// Private types
|
||||
private:
|
||||
|
||||
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_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 <class Facet>
|
||||
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 <class Vertex>
|
||||
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_
|
||||
|
|
@ -12,8 +12,8 @@
|
|||
// CGAL
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Memory_sizer.h>
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
|
||||
// This package
|
||||
|
|
@ -25,12 +25,11 @@
|
|||
#include <CGAL/IO/read_xyz_point_set.h>
|
||||
#include <CGAL/IO/write_xyz_point_set.h>
|
||||
|
||||
#include "enriched_polyhedron.h"
|
||||
#include "compute_normal.h"
|
||||
|
||||
#include <deque>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -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<Kernel,Enriched_items> Polyhedron;
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Polyhedron::Vertex,Kernel>(*v);
|
||||
m_points->push_back(UI_point(p,n));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <CGAL/make_surface_mesh.h>
|
||||
#include <CGAL/Implicit_surface_3.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/IO/File_scanner_OFF.h>
|
||||
#include <CGAL/Timer.h>
|
||||
|
|
@ -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<Kernel> Polyhedron;
|
||||
// Read the mesh file in a polyhedron
|
||||
std::ifstream stream(lpszPathName);
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*v);
|
||||
m_points.push_back(Point_with_normal(p,n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _COMPUTE_NORMAL_
|
||||
#define _COMPUTE_NORMAL_
|
||||
|
||||
template <class Facet, class Kernel>
|
||||
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 <class Vertex, class Kernel>
|
||||
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<Facet,Kernel>(*he->facet());
|
||||
normal = normal + (n / std::sqrt(n*n));
|
||||
}
|
||||
}
|
||||
return normal / std::sqrt(normal * normal);
|
||||
}
|
||||
|
||||
#endif // _COMPUTE_NORMAL_
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Class: Enriched_polyhedron //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _POLYGON_MESH_
|
||||
#define _POLYGON_MESH_
|
||||
|
||||
// CGAL
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
// Forward declarations
|
||||
struct Vertex_normal;
|
||||
struct Facet_normal;
|
||||
|
||||
|
||||
// a refined facet with a normal
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_facet : public CGAL::HalfedgeDS_face_base<Refs, Tag>
|
||||
{
|
||||
// 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 Refs, class Tprev, class Tvertex, class Tface, class Norm>
|
||||
class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
// life cycle
|
||||
Enriched_halfedge()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// a refined vertex with a normal, tag and camera
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>
|
||||
{
|
||||
// normal
|
||||
Norm m_normal;
|
||||
|
||||
public:
|
||||
// life cycle
|
||||
Enriched_vertex() {}
|
||||
// repeat mandatory constructors
|
||||
Enriched_vertex(const Point_3_& pt)
|
||||
: CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>(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 <class Refs, class Traits>
|
||||
struct Vertex_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_vertex<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Vertex;
|
||||
};
|
||||
|
||||
// wrap face
|
||||
template <class Refs, class Traits>
|
||||
struct Face_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_facet<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Face;
|
||||
};
|
||||
|
||||
// wrap halfedge
|
||||
template <class Refs, class Traits>
|
||||
struct Halfedge_wrapper
|
||||
{
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_halfedge<Refs,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
Normal> Halfedge;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Enriched polyhedron
|
||||
template <class PolyhedronTraits_3,
|
||||
class PolyhedronItems_3 = Enriched_items>
|
||||
class Enriched_polyhedron
|
||||
: public CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3>
|
||||
{
|
||||
// Private types
|
||||
private:
|
||||
|
||||
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3> Base;
|
||||
|
||||
// Auxiliary class to build a triangles iterator
|
||||
template <class Node> // 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<Facet_const_iterator, Project_triangle<Facet> >
|
||||
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 <class Facet>
|
||||
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 <class Vertex>
|
||||
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_
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
// CGAL
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Surface_mesh_default_triangulation_3.h>
|
||||
#include <CGAL/make_surface_mesh.h>
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/IO/read_xyz_point_set.h>
|
||||
|
||||
#include "enriched_polyhedron.h"
|
||||
#include "compute_normal.h"
|
||||
|
||||
#include <deque>
|
||||
#include <cstdlib>
|
||||
|
|
@ -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<Kernel,Enriched_items> Polyhedron;
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*v);
|
||||
points.push_back(Point_with_normal(p,n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _COMPUTE_NORMAL_
|
||||
#define _COMPUTE_NORMAL_
|
||||
|
||||
template <class Facet, class Kernel>
|
||||
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 <class Vertex, class Kernel>
|
||||
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<Facet,Kernel>(*he->facet());
|
||||
normal = normal + (n / std::sqrt(n*n));
|
||||
}
|
||||
}
|
||||
return normal / std::sqrt(normal * normal);
|
||||
}
|
||||
|
||||
#endif // _COMPUTE_NORMAL_
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Class: Enriched_polyhedron //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _POLYGON_MESH_
|
||||
#define _POLYGON_MESH_
|
||||
|
||||
// CGAL
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
// Forward declarations
|
||||
struct Vertex_normal;
|
||||
struct Facet_normal;
|
||||
|
||||
|
||||
// a refined facet with a normal
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_facet : public CGAL::HalfedgeDS_face_base<Refs, Tag>
|
||||
{
|
||||
// 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 Refs, class Tprev, class Tvertex, class Tface, class Norm>
|
||||
class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
// life cycle
|
||||
Enriched_halfedge()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// a refined vertex with a normal, tag and camera
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>
|
||||
{
|
||||
// normal
|
||||
Norm m_normal;
|
||||
|
||||
public:
|
||||
// life cycle
|
||||
Enriched_vertex() {}
|
||||
// repeat mandatory constructors
|
||||
Enriched_vertex(const Point_3_& pt)
|
||||
: CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>(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 <class Refs, class Traits>
|
||||
struct Vertex_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_vertex<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Vertex;
|
||||
};
|
||||
|
||||
// wrap face
|
||||
template <class Refs, class Traits>
|
||||
struct Face_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_facet<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Face;
|
||||
};
|
||||
|
||||
// wrap halfedge
|
||||
template <class Refs, class Traits>
|
||||
struct Halfedge_wrapper
|
||||
{
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_halfedge<Refs,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
Normal> Halfedge;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Enriched polyhedron
|
||||
template <class PolyhedronTraits_3,
|
||||
class PolyhedronItems_3 = Enriched_items>
|
||||
class Enriched_polyhedron
|
||||
: public CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3>
|
||||
{
|
||||
// Private types
|
||||
private:
|
||||
|
||||
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_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 <class Facet>
|
||||
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 <class Vertex>
|
||||
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_
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
// CGAL
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Surface_mesh_default_triangulation_3.h>
|
||||
#include <CGAL/make_surface_mesh.h>
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/IO/read_xyz_point_set.h>
|
||||
|
||||
#include "enriched_polyhedron.h"
|
||||
#include "compute_normal.h"
|
||||
|
||||
#include <deque>
|
||||
#include <cstdlib>
|
||||
|
|
@ -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<Kernel,Enriched_items> Polyhedron;
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*v);
|
||||
points.push_back(Point_with_normal(p,n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <CGAL/Polyhedron_3.h>
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
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<class Polyhedron>
|
||||
typename Polyhedron::Vertex_handle
|
||||
get_any_vertex_tag(Polyhedron& polyhedron,
|
||||
std::map<typename Polyhedron::Vertex*, int>& 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<class Polyhedron>
|
||||
unsigned int tag_component(Polyhedron& polyhedron,
|
||||
typename Polyhedron::Vertex_handle pSeedVertex,
|
||||
std::map<typename Polyhedron::Vertex*, int>& 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<Vertex_handle> 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<class Polyhedron>
|
||||
std::multimap<unsigned int, typename Polyhedron::Halfedge_handle>
|
||||
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<typename Polyhedron::Vertex*, int> 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<unsigned int, Halfedge_handle> 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
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Memory_sizer.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Surface_mesh_default_triangulation_3.h>
|
||||
#include <CGAL/make_surface_mesh.h>
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/IO/read_xyz_point_set.h>
|
||||
|
||||
#include "enriched_polyhedron.h"
|
||||
#include "compute_normal.h"
|
||||
|
||||
#include <deque>
|
||||
#include <cstdlib>
|
||||
|
|
@ -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<Kernel,Enriched_items> Polyhedron;
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*v);
|
||||
points.push_back(Point_with_normal(p,n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _COMPUTE_NORMAL_
|
||||
#define _COMPUTE_NORMAL_
|
||||
|
||||
template <class Facet, class Kernel>
|
||||
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 <class Vertex, class Kernel>
|
||||
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<Facet,Kernel>(*he->facet());
|
||||
normal = normal + (n / std::sqrt(n*n));
|
||||
}
|
||||
}
|
||||
return normal / std::sqrt(normal * normal);
|
||||
}
|
||||
|
||||
#endif // _COMPUTE_NORMAL_
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Class: Enriched_polyhedron //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _POLYGON_MESH_
|
||||
#define _POLYGON_MESH_
|
||||
|
||||
// CGAL
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
// Forward declarations
|
||||
struct Vertex_normal;
|
||||
struct Facet_normal;
|
||||
|
||||
|
||||
// a refined facet with a normal
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_facet : public CGAL::HalfedgeDS_face_base<Refs, Tag>
|
||||
{
|
||||
// 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 Refs, class Tprev, class Tvertex, class Tface, class Norm>
|
||||
class Enriched_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
// life cycle
|
||||
Enriched_halfedge()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// a refined vertex with a normal, tag and camera
|
||||
template <class Refs, class Tag, class Point_3_, class Norm>
|
||||
class Enriched_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>
|
||||
{
|
||||
// normal
|
||||
Norm m_normal;
|
||||
|
||||
public:
|
||||
// life cycle
|
||||
Enriched_vertex() {}
|
||||
// repeat mandatory constructors
|
||||
Enriched_vertex(const Point_3_& pt)
|
||||
: CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point_3_>(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 <class Refs, class Traits>
|
||||
struct Vertex_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_vertex<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Vertex;
|
||||
};
|
||||
|
||||
// wrap face
|
||||
template <class Refs, class Traits>
|
||||
struct Face_wrapper
|
||||
{
|
||||
typedef typename Traits::Point_3 Point;
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_facet<Refs,
|
||||
CGAL::Tag_true,
|
||||
Point,
|
||||
Normal> Face;
|
||||
};
|
||||
|
||||
// wrap halfedge
|
||||
template <class Refs, class Traits>
|
||||
struct Halfedge_wrapper
|
||||
{
|
||||
typedef typename Traits::Vector_3 Normal;
|
||||
typedef Enriched_halfedge<Refs,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
CGAL::Tag_true,
|
||||
Normal> Halfedge;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Enriched polyhedron
|
||||
template <class PolyhedronTraits_3,
|
||||
class PolyhedronItems_3 = Enriched_items>
|
||||
class Enriched_polyhedron
|
||||
: public CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3>
|
||||
{
|
||||
// Private types
|
||||
private:
|
||||
|
||||
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_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 <class Facet>
|
||||
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 <class Vertex>
|
||||
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_
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Memory_sizer.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Surface_mesh_default_triangulation_3.h>
|
||||
#include <CGAL/make_surface_mesh.h>
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/IO/read_xyz_point_set.h>
|
||||
|
||||
#include "enriched_polyhedron.h"
|
||||
#include "compute_normal.h"
|
||||
|
||||
#include <deque>
|
||||
#include <cstdlib>
|
||||
|
|
@ -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<Kernel,Enriched_items> Polyhedron;
|
||||
typedef CGAL::Polyhedron_3<Kernel> 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<Polyhedron::Vertex,Kernel>(*v);
|
||||
points.push_back(Point_with_normal(p,n));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue