added check in MCSimplify

if the mesh does not have straight edges, it cannot be simplified "guessing" the error because it is not a MC-generated mesh.
Before, when it fould no straigth edges, it was crashing :)
This commit is contained in:
Marco Callieri 2018-04-03 13:06:26 +02:00
parent 7fdb93f773
commit ce1f23a37b
1 changed files with 51 additions and 48 deletions

View File

@ -59,7 +59,7 @@ namespace tri {
// Simple prototype for later use... // Simple prototype for later use...
template<class MeshType> template<class MeshType>
void MCSimplify( MeshType &m, float perc, bool preserveBB=true, vcg::CallBackPos *cb=0); int MCSimplify( MeshType &m, float perc, bool preserveBB=true, vcg::CallBackPos *cb=0);
/** Surface Reconstruction /** Surface Reconstruction
@ -550,63 +550,66 @@ template < class MeshType, class VertexPair>
template< class MeshType> template< class MeshType>
void MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBackPos *cb) int MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBackPos *cb)
{ {
typedef PlyMCTriEdgeCollapse<MeshType,BasicVertexPair<typename MeshType::VertexType> > MyColl; typedef PlyMCTriEdgeCollapse<MeshType,BasicVertexPair<typename MeshType::VertexType> > MyColl;
typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceIterator FaceIterator;
typedef typename MeshType::CoordType CoordType; typedef typename MeshType::CoordType CoordType;
tri::UpdateBounding<MeshType>::Box(m); tri::UpdateBounding<MeshType>::Box(m);
tri::UpdateTopology<MeshType>::VertexFace(m); tri::UpdateTopology<MeshType>::VertexFace(m);
TriEdgeCollapseMCParameter pp; TriEdgeCollapseMCParameter pp;
pp.bb.Import(m.bbox); pp.bb.Import(m.bbox);
pp.preserveBBox=preserveBB; pp.preserveBBox=preserveBB;
vcg::LocalOptimization<MeshType> DeciSession(m,&pp); vcg::LocalOptimization<MeshType> DeciSession(m,&pp);
if(absoluteError==0) if(absoluteError==0)
{ {
// guess the mc side. // guess the mc side.
// In a MC mesh the vertices are on the egdes of the cells. and the edges are (mostly) on face of the cells. // In a MC mesh the vertices are on the egdes of the cells. and the edges are (mostly) on face of the cells.
// If you have 2 vert over the same face xy they share z // If you have 2 vert over the same face xy they share z
std::vector<float> ZSet; std::vector<float> ZSet;
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())
{ {
CoordType v0=(*fi).V(0)->P(); CoordType v0=(*fi).V(0)->P();
CoordType v1=(*fi).V(1)->P(); CoordType v1=(*fi).V(1)->P();
CoordType v2=(*fi).V(2)->P(); CoordType v2=(*fi).V(2)->P();
if(v0[2]==v1[2] && v0[1]!=v1[1] && v0[0]!=v1[0]) ZSet.push_back(v0[2]); if(v0[2]==v1[2] && v0[1]!=v1[1] && v0[0]!=v1[0]) ZSet.push_back(v0[2]);
if(v0[2]==v2[2] && v0[1]!=v1[1] && v2[0]!=v2[0]) ZSet.push_back(v0[2]); if(v0[2]==v2[2] && v0[1]!=v2[1] && v0[0]!=v2[0]) ZSet.push_back(v0[2]);
if(v1[2]==v2[2] && v1[1]!=v1[1] && v2[0]!=v2[0]) ZSet.push_back(v0[2]); if(v1[2]==v2[2] && v1[1]!=v2[1] && v1[0]!=v2[0]) ZSet.push_back(v1[2]);
if(ZSet.size()>100) break; if(ZSet.size()>100) break;
} }
std::sort(ZSet.begin(),ZSet.end()); if (ZSet.size() == 0) return -1; //no straight edges found. exit with error
std::vector<float>::iterator lastV = std::unique(ZSet.begin(),ZSet.end()); std::sort(ZSet.begin(),ZSet.end());
ZSet.resize(lastV-ZSet.begin()); std::vector<float>::iterator lastV = std::unique(ZSet.begin(),ZSet.end());
float Delta=0; ZSet.resize(lastV-ZSet.begin());
for(size_t i = 0; i< ZSet.size()-1;++i) float Delta=0;
{ for(size_t i = 0; i< ZSet.size()-1;++i)
Delta = std::max(ZSet[i+1]-ZSet[i],Delta); {
// qDebug("%f",Delta); Delta = std::max(ZSet[i+1]-ZSet[i],Delta);
} //qDebug("%f",Delta);
absoluteError= Delta/4.0f; }
} absoluteError= Delta/4.0f;
// qDebug("Simplifying at absoluteError=%f",absoluteError); }
//qDebug("Simplifying at absoluteError=%f",absoluteError);
float TargetError = absoluteError; float TargetError = absoluteError;
char buf[1024]; char buf[1024];
DeciSession.template Init< MyColl > (); DeciSession.template Init< MyColl > ();
pp.areaThr=TargetError*TargetError; pp.areaThr=TargetError*TargetError;
DeciSession.SetTimeBudget(1.0f); DeciSession.SetTimeBudget(1.0f);
if(TargetError < std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError); if(TargetError < std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
while(DeciSession.DoOptimization() && DeciSession.currMetric < TargetError) while(DeciSession.DoOptimization() && DeciSession.currMetric < TargetError)
{ {
sprintf(buf,"Simplyfing %7i err %9g \r",m.fn,DeciSession.currMetric); sprintf(buf,"Simplyfing %7i err %9g \r",m.fn,DeciSession.currMetric);
if (cb) cb(int(100.0f*DeciSession.currMetric/TargetError),buf); if (cb) cb(int(100.0f*DeciSession.currMetric/TargetError),buf);
} }
return 1; //success
} }