From 05df93e1f7657af3543b441ee28863c1db1804e7 Mon Sep 17 00:00:00 2001 From: cignoni Date: Tue, 10 Oct 2006 10:01:11 +0000 Subject: [PATCH] Heavily restructured. Now it use the new faceplus classes. --- apps/tridecimator/tridecimator.cpp | 122 ++++++++++++++++++----------- 1 file changed, 76 insertions(+), 46 deletions(-) diff --git a/apps/tridecimator/tridecimator.cpp b/apps/tridecimator/tridecimator.cpp index f7127129..dfa98b61 100644 --- a/apps/tridecimator/tridecimator.cpp +++ b/apps/tridecimator/tridecimator.cpp @@ -7,12 +7,13 @@ using namespace std; // stuff to define the mesh -#include +#include +#include #include -#include #include + +#include #include -#include // io #include @@ -20,6 +21,7 @@ using namespace std; // update #include + // local optimization #include #include @@ -27,37 +29,63 @@ using namespace std; using namespace vcg; using namespace tri; -class MyEdge; -class MyFace; -class MyVertex; +/********************************************************** +Mesh Classes for Quadric Edge collapse based simplification -// 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{ +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 : public VertexSimp2< MyVertex, MyEdge, MyFace, + vert::VFAdj, + vert::Coord3f, + vert::Normal3f, + vert::Mark, + vert::BitFlags >{ public: - ScalarType w; - vcg::math::Quadricq; - ScalarType & W(){return w;} + vcg::math::Quadric &Qd() {return q;} +private: + math::Quadric q; + }; + +class MyEdge : public Edge { +public: + inline MyEdge() {}; + inline MyEdge( MyVertex * v0, MyVertex * v1):Edge(v0,v1){}; + inline MyEdge( Edge &e):Edge(e){}; }; -class MyEdge : public Edge {}; -class MyFace : public vcg::FaceAV , MyFace>{}; -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector >{}; + +class MyFace : public FaceSimp2 < MyVertex, MyEdge, MyFace, + face::VFAdj, + face::VertexRef, + face::BitFlags > {}; + +/// the main mesh class +class MyMesh : public vcg::tri::TriMesh, std::vector > {}; + class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > { public: typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > TECQ; - typedef TECQ::EdgeType EdgeType; - inline MyTriEdgeCollapse( const EdgeType &p, int i) :TECQ(p,i){} + 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(); @@ -103,11 +133,11 @@ if(argc<4) Usage(); exit(-1); } printf("mesh loaded %d %d \n",mesh.vn,mesh.fn); - - -MyTriEdgeCollapse::SetDefaultParams(); - MyTriEdgeCollapse::Params().QualityThr =.3; - double TargetError=numeric_limits::max(); + + TriEdgeCollapseQuadricParameter qparams; + MyTriEdgeCollapse::SetDefaultParams(); + qparams.QualityThr =.3; + float TargetError=numeric_limits::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::max() ) DeciSession.SetTargetMetric(TargetError); + if(TargetError< numeric_limits::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);