Heavily reformatted and cleaned for documentation. Hopefully no semantic changes involved...
This commit is contained in:
parent
c22ebbf304
commit
33e1231056
|
@ -75,58 +75,27 @@ static void PerVertexClear(ComputeMeshType &m, bool ClearAllVertNormal=false)
|
||||||
(*vi).N() = NormalType((ScalarType)0,(ScalarType)0,(ScalarType)0);
|
(*vi).N() = NormalType((ScalarType)0,(ScalarType)0,(ScalarType)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Calculates the face normal (if stored in the current face type)
|
/// \brief Calculates the vertex normal as the classic area weighted average. It does not need or exploit current face normals.
|
||||||
|
|
||||||
static void PerFace(ComputeMeshType &m)
|
|
||||||
{
|
|
||||||
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
|
||||||
for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
|
|
||||||
if( !(*f).IsD() ) face::ComputeNormal(*f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Calculates the vertex normal. Exploiting or current face normals.
|
|
||||||
/**
|
/**
|
||||||
The normal of a vertex v is the weigthed average of the normals of the faces incident on v.
|
The normal of a vertex v is the classical area-weigthed average of the normals of the faces incident on v.
|
||||||
*/
|
*/
|
||||||
static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
|
static void PerVertex(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
if(!HasPerVertexNormal(m)) throw vcg::MissingComponentException();
|
PerVertexClear(m);
|
||||||
|
FaceIterator f;
|
||||||
|
for(f=m.face.begin();f!=m.face.end();++f)
|
||||||
|
if( !(*f).IsD() && (*f).IsR() )
|
||||||
|
{
|
||||||
|
//typename FaceType::NormalType t = (*f).Normal();
|
||||||
|
typename FaceType::NormalType t = vcg::Normal(*f);
|
||||||
|
|
||||||
VertexIterator vi;
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
|
||||||
if( !(*vi).IsD() && (*vi).IsRW() )
|
|
||||||
(*vi).N()=CoordType(0,0,0);
|
|
||||||
|
|
||||||
FaceIterator fi;
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
|
||||||
if( !(*fi).IsD())
|
|
||||||
{
|
|
||||||
for(int j=0; j<3; ++j)
|
for(int j=0; j<3; ++j)
|
||||||
if( !(*fi).V(j)->IsD())
|
if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
|
||||||
(*fi).V(j)->N() += (*fi).cN();
|
(*f).V(j)->N() += t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// \brief Calculates the vertex normal. Exploiting or current face normals.
|
|
||||||
/**
|
|
||||||
The normal of a face f is the average of the normals of the vertices of f.
|
|
||||||
*/
|
|
||||||
static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
|
|
||||||
{
|
|
||||||
if(!HasPerVertexNormal(m) || !HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
|
||||||
for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
|
|
||||||
if( !(*fi).IsD())
|
|
||||||
{
|
|
||||||
NormalType n;
|
|
||||||
n.SetZero();
|
|
||||||
for(int j=0; j<3; ++j)
|
|
||||||
n += fi->V(j)->cN();
|
|
||||||
n.Normalize();
|
|
||||||
fi->N() = n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// \brief Calculates the vertex normal as an angle weighted average. It does not need or exploit current face normals.
|
||||||
/// \brief Calculates the vertex normal. Without exploiting or touching face normals.
|
|
||||||
/**
|
/**
|
||||||
The normal of a vertex v computed as a weighted sum f the incident face normals.
|
The normal of a vertex v computed as a weighted sum f the incident face normals.
|
||||||
The weight is simlply the angle of the involved wedge. Described in:
|
The weight is simlply the angle of the involved wedge. Described in:
|
||||||
|
@ -135,8 +104,7 @@ G. Thurmer, C. A. Wuthrich
|
||||||
"Computing vertex normals from polygonal facets"
|
"Computing vertex normals from polygonal facets"
|
||||||
Journal of Graphics Tools, 1998
|
Journal of Graphics Tools, 1998
|
||||||
*/
|
*/
|
||||||
|
static void PerVertexAngleWeighted(ComputeMeshType &m)
|
||||||
static void PerVertexAngleWeighted(ComputeMeshType &m)
|
|
||||||
{
|
{
|
||||||
PerVertexClear(m);
|
PerVertexClear(m);
|
||||||
FaceIterator f;
|
FaceIterator f;
|
||||||
|
@ -154,7 +122,7 @@ static void PerVertexAngleWeighted(ComputeMeshType &m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Calculates the vertex normal. Without exploiting or touching face normals.
|
/// \brief Calculates the vertex normal using the Max et al. weighting scheme. It does not need or exploit current face normals.
|
||||||
/**
|
/**
|
||||||
The normal of a vertex v is computed according to the formula described by Nelson Max in
|
The normal of a vertex v is computed according to the formula described by Nelson Max in
|
||||||
Max, N., "Weights for Computing Vertex Normals from Facet Normals", Journal of Graphics Tools, 4(2) (1999)
|
Max, N., "Weights for Computing Vertex Normals from Facet Normals", Journal of Graphics Tools, 4(2) (1999)
|
||||||
|
@ -180,59 +148,63 @@ static void PerVertexNelsonMaxWeighted(ComputeMeshType &m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Calculates the vertex normal. Without exploiting or touching face normals.
|
/// \brief Calculates the face normal
|
||||||
/**
|
///
|
||||||
The normal of a vertex v is the classical area weigthed average of the normals of the faces incident on v.
|
/// Not normalized. Use PerFaceNormalized() or call NormalizePerVertex() if you need unit length per face normals.
|
||||||
*/
|
static void PerFace(ComputeMeshType &m)
|
||||||
|
|
||||||
static void PerVertex(ComputeMeshType &m)
|
|
||||||
{
|
{
|
||||||
PerVertexClear(m);
|
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
||||||
FaceIterator f;
|
for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
|
||||||
for(f=m.face.begin();f!=m.face.end();++f)
|
if( !(*f).IsD() ) face::ComputeNormal(*f);
|
||||||
if( !(*f).IsD() && (*f).IsR() )
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Calculates the vertex normal by averaging the current per-face normals.
|
||||||
|
/**
|
||||||
|
The normal of a vertex v is the average of the un-normalized normals of the faces incident on v.
|
||||||
|
*/
|
||||||
|
static void PerVertexFromCurrentFaceNormal(ComputeMeshType &m)
|
||||||
|
{
|
||||||
|
if(!HasPerVertexNormal(m)) throw vcg::MissingComponentException();
|
||||||
|
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
if( !(*vi).IsD() && (*vi).IsRW() )
|
||||||
|
(*vi).N()=CoordType(0,0,0);
|
||||||
|
|
||||||
|
FaceIterator fi;
|
||||||
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
|
if( !(*fi).IsD())
|
||||||
{
|
{
|
||||||
//typename FaceType::NormalType t = (*f).Normal();
|
|
||||||
typename FaceType::NormalType t = vcg::Normal(*f);
|
|
||||||
|
|
||||||
for(int j=0; j<3; ++j)
|
for(int j=0; j<3; ++j)
|
||||||
if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
|
if( !(*fi).V(j)->IsD())
|
||||||
(*f).V(j)->N() += t;
|
(*fi).V(j)->N() += (*fi).cN();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Calculates the face normal by averaging the current per-vertex normals.
|
||||||
/// \brief Calculates both vertex and face normals.
|
|
||||||
/**
|
/**
|
||||||
The normal of a vertex v is the weigthed average of the normals of the faces incident on v.
|
The normal of a face f is the average of the normals of the vertices of f.
|
||||||
*/
|
*/
|
||||||
|
static void PerFaceFromCurrentVertexNormal(ComputeMeshType &m)
|
||||||
static void PerVertexPerFace(ComputeMeshType &m)
|
|
||||||
{
|
{
|
||||||
PerFace(m);
|
if(!HasPerVertexNormal(m) || !HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
||||||
PerVertexClear(m);
|
for (FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
|
||||||
for(FaceIterator f=m.face.begin();f!=m.face.end();++f)
|
if( !(*fi).IsD())
|
||||||
if( !(*f).IsD() && (*f).IsR() )
|
{
|
||||||
{
|
NormalType n;
|
||||||
for(int j=0; j<3; ++j)
|
n.SetZero();
|
||||||
if( !(*f).V(j)->IsD() && (*f).V(j)->IsRW() )
|
for(int j=0; j<3; ++j)
|
||||||
(*f).V(j)->N() += (*f).cN();
|
n += fi->V(j)->cN();
|
||||||
}
|
n.Normalize();
|
||||||
|
fi->N() = n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Calculates both vertex and face normals.
|
|
||||||
/**
|
|
||||||
The normal of a vertex v is the weigthed average of the normals of the faces incident on v.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void PerVertexNormalizedPerFace(ComputeMeshType &m)
|
|
||||||
{
|
|
||||||
PerVertexPerFace(m);
|
|
||||||
NormalizeVertex(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Normalize the lenght of the face normals.
|
/// \brief Normalize the length of the vertex normals.
|
||||||
static void NormalizeVertex(ComputeMeshType &m)
|
static void NormalizePerVertex(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
if(!HasPerVertexNormal(m)) throw vcg::MissingComponentException();
|
if(!HasPerVertexNormal(m)) throw vcg::MissingComponentException();
|
||||||
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
@ -240,15 +212,16 @@ static void NormalizeVertex(ComputeMeshType &m)
|
||||||
(*vi).N().Normalize();
|
(*vi).N().Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Normalize the lenght of the face normals.
|
/// \brief Normalize the length of the face normals.
|
||||||
static void NormalizeFace(ComputeMeshType &m)
|
static void NormalizePerFace(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
||||||
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
|
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if( !(*fi).IsD() ) (*fi).N().Normalize();
|
if( !(*fi).IsD() ) (*fi).N().Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AreaNormalizeFace(ComputeMeshType &m)
|
/// \brief Set the length of the face normals to their area (without recomputing their directions).
|
||||||
|
static void NormalizePerFaceByArea(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
@ -260,53 +233,44 @@ static void AreaNormalizeFace(ComputeMeshType &m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Equivalent to PerVertex() and NormalizePerVertex()
|
||||||
|
static void PerVertexNormalized(ComputeMeshType &m)
|
||||||
|
{
|
||||||
|
PerVertex(m);
|
||||||
|
NormalizePerVertex(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Equivalent to PerFace() and NormalizePerVertex()
|
||||||
|
static void PerFaceNormalized(ComputeMeshType &m)
|
||||||
|
{
|
||||||
|
PerFace(m);
|
||||||
|
NormalizePerFace(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Equivalent to PerVertex() and PerFace().
|
||||||
|
static void PerVertexPerFace(ComputeMeshType &m)
|
||||||
|
{
|
||||||
|
PerFace(m);
|
||||||
|
PerVertex(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Equivalent to PerVertexNormalized() and PerFace().
|
||||||
|
static void PerVertexNormalizedPerFace(ComputeMeshType &m)
|
||||||
|
{
|
||||||
|
PerVertexPerFace(m);
|
||||||
|
NormalizePerVertex(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Equivalent to PerVertexNormalizedPerFace() and NormalizePerFace().
|
||||||
static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
|
static void PerVertexNormalizedPerFaceNormalized(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
PerVertexNormalizedPerFace(m);
|
PerVertexNormalizedPerFace(m);
|
||||||
NormalizeFace(m);
|
NormalizePerFace(m);
|
||||||
}
|
|
||||||
|
|
||||||
static void PerFaceRW(ComputeMeshType &m, bool normalize=false)
|
|
||||||
{
|
|
||||||
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
|
||||||
FaceIterator f;
|
|
||||||
bool cn = true;
|
|
||||||
|
|
||||||
if(normalize)
|
|
||||||
{
|
|
||||||
for(f=m.m.face.begin();f!=m.m.face.end();++f)
|
|
||||||
if( !(*f).IsD() && (*f).IsRW() )
|
|
||||||
{
|
|
||||||
for(int j=0; j<3; ++j)
|
|
||||||
if( !(*f).V(j)->IsR()) cn = false;
|
|
||||||
if( cn ) face::ComputeNormalizedNormal(*f);
|
|
||||||
cn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(f=m.m.face.begin();f!=m.m.face.end();++f)
|
|
||||||
if( !(*f).IsD() && (*f).IsRW() )
|
|
||||||
{
|
|
||||||
for(int j=0; j<3; ++j)
|
|
||||||
if( !(*f).V(j)->IsR()) cn = false;
|
|
||||||
|
|
||||||
if( cn )
|
|
||||||
(*f).ComputeNormal();
|
|
||||||
cn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void PerFaceNormalized(ComputeMeshType &m)
|
/// \brief
|
||||||
{
|
|
||||||
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
|
||||||
FaceIterator f;
|
|
||||||
for(f=m.face.begin();f!=m.face.end();++f)
|
|
||||||
if( !(*f).IsD() ) face::ComputeNormalizedNormal(*f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PerBitQuadFaceNormalized(ComputeMeshType &m)
|
static void PerBitQuadFaceNormalized(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
PerFace(m);
|
PerFace(m);
|
||||||
|
@ -322,15 +286,6 @@ static void PerBitQuadFaceNormalized(ComputeMeshType &m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Calculates the vertex normal.
|
|
||||||
static void PerVertexNormalized(ComputeMeshType &m)
|
|
||||||
{
|
|
||||||
PerVertex(m);
|
|
||||||
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
|
|
||||||
if( !(*vi).IsD() && (*vi).IsRW() )
|
|
||||||
(*vi).N().Normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Multiply the vertex normals by the matrix passed. By default, the scale component is removed.
|
/// \brief Multiply the vertex normals by the matrix passed. By default, the scale component is removed.
|
||||||
static void PerVertexMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
|
static void PerVertexMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, bool remove_scaling= true)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +329,74 @@ static void PerFaceMatrix(ComputeMeshType &m, const Matrix44<ScalarType> &mat, b
|
||||||
(*fi).N() = mat33* (*fi).N();
|
(*fi).N() = mat33* (*fi).N();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Compute per wedge normals taking into account the angle between adjacent faces.
|
||||||
|
///
|
||||||
|
/// The PerWedge normals are averaged on common vertexes only if the angle between two faces is \b larger than \p angleRad.
|
||||||
|
/// It requires FFAdjacency.
|
||||||
|
static void PerWedgeCrease(ComputeMeshType &m, ScalarType angleRad)
|
||||||
|
{
|
||||||
|
if(!HasPerWedgeNormal(m) ) throw vcg::MissingComponentException();
|
||||||
|
if(!HasFFAdjacency(m)) throw vcg::MissingComponentException();
|
||||||
|
|
||||||
|
ScalarType cosangle=Cos(angleRad);
|
||||||
|
|
||||||
|
// Clear the per wedge normals
|
||||||
|
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
|
{
|
||||||
|
(*fi).WN(0)=NormalType(0,0,0);
|
||||||
|
(*fi).WN(1)=NormalType(0,0,0);
|
||||||
|
(*fi).WN(2)=NormalType(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
|
{
|
||||||
|
NormalType nn= vcg::Normal(*fi);
|
||||||
|
for(int i=0;i<3;++i)
|
||||||
|
{
|
||||||
|
const NormalType &na=vcg::Normal(*(*fi).FFp(i));
|
||||||
|
if(nn*na > cosangle )
|
||||||
|
{
|
||||||
|
fi->WN((i+0)%3) +=na;
|
||||||
|
fi->WN((i+1)%3) +=na;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PerFaceRW(ComputeMeshType &m, bool normalize=false)
|
||||||
|
{
|
||||||
|
if(!HasPerFaceNormal(m)) throw vcg::MissingComponentException();
|
||||||
|
FaceIterator f;
|
||||||
|
bool cn = true;
|
||||||
|
|
||||||
|
if(normalize)
|
||||||
|
{
|
||||||
|
for(f=m.m.face.begin();f!=m.m.face.end();++f)
|
||||||
|
if( !(*f).IsD() && (*f).IsRW() )
|
||||||
|
{
|
||||||
|
for(int j=0; j<3; ++j)
|
||||||
|
if( !(*f).V(j)->IsR()) cn = false;
|
||||||
|
if( cn ) face::ComputeNormalizedNormal(*f);
|
||||||
|
cn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(f=m.m.face.begin();f!=m.m.face.end();++f)
|
||||||
|
if( !(*f).IsD() && (*f).IsRW() )
|
||||||
|
{
|
||||||
|
for(int j=0; j<3; ++j)
|
||||||
|
if( !(*f).V(j)->IsR()) cn = false;
|
||||||
|
|
||||||
|
if( cn )
|
||||||
|
(*f).ComputeNormal();
|
||||||
|
cn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // end class
|
}; // end class
|
||||||
|
|
||||||
} // End namespace
|
} // End namespace
|
||||||
|
|
Loading…
Reference in New Issue