26 #include <vcg/complex/complex.h>
28 #include <vcg/complex/algorithms/clean.h>
30 #include <wrap/io_trimesh/import.h>
31 #include <wrap/io_trimesh/export_off.h>
32 #include <vcg/complex/algorithms/polygon_support.h>
33 #include <vcg/complex/algorithms/local_optimization/quad_diag_collapse.h>
34 #include <vcg/complex/algorithms/update/fitmaps.h>
46 struct CUsedTypes:
public vcg::UsedTypes< vcg::Use<CVertex>::AsVertexType, vcg::Use<CFace>::AsFaceType >{};
49 class CVertex :
public Vertex<
56 vcg::vertex::Curvaturef,
57 vcg::vertex::CurvatureDirf,
62 class CFace :
public Face<
73 class CMesh :
public vcg::tri::TriMesh< vector<CVertex>, vector<CFace> > {};
82 struct PolyUsedTypes:
public vcg::UsedTypes<
83 vcg::Use<MyPolyVertex> ::AsVertexType,
84 vcg::Use<CEdge> ::AsEdgeType,
85 vcg::Use<CHEdge> ::AsHEdgeType,
86 vcg::Use<MyPolyFace> ::AsFaceType
89 class MyPolyVertex:
public Vertex<
99 class CEdge :
public Edge<PolyUsedTypes>{};
101 class CHEdge :
public HEdge<
112 class MyPolyFace:
public Face<
123 class MyPolyMesh:
public tri::TriMesh<
124 std::vector<MyPolyVertex>,
125 std::vector<MyPolyFace>,
136 class MyCollapseAdaptive:
public vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh> ,vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> >
140 typedef vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh>, vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> > constructor;
142 MyCollapseAdaptive(HEdgePointer he,
int mark):constructor(he,mark){}
149 class MyCollapse:
public vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> >
153 typedef vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> > constructor;
155 MyCollapse(HEdgePointer he,
int mark):constructor(he,mark){}
159 typedef CMesh::FaceType TriFaceType;
160 typedef vcg::GridStaticPtr<CMesh::FaceType, TriFaceType::ScalarType> GRID;
162 typedef CMesh::PerVertexAttributeHandle<float> Fitmap_attr;
169 void initGrid(CMesh & m)
172 GRID* grid =
new GRID();
175 vcg::tri::UpdateEdges<CMesh>::Set(m);
177 grid->Set(m.face.begin(), m.face.end());
180 MyCollapse::grid() = grid;
181 MyCollapseAdaptive::grid() = grid;
192 void init_heap(MyPolyMesh &m, vcg::LocalOptimization<MyPolyMesh> &loc,
bool adaptive)
195 MyCollapseAdaptive::Init(m, loc.h);
197 MyCollapse::Init(m,loc.h);
199 std::make_heap(loc.h.begin(),loc.h.end());
202 loc.currMetric=loc.h.front().pri;
211 bool read_fitmaps(CMesh &m,
const char *fn)
216 if(! fitmaps.is_open())
226 fitmaps >> index >> S_fit >> M_fit;
227 S_Fit[m.vert[index]] = S_fit;
228 M_Fit[m.vert[index]] = M_fit;
230 }
while(fitmaps.good());
233 bool eof = fitmaps.eof();
246 bool store_fitmaps(CMesh &m,
const char *fn)
251 if(! fitmaps.is_open())
257 for(
unsigned int i =0; i< m.vert.size(); i++)
259 if( !(m.vert[i].IsD()) )
261 fitmaps << i <<
" " << S_Fit[m.vert[i]] <<
" " << M_Fit[m.vert[i]] << endl;
281 void load_fitmaps(CMesh &m,
char* fn)
289 int found = filename.find_last_of(
"/");
291 string name = filename.substr(found+1);
293 string suffix =
".fmp";
295 if( !read_fitmaps( m, (name + suffix).c_str()) )
297 tri::Fitmaps<CMesh>::computeSFitmap(m);
299 for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
302 tri::Fitmaps<CMesh>::computeMFitmap(m, 5);
304 for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
307 store_fitmaps(m, ( name + suffix).c_str());
319 void loadMesh(CMesh & m,
char* fn,
bool loadFitmaps =
false)
322 int ret = vcg::tri::io::Importer<CMesh>::Open(m,fn);
326 cerr <<
"Error reading file " << fn << endl;
347 vcg::tri::UpdateNormals<CMesh>::PerVertexNormalizedPerFace(m);
348 vcg::tri::UpdateNormals<CMesh>::PerFaceNormalized(m);
355 int main(
int argc,
char *argv[]) {
364 char* meshfile = NULL;
365 char* trimeshfile = NULL;
366 char* outfile =
"output.off";
368 bool adaptive =
false;
372 cerr <<
"Usage: " << argv[0] <<
" -meshfile filename [-trimeshfile filename] -faces num_faces [-adaptive] [-outfile filename]" << endl;
375 for(
int i=1; i< argc; i++)
377 string arg = string(argv[i]);
379 if ( arg ==
"-meshfile")
380 meshfile = argv[++i];
382 else if (arg ==
"-trimeshfile")
383 trimeshfile = argv[++i];
385 else if (arg ==
"-faces")
387 stringstream myStream(argv[++i], stringstream::in | stringstream::out);
391 else if (arg ==
"-outfile")
394 else if (arg ==
"-adaptive")
401 cerr <<
"Missing mesh filename" << endl;
407 cerr <<
"Missing faces number" << endl;
413 loadMesh(mesh, meshfile);
417 loadMesh(refMesh, trimeshfile, adaptive);
419 loadMesh(refMesh, meshfile, adaptive);
423 MyCollapse::refMesh() = &refMesh;
424 MyCollapseAdaptive::refMesh() = &refMesh;
427 vcg::tri::PolygonSupport<CMesh,MyPolyMesh>::ImportFromTriMesh(pm,mesh);
433 HalfedgeQuadClean<MyPolyMesh>::remove_singlets(pm);
434 HalfedgeQuadClean<MyPolyMesh>::remove_doublets(pm);
436 vcg::LocalOptimization<MyPolyMesh> loc(pm);
437 init_heap(pm, loc, adaptive);
439 loc.HeapSimplexRatio = 9;
440 loc.SetTargetSimplices(faces);
443 loc.DoOptimization();
447 vcg::tri::UpdateIndexed<MyPolyMesh>::FromHalfEdges(pm );
450 int ret = tri::io::ExporterOFF<MyPolyMesh>::Save(pm, outfile, tri::io::Mask::IOM_BITPOLYGONAL );
453 cerr <<
"Error saving file" << endl;
457 cout <<
"Simplification ended successfully!" << endl;