Cleaning type mismatch in update quality (quality has its own type!)

This commit is contained in:
Paolo Cignoni 2017-04-03 17:23:25 +02:00
parent cc5ed5f4c3
commit e7161dfa56
2 changed files with 47 additions and 39 deletions

View File

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
project (trimesh_base)
add_executable(trimesh_base trimesh_base.cpp)
include_directories(../../..)
include_directories(../../../eigenlib)

View File

@ -46,17 +46,20 @@ class UpdateQuality
public:
typedef UpdateMeshType MeshType;
typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::FacePointer FacePointer;
typedef typename MeshType::FaceIterator FaceIterator;
typedef typename MeshType::VertexType::QualityType VertexQualityType;
typedef typename MeshType::FaceType::QualityType FaceQualityType;
/** Assign to each vertex of the mesh a constant quality value. Useful for initialization.
*/
static void VertexConstant(MeshType &m, ScalarType q)
static void VertexConstant(MeshType &m, VertexQualityType q)
{
tri::RequirePerVertexQuality(m);
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
@ -83,8 +86,8 @@ static void VertexValence(UpdateMeshType &m)
/** Clamp each vertex of the mesh with a range of values.
*/
static void VertexClamp(MeshType &m,
typename MeshType::VertexType::QualityType qmin,
typename MeshType::VertexType::QualityType qmax)
VertexQualityType qmin,
VertexQualityType qmax)
{
tri::RequirePerVertexQuality(m);
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
@ -93,7 +96,7 @@ static void VertexClamp(MeshType &m,
/** Normalize the vertex quality so that it fits in the specified range.
*/
static void VertexNormalize(MeshType &m, float qmin=0.0, float qmax=1.0)
static void VertexNormalize(MeshType &m, VertexQualityType qmin=0.0, VertexQualityType qmax=1.0)
{
tri::RequirePerVertexQuality(m);
ScalarType deltaRange = qmax-qmin;
@ -105,18 +108,18 @@ static void VertexNormalize(MeshType &m, float qmin=0.0, float qmax=1.0)
/** Normalize the face quality so that it fits in the specified range.
*/
static void FaceNormalize(MeshType &m, float qmin=0.0, float qmax=1.0)
static void FaceNormalize(MeshType &m, FaceQualityType qmin=0.0, FaceQualityType qmax=1.0)
{
tri::RequirePerFaceQuality(m);
ScalarType deltaRange = qmax-qmin;
std::pair<ScalarType,ScalarType> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m);
FaceQualityType deltaRange = qmax-qmin;
std::pair<FaceQualityType,FaceQualityType> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m);
for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
(*fi).Q() = qmin+deltaRange*((*fi).Q() - minmax.first)/(minmax.second - minmax.first);
}
/** Assign to each face of the mesh a constant quality value. Useful for initialization.
*/
static void FaceConstant(MeshType &m, float q)
static void FaceConstant(MeshType &m, FaceQualityType q)
{
tri::RequirePerFaceQuality(m);
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
@ -129,7 +132,7 @@ static void FaceArea(MeshType &m)
{
tri::RequirePerFaceQuality(m);
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
(*fi).Q()=vcg::DoubleArea(*fi)/ScalarType(2.0);
(*fi).Q()=FaceQualityType(vcg::DoubleArea(*fi)/ScalarType(2.0));
}
static void VertexFromFace( MeshType &m, bool areaWeighted=true)
@ -142,7 +145,7 @@ static void VertexFromFace( MeshType &m, bool areaWeighted=true)
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
{
ScalarType weight=1.0;
VertexQualityType weight=1.0;
if(areaWeighted) weight = vcg::DoubleArea(*fi);
for(int j=0;j<3;++j)
{
@ -163,14 +166,14 @@ static void VertexFromAttributeHandle(MeshType &m, typename MeshType::template P
{
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
if(!(*vi).IsD())
(*vi).Q()=ScalarType(h[vi]);
(*vi).Q()=VertexQualityType(h[vi]);
}
template <class HandleScalar>
static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template PerFaceAttributeHandle<HandleScalar> &h)
{
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
(*fi).Q() =h[fi];
(*fi).Q() =FaceQualityType(h[fi]);
}
static void FaceFromVertex( MeshType &m)
@ -182,7 +185,7 @@ static void FaceFromVertex( MeshType &m)
(*fi).Q() =0;
for (size_t i=0;i<(*fi).VN();i++)
(*fi).Q() += (*fi).V(i)->Q();
(*fi).Q()/=(ScalarType)(*fi).VN();
(*fi).Q()/=(FaceQualityType)(*fi).VN();
}
}
@ -303,14 +306,14 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m)
static void VertexFromAbsoluteCurvature(MeshType &m)
{
VertexIterator vi;
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
{
if((*vi).Kg() >= 0)
(*vi).Q() = math::Abs( 2*(*vi).Kh() );
else
(*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg()));
}
VertexIterator vi;
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
{
if((*vi).Kg() >= 0)
(*vi).Q() = math::Abs( 2*(*vi).Kh() );
else
(*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg()));
}
}
/*
@ -333,11 +336,8 @@ static void VertexFromRMSCurvature(MeshType &m)
Note: requires FF adjacency.
*/
static void FaceSaturate(MeshType &m, ScalarType gradientThr=1.0)
static void FaceSaturate(MeshType &m, FaceQualityType gradientThr=1.0)
{
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::ScalarType ScalarType;
UpdateFlags<MeshType>::FaceClearV(m);
std::stack<FacePointer> st;
@ -361,9 +361,9 @@ static void FaceSaturate(MeshType &m, ScalarType gradientThr=1.0)
for(ffi=star.begin();ffi!=star.end();++ffi )
{
assert(fc!=(*ffi));
ScalarType &qi = (*ffi)->Q();
FaceQualityType &qi = (*ffi)->Q();
CoordType bary1=((*ffi)->P(0)+(*ffi)->P(1)+(*ffi)->P(2))/3;
ScalarType distGeom = Distance(bary0,bary1) / gradientThr;
FaceQualityType distGeom = Distance(bary0,bary1) / gradientThr;
// Main test if the quality varies more than the geometric displacement we have to lower something.
if( distGeom < fabs(qi - fc->Q()))
{
@ -382,7 +382,7 @@ static void FaceSaturate(MeshType &m, ScalarType gradientThr=1.0)
// second case: you have to lower qi, the vertex under examination.
assert( distGeom < fabs(qi - fc->Q()));
assert(fc->Q() < qi);
float newQi = fc->Q() + distGeom -(ScalarType)0.00001;
FaceQualityType newQi = fc->Q() + distGeom -(FaceQualityType)0.00001;
assert(newQi <= qi);
assert(fc->Q() < newQi);
assert( distGeom > fabs(newQi - fc->Q()) );
@ -401,11 +401,12 @@ static void FaceSaturate(MeshType &m, ScalarType gradientThr=1.0)
}
}
/*
Saturate the vertex quality so that for each vertex the gradient of the quality is lower than the given threshold value (in absolute value)
The saturation is done in a conservative way (quality is always decreased and never increased)
/** \brief Saturate Vertex Quality
* Saturate the vertex quality so that for each vertex the gradient of the quality field
* is lower than the given threshold value (in absolute value)
* The saturation is done in a conservative way (quality is always decreased and never increased)
Note: requires VF adjacency.
* Note: requires VF adjacency.
*/
static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
{
@ -422,11 +423,10 @@ static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
st.pop();
vc->SetV();
std::vector<VertexPointer> star;
typename std::vector<VertexPointer>::iterator vvi;
face::VVStarVF<FaceType>(vc,star);
for(vvi=star.begin();vvi!=star.end();++vvi )
for(auto vvi=star.begin();vvi!=star.end();++vvi )
{
ScalarType &qi = (*vvi)->Q();
ScalarType qi = (*vvi)->Q();
ScalarType distGeom = Distance((*vvi)->cP(),vc->cP()) / gradientThr;
// Main test if the quality varies more than the geometric displacement we have to lower something.
if( distGeom < fabs(qi - vc->Q()))
@ -436,8 +436,8 @@ static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
if(vc->Q() > qi) // first case: the center of the star has to be lowered (and re-inserted in the queue).
{
//printf("Reinserting center %i \n",vc - &*m.vert.begin());
ScalarType delta=std::min((ScalarType)0.00001,(ScalarType)distGeom/2.0);
vc->Q() = qi+distGeom-delta;
VertexQualityType delta=std::min(ScalarType(0.00001),ScalarType(distGeom/2.0));
vc->Q() = VertexQualityType(qi+distGeom-delta);
assert( distGeom > fabs(qi - vc->Q()));
st.push(vc);
break;
@ -447,8 +447,8 @@ static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
// second case: you have to lower qi, the vertex under examination.
assert( distGeom < fabs(qi - vc->Q()));
assert(vc->Q() < qi);
ScalarType delta=std::min((ScalarType)0.00001,(ScalarType)distGeom/2.0);
float newQi = vc->Q() + distGeom -delta;
VertexQualityType delta=std::min(VertexQualityType(0.00001),VertexQualityType(distGeom/2.0));
VertexQualityType newQi = vc->Q() + distGeom -delta;
assert(newQi <= qi);
assert(vc->Q() < newQi);
assert( distGeom > fabs(newQi - vc->Q()) );