Heavily restructured. Now it use the new faceplus classes.

This commit is contained in:
Paolo Cignoni 2006-10-10 10:01:11 +00:00
parent b44fce7de9
commit 05df93e1f7
1 changed files with 76 additions and 46 deletions

View File

@ -7,12 +7,13 @@
using namespace std;
// stuff to define the mesh
#include <vcg/simplex/vertex/with/afvmvn.h>
#include <vcg/simplex/vertexplus/base.h>
#include <vcg/simplex/faceplus/base.h>
#include <vcg/simplex/edge/edge.h>
#include <vcg/math/quadric.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/math/quadric.h>
#include <vcg/complex/trimesh/clean.h>
#include <vcg/simplex/face/with/av.h>
// io
#include <wrap/io_trimesh/import.h>
@ -20,6 +21,7 @@ using namespace std;
// update
#include <vcg/complex/trimesh/update/topology.h>
// local optimization
#include <vcg/complex/local_optimization.h>
#include <vcg/complex/local_optimization/tri_edge_collapse_quadric.h>
@ -27,37 +29,63 @@ using namespace std;
using namespace vcg;
using namespace tri;
/**********************************************************
Mesh Classes for Quadric Edge collapse based simplification
For edge collpases we need verteses with:
- V->F adjacency
- per vertex incremental mark
- per vertex Normal
Moreover for using a quadric based collapse the vertex class
must have also a Quadric member Q();
Otherwise the user have to provide an helper function object
to recover the quadric.
******************************************************/
// The class prototypes.
class MyVertex;
class MyEdge;
class MyFace;
class MyVertex;
// for edge collpases we need verteses with:
// AF V->F adjacency
// VM per vertex incremental mark
// VN per vertex Normal
// Moreover for using this vertex also in a quadric based collapse it must have also a Quadric member Q();
class MyVertex:public vcg::VertexAFVMVNd<MyEdge , MyFace,DUMMYTETRATYPE>{
class MyVertex : public VertexSimp2< MyVertex, MyEdge, MyFace,
vert::VFAdj,
vert::Coord3f,
vert::Normal3f,
vert::Mark,
vert::BitFlags >{
public:
ScalarType w;
vcg::math::Quadric<double>q;
ScalarType & W(){return w;}
vcg::math::Quadric<double> &Qd() {return q;}
private:
math::Quadric<double> q;
};
class MyEdge : public Edge<MyEdge,MyVertex> {
public:
inline MyEdge() {};
inline MyEdge( MyVertex * v0, MyVertex * v1):Edge<MyEdge,MyVertex>(v0,v1){};
inline MyEdge( Edge<MyEdge,MyVertex> &e):Edge<MyEdge,MyVertex>(e){};
};
class MyEdge : public Edge<MyEdge,MyVertex> {};
class MyFace : public vcg::FaceAV<MyVertex,Edge<MyEdge,MyVertex> , MyFace>{};
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
class MyFace : public FaceSimp2 < MyVertex, MyEdge, MyFace,
face::VFAdj,
face::VertexRef,
face::BitFlags > {};
/// the main mesh class
class MyMesh : public vcg::tri::TriMesh<vector<MyVertex>, std::vector<MyFace> > {};
class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > {
public:
typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > TECQ;
typedef TECQ::EdgeType EdgeType;
typedef MyMesh::VertexType::EdgeType EdgeType;
inline MyTriEdgeCollapse( const EdgeType &p, int i) :TECQ(p,i){}
};
// mesh to simplify
MyMesh mesh;
void Usage()
{
printf(
@ -90,6 +118,8 @@ void Usage()
exit(-1);
}
// mesh to simplify
MyMesh mesh;
int main(int argc ,char**argv){
if(argc<4) Usage();
@ -104,10 +134,10 @@ if(argc<4) Usage();
}
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
MyTriEdgeCollapse::SetDefaultParams();
MyTriEdgeCollapse::Params().QualityThr =.3;
double TargetError=numeric_limits<double>::max();
TriEdgeCollapseQuadricParameter qparams;
MyTriEdgeCollapse::SetDefaultParams();
qparams.QualityThr =.3;
float TargetError=numeric_limits<float>::max();
bool CleaningFlag =false;
// parse command line.
for(int i=4; i < argc;)
@ -116,22 +146,22 @@ MyTriEdgeCollapse::SetDefaultParams();
switch(argv[i][1])
{
case 'H' : MyTriEdgeCollapse::Params().SafeHeapUpdate=true; printf("Using Safe heap option\n"); break;
case 'Q' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().QualityCheck = true; printf("Using Quality Checking\n"); }
else { MyTriEdgeCollapse::Params().QualityCheck = false; printf("NOT Using Quality Checking\n"); } break;
case 'N' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().NormalCheck = true; printf("Using Normal Deviation Checking\n"); }
else { MyTriEdgeCollapse::Params().NormalCheck = false; printf("NOT Using Normal Deviation Checking\n"); } break;
case 'O' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().OptimalPlacement = true; printf("Using OptimalPlacement\n"); }
else { MyTriEdgeCollapse::Params().OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break;
case 'S' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().ScaleIndependent = true; printf("Using ScaleIndependent\n"); }
else { MyTriEdgeCollapse::Params().ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break;
case 'B' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().PreserveBoundary = true; printf("Preserving Boundary\n"); }
else { MyTriEdgeCollapse::Params().PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break;
case 'T' : if(argv[i][2]=='y') { MyTriEdgeCollapse::Params().PreserveTopology = true; printf("Preserving Topology\n"); }
else { MyTriEdgeCollapse::Params().PreserveTopology = false; printf("NOT Preserving Topology\n"); } break;
case 'q' : MyTriEdgeCollapse::Params().QualityThr = atof(argv[i]+2); printf("Setting Quality Thr to %f\n",atof(argv[i]+2)); break;
case 'n' : MyTriEdgeCollapse::Params().NormalThr = atof(argv[i]+2)*M_PI/180.0; printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break;
case 'b' : MyTriEdgeCollapse::Params().BoundaryWeight = atof(argv[i]+2); printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break;
case 'e' : TargetError = atof(argv[i]+2); printf("Setting TargetError to %g\n",atof(argv[i]+2)); break;
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;
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;
case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement = true; printf("Using OptimalPlacement\n"); }
else { qparams.OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break;
case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent = true; printf("Using ScaleIndependent\n"); }
else { qparams.ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break;
case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary = true; printf("Preserving Boundary\n"); }
else { qparams.PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break;
case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology = true; printf("Preserving Topology\n"); }
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 'n' : qparams.NormalThr = atof(argv[i]+2)*M_PI/180.0; 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 '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",atof(argv[i]+2)); break;
default : printf("Unknown option '%s'\n", argv[i]);
@ -163,7 +193,7 @@ MyTriEdgeCollapse::SetDefaultParams();
DeciSession.SetTargetSimplices(FinalSize);
DeciSession.SetTimeBudget(0.5f);
if(TargetError< numeric_limits<double>::max() ) DeciSession.SetTargetMetric(TargetError);
if(TargetError< numeric_limits<float>::max() ) DeciSession.SetTargetMetric(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);