polygonmesh_quadsimpl.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002  * VCGLib                                                            o o     *
00003  * Visual and Computer Graphics Library                            o     o   *
00004  *                                                                _   O  _   *
00005  * Copyright(C) 2004                                                \/)\/    *
00006  * Visual Computing Lab                                            /\/|      *
00007  * ISTI - Italian National Research Council                           |      *
00008  *                                                                    \      *
00009  * All rights reserved.                                                      *
00010  *                                                                           *
00011  * This program is free software; you can redistribute it and/or modify      *   
00012  * it under the terms of the GNU General Public License as published by      *
00013  * the Free Software Foundation; either version 2 of the License, or         *
00014  * (at your option) any later version.                                       *
00015  *                                                                           *
00016  * This program is distributed in the hope that it will be useful,           *
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019  * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020  * for more details.                                                         *
00021  *                                                                           *
00022  ****************************************************************************/
00023 
00024 #include <vector>
00025 #include <string>
00026 #include <sstream>
00027 
00028 /*include the base definition for the vertex */
00029 #include <vcg/simplex/vertex/base.h>
00030 
00031 /*include the base definition for the face */
00032 #include <vcg/simplex/face/base.h>
00033 
00034 /*include the base definition for the edge */
00035 #include <vcg/connectors/hedge.h>
00036 
00037 /*include the base definition for the trimesh*/
00038 #include <vcg/complex/complex.h>
00039 
00040 /*include the algorithms for updating: */
00041 #include <vcg/complex/algorithms/update/topology.h>     /* topology */
00042 #include <vcg/complex/algorithms/update/bounding.h>     /* bounding box */
00043 #include <vcg/complex/algorithms/update/normal.h>               /* normal */
00044 
00045 /*include the algorithms for mesh fixing  */
00046 #include <vcg/complex/algorithms/clean.h>
00047 
00048 /*include the importer from disk*/
00049 #include <wrap/io_trimesh/import.h>
00050 
00051 #include <wrap/io_trimesh/export_off.h>
00052 
00053 /* include the support for polygon meshes (function to convert from/to trimesh)*/
00054 #include <vcg/complex/algorithms/polygon_support.h>
00055 
00056 /* include the support for polygon meshes (the component for the face )*/
00057 #include <vcg/simplex/face/component_polygon.h>
00058 
00059 /* include the support for half edges */
00060 #include <vcg/complex/algorithms/update/halfedge_indexed.h>
00061 
00062 #include <vcg/complex/algorithms/local_optimization/quad_diag_collapse.h>
00063 
00064 #include <vcg/complex/algorithms/update/edges.h>
00065 
00066 #include <vcg/simplex/face/component_rt.h>
00067 
00068 #include <vcg/complex/algorithms/update/fitmaps.h>
00069 
00070 using namespace vcg;
00071 using namespace std;
00072 
00073 // forward declarations
00074 class CFace;
00075 class CVertex;
00076 class CHEdge;
00077 class CEdge;
00078 class MyPolyVertex;
00079 
00080 struct CUsedTypes: public vcg::UsedTypes< vcg::Use<CVertex>::AsVertexType, vcg::Use<CFace>::AsFaceType >{};
00081 
00082 // Mesh of triangles
00083 class CVertex : public Vertex<
00084         CUsedTypes,
00085         vertex::BitFlags,
00086         vertex::Coord3f, 
00087         vertex::Normal3f,
00088         vertex::VFAdj,
00089         vertex::Mark,
00090         vcg::vertex::Curvaturef,
00091         vcg::vertex::CurvatureDirf,
00092         vertex::Color4b,
00093         vertex::Qualityf
00094         >{};
00095 
00096 class CFace   : public Face<
00097         CUsedTypes,
00098         face::VertexRef,
00099         face::Normal3f,
00100         face::BitFlags,
00101         face::FFAdj,
00102         face::VFAdj,
00103         face::Mark,
00104         face::EdgePlane
00105         > {};
00106 
00107 class CMesh : public vcg::tri::TriMesh< vector<CVertex>, vector<CFace> > {};
00108 
00109 
00110 
00111 
00112 // Poly mesh
00113 class MyPolyFace;
00114 class MyPolyVertex;
00115 
00116 struct PolyUsedTypes: public vcg::UsedTypes<
00117     vcg::Use<MyPolyVertex>  ::AsVertexType,
00118     vcg::Use<CEdge>         ::AsEdgeType,
00119     vcg::Use<CHEdge>        ::AsHEdgeType,
00120     vcg::Use<MyPolyFace>    ::AsFaceType
00121     >{};
00122 
00123 class MyPolyVertex:public Vertex<
00124     PolyUsedTypes,
00125     vertex::Coord3f,
00126     vertex::Normal3f,
00127     vertex::Mark,
00128     vertex::BitFlags,
00129     vertex::VHAdj,
00130     vertex::VFAdj
00131     >{};
00132 
00133 class CEdge : public Edge<PolyUsedTypes>{};
00134 
00135 class CHEdge : public HEdge<
00136     PolyUsedTypes,
00137     hedge::BitFlags,
00138     hedge::HFAdj,
00139     hedge::HOppAdj,
00140     hedge::HNextAdj,
00141     hedge::HVAdj,
00142     hedge::HPrevAdj,
00143     hedge::Mark
00144     >{};
00145 
00146 class MyPolyFace:public Face<
00147     PolyUsedTypes,
00148     face::PolyInfo,
00149     face::PFVAdj,
00150     face::PFFAdj,
00151     face::PFHAdj,
00152     face::BitFlags,
00153     face::Normal3f,
00154     face::Mark
00155     > {};
00156 
00157 class MyPolyMesh: public tri::TriMesh<
00158     std::vector<MyPolyVertex>,
00159     std::vector<MyPolyFace>,
00160     std::vector<CHEdge>,
00161     std::vector<CEdge>
00162     >{};
00163 
00164 
00165 
00170 class MyCollapseAdaptive: public vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh> ,vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> >
00171 {
00172 public:
00173 
00174     typedef vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg<MyPolyMesh>, vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> , vcg::tri::FitmapsCollapse<MyPolyMesh, CMesh> > constructor;
00175 
00176     MyCollapseAdaptive(HEdgePointer he, int mark):constructor(he,mark){}
00177 };
00178 
00183 class MyCollapse: public vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> >
00184 {
00185 public:
00186 
00187     typedef vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg<MyPolyMesh> > constructor;
00188 
00189     MyCollapse(HEdgePointer he, int mark):constructor(he,mark){}
00190 };
00191 
00192 
00193 typedef CMesh::FaceType TriFaceType;
00194 typedef vcg::GridStaticPtr<CMesh::FaceType, TriFaceType::ScalarType> GRID;
00195 
00196 typedef CMesh::PerVertexAttributeHandle<float> Fitmap_attr;
00197 
00203 void initGrid(CMesh & m)
00204 {
00205 
00206   GRID* grid = new GRID();
00207 
00208   vcg::tri::UpdateBounding<CMesh>::Box(m);
00209   vcg::tri::UpdateEdges<CMesh>::Set(m);
00210 
00211   grid->Set(m.face.begin(), m.face.end());
00212 
00213 //  grid->ShowStats(stdout);
00214   MyCollapse::grid() = grid;
00215   MyCollapseAdaptive::grid() = grid;
00216 
00217 }
00218 
00226 void init_heap(MyPolyMesh &m, vcg::LocalOptimization<MyPolyMesh> &loc, bool adaptive)
00227 {
00228     if(adaptive)
00229         MyCollapseAdaptive::Init(m, loc.h);
00230     else
00231         MyCollapse::Init(m,loc.h);
00232 
00233     std::make_heap(loc.h.begin(),loc.h.end());
00234 
00235     if(!loc.h.empty())
00236         loc.currMetric=loc.h.front().pri;
00237 }
00238 
00245 bool read_fitmaps(CMesh &m, const char *fn)
00246 {
00247     ifstream fitmaps;
00248     fitmaps.open(fn);
00249 
00250     if(! fitmaps.is_open())
00251         return false;
00252 
00253     Fitmap_attr S_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"S-Fitmap");
00254     Fitmap_attr M_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"M-Fitmap");
00255 
00256     int index;
00257     float S_fit, M_fit;
00258     do
00259     {
00260         fitmaps >> index >> S_fit >> M_fit;
00261         S_Fit[m.vert[index]] = S_fit;
00262         M_Fit[m.vert[index]] = M_fit;
00263 
00264     }while(fitmaps.good());
00265 
00266 
00267     bool eof = fitmaps.eof();
00268 
00269     fitmaps.close();
00270     return eof;
00271 
00272 }
00273 
00280 bool store_fitmaps(CMesh &m, const char *fn)
00281 {
00282     ofstream fitmaps;
00283     fitmaps.open(fn);
00284 
00285     if(! fitmaps.is_open())
00286         return false;
00287 
00288     Fitmap_attr S_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"S-Fitmap");
00289     Fitmap_attr M_Fit = tri::Allocator<CMesh>::GetPerVertexAttribute<float>(m,"M-Fitmap");
00290 
00291     for(unsigned int i =0; i< m.vert.size(); i++)
00292     {
00293         if( !(m.vert[i].IsD()) )
00294         {
00295             fitmaps << i << " " << S_Fit[m.vert[i]] << " " << M_Fit[m.vert[i]] << endl;
00296 
00297             if(!fitmaps.good())
00298             {
00299                 fitmaps.close();
00300                 return false;
00301             }
00302         }
00303     }
00304 
00305     fitmaps.close();
00306     return true;
00307 }
00308 
00315 void load_fitmaps(CMesh &m, char* fn)
00316 {
00317 
00318     Fitmap_attr S_Fit = tri::Allocator<CMesh>::AddPerVertexAttribute<float>  (m, string("S-Fitmap"));
00319     Fitmap_attr M_Fit = tri::Allocator<CMesh>::AddPerVertexAttribute<float>  (m, string("M-Fitmap"));
00320 
00321     string filename(fn);
00322 
00323     int found = filename.find_last_of("/");
00324 
00325     string name = filename.substr(found+1);
00326 
00327     string suffix = ".fmp";
00328 
00329     if( !read_fitmaps( m, (name + suffix).c_str()) )
00330     {
00331         tri::Fitmaps<CMesh>::computeSFitmap(m);
00332 
00333         for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00334         S_Fit[vi] = vi->Q();
00335 
00336         tri::Fitmaps<CMesh>::computeMFitmap(m, 5);
00337 
00338         for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
00339         M_Fit[vi] = vi->Q();
00340 
00341         store_fitmaps(m, ( name + suffix).c_str());
00342     }
00343 
00344 }
00345 
00353 void loadMesh(CMesh & m, char* fn, bool loadFitmaps = false)
00354 {
00355 
00356     int ret = vcg::tri::io::Importer<CMesh>::Open(m,fn);
00357 
00358     if(ret != 0)
00359     {
00360         cerr << "Error reading file " << fn << endl;
00361         exit(1);
00362     }
00363 
00364     tri::Clean<CMesh>::RemoveDegenerateFace(m);
00365     tri::Clean<CMesh>::RemoveDuplicateFace(m);
00366     tri::Clean<CMesh>::RemoveDuplicateVertex(m);
00367     tri::Clean<CMesh>::RemoveUnreferencedVertex(m);
00368 
00369     tri::UpdateTopology<CMesh>::FaceFace(m);
00370 
00371     tri::Clean<CMesh>::RemoveNonManifoldFace(m);
00372     tri::UpdateTopology<CMesh>::FaceFace(m);
00373 
00374     tri::Clean<CMesh>::RemoveNonManifoldVertex(m);
00375     tri::UpdateTopology<CMesh>::FaceFace(m);
00376 
00377     // update bounding box
00378     vcg::tri::UpdateBounding<CMesh>::Box (m);
00379 
00380     // update Normals
00381     vcg::tri::UpdateNormals<CMesh>::PerVertexNormalizedPerFace(m);
00382     vcg::tri::UpdateNormals<CMesh>::PerFaceNormalized(m);
00383 
00384     if(loadFitmaps)
00385         load_fitmaps(m,fn);
00386 
00387 }
00388 
00389 int main(int argc, char *argv[]) {
00390 
00391 
00392     // HE mesh
00393     MyPolyMesh pm;
00394 
00395     // Tri meshes
00396     CMesh mesh,refMesh;
00397 
00398     char* meshfile = NULL;
00399     char* trimeshfile = NULL;
00400     char* outfile = "output.off";
00401     int faces;
00402     bool adaptive = false;
00403 
00404     if(argc < 2)
00405     {
00406         cerr << "Usage: " << argv[0] << " -meshfile filename [-trimeshfile filename] -faces num_faces [-adaptive] [-outfile filename]" << endl;
00407     }
00408 
00409     for(int i=1; i< argc; i++)
00410     {
00411         string arg = string(argv[i]);
00412 
00413         if ( arg == "-meshfile")
00414             meshfile = argv[++i];
00415 
00416         else if (arg == "-trimeshfile")
00417             trimeshfile = argv[++i];
00418 
00419         else if (arg == "-faces")
00420         {
00421             stringstream myStream(argv[++i], stringstream::in | stringstream::out);
00422             myStream >> faces;
00423         }
00424 
00425         else if (arg == "-outfile")
00426             outfile = argv[++i];
00427 
00428         else if (arg == "-adaptive")
00429             adaptive = true;
00430     }
00431 
00432 
00433     if( !meshfile)
00434     {
00435         cerr << "Missing mesh filename" << endl;
00436         exit(1);
00437     }
00438 
00439     if(faces < 0)
00440     {
00441         cerr << "Missing faces number" << endl;
00442         exit(1);
00443     }
00444 
00445 
00446     // Load the mesh to simplify
00447     loadMesh(mesh, meshfile);
00448 
00449     // Load the reference mesh
00450     if(trimeshfile)
00451         loadMesh(refMesh, trimeshfile, adaptive);
00452     else
00453         loadMesh(refMesh, meshfile, adaptive);
00454 
00455     initGrid(refMesh);
00456 
00457     MyCollapse::refMesh() = &refMesh;
00458     MyCollapseAdaptive::refMesh() = &refMesh;
00459 
00460 
00461     vcg::tri::PolygonSupport<CMesh,MyPolyMesh>::ImportFromTriMesh(pm,mesh);
00462     vcg::tri::UpdateHalfEdges<MyPolyMesh>::FromIndexed(pm);
00463 
00464     // After loading check mesh consistency
00465     assert(vcg::tri::UpdateHalfEdges<MyPolyMesh>::CheckConsistency(pm));
00466 
00467     HalfedgeQuadClean<MyPolyMesh>::remove_singlets(pm);
00468     HalfedgeQuadClean<MyPolyMesh>::remove_doublets(pm);
00469 
00470     vcg::LocalOptimization<MyPolyMesh> loc(pm);
00471     init_heap(pm, loc, adaptive);
00472 
00473     loc.HeapSimplexRatio = 9;
00474     loc.SetTargetSimplices(faces);
00475 
00476     // Perform simplification
00477     loc.DoOptimization();
00478 
00479 
00480     assert(vcg::tri::UpdateHalfEdges<MyPolyMesh>::CheckConsistency(pm));
00481     vcg::tri::UpdateIndexed<MyPolyMesh>::FromHalfEdges(pm );
00482 
00483 
00484     int ret = tri::io::ExporterOFF<MyPolyMesh>::Save(pm, outfile, tri::io::Mask::IOM_BITPOLYGONAL );
00485     if(ret != 0 )
00486     {
00487         cerr << "Error saving file" << endl;
00488         exit(1);
00489     }
00490 
00491     cout << "Simplification ended successfully!" << endl;
00492 
00493 }


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