Updated the tridecimator sample to the new localoptimimization framework
This commit is contained in:
parent
bd8f86bff5
commit
0941ea0474
|
@ -4,7 +4,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// stuff to define the mesh
|
// stuff to define the mesh
|
||||||
#include <vcg/simplex/vertex/base.h>
|
#include <vcg/simplex/vertex/base.h>
|
||||||
|
@ -63,34 +62,24 @@ private:
|
||||||
math::Quadric<double> q;
|
math::Quadric<double> q;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DummyType;
|
class MyEdge : public Edge< MyUsedTypes> {};
|
||||||
class MyEdge : public Edge<MyUsedTypes,edge::VertexRef> {
|
|
||||||
public:
|
|
||||||
inline MyEdge() {};
|
|
||||||
inline MyEdge( MyVertex * v0, MyVertex * v1){V(0) = v0; V(1) = v1; };
|
|
||||||
static inline MyEdge OrderedEdge(MyVertex* v0,MyVertex* v1){
|
|
||||||
if(v0<v1) return MyEdge(v0,v1);
|
|
||||||
else return MyEdge(v1,v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// inline MyEdge( Edge<MyEdge,MyVertex> &e):Edge<MyEdge,MyVertex>(e){};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
typedef BasicVertexPair<MyVertex> VertexPair;
|
||||||
|
|
||||||
class MyFace : public Face< MyUsedTypes,
|
class MyFace : public Face< MyUsedTypes,
|
||||||
face::VFAdj,
|
face::VFAdj,
|
||||||
face::VertexRef,
|
face::VertexRef,
|
||||||
face::BitFlags > {};
|
face::BitFlags > {};
|
||||||
|
|
||||||
/// the main mesh class
|
// the main mesh class
|
||||||
class MyMesh : public vcg::tri::TriMesh<std::vector<MyVertex>, std::vector<MyFace> > {};
|
class MyMesh : public vcg::tri::TriMesh<std::vector<MyVertex>, std::vector<MyFace> > {};
|
||||||
|
|
||||||
|
|
||||||
class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse, QInfoStandard<MyVertex> > {
|
class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, VertexPair, MyTriEdgeCollapse, QInfoStandard<MyVertex> > {
|
||||||
public:
|
public:
|
||||||
typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse, QInfoStandard<MyVertex> > TECQ;
|
typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, VertexPair, MyTriEdgeCollapse, QInfoStandard<MyVertex> > TECQ;
|
||||||
typedef MyMesh::VertexType::EdgeType EdgeType;
|
typedef MyMesh::VertexType::EdgeType EdgeType;
|
||||||
inline MyTriEdgeCollapse( const EdgeType &p, int i) :TECQ(p,i){}
|
inline MyTriEdgeCollapse( const VertexPair &p, int i, BaseParameterClass *pp) :TECQ(p,i,pp){}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Usage()
|
void Usage()
|
||||||
|
@ -132,46 +121,45 @@ int main(int argc ,char**argv){
|
||||||
if(argc<4) Usage();
|
if(argc<4) Usage();
|
||||||
|
|
||||||
int FinalSize=atoi(argv[3]);
|
int FinalSize=atoi(argv[3]);
|
||||||
//int t0=clock();
|
//int t0=clock();
|
||||||
int err=vcg::tri::io::Importer<MyMesh>::Open(mesh,argv[1]);
|
int err=vcg::tri::io::Importer<MyMesh>::Open(mesh,argv[1]);
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
printf("Unable to open mesh %s : '%s'\n",argv[1],vcg::tri::io::Importer<MyMesh>::ErrorMsg(err));
|
printf("Unable to open mesh %s : '%s'\n",argv[1],vcg::tri::io::Importer<MyMesh>::ErrorMsg(err));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
|
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
|
||||||
|
|
||||||
TriEdgeCollapseQuadricParameter &qparams = MyTriEdgeCollapse::Params() ;
|
TriEdgeCollapseQuadricParameter qparams;
|
||||||
MyTriEdgeCollapse::SetDefaultParams();
|
|
||||||
qparams.QualityThr =.3;
|
qparams.QualityThr =.3;
|
||||||
float TargetError=numeric_limits<float>::max();
|
float TargetError=std::numeric_limits<float>::max();
|
||||||
bool CleaningFlag =false;
|
bool CleaningFlag =false;
|
||||||
// parse command line.
|
// parse command line.
|
||||||
for(int i=4; i < argc;)
|
for(int i=4; i < argc;)
|
||||||
{
|
{
|
||||||
if(argv[i][0]=='-')
|
if(argv[i][0]=='-')
|
||||||
switch(argv[i][1])
|
switch(argv[i][1])
|
||||||
{
|
{
|
||||||
case 'H' : MyTriEdgeCollapse::Params().SafeHeapUpdate=true; printf("Using Safe heap option\n"); break;
|
case 'H' : qparams.SafeHeapUpdate=true; printf("Using Safe heap option\n"); break;
|
||||||
case 'Q' : if(argv[i][2]=='y') { qparams.QualityCheck = true; printf("Using Quality Checking\n"); }
|
case 'Q' : if(argv[i][2]=='y') { qparams.QualityCheck = true; printf("Using Quality Checking\n"); }
|
||||||
else { qparams.QualityCheck = false; printf("NOT Using Quality Checking\n"); } break;
|
else { qparams.QualityCheck = false; printf("NOT Using Quality Checking\n"); } break;
|
||||||
case 'N' : if(argv[i][2]=='y') { qparams.NormalCheck = true; printf("Using Normal Deviation Checking\n"); }
|
case 'N' : if(argv[i][2]=='y') { qparams.NormalCheck = true; printf("Using Normal Deviation Checking\n"); }
|
||||||
else { qparams.NormalCheck = false; printf("NOT Using Normal Deviation Checking\n"); } break;
|
else { qparams.NormalCheck = false; printf("NOT Using Normal Deviation Checking\n"); } break;
|
||||||
case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement = true; printf("Using OptimalPlacement\n"); }
|
case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement = true; printf("Using OptimalPlacement\n"); }
|
||||||
else { qparams.OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break;
|
else { qparams.OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break;
|
||||||
case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent = true; printf("Using ScaleIndependent\n"); }
|
case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent = true; printf("Using ScaleIndependent\n"); }
|
||||||
else { qparams.ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break;
|
else { qparams.ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break;
|
||||||
case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary = true; printf("Preserving Boundary\n"); }
|
case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary = true; printf("Preserving Boundary\n"); }
|
||||||
else { qparams.PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break;
|
else { qparams.PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break;
|
||||||
case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology = true; printf("Preserving Topology\n"); }
|
case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology = true; printf("Preserving Topology\n"); }
|
||||||
else { qparams.PreserveTopology = false; printf("NOT Preserving Topology\n"); } break;
|
else { qparams.PreserveTopology = false; printf("NOT Preserving Topology\n"); } break;
|
||||||
case 'q' : qparams.QualityThr = atof(argv[i]+2); printf("Setting Quality Thr to %f\n",atof(argv[i]+2)); break;
|
case 'q' : qparams.QualityThr = atof(argv[i]+2); printf("Setting Quality Thr to %f\n",atof(argv[i]+2)); break;
|
||||||
case 'n' : qparams.NormalThrRad = math::ToRad(atof(argv[i]+2)); printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break;
|
case 'n' : qparams.NormalThrRad = math::ToRad(atof(argv[i]+2)); printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break;
|
||||||
case 'b' : qparams.BoundaryWeight = atof(argv[i]+2); printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break;
|
case 'b' : qparams.BoundaryWeight = atof(argv[i]+2); printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break;
|
||||||
case 'e' : TargetError = float(atof(argv[i]+2)); printf("Setting TargetError to %g\n",atof(argv[i]+2)); break;
|
case 'e' : TargetError = float(atof(argv[i]+2)); printf("Setting TargetError to %g\n",atof(argv[i]+2)); break;
|
||||||
case 'P' : CleaningFlag=true; printf("Cleaning mesh before simplification\n"); break;
|
case 'P' : CleaningFlag=true; printf("Cleaning mesh before simplification\n"); break;
|
||||||
|
|
||||||
default : printf("Unknown option '%s'\n", argv[i]);
|
default : printf("Unknown option '%s'\n", argv[i]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -188,22 +176,23 @@ if(argc<4) Usage();
|
||||||
|
|
||||||
printf("reducing it to %i\n",FinalSize);
|
printf("reducing it to %i\n",FinalSize);
|
||||||
|
|
||||||
vcg::tri::UpdateBounding<MyMesh>::Box(mesh);
|
vcg::tri::UpdateBounding<MyMesh>::Box(mesh);
|
||||||
|
|
||||||
// decimator initialization
|
// decimator initialization
|
||||||
vcg::LocalOptimization<MyMesh> DeciSession(mesh);
|
vcg::LocalOptimization<MyMesh> DeciSession(mesh,&qparams);
|
||||||
|
|
||||||
int t1=clock();
|
int t1=clock();
|
||||||
DeciSession.Init<MyTriEdgeCollapse >();
|
DeciSession.Init<MyTriEdgeCollapse>();
|
||||||
int t2=clock();
|
int t2=clock();
|
||||||
printf("Initial Heap Size %i\n",DeciSession.h.size());
|
printf("Initial Heap Size %i\n",int(DeciSession.h.size()));
|
||||||
|
|
||||||
DeciSession.SetTargetSimplices(FinalSize);
|
DeciSession.SetTargetSimplices(FinalSize);
|
||||||
DeciSession.SetTimeBudget(0.5f);
|
DeciSession.SetTimeBudget(0.5f);
|
||||||
if(TargetError< numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
|
if(TargetError< std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
|
||||||
|
|
||||||
while(DeciSession.DoOptimization() && mesh.fn>FinalSize && DeciSession.currMetric < TargetError)
|
while(DeciSession.DoOptimization() && mesh.fn>FinalSize && DeciSession.currMetric < TargetError)
|
||||||
printf("Current Mesh size %7i heap sz %9i err %9g \r",mesh.fn,DeciSession.h.size(),DeciSession.currMetric);
|
printf("Current Mesh size %7i heap sz %9i err %9g \r",mesh.fn, int(DeciSession.h.size()),DeciSession.currMetric);
|
||||||
|
|
||||||
int t3=clock();
|
int t3=clock();
|
||||||
printf("mesh %d %d Error %g \n",mesh.vn,mesh.fn,DeciSession.currMetric);
|
printf("mesh %d %d Error %g \n",mesh.vn,mesh.fn,DeciSession.currMetric);
|
||||||
printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2);
|
printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2);
|
||||||
|
|
Loading…
Reference in New Issue