tridecimator.cpp
Go to the documentation of this file.
00001 // stuff to define the mesh
00002 #include <vcg/complex/complex.h>
00003 
00004 // io
00005 #include <wrap/io_trimesh/import.h>
00006 #include <wrap/io_trimesh/export_ply.h>
00007 
00008 // local optimization
00009 #include <vcg/complex/algorithms/local_optimization.h>
00010 #include <vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric.h>
00011 
00012 using namespace vcg;
00013 using namespace tri;
00014 
00015 /**********************************************************
00016 Mesh Classes for Quadric Edge collapse based simplification
00017 
00018 For edge collpases we need verteses with:
00019 - V->F adjacency
00020 - per vertex incremental mark
00021 - per vertex Normal
00022 
00023 
00024 Moreover for using a quadric based collapse the vertex class
00025 must have also a Quadric member Q();
00026 Otherwise the user have to provide an helper function object
00027 to recover the quadric.
00028 
00029 ******************************************************/
00030 // The class prototypes.
00031 class MyVertex;
00032 class MyEdge;
00033 class MyFace;
00034 
00035 struct MyUsedTypes: public UsedTypes<Use<MyVertex>::AsVertexType,Use<MyEdge>::AsEdgeType,Use<MyFace>::AsFaceType>{};
00036 
00037 class MyVertex  : public Vertex< MyUsedTypes,
00038   vertex::VFAdj,
00039   vertex::Coord3f,
00040   vertex::Normal3f,
00041   vertex::Mark,
00042   vertex::BitFlags  >{
00043 public:
00044   vcg::math::Quadric<double> &Qd() {return q;}
00045 private:
00046   math::Quadric<double> q;
00047   };
00048 
00049 class MyEdge : public Edge< MyUsedTypes> {};
00050 
00051 typedef BasicVertexPair<MyVertex> VertexPair;
00052 
00053 class MyFace    : public Face< MyUsedTypes,
00054   face::VFAdj,
00055   face::VertexRef,
00056   face::BitFlags > {};
00057 
00058 // the main mesh class
00059 class MyMesh    : public vcg::tri::TriMesh<std::vector<MyVertex>, std::vector<MyFace> > {};
00060 
00061 
00062 class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, VertexPair, MyTriEdgeCollapse, QInfoStandard<MyVertex>  > {
00063             public:
00064             typedef  vcg::tri::TriEdgeCollapseQuadric< MyMesh,  VertexPair, MyTriEdgeCollapse, QInfoStandard<MyVertex>  > TECQ;
00065             typedef  MyMesh::VertexType::EdgeType EdgeType;
00066             inline MyTriEdgeCollapse(  const VertexPair &p, int i, BaseParameterClass *pp) :TECQ(p,i,pp){}
00067 };
00068 
00069 void Usage()
00070 {
00071     printf(
00072            "---------------------------------\n"
00073            "         TriSimp V.1.0 \n"
00074            "     http://vcg.isti.cnr.it\n"
00075            "    http://vcg.sourceforge.net\n"
00076            "   release date: "__DATE__"\n"
00077            "---------------------------------\n\n"
00078           "TriDecimator 1.0 \n"__DATE__"\n"
00079       "Copyright 2003-2012 Visual Computing Lab I.S.T.I. C.N.R.\n"
00080       "\nUsage:  "\
00081       "tridecimator fileIn fileOut face_num [opt]\n"\
00082       "Where opt can be:\n"\
00083       "     -e# QuadricError threshold  (range [0,inf) default inf)\n"
00084             "     -b# Boundary Weight (default .5)\n"
00085             "     -q# Quality threshold (range [0.0, 0.866],  default .3 )\n"
00086             "     -n# Normal threshold  (degree range [0,180] default 90)\n"
00087             "     -E# Minimal admitted quadric value (default 1e-15, must be >0)\n"
00088             "     -Q[y|n]  Use or not Quality Threshold (default yes)\n"
00089             "     -N[y|n]  Use or not Normal Threshold (default no)\n"
00090             "     -A[y|n]  Use or not Area Weighted Quadrics (default yes)\n"
00091             "     -O[y|n]  Use or not vertex optimal placement (default yes)\n"
00092             "     -S[y|n]  Use or not Scale Independent quadric measure(default yes) \n"
00093             "     -B[y|n]  Preserve or not mesh boundary (default no)\n"
00094             "     -T[y|n]  Preserve or not Topology (default no)\n"
00095             "     -H[y|n]  Use or not Safe Heap Update (default no)\n"
00096           "     -P       Before simplification, remove duplicate & unreferenced vertices\n"
00097                                        );
00098   exit(-1);
00099 }
00100 
00101 // mesh to simplify
00102 MyMesh mesh;
00103 
00104 int main(int argc ,char**argv){
00105 if(argc<4) Usage();
00106 
00107   int FinalSize=atoi(argv[3]);
00108   //int t0=clock();
00109   int err=vcg::tri::io::Importer<MyMesh>::Open(mesh,argv[1]);
00110   if(err)
00111   {
00112     printf("Unable to open mesh %s : '%s'\n",argv[1],vcg::tri::io::Importer<MyMesh>::ErrorMsg(err));
00113     exit(-1);
00114   }
00115   printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
00116 
00117   TriEdgeCollapseQuadricParameter qparams;
00118   qparams.QualityThr  =.3;
00119   float TargetError=std::numeric_limits<float>::max();
00120   bool CleaningFlag =false;
00121      // parse command line.
00122     for(int i=4; i < argc;)
00123     {
00124       if(argv[i][0]=='-')
00125         switch(argv[i][1])
00126       {
00127         case 'H' : qparams.SafeHeapUpdate=true; printf("Using Safe heap option\n"); break;
00128         case 'Q' : if(argv[i][2]=='y') { qparams.QualityCheck   = true;  printf("Using Quality Checking\n");    }
00129                                   else { qparams.QualityCheck   = false; printf("NOT Using Quality Checking\n");        }                break;
00130         case 'N' : if(argv[i][2]=='y') { qparams.NormalCheck    = true;  printf("Using Normal Deviation Checking\n");   }
00131                                   else { qparams.NormalCheck    = false; printf("NOT Using Normal Deviation Checking\n");       }        break;
00132         case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement       = true;  printf("Using OptimalPlacement\n");    }
00133                                   else { qparams.OptimalPlacement       = false; printf("NOT Using OptimalPlacement\n");        }        break;
00134         case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent       = true;  printf("Using ScaleIndependent\n");    }
00135                                   else { qparams.ScaleIndependent       = false; printf("NOT Using ScaleIndependent\n");        }        break;
00136         case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary       = true;  printf("Preserving Boundary\n");       }
00137                                   else { qparams.PreserveBoundary       = false; printf("NOT Preserving Boundary\n");   }        break;
00138         case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology       = true;  printf("Preserving Topology\n");       }
00139                                   else { qparams.PreserveTopology       = false; printf("NOT Preserving Topology\n");   }        break;
00140         case 'q' :      qparams.QualityThr      = atof(argv[i]+2);                 printf("Setting Quality Thr to %f\n",atof(argv[i]+2));        break;
00141         case 'n' :      qparams.NormalThrRad = math::ToRad(atof(argv[i]+2));  printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break;
00142         case 'b' :      qparams.BoundaryWeight  = atof(argv[i]+2);                      printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break;
00143         case 'e' :      TargetError = float(atof(argv[i]+2));                   printf("Setting TargetError to %g\n",atof(argv[i]+2)); break;
00144         case 'P' :      CleaningFlag=true;  printf("Cleaning mesh before simplification\n"); break;
00145 
00146         default  :  printf("Unknown option '%s'\n", argv[i]);
00147           exit(0);
00148       }
00149       i++;
00150     }
00151 
00152 
00153 
00154   if(CleaningFlag){
00155       int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(mesh);
00156       int unref =  tri::Clean<MyMesh>::RemoveUnreferencedVertex(mesh);
00157       printf("Removed %i duplicate and %i unreferenced vertices from mesh \n",dup,unref);
00158   }
00159 
00160 
00161   printf("reducing it to %i\n",FinalSize);
00162 
00163   vcg::tri::UpdateBounding<MyMesh>::Box(mesh);
00164 
00165   // decimator initialization
00166   vcg::LocalOptimization<MyMesh> DeciSession(mesh,&qparams);
00167 
00168   int t1=clock();
00169   DeciSession.Init<MyTriEdgeCollapse>();
00170   int t2=clock();
00171   printf("Initial Heap Size %i\n",int(DeciSession.h.size()));
00172 
00173   DeciSession.SetTargetSimplices(FinalSize);
00174   DeciSession.SetTimeBudget(0.5f);
00175   if(TargetError< std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
00176 
00177   while(DeciSession.DoOptimization() && mesh.fn>FinalSize && DeciSession.currMetric < TargetError)
00178     printf("Current Mesh size %7i heap sz %9i err %9g \r",mesh.fn, int(DeciSession.h.size()),DeciSession.currMetric);
00179 
00180   int t3=clock();
00181   printf("mesh  %d %d Error %g \n",mesh.vn,mesh.fn,DeciSession.currMetric);
00182   printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2);
00183 
00184   vcg::tri::io::ExporterPLY<MyMesh>::Save(mesh,argv[2]);
00185     return 0;
00186 
00187 }


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:37:55