trimeshinfo.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) 2005                                                \/)\/    *
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 History
00025 
00026 $Log: not supported by cvs2svn $
00027 Revision 1.41  2007/03/08 22:49:35  cignoni
00028 Changed the include order and the order in which cleaning filters are applied.
00029 
00030 Revision 1.40  2006/05/16 21:55:28  cignoni
00031 Updated to the new remove zero area syntax
00032 
00033 Revision 1.39  2006/03/29 09:27:07  cignoni
00034 Added managemnt of non critical errors
00035 
00036 Revision 1.38  2006/03/29 08:17:56  corsini
00037 fix typo
00038 
00039 Revision 1.37  2006/03/27 07:15:59  cignoni
00040 Added LoadMask
00041 
00042 Revision 1.36  2006/02/28 14:54:10  corsini
00043 Fix load mask initialization
00044 
00045 Revision 1.35  2006/02/09 16:12:27  corsini
00046 Add normal, color, texture information
00047 
00048 Revision 1.34  2006/02/06 12:59:12  corsini
00049 Fix mesh info structure initialization
00050 
00051 Revision 1.33  2006/01/27 14:18:07  corsini
00052 fix boolean entry type
00053 
00054 Revision 1.32  2006/01/27 14:17:10  corsini
00055 remove junk code
00056 
00057 Revision 1.31  2006/01/27 13:35:51  corsini
00058 fix signed/unsigned mismatch
00059 
00060 Revision 1.30  2006/01/26 16:29:21  corsini
00061 fix typo
00062 
00063 Revision 1.29  2005/12/29 12:27:35  cignoni
00064 Splitted IsComplexManifold in IsTwoManifoldFace and IsTwoManifoldVertex
00065 
00066 Revision 1.28  2005/12/21 14:11:59  corsini
00067 Out the number of self intersection
00068 
00069 Revision 1.27  2005/12/21 13:26:58  corsini
00070 Re-add save xml feature
00071 
00072 Revision 1.26  2005/12/21 13:10:10  corsini
00073 Move duplicated vertices routine
00074 Modify genus computation call
00075 
00076 Revision 1.25  2005/12/20 14:44:10  corsini
00077 Modify html table
00078 
00079 Revision 1.24  2005/12/20 13:29:41  corsini
00080 Remove unuseful Clear function
00081 
00082 Revision 1.23  2005/12/19 15:00:53  corsini
00083 Disable xml output temporarily
00084 
00085 Revision 1.22  2005/12/19 11:35:13  corsini
00086 Add html output support
00087 
00088 Revision 1.21  2005/12/16 11:16:36  corsini
00089 Add manifold check to some properties
00090 
00091 Revision 1.20  2005/12/15 11:20:00  corsini
00092 Add vertex-face topology
00093 
00094 Revision 1.19  2005/12/14 14:05:37  corsini
00095 Adjust comments
00096 
00097 Revision 1.18  2005/12/14 12:15:37  corsini
00098 Re-add clean mesh saving feature
00099 
00100 Revision 1.17  2005/12/13 15:46:30  corsini
00101 Restructuring code
00102 
00103 Revision 1.16  2005/12/12 12:09:08  cignoni
00104 Changed names of clean function and tested inertia.h
00105 
00106 Revision 1.15  2005/12/12 11:29:21  corsini
00107 Minor changes
00108 
00109 Revision 1.14  2005/12/12 10:48:16  corsini
00110 Fix indentation
00111 
00112 Revision 1.13  2005/11/17 00:42:03  cignoni
00113 Changed include order
00114 removed clean::initialize
00115 
00116 Revision 1.12  2005/11/16 16:45:51  rita_borgo
00117 Minor changes
00118 
00119 Revision 1.11  2005/11/16 15:59:46  cignoni
00120 Changed name of the component from <Flag> to <BitFlags>
00121 
00122 Revision 1.10  2005/11/14 09:21:07  cignoni
00123 Heavily restructured the code of Trimeshinfo.
00124 Now divided the collecting part from the reporting one (xml and ascii)
00125 
00126 Revision 1.9  2005/11/04 15:37:57  rita_borgo
00127 Removed Debug option
00128 
00129 Revision 1.8  2005/10/11 16:03:40  rita_borgo
00130 Moved all the main functions inside clean.h
00131 
00132 Revision 1.7    2005/09/30 15:48:46      rita_borgo
00133 Fixed   manifold Test
00134 
00135 Revision 1.6 2005/09/30 14:13:01 rita_borgo
00136 Problem: Text   not     aligned
00137 
00138 Revision 1.5 2005/09/30 13:29:40 rita_borgo
00139 Fixed   Manifold Test
00140 
00141 Revision 1.4 2005/09/29 14:48:15 rita_borgo
00142 Fixed   code related to creation of     the     XML     file
00143 
00144 Revision 1.3 2005/09/28 13:57:09 rita_borgo
00145 Fixed   some printout   not     alligned
00146 
00147 Revision 1.2 2005/09/28 10:46:04 rita_borgo
00148 Added   possibility     of saving       File in OFF     format
00149 
00150 Revision 1.1 2005/09/20 10:15:27 rita_borgo
00151 Changed file name       to uniform with other   solution projects,
00152 before was main.cpp
00153 
00154 Revision 1.8 2005/02/15 12:26:06 rita_borgo
00155 Minor   changes to self-intersection
00156 
00157 Revision 1.7 2005/02/07 15:44:31 rita_borgo
00158 Fixed   Color   and     Volume
00159 
00160 Revision 1.6 2005/02/01 17:37:53 rita_borgo
00161 Fixed   Volume and Color
00162 
00163 Revision 1.5 2005/01/18 16:33:12 rita_borgo
00164 Added   OFF     file Option
00165 
00166 Revision 1.4 2005/01/17 18:19:00 rita_borgo
00167 Added   new     routines.
00168 Self-intersection       first   release
00169 
00170 Revision 1.2 2005/01/03 16:13:09 rita_borgo
00171 Added   Standard comments
00172 
00173 ****************************************************************************/
00174 
00175 // Standard headers
00176 #include <iostream>
00177 #include <fstream>
00178 #include <vector>
00179 #include <string>
00180 #include <stack>
00181 
00182 using namespace std;
00183 
00184 // VCG headers
00185 #include <vcg/simplex/vertex/base.h>
00186 #include <vcg/simplex/vertex/component.h>
00187 
00188 #include <vcg/simplex/face/base.h>
00189 #include <vcg/simplex/face/component.h>
00190 
00191 #include <vcg/complex/complex.h>
00192 #include <vcg/complex/algorithms/update/topology.h>
00193 #include <vcg/complex/algorithms/update/edges.h>
00194 #include <vcg/complex/algorithms/update/bounding.h>
00195 #include <vcg/complex/algorithms/update/flag.h>
00196 #include <vcg/complex/algorithms/clean.h>
00197 #include <vcg/space/intersection/triangle_triangle3.h>
00198 
00199 #include <vcg/math/histogram.h>
00200 #include <wrap/io_trimesh/import.h>
00201 #include <wrap/io_trimesh/export.h>
00202 
00203 #include <vcg/simplex/face/pos.h> 
00204 #include <vcg/complex/algorithms/inertia.h> 
00205 
00206 #include "XMLTree.h"
00207 
00208 #include <vcg/space/index/grid_static_ptr.h>
00209 #include "defs.h"
00210 
00211 using namespace vcg;
00212 
00213 
00214 class CVertex;
00215 class CFace;
00216 
00217 struct MyTypes: public UsedTypes< Use<CVertex>::AsVertexType,Use<CFace>::AsFaceType>{};
00218 
00219 class CVertex  : public Vertex< MyTypes, vertex::VFAdj, vertex::Coord3f,vertex::BitFlags, vertex::Normal3f > {};
00220 class CFace    : public Face< MyTypes, face::FFAdj, face::VFAdj, face::VertexRef, face::Normal3f, face::BitFlags, face::Mark > {};
00221 class CMesh    : public vcg::tri::TriMesh< vector<CVertex>, vector<CFace> > {};
00222 
00223 typedef CMesh::VertexPointer VertexPointer;
00224 typedef CMesh::VertexIterator VertexIterator;
00225 typedef Point3<CMesh::ScalarType> Point3x;
00226 typedef vector<Point3x> Hole;
00227 
00228 typedef CMesh::VertexPointer VertexPointer;
00229 typedef CMesh::VertexIterator VertexIterator;
00230 typedef CMesh::FaceContainer FaceContainer;
00231 typedef CMesh::ScalarType ScalarType;
00232 
00233 struct MeshInfo
00234 {
00235         string FileName;
00236         bool hasVNormal;
00237         bool hasFNormal;
00238         bool hasVColor;
00239         bool hasFColor;
00240         bool hasTexture;
00241         int vn,fn;
00242         bool VManifold;
00243         bool FManifold;
00244         int count_e,boundary_e,count_fd,count_uv,numholes;
00245         int BEdges;
00246         float Volume;
00247         int numcomponents,Genus;
00248         bool Regular,Semiregular;
00249         bool Orientable,Oriented;
00250         int dv;
00251         bool SelfIntersect;
00252         std::vector<CMesh::FaceType *> intersections;
00253 };
00254 
00255 
00256 static const int HTML_LINES = 31;
00257 static const char * HTML_TABLE[HTML_LINES]=
00258 {
00259 "<html>",
00260 "  <head>",
00261 "    <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">",
00262 "    <title>description.html</title>",
00263 "  </head>",
00264 "  <body>",
00265 "    <span style=\"font-weight: bold;\"></span>",
00266 "    <h2>TriMeshInfo V.1.2 - Results</h2>",
00267 "    <hr style=\"width: 100%; height: 2px;\"><br>",
00268 "    <table",
00269 "      style=\"width: 100%; text-align: center; margin-left: auto; margin-right: auto;\" ",
00270 "      border=\"1\" cellpadding=\"2\" cellspacing=\"2\">",
00271 "      <tbody>",
00272 "        <tr>",
00273 "          <td>Name</td>",
00274 "          <td>Vertices</td>",
00275 "          <td>Faces</td>",
00276 "          <td>Edges</td>",
00277 "          <td>Holes/<br>Boundaries</td>",
00278 "          <td>Connected<br>Components</td>",
00279 "          <td>Isolated<br>Vertices</td>",
00280 "          <td>Duplicated<br>Vertices</td>",
00281 "          <td>Self<br>Interesection</td>",
00282 "          <td>Manifold</td>",
00283 "          <td>Orientable/<br>Oriented</td>",
00284 "          <td>Genus</td>",
00285 "        </tr>",
00286 "      </tbody>",
00287 "    </table>",
00288 "  </body>",
00289 "</html>"
00290 };
00291 
00292 
00293 int OpenMesh(const      char *filename, CMesh &m)
00294 {
00295         printf("    Mesh loading...");
00296 
00297         int mask = 0;
00298         
00299         tri::io::Importer<CMesh>::LoadMask(filename,mask);
00300         int err = tri::io::Importer<CMesh>::Open(m, filename);
00301 
00302         if (err)
00303         {
00304    if(tri::io::Importer<CMesh>::ErrorCritical(err))
00305    {
00306                 printf("\n    Error during loading %s: '%s'\n",filename, 
00307                         tri::io::Importer<CMesh>::ErrorMsg(err));
00308                 exit(-1);
00309    }
00310    else
00311    {
00312     printf("\n    Non Critical Troubles during loading %s: '%s'\n",filename, 
00313                         tri::io::Importer<CMesh>::ErrorMsg(err));
00314    }
00315         }
00316         else
00317                 printf(" done.\n\n");
00318 
00319         return mask;
00320 }
00321 
00322 void initMeshInfo(MeshInfo &mi)
00323 {
00324         mi.vn = 0;
00325         mi.fn = 0;
00326         mi.hasVColor = false;
00327         mi.hasFColor = false;
00328         mi.hasFNormal = false;
00329         mi.hasVNormal = false;
00330         mi.hasTexture = false;
00331         mi.VManifold = false;
00332         mi.FManifold = false;
00333         mi.count_e = 0;
00334         mi.boundary_e = 0;
00335         mi.count_fd = 0;
00336         mi.count_uv = 0;
00337         mi.numholes = 0;
00338         mi.BEdges = 0;
00339         mi.Volume = 0;
00340         mi.numcomponents = 0;
00341         mi.Genus = 0;
00342         mi.Regular = false;
00343         mi.Semiregular = false;
00344         mi.Orientable = false;
00345         mi.Oriented = false;
00346         mi.dv = 0;
00347         mi.SelfIntersect = false;
00348         // mi.FileName has a constructor
00349         // mi.intersections has a constructor
00350 }
00351 
00352 void PrintMeshInfo(MeshInfo &mi)
00353 {
00354         printf("    *** Mesh information ***\n\n");
00355         printf("    Mesh: '%s' \n", mi.FileName.c_str());
00356         printf("    Number of vertices: %d \n", mi.vn);
00357         printf("    Number of faces: %d \n",    mi.fn);
00358         printf("    Number of edges: %d \n", mi.count_e);
00359         printf("    Number of internal edges: %d \n", mi.count_e-mi.boundary_e);
00360         printf("    Number of boundary edges: %i \n", mi.boundary_e);
00361         printf("    Number of degenerated faces: %d\n", mi.count_fd);
00362         printf("    Number of unreferenced vertices: %d\n",mi.count_uv);
00363         printf("    Number of duplicated vertices found: %d\n", mi.dv);
00364         printf("    Number of holes/boundaries: %d \n", mi.numholes);
00365 
00366         if (mi.hasVNormal)
00367                 printf("    Has Per-Vertex Normal: YES\n");
00368         else
00369                 printf("    Has Per-Vertex Normal: NO\n");
00370 
00371         if (mi.hasFNormal)
00372                 printf("    Has Per-Face Normal: YES\n");
00373         else
00374                 printf("    Has Per-Face Normal: NO\n");
00375 
00376         if (mi.hasVColor)
00377                 printf("    Has Per-Vertex Color: YES\n");      
00378         else
00379                 printf("    Has Per-Vertex Color: NO\n");
00380         
00381         if (mi.hasFColor)
00382                 printf("    Has Per-Face Color: YES\n");
00383         else
00384                 printf("    Has Per-Face Color: NO\n");
00385 
00386         if (mi.hasTexture)
00387                 printf("    Has Texture information: YES\n");
00388         else
00389                 printf("    Has Texture information: NO\n");
00390 
00391         if ((mi.VManifold && mi.FManifold )&&(mi.Oriented)&&(!mi.numholes))
00392                 printf("    Volume: %f \n", mi.Volume);
00393         else 
00394                 printf("    Volume: UNDEFINED  (a closed oriented manifold is required)\n");
00395 
00396         printf("    Number of connected components: %d\n",      mi.numcomponents);
00397 
00398         // Orientation
00399         if (!mi.VManifold && mi.FManifold)
00400         {
00401                 printf("    Orientable Mesh: NO\n");
00402                 printf("    Oriented Mesh: NO\n");
00403         }
00404         else
00405         {
00406                 if (mi.Orientable)
00407       printf("    Orientable Mesh: YES\n");
00408                 else 
00409                         printf("    Orientable Mesh: NO\n");
00410 
00411                 if (mi.Oriented)
00412                         printf("    Oriented Mesh: YES\n");
00413                 else 
00414                         printf("    Oriented Mesh: NO\n");
00415         }
00416 
00417         // Manifold
00418         if (mi.VManifold && mi.FManifold ) 
00419                 printf("    Manifold: YES\n");
00420         else
00421                 printf("    Manifold: NO\n");
00422 
00423         // Genus
00424         if (mi.VManifold && mi.FManifold)
00425                 printf("    Genus: %d \n", mi.Genus);
00426         else
00427                 printf("    Genus: N/A \n");
00428 
00429         // Mesh Type
00430         if (mi.Regular) 
00431                 printf("    Mesh Type: REGULAR\n");
00432         else if (mi.Semiregular)
00433                 printf("    Mesh Type: SEMIREGULAR\n");
00434         else
00435                 printf("    Mesh Type: IRREGULAR\n");
00436 
00437         // Further details
00438         if (mi.SelfIntersect)
00439                 printf("    Self Intersection: %d\n", mi.intersections.size());
00440         else
00441                 printf("    Self Intersection: NONE.\n");
00442 }
00443 
00444 void SaveXMLInfo(MeshInfo &mi)
00445 {
00446         XMLTree doc;
00447         doc.initializeMain();
00448 
00449         char s[256];
00450         sprintf(s,"%d",mi.vn);
00451         doc.addNode(s, VALUE_INTEGER, "Number of Vertices");
00452         sprintf(s,"%d",mi.fn);
00453         doc.addNode(s, VALUE_INTEGER, "Number of Faces");
00454 
00455         if(mi.VManifold && mi.FManifold)
00456                 doc.addNode("false", VALUE_BOOL,"Manifold");
00457         else
00458                 doc.addNode("true", VALUE_BOOL,"Manifold");
00459 
00460         sprintf(s,"%d",mi.count_e);
00461         doc.addNode(s, VALUE_INTEGER,"Number of Edges");
00462         sprintf(s,"%d",mi.count_fd);
00463         doc.addNode(s, VALUE_INTEGER,"Number of Degenerated Faces");
00464 
00465         sprintf(s,"%d",mi.count_uv);
00466         doc.addNode(s, VALUE_INTEGER,"Number of unreferenced vertices");
00467         sprintf(s,"%d",mi.numholes);
00468         doc.addNode(s, VALUE_INTEGER, "Number of Holes");
00469         sprintf(s,"%d",mi.BEdges);
00470         doc.addNode(s, VALUE_INTEGER, "Number of Border Edges");
00471 
00472         if (mi.hasVColor)
00473                 doc.addNode("true", VALUE_BOOL, "Per-Vertex Color Information");
00474         else
00475                 doc.addNode("false", VALUE_BOOL, "Per-Vertex Color Information");
00476 
00477         if (mi.hasFColor)
00478                 doc.addNode("true", VALUE_BOOL, "Per-Face Color Information");
00479         else
00480                 doc.addNode("false", VALUE_BOOL, "Per-Face Color Information");
00481 
00482         if (mi.hasVNormal)
00483                 doc.addNode("true", VALUE_BOOL, "Per-Vertex Normal");
00484         else
00485                 doc.addNode("false", VALUE_BOOL, "Per-Vertex Normal");
00486 
00487         if (mi.hasFNormal)
00488                 doc.addNode("true", VALUE_BOOL, "Per-Face Normal");
00489         else
00490                 doc.addNode("false", VALUE_BOOL, "Per-Face Normal");
00491 
00492         if (mi.hasTexture)
00493                 doc.addNode("true", VALUE_BOOL, "Texture Information");
00494         else
00495                 doc.addNode("false", VALUE_BOOL, "Texture Information");
00496 
00497         sprintf(s,"%f",mi.Volume);
00498         doc.addNode(s, VALUE_FLOAT,"Volume");
00499         sprintf(s,"%d",mi.numcomponents);
00500         doc.addNode(s, VALUE_INTEGER,"Number of Connected Components");
00501         sprintf(s,"%d",mi.Genus);
00502         doc.addNode(s, VALUE_INTEGER,"Genus");
00503 
00504         if (mi.Regular)
00505                 doc.addNode("REGULAR", VALUE_STRING,"Type of Mesh");
00506         else if (mi.Semiregular)
00507                 doc.addNode("SEMIREGULAR", VALUE_STRING,"Type of Mesh");
00508         else 
00509                 doc.addNode("IRREGULAR", VALUE_STRING,"Type of Mesh");
00510         
00511         if (!mi.VManifold && mi.FManifold) 
00512         {
00513                 doc.addNode("NO", VALUE_STRING,"Orientable Mesh");
00514                 doc.addNode("NO", VALUE_STRING,"Oriented Mesh");
00515         }
00516         else
00517         {
00518                 doc.addNode(mi.Orientable?"Yes":"No", VALUE_STRING,"Orientable Mesh");
00519                 doc.addNode(mi.Oriented?"Yes":"No", VALUE_STRING,"Oriented Mesh");
00520         }
00521 
00522         sprintf(s,"%d",mi.dv);
00523         doc.addNode(s, VALUE_INTEGER,"Duplicated Vertices");
00524         doc.addNode(mi.SelfIntersect?"Yes":"No", VALUE_STRING,"Self Intersection");
00525 
00526         doc.finalizeMain();
00527 
00528         // save xml tree
00529         string filename = mi.FileName;
00530 
00531         int l = static_cast<int>(filename.size());
00532         int index = static_cast<int>(filename.find_first_of('.'));
00533         filename.erase(index, l - index);
00534         filename.append(".xml");
00535 
00536         doc.setName(filename.c_str());
00537         doc.printXMLTree();
00538 }
00539 
00540 void SaveMeshInfoHtmlTable(fstream &fout, MeshInfo &mi)
00541 {
00542         fout << "        <tr>" << std::endl;
00543         fout << "          <td>" << mi.FileName << "</td>" << std::endl;
00544         fout << "          <td>" << mi.vn << "</td>" << std::endl;
00545         fout << "          <td>" << mi.fn << "</td>" << std::endl;
00546         fout << "          <td>" << mi.count_e << "</td>" << std::endl;
00547         
00548         if (mi.VManifold && mi.FManifold)
00549                 fout << "          <td>" << mi.numholes << "</td>" << std::endl;
00550         else
00551                 fout << "          <td>N/A</td>" << std::endl;
00552 
00553 
00554         fout << "          <td>" << mi.numcomponents << "</td>" << std::endl;
00555         fout << "          <td>" << mi.count_uv << "</td>" << std::endl;
00556         fout << "          <td>" << mi.dv << "</td>" << std::endl;
00557 
00558         if (mi.SelfIntersect)
00559                 fout << "          <td>" << static_cast<unsigned int>(mi.intersections.size()) 
00560                         << "</td>" << std::endl;
00561         else
00562                 fout << "          <td>None</td>" << std::endl;
00563 
00564         if(mi.VManifold && mi.FManifold)
00565                 fout << "          <td>Yes</td>" << std::endl;
00566         else
00567                 fout << "          <td>No</td>" << std::endl;
00568 
00569         if ((mi.Orientable)&&(mi.Oriented))
00570                 fout << "          <td>Yes / Yes</td>" << std::endl;
00571         else if ((mi.Orientable)&&(!mi.Oriented))
00572                 fout << "          <td>Yes / No</td>" << std::endl;
00573         else if (!mi.Orientable)
00574                 fout << "          <td>No / No</td>" << std::endl;
00575 
00576         if (mi.VManifold && mi.FManifold)
00577                 fout << "          <td>" << mi.Genus << "</td>" << std::endl;
00578         else
00579                 fout << "          <td>N/A</td>" << std::endl;
00580 
00581         fout << "        </tr>" << std::endl;
00582 }
00583 
00584 void SaveHtmlInfo(MeshInfo &mi)
00585 {
00586         char buff[1024];
00587         bool flagInsert = false;
00588         ifstream fin;
00589         fstream fout;
00590         
00591         // Try to open
00592         fin.open("result.html");
00593         long pos;
00594         if (fin.is_open())
00595         {
00596                 while (!fin.eof())
00597                 {
00598                         pos = fin.tellg();
00599                         fin.getline(buff, 1024);
00600                         string str(buff);
00601                         if (str == "      </tbody>")
00602                                 break;
00603                 }
00604                 flagInsert = true;
00605         }
00606         fin.close();
00607 
00608         if (flagInsert)
00609                 fout.open("result.html", ios::in | ios::out);
00610         else
00611                 fout.open("result.html", ios::out);
00612 
00613         if (!fout.is_open())
00614         {
00615                 printf("\n  Impossible to write the HTML output file.\n");
00616         }
00617         else
00618         {
00619                 if (flagInsert)
00620                 {
00621                         // Insert the mesh information into an existing table
00622                         fout.seekp(pos, ios::beg);
00623 
00624                         SaveMeshInfoHtmlTable(fout, mi);
00625 
00626                         for (int i = HTML_LINES - 4; i < HTML_LINES; i++)
00627                                 fout << HTML_TABLE[i] << std::endl;
00628                 }
00629                 else
00630                 {
00631                         // Create a new table
00632                         for (int i = 0; i < HTML_LINES - 4; i++)
00633                                 fout << HTML_TABLE[i] << std::endl;
00634 
00635                         SaveMeshInfoHtmlTable(fout, mi);
00636 
00637                         for (int i = HTML_LINES - 4; i < HTML_LINES; i++)
00638                                 fout << HTML_TABLE[i] << std::endl;
00639                 }
00640         }
00641 
00642         fout.close();
00643 }
00644 
00645 int main(int argc, char ** argv)
00646 {
00647         CMesh m;
00648         bool saveCleanMeshFlag = false;   // Save the clean mesh
00649         bool verboseFlag = true;          // Verbose mode on/off
00650         bool XmlFlag= false;              // XML output enabled/disabled
00651         bool HtmlFlag = false;            // HTML output enabled/disabled
00652 
00653         string SaveName;
00654         
00655         MeshInfo mi;
00656         initMeshInfo(mi);
00657 
00658         printf("\n  -------------------------------\n"
00659                 "     TriMeshInfo V.1.23 \n"
00660                 "     http://vcg.isti.cnr.it\n"
00661                 "     release date: "__DATE__"\n"
00662                 "  -------------------------------\n\n\n");
00663 
00664 
00665         // Parsing arguments
00667         
00668         if (argc <= 1)
00669         {
00670                 printf(MSG_ERR_N_ARGS);
00671                 exit(-1);
00672         }
00673 
00674         mi.FileName = argv[1];
00675 
00676         int i = 2;
00677         while (i < argc)
00678         {
00679                 if (argv[i][0] == '-')
00680                 {
00681                         switch(argv[i][1])
00682                         {
00683                         case 'q' : 
00684                                 // Quiet mode, disable verbose mode
00685                                 verboseFlag = false;
00686                         break;
00687 
00688                         case 's':
00689                                 // Save the clean mesh with the name specified
00690                                 saveCleanMeshFlag = true;
00691 
00692                                 // Check clean mesh name (minimal check)
00693                                 if (i+1 >= argc)
00694                                 {
00695                                         printf("    Invalid output mesh name.\n\n");
00696                                         exit(-1);
00697                                 }
00698                                 else if (argv[i+1][0] != '-')
00699                                         SaveName = argv[i+1];
00700                                 else
00701                                 {
00702                                         printf("    Invalid output mesh name.\n\n");
00703                                         exit(-1);
00704                                 }
00705 
00706                                 i++;
00707                         break;
00708 
00709                         case 'x' :
00710                                 // Enable XML output
00711                                 XmlFlag = true;
00712                         break;
00713 
00714                         case 'h' :
00715                                 // Enable HTML output
00716                                 HtmlFlag = true;
00717                         break;
00718 
00719                         default:
00720                                 printf(MSG_ERR_INVALID_OPTION, argv[i]);
00721                                 exit(0);
00722                         break;
00723                         }
00724                 }
00725 
00726                 i++;
00727         };
00728 
00729         // Mesh loading
00731         
00732         int load_mask = OpenMesh(mi.FileName.c_str(), m);
00733 
00734         if (load_mask & vcg::tri::io::Mask::IOM_VERTNORMAL)
00735                 mi.hasVNormal = true;
00736         else
00737                 mi.hasVNormal = false;
00738 
00739         if (load_mask & vcg::tri::io::Mask::IOM_FACENORMAL)
00740                 mi.hasFNormal = true;
00741         else
00742                 mi.hasFNormal = false;
00743 
00744         if (load_mask & vcg::tri::io::Mask::IOM_VERTCOLOR)
00745                 mi.hasVColor = true;
00746         else
00747                 mi.hasVColor = false;
00748 
00749         if (load_mask & vcg::tri::io::Mask::IOM_FACECOLOR)
00750                 mi.hasFColor = true;
00751         else
00752                 mi.hasFColor = false;
00753 
00754         if( (load_mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) ||
00755       (load_mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) )
00756                 mi.hasTexture = true;
00757         else
00758                 mi.hasTexture = false;
00759 
00760         // Mesh processing
00762 
00763         printf("    Mesh processing...\n\n");
00764         
00765         // Number of vertices
00766         mi.vn = m.vn;
00767 
00768         // Number of faces
00769         mi.fn = m.fn;
00770 
00771         // DUPLICATED VERTICES
00772         mi.dv = tri::Clean<CMesh>::RemoveDuplicateVertex(m);
00773 
00774         // DEGENERATED FACES => (faces with area zero)
00775         mi.count_fd = tri::Clean<CMesh>::RemoveDegenerateFace(m);
00776         mi.count_fd += tri::Clean<CMesh>::RemoveFaceOutOfRangeArea<false>(m,0);
00777         
00778         // UNREFERENCED VERTEX
00779         mi.count_uv = tri::Clean<CMesh>::RemoveUnreferencedVertex(m);
00780   
00781         // Update topology (face-to-face)
00782         tri::UpdateTopology<CMesh>::FaceFace(m);
00783         tri::UpdateTopology<CMesh>::VertexFace(m);
00784 
00785         // IS MANIFOLD?
00786         mi.VManifold = tri::Clean<CMesh>::CountNonManifoldVertexFF(m)>0;
00787         mi.FManifold = tri::Clean<CMesh>::CountNonManifoldEdgeFF(m)>0;
00788  
00789         // COUNT EDGES
00790         tri::Clean<CMesh>::CountEdges(m, mi.count_e, mi.boundary_e);
00791 
00792         // HOLES COUNT
00793         if(mi.VManifold && mi.FManifold)
00794         {
00795                 mi.numholes = tri::Clean<CMesh>::CountHoles(m);
00796                 tri::Clean<CMesh>::CountEdges(m, mi.BEdges,mi.numholes);
00797         }
00798 
00799         // CONNECTED COMPONENTS
00800         mi.numcomponents = tri::Clean<CMesh>::CountConnectedComponents(m);
00801 
00802         // ORIENTATION
00803         if (mi.VManifold && mi.FManifold)
00804                 tri::Clean<CMesh>::IsOrientedMesh(m, mi.Oriented, mi.Orientable);
00805         else
00806         {
00807                 mi.Oriented = false;
00808                 mi.Orientable = false;
00809         }
00810 
00811         // Rebuild Vertex-Face topology
00812         tri::UpdateTopology<CMesh>::VertexFace(m);
00813 
00814         // VOLUME (require a closed oriented manifold)
00815         if ((mi.VManifold && mi.FManifold)&&(mi.Oriented)&&(!mi.numholes))
00816         {
00817                 tri::Inertia<CMesh> mm;
00818                 mm.Compute(m);
00819                 mi.Volume = mm.Mass();
00820 
00821                 // the sign of the volume depend on the mesh orientation
00822                 if (mi.Volume < 0.0)
00823                         mi.Volume = -mi.Volume;
00824         }
00825 
00826         // GENUS
00827         if(mi.VManifold && mi.FManifold) 
00828                 mi.Genus = tri::Clean<CMesh>::MeshGenus(m, mi.numholes,
00829                         mi.numcomponents, mi.count_e);
00830         
00831         // REGULARITY
00832         if (mi.VManifold && mi.FManifold)
00833                 tri::Clean<CMesh>::IsRegularMesh(m, mi.Regular, mi.Semiregular);
00834         else
00835         {
00836                 mi.Regular = false;
00837                 mi.Semiregular = false;
00838         }
00839 
00840         // SELF INTERSECTION
00841         mi.SelfIntersect = tri::Clean<CMesh>::SelfIntersections(m, mi.intersections);
00842 
00843         // Mesh Information Output
00845 
00846         // Print mesh information
00847         if(verboseFlag)
00848                 PrintMeshInfo(mi);
00849 
00850         // Save mesh information in XML format
00851         if(XmlFlag)
00852                 SaveXMLInfo(mi);
00853 
00854         // Save mesh information in HTML format
00855         if (HtmlFlag)
00856                 SaveHtmlInfo(mi);
00857 
00858         // Save the clean mesh
00859         if (saveCleanMeshFlag)
00860         {
00861                 printf("    Save the 'clean' mesh...");
00862                 tri::io::Exporter<CMesh>::Save(m, SaveName.c_str());
00863                 printf(" done.\n\n");
00864         }
00865 
00866         mi.intersections.clear();
00867 
00868         return 0;
00869 }
00870 


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