cgal/Polyhedron/demo/Polyhedron.old/include/CGAL/textured_polyhedron.h

253 lines
6.6 KiB
C++

#ifndef _TEXTURED_MESH_
#define _TEXTURED_MESH_
#include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/HalfedgeDS_default.h>
#include <CGAL/gl.h>
namespace CGAL
{
template <class Refs, class T, class P, class Norm>
class Textured_facet : public CGAL::HalfedgeDS_face_base<Refs, T>
{
// normal
Norm m_normal;
public:
// life cycle
// no constructors to repeat, since only
// default constructor mandatory
Textured_facet()
{
}
// normal
typedef Norm Normal_3;
Normal_3& normal() { return m_normal; }
const Normal_3& normal() const { return m_normal; }
};
template <class Refs, class Tprev, class Tvertex, class Tface, class Norm>
class Textured_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
{
public:
// life cycle
Textured_halfedge()
{
}
};
template <class Refs, class T, class P, class Norm>
class Textured_vertex : public CGAL::HalfedgeDS_vertex_base<Refs, T, P>
{
// normal
Norm m_normal;
double m_u;
double m_v;
public:
// life cycle
Textured_vertex() {}
// repeat mandatory constructors
Textured_vertex(const P& pt)
: CGAL::HalfedgeDS_vertex_base<Refs, T, P>(pt)
{
}
// normal
typedef Norm Normal_3;
Normal_3& normal() { return m_normal; }
const Normal_3& normal() const { return m_normal; }
// u,v coordinates
double& u() { return m_u; }
const double& u() const { return m_u; }
double& v() { return m_v; }
const double& v() const { return m_v; }
};
struct Textured_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 Textured_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 Textured_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 Textured_halfedge<Refs,
CGAL::Tag_true,
CGAL::Tag_true,
CGAL::Tag_true,
Normal> Halfedge;
};
};
// compute facet normal
struct Facet_normal // (functor)
{
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 / (float)std::sqrt(sqnorm);
sum = sum + normal;
} while (++h != f.facet_begin());
float sqnorm = sum * sum;
if (sqnorm != 0.0)
f.normal() = sum / std::sqrt(sqnorm);
else
f.normal() = CGAL::NULL_VECTOR;
}
};
// compute vertex normal
struct Vertex_normal // (functor)
{
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();
float sqnorm = normal * normal;
if (sqnorm != 0.0f)
v.normal() = normal / (float)std::sqrt(sqnorm);
else
v.normal() = CGAL::NULL_VECTOR;
}
};
//*********************************************************
template <class Kernel, class Items>
class Textured_polyhedron : public CGAL::Polyhedron_3<Kernel,Items>
{
public :
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Vector_3 Vector;
typedef typename CGAL::Polyhedron_3<Kernel,Items> Base;
typedef typename CGAL::Polyhedron_3<Kernel,CGAL::Polyhedron_items_3> Basic_polyhedron;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Base::Vertex_iterator Vertex_iterator;
typedef typename Base::Halfedge_handle Halfedge_handle;
typedef typename Base::Halfedge_iterator Halfedge_iterator;
typedef typename Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
typedef typename Base::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator;
typedef typename Base::Edge_iterator Edge_iterator;
typedef typename Base::Facet Facet;
typedef typename Base::Facet_iterator Facet_iterator;
typedef typename Base::Facet_handle Facet_handle;
public :
// life cycle
Textured_polyhedron()
{
}
virtual ~Textured_polyhedron()
{
}
// normals (per facet, then per vertex)
void compute_normals_per_facet()
{
std::for_each(this->facets_begin(),this->facets_end(),Facet_normal());
}
void compute_normals_per_vertex()
{
std::for_each(this->vertices_begin(),this->vertices_end(),Vertex_normal());
}
void compute_normals()
{
compute_normals_per_facet();
compute_normals_per_vertex();
}
void gl_draw_textured_triangles(bool smooth_shading,
bool use_normals,
const double scaling_tex_coordinates)
{
::glBegin(GL_TRIANGLES);
Facet_iterator f = this->facets_begin();
for(;f!= this->facets_end();f++)
gl_draw_textured_facet(f,smooth_shading,use_normals,scaling_tex_coordinates);
::glEnd();
}
void gl_draw_textured_facet(Facet_handle f,
bool smooth_shading,
bool use_normals,
const double scaling_tex_coordinates)
{
// one normal per face
if(use_normals && !smooth_shading)
{
const typename Facet::Normal_3& n = f->normal();
::glNormal3f(n[0],n[1],n[2]);
}
// revolve around current face to get vertices
Halfedge_around_facet_circulator he = f->facet_begin();
do
{
// one normal per vertex
if(use_normals && smooth_shading)
{
const typename Facet::Normal_3& n = he->vertex()->normal();
::glNormal3d(n[0],n[1],n[2]);
}
// polygon assembly is performed per vertex
const Point& p = he->vertex()->point();
const double u = he->vertex()->u();
const double v = he->vertex()->v();
// std::cout << u << " " << v << std::endl;
::glTexCoord2d(u * scaling_tex_coordinates, v * scaling_tex_coordinates);
::glVertex3d(p[0],p[1],p[2]);
}
while(++he != f->facet_begin());
}
}; // end class Textured_polyhedron
}; // end namespace CGAL
#endif // _TEXTURED_MESH_