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: public:
typedef UpdateMeshType MeshType; typedef UpdateMeshType MeshType;
typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::FacePointer FacePointer; typedef typename MeshType::FacePointer FacePointer;
typedef typename MeshType::FaceIterator FaceIterator; 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. /** 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); tri::RequirePerVertexQuality(m);
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) 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. /** Clamp each vertex of the mesh with a range of values.
*/ */
static void VertexClamp(MeshType &m, static void VertexClamp(MeshType &m,
typename MeshType::VertexType::QualityType qmin, VertexQualityType qmin,
typename MeshType::VertexType::QualityType qmax) VertexQualityType qmax)
{ {
tri::RequirePerVertexQuality(m); tri::RequirePerVertexQuality(m);
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) 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. /** 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); tri::RequirePerVertexQuality(m);
ScalarType deltaRange = qmax-qmin; 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. /** 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); tri::RequirePerFaceQuality(m);
ScalarType deltaRange = qmax-qmin; FaceQualityType deltaRange = qmax-qmin;
std::pair<ScalarType,ScalarType> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m); std::pair<FaceQualityType,FaceQualityType> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m);
for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
(*fi).Q() = qmin+deltaRange*((*fi).Q() - minmax.first)/(minmax.second - minmax.first); (*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. /** 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); tri::RequirePerFaceQuality(m);
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
@ -129,7 +132,7 @@ static void FaceArea(MeshType &m)
{ {
tri::RequirePerFaceQuality(m); tri::RequirePerFaceQuality(m);
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) 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) 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) for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()) if(!(*fi).IsD())
{ {
ScalarType weight=1.0; VertexQualityType weight=1.0;
if(areaWeighted) weight = vcg::DoubleArea(*fi); if(areaWeighted) weight = vcg::DoubleArea(*fi);
for(int j=0;j<3;++j) 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) for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi)
if(!(*vi).IsD()) if(!(*vi).IsD())
(*vi).Q()=ScalarType(h[vi]); (*vi).Q()=VertexQualityType(h[vi]);
} }
template <class HandleScalar> template <class HandleScalar>
static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template PerFaceAttributeHandle<HandleScalar> &h) 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()) 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) static void FaceFromVertex( MeshType &m)
@ -182,7 +185,7 @@ static void FaceFromVertex( MeshType &m)
(*fi).Q() =0; (*fi).Q() =0;
for (size_t i=0;i<(*fi).VN();i++) for (size_t i=0;i<(*fi).VN();i++)
(*fi).Q() += (*fi).V(i)->Q(); (*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) static void VertexFromAbsoluteCurvature(MeshType &m)
{ {
VertexIterator vi; VertexIterator vi;
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
{ {
if((*vi).Kg() >= 0) if((*vi).Kg() >= 0)
(*vi).Q() = math::Abs( 2*(*vi).Kh() ); (*vi).Q() = math::Abs( 2*(*vi).Kh() );
else else
(*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg())); (*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. 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); UpdateFlags<MeshType>::FaceClearV(m);
std::stack<FacePointer> st; 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 ) for(ffi=star.begin();ffi!=star.end();++ffi )
{ {
assert(fc!=(*ffi)); assert(fc!=(*ffi));
ScalarType &qi = (*ffi)->Q(); FaceQualityType &qi = (*ffi)->Q();
CoordType bary1=((*ffi)->P(0)+(*ffi)->P(1)+(*ffi)->P(2))/3; 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. // Main test if the quality varies more than the geometric displacement we have to lower something.
if( distGeom < fabs(qi - fc->Q())) 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. // second case: you have to lower qi, the vertex under examination.
assert( distGeom < fabs(qi - fc->Q())); assert( distGeom < fabs(qi - fc->Q()));
assert(fc->Q() < qi); assert(fc->Q() < qi);
float newQi = fc->Q() + distGeom -(ScalarType)0.00001; FaceQualityType newQi = fc->Q() + distGeom -(FaceQualityType)0.00001;
assert(newQi <= qi); assert(newQi <= qi);
assert(fc->Q() < newQi); assert(fc->Q() < newQi);
assert( distGeom > fabs(newQi - fc->Q()) ); assert( distGeom > fabs(newQi - fc->Q()) );
@ -401,11 +401,12 @@ static void FaceSaturate(MeshType &m, ScalarType gradientThr=1.0)
} }
} }
/* /** \brief Saturate Vertex Quality
Saturate the vertex quality so that for each vertex the gradient of the quality is lower than the given threshold value (in absolute value) * Saturate the vertex quality so that for each vertex the gradient of the quality field
The saturation is done in a conservative way (quality is always decreased and never increased) * 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) static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
{ {
@ -422,11 +423,10 @@ static void VertexSaturate(MeshType &m, ScalarType gradientThr=1.0)
st.pop(); st.pop();
vc->SetV(); vc->SetV();
std::vector<VertexPointer> star; std::vector<VertexPointer> star;
typename std::vector<VertexPointer>::iterator vvi;
face::VVStarVF<FaceType>(vc,star); 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; ScalarType distGeom = Distance((*vvi)->cP(),vc->cP()) / gradientThr;
// Main test if the quality varies more than the geometric displacement we have to lower something. // Main test if the quality varies more than the geometric displacement we have to lower something.
if( distGeom < fabs(qi - vc->Q())) 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). 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()); //printf("Reinserting center %i \n",vc - &*m.vert.begin());
ScalarType delta=std::min((ScalarType)0.00001,(ScalarType)distGeom/2.0); VertexQualityType delta=std::min(ScalarType(0.00001),ScalarType(distGeom/2.0));
vc->Q() = qi+distGeom-delta; vc->Q() = VertexQualityType(qi+distGeom-delta);
assert( distGeom > fabs(qi - vc->Q())); assert( distGeom > fabs(qi - vc->Q()));
st.push(vc); st.push(vc);
break; 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. // second case: you have to lower qi, the vertex under examination.
assert( distGeom < fabs(qi - vc->Q())); assert( distGeom < fabs(qi - vc->Q()));
assert(vc->Q() < qi); assert(vc->Q() < qi);
ScalarType delta=std::min((ScalarType)0.00001,(ScalarType)distGeom/2.0); VertexQualityType delta=std::min(VertexQualityType(0.00001),VertexQualityType(distGeom/2.0));
float newQi = vc->Q() + distGeom -delta; VertexQualityType newQi = vc->Q() + distGeom -delta;
assert(newQi <= qi); assert(newQi <= qi);
assert(vc->Q() < newQi); assert(vc->Q() < newQi);
assert( distGeom > fabs(newQi - vc->Q()) ); assert( distGeom > fabs(newQi - vc->Q()) );