diff --git a/apps/tridecimator/Tetraascii.ply b/apps/tridecimator/Tetraascii.ply new file mode 100644 index 00000000..71145cee --- /dev/null +++ b/apps/tridecimator/Tetraascii.ply @@ -0,0 +1,18 @@ +ply +format ascii 1.0 +comment VCGLIB generated +element vertex 4 +property float x +property float y +property float z +element face 4 +property list uchar int vertex_indices +end_header +1 1 1 +-1 1 -1 +-1 -1 1 +1 -1 -1 +3 0 1 2 +3 0 2 3 +3 0 3 1 +3 3 2 1 diff --git a/apps/tridecimator/history.txt b/apps/tridecimator/history.txt new file mode 100644 index 00000000..5c1495aa --- /dev/null +++ b/apps/tridecimator/history.txt @@ -0,0 +1,28 @@ + + VCGLib http://vcg.sf.net o o + Visual and Computer Graphics Library o o + _ O _ + Copyright(C) 2005-2006 \/)\/ + Visual Computing Lab http://vcg.isti.cnr.it /\/| + ISTI - Italian National Research Council | + \ + Metro 4.04 25/01/2005 + All rights reserved. + + + +2005/04/04 Release 4.05 +Added saving of Error Histogram + +2005/01/26 Release 4.04 +Gcc compiling issues +Moved to the library core the code for computing min distance froma a point to a mesh using a uniform grid. +Slightly faster. + +2005/01/03 Release 4.03 +Better ply compatibility, and improved error reporting + +2004/11/29 Release 4.02 +removed bug in printing Hausdorf distance, +removed bug in command line parsing, +upgraded import mesh library to support off format diff --git a/apps/tridecimator/quad.ply b/apps/tridecimator/quad.ply new file mode 100644 index 00000000..bf223eab --- /dev/null +++ b/apps/tridecimator/quad.ply @@ -0,0 +1,16 @@ +ply +format ascii 1.0 +comment VCGLIB generated +element vertex 4 +property float x +property float y +property float z +element face 2 +property list uchar int vertex_indices +end_header +-1 -1 0 + 1 -1 0 + 1 1 0 +-1 1 0 +3 0 1 2 +3 0 2 3 diff --git a/apps/tridecimator/quad4.ply b/apps/tridecimator/quad4.ply new file mode 100644 index 00000000..33455422 --- /dev/null +++ b/apps/tridecimator/quad4.ply @@ -0,0 +1,19 @@ +ply +format ascii 1.0 +comment VCGLIB generated +element vertex 5 +property float x +property float y +property float z +element face 4 +property list uchar int vertex_indices +end_header +-1 -1 0 + 1 -1 0 + 1 1 0 +-1 1 0 +0 0 0 +3 0 1 4 +3 1 2 4 +3 2 3 4 +3 3 0 4 diff --git a/apps/tridecimator/quad5.ply b/apps/tridecimator/quad5.ply new file mode 100644 index 00000000..a377c0bd --- /dev/null +++ b/apps/tridecimator/quad5.ply @@ -0,0 +1,22 @@ +ply +format ascii 1.0 +comment VCGLIB generated +element vertex 6 +property float x +property float y +property float z +element face 6 +property list uchar int vertex_indices +end_header +-1 -1 0 + 1 -1 0 + 1 1 0 +-1 1 0 +-.1 -.1 0 + .1 .1 0 +3 0 1 4 +3 1 4 5 +3 1 2 5 +3 2 3 5 +3 3 4 5 +3 3 0 4 diff --git a/apps/tridecimator/readme.txt b/apps/tridecimator/readme.txt new file mode 100644 index 00000000..86d407d6 --- /dev/null +++ b/apps/tridecimator/readme.txt @@ -0,0 +1,82 @@ + + VCGLib http://vcg.sf.net o o + Visual and Computer Graphics Library o o + _ O _ + Copyright(C) 2005-2006 \/)\/ + Visual Computing Lab http://vcg.isti.cnr.it /\/| + ISTI - Italian National Research Council | + \ + Metro 4.05 04/05/2005 + All rights reserved. + + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License (http://www.gnu.org/licenses/gpl.txt) +for more details. + +--- Synopsis --- + +Metro is a tool designed to evaluate the difference between two triangular meshes. +Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation. +Please, when using this tool, cite the following reference: + + +P. Cignoni, C. Rocchini and R. Scopigno +"Metro: measuring error on simplified surfaces" +Computer Graphics Forum, Blackwell Publishers, vol. 17(2), June 1998, pp 167-174 +Available at http://vcg.sf.net + + + +You can find some sample mesh to test in the 'Metro Sample dataset' package downloadable from sourceforge. + +For any question about this software please contact: +Paolo Cignoni ( p.cignoni@isti.cnr.it ) + +--- General Info --- + +Metro is a tool designed to evaluate the difference between two triangular meshes. +Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation. +Three different surface sampling methods are implemented: + + * Montecarlo sampling (pick k random samples in the interior of each face) + * Subdivision sampling (recursively subdivide each face along the longest edge and choose the sample in the center of each cell) + * Similar Triangles sampling (subdivide each face F in k polygons similar to F and sample the face in correspondence with the vertices of these polygons, internal to F) + +Note that the three methods described above are used to sample only the interior of each face. +A different scheme is used to sample vertices and edges: vertices are sampled in the straightforward manner, +while edges are sampled by uniformly interleaving samples along each edge. + +--- Basic usage --- + +Metro is a command-line tool which allows the user to select among different sampling schemes. +A list of the command-line parameters accepted by the tool is shown in the following. + +Usage: Metro file1 file2 [opts] + +where "file1" and "file2" are the input meshes in PLY, OFF or STL format, and opts can be: + + -v disable vertex sampling + -e disable edge sampling + -f disable face sampling + -u does not ignore unreferred vertices and sample also unreferenced vertices + (useful for sampling point clouds against meshes) + -sx set the face sampling mode + where x can be: + -S0 montecarlo sampling + -S1 subdivision sampling + -S2 similar triangles sampling (Default) + -n# set the required number of samples (overrides -a) + -a# set the required number of samples per area unit (overrides -n) + -c save computed error as vertex colour and quality in two ply files + -C # # Set the min/max values used for color mapping (useful for taking snapshot with coherent color ramp) + -L Remove duplicated and unreferenced vertices before processing to avoid + -H write files with histograms of error distribution \ No newline at end of file diff --git a/apps/tridecimator/tridecimator.cpp b/apps/tridecimator/tridecimator.cpp new file mode 100644 index 00000000..de884b1d --- /dev/null +++ b/apps/tridecimator/tridecimator.cpp @@ -0,0 +1,182 @@ +#include +#include +#include + +using namespace std; + +// stuff to define the mesh +#include +#include +#include +#include +#include + +// io +#include +#include + +// update +#include +// local optimization +#include +#include + +using namespace vcg; +using namespace tri; + +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{ +public: + ScalarType w; + vcg::math::Quadricq; + ScalarType & W(){return w;} +}; + +class MyEdge: public Edge { +//public: + //inline MyEdge():Edge(){UberFlags()=0;} + inline MyEdge(MyVertex* a,MyVertex* b):Edge(a,b){UberFlags()=0;} +}; + +// for edge collpases we need faces and verteses with V->F adjacency +class MyFace : public vcg::FaceAV , MyFace>{}; +class MyMesh: public vcg::tri::TriMesh< std::vector, 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){} +}; + + +// mesh to simplify +MyMesh mesh; + +void Usage() +{ + printf( + "---------------------------------\n" + " TriSimp V.1.0 \n" + " http://vcg.isti.cnr.it\n" + " http://vcg.sourceforge.net\n" + " release date: "__DATE__"\n" + "---------------------------------\n\n" + "TriDecimator 1.0 \n"__DATE__"\n" + "Copyright 2003-2004 Visual Computing Lab I.S.T.I. C.N.R.\n" + "\nUsage: "\ + "tri_decimator file1 file2 face_num [opt]\n"\ + "Where opt can be:\n"\ + " -e# QuadricError threshold (range [0,inf) default inf)\n" + " -b# Boundary Weight (default .5)\n" + " -q# Quality threshold (range [0.0, 0.866], default .1 )\n" + " -n# Normal threshold (degree range [0,180] default 90)\n" + " -E# Minimal admitted quadric value (default 1e-15, must be >0)\n" + " -Q[y|n] Use or not Quality Threshold (default yes)\n" + " -N[y|n] Use or not Normal Threshold (default no)\n" + " -A[y|n] Use or not Area Weighted Quadrics (default yes)\n" + " -O[y|n] Use or not vertex optimal placement (default yes)\n" + " -S[y|n] Use or not Scale Independent quadric measure(default yes) \n" + " -B[y|n] Preserve or not mesh boundary (default no)\n" + " -T[y|n] Preserve or not Topology (default no)\n" + " -H[y|n] Use or not Safe Heap Update (default no)\n" + " ----- Preprocessing Options ---------------\n" + " -Pv Remove duplicate vertices\n" + " -Pf Remove degenerated faces\n" + " -Pa Remove face with null area\n" + " -Pu Remove unreferenced vertices \n" + " -PA All the above preprocessing options\n" + ); + exit(-1); +} + + + + +int main(int argc ,char**argv){ +if(argc<4) Usage(); + + int FinalSize=atoi(argv[3]); + //int t0=clock(); + int err=vcg::tri::io::Importer::Open(mesh,argv[1]); + if(err) + { + printf("Unable to open mesh %s : '%s'\n",argv[1],vcg::tri::io::Importer::ErrorMsg(err)); + exit(-1); + } + printf("mesh loaded %d %d \n",mesh.vn,mesh.fn); + printf("reducing it to %i\n",FinalSize); + clock_t u=clock(); + vcg::tri::UpdateTopology::VertexFace(mesh); + printf("vf topology %i\n",int(clock()-u)); + + MyMesh::VertexIterator vi; + vcg::tri::UpdateBounding::Box(mesh); + //int i=0; + + // decimator initialization + vcg::LocalOptimization DeciSession(mesh); + MyTriEdgeCollapse::SetDefaultParams(); + + // parse command line. + for(int i=4; i < argc;) + { + if(argv[i][0]=='-') + 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 '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; + default : printf("Unknown option '%s'\n", argv[i]); + exit(0); + } + i++; + } + + + int t1=clock(); + DeciSession.Init(); + int t2=clock(); + printf("Initial Heap Size %i\n",DeciSession.h.size()); + + DeciSession.SetTargetSimplices(FinalSize); + DeciSession.DoOptimization(); + int t3=clock(); + + printf(" vol %d \n lkv %d \n lke %d \n lkf %d \n ood %d\n bor %d\n ", + MyTriEdgeCollapse::FailStat::Volume() , + MyTriEdgeCollapse::FailStat::LinkConditionFace(), + MyTriEdgeCollapse::FailStat::LinkConditionEdge(), + MyTriEdgeCollapse::FailStat::LinkConditionVert(), + MyTriEdgeCollapse::FailStat::OutOfDate() , + MyTriEdgeCollapse::FailStat::Border() + ); + + + vcg::tri::io::ExporterPLY::Save(mesh,argv[2]); + printf("Completed in (%i+%i) msec\n",t2-t1,t3-t2); + printf("mesh %d %d \n",mesh.vn,mesh.fn); + return 0; + +}