added support for halfedge normals (normals per face/vertex to allow for smooth shading with feature edges)
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@512 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
@@ -119,6 +119,7 @@ public:
|
|||||||
refcount_htexcoords1D_(0),
|
refcount_htexcoords1D_(0),
|
||||||
refcount_htexcoords2D_(0),
|
refcount_htexcoords2D_(0),
|
||||||
refcount_htexcoords3D_(0),
|
refcount_htexcoords3D_(0),
|
||||||
|
refcount_henormals_(0),
|
||||||
refcount_hecolors_(0),
|
refcount_hecolors_(0),
|
||||||
refcount_ecolors_(0),
|
refcount_ecolors_(0),
|
||||||
refcount_fnormals_(0),
|
refcount_fnormals_(0),
|
||||||
@@ -160,6 +161,9 @@ public:
|
|||||||
if (HAttribs & Attributes::Status)
|
if (HAttribs & Attributes::Status)
|
||||||
Connectivity::request_halfedge_status();
|
Connectivity::request_halfedge_status();
|
||||||
|
|
||||||
|
if (HAttribs & Attributes::Normal)
|
||||||
|
request_halfedge_normals();
|
||||||
|
|
||||||
if (EAttribs & Attributes::Status)
|
if (EAttribs & Attributes::Status)
|
||||||
Connectivity::request_edge_status();
|
Connectivity::request_edge_status();
|
||||||
|
|
||||||
@@ -399,6 +403,15 @@ public:
|
|||||||
{ property(edge_colors_, _eh) = _c; }
|
{ property(edge_colors_, _eh) = _c; }
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------- halfedge normals
|
||||||
|
|
||||||
|
const Normal& normal(HalfedgeHandle _heh) const
|
||||||
|
{ return property(halfedge_normals_, _heh); }
|
||||||
|
|
||||||
|
void set_normal(HalfedgeHandle _heh, const Normal& _n)
|
||||||
|
{ property(halfedge_normals_, _heh) = _n; }
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------- halfedge colors
|
//------------------------------------------------------------- halfedge colors
|
||||||
|
|
||||||
const Color* halfedge_colors() const
|
const Color* halfedge_colors() const
|
||||||
@@ -490,6 +503,12 @@ public:
|
|||||||
add_property( edge_colors_, "e:colors" );
|
add_property( edge_colors_, "e:colors" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void request_halfedge_normals()
|
||||||
|
{
|
||||||
|
if (!refcount_henormals_++)
|
||||||
|
add_property( halfedge_normals_, "h:normals" );
|
||||||
|
}
|
||||||
|
|
||||||
void request_halfedge_colors()
|
void request_halfedge_colors()
|
||||||
{
|
{
|
||||||
if (!refcount_hecolors_++)
|
if (!refcount_hecolors_++)
|
||||||
@@ -564,6 +583,12 @@ public:
|
|||||||
remove_property(edge_colors_);
|
remove_property(edge_colors_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void release_halfedge_normals()
|
||||||
|
{
|
||||||
|
if ((refcount_henormals_ > 0) && (! --refcount_henormals_))
|
||||||
|
remove_property(halfedge_normals_);
|
||||||
|
}
|
||||||
|
|
||||||
void release_halfedge_colors()
|
void release_halfedge_colors()
|
||||||
{
|
{
|
||||||
if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_))
|
if ((refcount_hecolors_ > 0) && (! --refcount_hecolors_))
|
||||||
@@ -599,6 +624,7 @@ public:
|
|||||||
bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();}
|
bool has_halfedge_texcoords2D() const { return halfedge_texcoords2D_.is_valid();}
|
||||||
bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();}
|
bool has_halfedge_texcoords3D() const { return halfedge_texcoords3D_.is_valid();}
|
||||||
bool has_edge_colors() const { return edge_colors_.is_valid(); }
|
bool has_edge_colors() const { return edge_colors_.is_valid(); }
|
||||||
|
bool has_halfedge_normals() const { return halfedge_normals_.is_valid(); }
|
||||||
bool has_halfedge_colors() const { return halfedge_colors_.is_valid(); }
|
bool has_halfedge_colors() const { return halfedge_colors_.is_valid(); }
|
||||||
bool has_face_normals() const { return face_normals_.is_valid(); }
|
bool has_face_normals() const { return face_normals_.is_valid(); }
|
||||||
bool has_face_colors() const { return face_colors_.is_valid(); }
|
bool has_face_colors() const { return face_colors_.is_valid(); }
|
||||||
@@ -616,6 +642,7 @@ public:
|
|||||||
typedef HPropHandleT<TexCoord2D> HalfedgeTexCoords2DPropertyHandle;
|
typedef HPropHandleT<TexCoord2D> HalfedgeTexCoords2DPropertyHandle;
|
||||||
typedef HPropHandleT<TexCoord3D> HalfedgeTexCoords3DPropertyHandle;
|
typedef HPropHandleT<TexCoord3D> HalfedgeTexCoords3DPropertyHandle;
|
||||||
typedef EPropHandleT<Color> EdgeColorsPropertyHandle;
|
typedef EPropHandleT<Color> EdgeColorsPropertyHandle;
|
||||||
|
typedef HPropHandleT<Normal> HalfedgeNormalsPropertyHandle;
|
||||||
typedef HPropHandleT<Color> HalfedgeColorsPropertyHandle;
|
typedef HPropHandleT<Color> HalfedgeColorsPropertyHandle;
|
||||||
typedef FPropHandleT<Normal> FaceNormalsPropertyHandle;
|
typedef FPropHandleT<Normal> FaceNormalsPropertyHandle;
|
||||||
typedef FPropHandleT<Color> FaceColorsPropertyHandle;
|
typedef FPropHandleT<Color> FaceColorsPropertyHandle;
|
||||||
@@ -651,6 +678,11 @@ public:
|
|||||||
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_pph() const
|
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_pph() const
|
||||||
{ return halfedge_texcoords3D_; }
|
{ return halfedge_texcoords3D_; }
|
||||||
|
|
||||||
|
// standard edge properties
|
||||||
|
HalfedgeNormalsPropertyHandle halfedge_normals_pph() const
|
||||||
|
{ return halfedge_normals_; }
|
||||||
|
|
||||||
|
|
||||||
// standard edge properties
|
// standard edge properties
|
||||||
HalfedgeColorsPropertyHandle halfedge_colors_pph() const
|
HalfedgeColorsPropertyHandle halfedge_colors_pph() const
|
||||||
{ return halfedge_colors_; }
|
{ return halfedge_colors_; }
|
||||||
@@ -705,6 +737,7 @@ private:
|
|||||||
HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_;
|
HalfedgeTexCoords1DPropertyHandle halfedge_texcoords1D_;
|
||||||
HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_;
|
HalfedgeTexCoords2DPropertyHandle halfedge_texcoords2D_;
|
||||||
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_;
|
HalfedgeTexCoords3DPropertyHandle halfedge_texcoords3D_;
|
||||||
|
HalfedgeNormalsPropertyHandle halfedge_normals_;
|
||||||
HalfedgeColorsPropertyHandle halfedge_colors_;
|
HalfedgeColorsPropertyHandle halfedge_colors_;
|
||||||
// standard edge properties
|
// standard edge properties
|
||||||
EdgeColorsPropertyHandle edge_colors_;
|
EdgeColorsPropertyHandle edge_colors_;
|
||||||
@@ -726,6 +759,7 @@ private:
|
|||||||
unsigned int refcount_htexcoords1D_;
|
unsigned int refcount_htexcoords1D_;
|
||||||
unsigned int refcount_htexcoords2D_;
|
unsigned int refcount_htexcoords2D_;
|
||||||
unsigned int refcount_htexcoords3D_;
|
unsigned int refcount_htexcoords3D_;
|
||||||
|
unsigned int refcount_henormals_;
|
||||||
unsigned int refcount_hecolors_;
|
unsigned int refcount_hecolors_;
|
||||||
unsigned int refcount_ecolors_;
|
unsigned int refcount_ecolors_;
|
||||||
unsigned int refcount_fnormals_;
|
unsigned int refcount_fnormals_;
|
||||||
|
|||||||
@@ -184,8 +184,9 @@ void
|
|||||||
PolyMeshT<Kernel>::
|
PolyMeshT<Kernel>::
|
||||||
update_normals()
|
update_normals()
|
||||||
{
|
{
|
||||||
if (Kernel::has_face_normals()) update_face_normals();
|
if (Kernel::has_face_normals()) update_face_normals();
|
||||||
if (Kernel::has_vertex_normals()) update_vertex_normals();
|
if (Kernel::has_vertex_normals()) update_vertex_normals();
|
||||||
|
if (Kernel::has_halfedge_normals()) update_halfedge_normals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -207,6 +208,102 @@ update_face_normals()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
template <class Kernel>
|
||||||
|
void
|
||||||
|
PolyMeshT<Kernel>::
|
||||||
|
update_halfedge_normals(const double _feature_angle)
|
||||||
|
{
|
||||||
|
HalfedgeIter h_it(Kernel::halfedges_begin()), h_end(Kernel::halfedges_end());
|
||||||
|
|
||||||
|
for (; h_it != h_end; ++h_it)
|
||||||
|
set_normal(h_it.handle(), calc_halfedge_normal(h_it.handle(), _feature_angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
template <class Kernel>
|
||||||
|
typename PolyMeshT<Kernel>::Normal
|
||||||
|
PolyMeshT<Kernel>::
|
||||||
|
calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle) const
|
||||||
|
{
|
||||||
|
if(Kernel::is_boundary(_heh))
|
||||||
|
return Normal(0,0,0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<FaceHandle> fhs; fhs.reserve(10);
|
||||||
|
|
||||||
|
HalfedgeHandle heh = _heh;
|
||||||
|
|
||||||
|
// collect CW face-handles
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fhs.push_back(Kernel::face_handle(heh));
|
||||||
|
|
||||||
|
heh = Kernel::next_halfedge_handle(heh);
|
||||||
|
heh = Kernel::opposite_halfedge_handle(heh);
|
||||||
|
}
|
||||||
|
while(heh != _heh && !Kernel::is_boundary(heh) && !is_estimated_feature_edge(heh, _feature_angle));
|
||||||
|
|
||||||
|
// collect CCW face-handles
|
||||||
|
if(heh != _heh && !is_estimated_feature_edge(_heh, _feature_angle))
|
||||||
|
{
|
||||||
|
heh = Kernel::opposite_halfedge_handle(_heh);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fhs.push_back(Kernel::face_handle(heh));
|
||||||
|
|
||||||
|
heh = Kernel::prev_halfedge_handle(heh);
|
||||||
|
heh = Kernel::opposite_halfedge_handle(heh);
|
||||||
|
}
|
||||||
|
while(!Kernel::is_boundary(heh) && !is_estimated_feature_edge(heh, _feature_angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
Normal n(0,0,0);
|
||||||
|
for(unsigned int i=0; i<fhs.size(); ++i)
|
||||||
|
n += Kernel::normal(fhs[i]);
|
||||||
|
|
||||||
|
return n.normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
template <class Kernel>
|
||||||
|
bool
|
||||||
|
PolyMeshT<Kernel>::
|
||||||
|
is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const
|
||||||
|
{
|
||||||
|
EdgeHandle eh = Kernel::edge_handle(_heh);
|
||||||
|
|
||||||
|
if(Kernel::has_edge_status())
|
||||||
|
{
|
||||||
|
if(Kernel::status(eh).feature())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Kernel::is_boundary(eh))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// compute angle between faces
|
||||||
|
FaceHandle fh0 = Kernel::face_handle(_heh);
|
||||||
|
FaceHandle fh1 = Kernel::face_handle(Kernel::opposite_halfedge_handle(_heh));
|
||||||
|
|
||||||
|
Normal fn0 = Kernel::normal(fh0);
|
||||||
|
Normal fn1 = Kernel::normal(fh1);
|
||||||
|
|
||||||
|
// dihedral angle above angle threshold
|
||||||
|
return ( (fn0|fn1) < cos(_feature_angle) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
template <class Kernel>
|
template <class Kernel>
|
||||||
typename PolyMeshT<Kernel>::Normal
|
typename PolyMeshT<Kernel>::Normal
|
||||||
PolyMeshT<Kernel>::
|
PolyMeshT<Kernel>::
|
||||||
|
|||||||
@@ -225,6 +225,24 @@ public:
|
|||||||
const Point& _p2) const;
|
const Point& _p2) const;
|
||||||
// calculates the average of the vertices defining _fh
|
// calculates the average of the vertices defining _fh
|
||||||
void calc_face_centroid(FaceHandle _fh, Point& _pt) const;
|
void calc_face_centroid(FaceHandle _fh, Point& _pt) const;
|
||||||
|
|
||||||
|
/// Update normal for halfedge _heh
|
||||||
|
void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8)
|
||||||
|
{ set_normal(_heh, calc_halfedge_normal(_heh)); }
|
||||||
|
|
||||||
|
/** Update normal vectors for all halfedges.
|
||||||
|
\attention Needs the Attributes::Normal attribute for faces. */
|
||||||
|
void update_halfedge_normals(const double _feature_angle = 0.8);
|
||||||
|
|
||||||
|
/** Calculate normal vector for halfedge _heh. */
|
||||||
|
/** requires valid face normals!!! */
|
||||||
|
virtual Normal calc_halfedge_normal(HalfedgeHandle _fh, const double _feature_angle = 0.8) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** identifies feature edges w.r.t. the minimal dihedral angle for feautre edges (in radians) */
|
||||||
|
/** and the status feature tag */
|
||||||
|
bool is_estimated_feature_edge(HalfedgeHandle _heh, const double _feature_angle) const;
|
||||||
|
|
||||||
/// Update normal for vertex _vh
|
/// Update normal for vertex _vh
|
||||||
void update_normal(VertexHandle _vh)
|
void update_normal(VertexHandle _vh)
|
||||||
{ set_normal(_vh, calc_vertex_normal(_vh)); }
|
{ set_normal(_vh, calc_vertex_normal(_vh)); }
|
||||||
|
|||||||
Reference in New Issue
Block a user