main.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   History
00025 
00026 $Log: not supported by cvs2svn $
00027 Revision 1.7  2005/02/07 15:44:31  rita_borgo
00028 Fixed Color and Volume
00029 
00030 Revision 1.6  2005/02/01 17:37:53  rita_borgo
00031 Fixed Volume and Color
00032 
00033 Revision 1.5  2005/01/18 16:33:12  rita_borgo
00034 Added OFF file Option
00035 
00036 Revision 1.4  2005/01/17 18:19:00  rita_borgo
00037 Added new routines.
00038 Self-intersection first release
00039 
00040 Revision 1.2  2005/01/03 16:13:09  rita_borgo
00041 Added Standard comments
00042 
00043 
00044 
00045 ****************************************************************************/
00046 #include <vector>
00047 #include <string>  
00048 #include <stack>
00049 
00050 
00051 using namespace std;
00052 
00053 
00054 #include<vcg/simplex/vertex/vertex.h>
00055 #include<vcg/simplex/face/with/afav.h>
00056 #include<vcg/simplex/face/topology.h>
00057 #include<vcg/simplex/face/pos.h>   // mi sembra di averlo aggiunto!
00058 
00059 
00060 #include<vcg/complex/complex.h>
00061 #include<vcg/complex/algorithms/update/topology.h>
00062 #include <vcg/complex/algorithms/update/edges.h>
00063 #include <vcg/complex/algorithms/update/bounding.h>
00064 #include <vcg/complex/algorithms/clean.h>
00065 #include <vcg/space/intersection/triangle_triangle3.h>
00066 #include <vcg/math/histogram.h>
00067 #include <wrap/io_trimesh/import.h>
00068 #include <wrap/io_trimesh/export_ply.h>
00069 
00070 
00071 // loader 
00072 #include<wrap/io_trimesh/import_ply.h>
00073 
00074 #include "defs.h"
00075 
00076 using namespace vcg;
00077 using namespace tri;
00078 using namespace face;
00079 
00080 class MyFace;
00081 class MyEdge;
00082 class MyVertex:public Vertex<float,MyEdge,MyFace>{};
00083 class MyFace :public FaceAFAV<MyVertex,MyEdge,MyFace>{};
00084 class MyMesh: public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
00085 
00086 void OpenMesh(const char *filename, MyMesh &m)
00087 {
00088   int err = tri::io::Importer<MyMesh>::Open(m,filename);
00089   if(err) {
00090       printf("Error in reading %s: '%s'\n",filename,tri::io::Importer<MyMesh>::ErrorMsg(err));
00091       exit(-1);
00092     }
00093   printf("read mesh `%s'\n", filename);           
00094 }
00095 
00096 
00097 inline char* GetExtension(char* filename)
00098 {
00099     for(int i=strlen(filename)-1; i >= 0; i--)
00100         if(filename[i] == '.')
00101             break;
00102     if(i > 0)
00103         return &(filename[i+1]);
00104     else
00105         return NULL;
00106 }
00107 
00108 
00109 typedef MyMesh::VertexPointer  VertexPointer;
00110 typedef MyMesh::VertexIterator  VertexIterator;
00111 
00112 /* classe di confronto per l'algoritmo di individuazione vertici duplicati*/
00113 template <class VertexIterator>
00114 class DuplicateVert_Compare{
00115 public:
00116         inline bool operator() (VertexIterator a, VertexIterator b)
00117                 {
00118                         return *a < *b;
00119                 }
00120 };
00121 
00122 static int DuplicateVertex( MyMesh & m )    // V1.0
00123 {
00124         if(m.vert.size()==0 || m.vn==0)
00125                 return 0;
00126         std::map<VertexPointer, VertexPointer> mp;
00127         int i,j;
00128         VertexIterator vi; 
00129         int deleted=0;
00130         int k=0;
00131         int num_vert = m.vert.size();
00132         vector<VertexPointer> perm(num_vert);
00133         for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++k)
00134                 perm[k] = &(*vi);
00135 
00136         DuplicateVert_Compare<VertexPointer> c_obj;
00137 
00138         std::sort(perm.begin(),perm.end(),c_obj);
00139         j = 0;
00140   i = j;
00141   mp[perm[i]] = perm[j];
00142   ++i;
00143   for(;i!=num_vert;)
00144         {
00145                 if( (! (*perm[i]).IsD()) && 
00146         (! (*perm[j]).IsD()) && 
00147                                 (*perm[i]).P() == (*perm[j]).cP() )
00148                 {
00149                         VertexPointer t = perm[i];
00150             mp[perm[i]] = perm[j];
00151             ++i;
00152                         (*t).SetD();
00153                         deleted++;
00154                 }
00155                 else
00156                 {
00157                         j = i;
00158             ++i;
00159                 }
00160         }
00161         return deleted;
00162 }
00163 void main(int argc,char ** argv){
00164 
00165         char                 *fmt;
00166         MyMesh m;
00167         bool DEBUG = false;
00168         //load the mesh
00169         //argv[1]=(char*)"c:\\checkup\\debug\\column1m.ply";
00170         //argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\prism.off";
00171 //argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\prova1.ply";
00172 
00173     // print program info
00174     printf("-------------------------------\n"
00175            "         TriMeshInfo V.1.01 \n"
00176            "     http://vcg.isti.cnr.it\n"
00177            "   release date: "__DATE__"\n"
00178            "-------------------------------\n\n");
00179 
00180 
00181  if(DEBUG)
00182         argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\cube1.stl";
00183  
00184  else
00185  {
00186  // load input meshes.
00187   if(argc <= 1)
00188   {
00189      printf(MSG_ERR_N_ARGS);
00190      exit(-1);
00191   }
00192  }
00193 
00194 
00195   OpenMesh(argv[1],m);
00196 
00197 
00198 
00199   FILE * index;
00200         index = fopen((string(argv[1])+string("2.html")).c_str(),"w");
00201         fprintf(index,"<p>Mesh info: %s </p>\n\n\n", argv[1]);
00202         
00203         fprintf(index,"<p>GENERAL INFO </p>\n\n");
00204         fprintf(index,"<p>Number of vertices: %d </p>\n", m.vn);
00205         fprintf(index,"<p>Number of faces: %d </p>\n", m.fn);
00206         printf("Mesh info:\n");
00207         printf("        M: '%s'\n\t Number of vertices: %d \n", argv[1], m.vn);
00208         printf("\t Number of faces: %d \n", m.fn);
00209 
00210         if(m.HasPerFaceColor()||m.HasPerVertexColor())
00211         {
00212                 Color4b Color=m.C();
00213                 fprintf(index, "<p>Object color(4b): %f %f %f </p>\n\n", Color[0], Color[1], Color[2]);
00214                 printf( "\t Object color(4b): %f %f %f \n", Color[0], Color[1], Color[2]);
00215         }
00216         
00217         
00218                 vcg::tri::UpdateTopology<MyMesh>::FaceFace(m);
00219         
00220         // IS MANIFOLD
00221         
00222         MyMesh::FaceIterator f;
00223         MyMesh::FaceIterator g;
00224         vcg::face::Pos<MyMesh::FaceType> he;
00225         vcg::face::Pos<MyMesh::FaceType> hei;
00226         int j;
00227         int man=0;
00228         bool Manifold = true;
00229         
00230         MyMesh::FaceIterator prova;
00231         prova = m.face.end();
00232         for(f=m.face.begin();f!=m.face.end();++f)
00233         {
00234                 for (j=0;j<3;++j)
00235                 {
00236                         if(!IsManifold(*f,j))
00237                         {
00238                                 Manifold = false;
00239                                 f= m.face.end();
00240                                 --f;
00241                                 j=3;
00242                         }
00243                 }
00244         }
00245         if (!Manifold)
00246         {
00247                 fprintf(index, "<p> Manifold: NO </p>"); 
00248           printf( "\t Manifold: NO\n"); 
00249         }
00250         else
00251         {
00252                 fprintf(index, "<p> Manifold: YES </p>"); 
00253           printf( "\t Manifold: YES\n "); 
00254         }
00255 
00256         // COUNT EDGES
00257 
00258         MyMesh::FaceIterator fi;
00259         int count_e = 0;
00260         bool counted=false;
00261         for(fi=m.face.begin();fi!=m.face.end();++fi)
00262                 (*fi).ClearS();
00263 
00264         for(fi=m.face.begin();fi!=m.face.end();++fi)
00265                 {
00266                         (*fi).SetS();
00267                         count_e +=3;
00268                         for(int i=0; i<3; ++i)
00269                         {
00270                                 if (IsManifold(*fi,i))
00271                                 {
00272                                         if((*fi).FFp(i)->IsS()) 
00273                                                 count_e--;
00274                                 }
00275                                 else
00276                                 {
00277                                         hei.Set(&(*fi), i , fi->V(i));
00278                                         he=hei;
00279                                         he.NextF();
00280                                         while (he.f!=hei.f)
00281                                         {
00282                                                 if (he.f->IsS())
00283                                                 {
00284                                                         counted=true;
00285                                                         break;
00286                                                 }
00287                                                 else 
00288                                                 {
00289                                                         he.NextF();
00290                                                 }
00291                                         }
00292                                         if (counted)
00293                                         {
00294                                                 count_e--;
00295                                                 counted=false;
00296                                         }
00297                                 }
00298                         }
00299                 }
00300         fprintf(index, "<p>Number of edges: %d </p>\n", count_e);
00301   printf("\t Number of edges: %d \n", count_e);
00302 
00303 
00304         // DA QUI IN POI!!!
00305         
00306         // DEGENERATED FACES
00307 
00308         int count_fd = 0;
00309         for(fi=m.face.begin(); fi!=m.face.end();++fi)
00310                 if((*fi).Area() == 0)
00311                         count_fd++;
00312         fprintf(index, "<p>Number of degenerated faces: %d </p>\n", count_fd);
00313   printf("\t Number of degenerated faces: %d \n", count_fd);
00314 
00315         // UNREFERENCED VERTEX
00316 
00317         int count_uv = 0;
00318         MyMesh::VertexIterator v;
00319         
00320         
00321         
00322         for(v=m.vert.begin();v!=m.vert.end();++v)
00323                 (*v).ClearV();
00324 
00325         for(f=m.face.begin();f!=m.face.end();++f)
00326                         for(j=0;j<3;++j)
00327                                         (*f).V(j)->SetV();
00328 
00329         for(v=m.vert.begin();v!=m.vert.end();++v)
00330                 if( !(*v).IsV() )
00331                         ++count_uv;
00332         fprintf(index,"<p>Number of unreferenced vertices: %d</p>\n",count_uv);
00333   printf("\t Number of unreferenced vertices: %d\n",count_uv);
00334 
00335 
00336 // HOLES COUNT  
00337 
00338         for(f=m.face.begin();f!=m.face.end();++f)
00339                 (*f).ClearS();
00340         g=m.face.begin(); f=g;
00341         
00342         int BEdges=0; int numholes=0;
00343         
00344 
00345         if (Manifold)
00346         {
00347         for(f=g;f!=m.face.end();++f)
00348                 {
00349                         if(!(*f).IsS())
00350                         {       
00351                                 for(j=0;j<3;j++)
00352                                 {
00353                                         if ((*f).IsBorder(j))
00354                                         {
00355                                                 BEdges++;
00356                                                 
00357                                                 if(!(IsManifold(*f,j)))
00358                                                 {
00359                                                         (*f).SetS();
00360                                                         hei.Set(&(*f),j,f->V(j));
00361                                                         he=hei;
00362                                                         do
00363                                                         {
00364                                                                 he.NextB();
00365                                                                 he.f->SetS();
00366                                                         //      BEdges++;
00367                                                         }
00368                                                         while (he.f!=hei.f);
00369                                                         //BEdges--;
00370                                                         numholes++;
00371                                                 }
00372                                         }
00373                                 }
00374                         }
00375                 }
00376         }
00377         else
00378         {
00379                 for(f=g;f!=m.face.end();++f)
00380                 {
00381                         for(j=0;j<3;j++)
00382                                 {
00383                                         if ((*f).IsBorder(j))
00384                                         {
00385                                                 BEdges++;
00386                                         }
00387                                 }
00388                 }
00389         }
00390         if (Manifold)
00391         {
00392         fprintf(index, "<p> Number of holes: %d </p> \n <p> Number of border edges: %d </p>", numholes, BEdges); 
00393         printf("\t Number of holes: %d \n", numholes, BEdges); 
00394         printf("\t Number of border edges: %d\n", numholes, BEdges); 
00395         }
00396         else
00397         {
00398         fprintf(index, "<p> Number of border edges: %d </p>", BEdges); 
00399         printf("\t Number of border edges: %d\n", BEdges); 
00400         }
00401 
00402         // Mesh Volume
00403         float vol = m.Volume();
00404         int nuh = numholes;
00405         if((m.Volume()>0.)&&(Manifold)&&(numholes==0))
00406         {
00407         fprintf(index,"<p>Volume: %d </p>\n", m.Volume());
00408         printf("\t Volume: %f \n", m.Volume());
00409         }
00410 
00411 
00412         // CONNECTED COMPONENTS
00413 
00414 
00415         for(f=m.face.begin();f!=m.face.end();++f)
00416                 (*f).ClearS();
00417         g=m.face.begin(); f=g;
00418         int CountComp=0; int CountOrient=0;
00419         stack<MyMesh::FaceIterator> sf; 
00420         MyMesh::FaceType *l;
00421         for(f=m.face.begin();f!=m.face.end();++f)
00422         {
00423                 if (!(*f).IsS())
00424                 {
00425                         (*f).SetS();
00426                         sf.push(f);
00427                         while (!sf.empty())
00428                         {
00429                                 g=sf.top();
00430                                 he.Set(&(*g),0,g->V(0));
00431                                 sf.pop();
00432                                 for(j=0;j<3;++j)
00433                                                 if( !(*g).IsBorder(j) )
00434                                                         {
00435                                                                 l=he.f->FFp(j);
00436                                                                 if( !(*l).IsS() )
00437                                                                         {
00438                                                                                 (*l).SetS();
00439                                                                                 sf.push(l);
00440                                                                         }
00441                                                         }
00442                         }
00443                 CountComp++;
00444                 }
00445         }
00446         fprintf(index, "<p> Number of connected components: %d </p>", CountComp); 
00447   printf("\t Number of connected components: %d\n", CountComp); 
00448         
00449         if(CountComp ==1)
00450         {
00451                 int eulero; //v-e+f 
00452                 eulero = (m.vn-count_uv)- (count_e+BEdges)+m.fn;
00453                 if(Manifold)
00454                 {
00455                         int genus = (2-eulero)>>1;
00456                         fprintf(index, "<p> Genus: %d </p> \n ", genus); 
00457                   printf( "\t Genus: %d \n", genus); 
00458                 }
00459         }
00460 // REGULARITY
00461 
00462         bool Regular=true;
00463         bool Semiregular=true;
00464         int inc=0;
00465         for(v=m.vert.begin();v!=m.vert.end();++v)
00466                 (*v).ClearS();
00467         for(f=m.face.begin();f!=m.face.end();++f)
00468         {
00469                 for (j=0; j<3; j++)
00470                 {
00471                         he.Set(&(*f),j,f->V(j));
00472                         if (!(*f).IsBorder(j) && !(*f).IsBorder((j+2)%3) && !f->V(j)->IsS())
00473                         {
00474                                 hei=he;
00475                                 inc=1;
00476                                 he.FlipE();
00477                                 he.NextF();
00478                                 while (he.f!=hei.f)
00479                                 {
00480                                         he.FlipE();
00481                                         if (he.IsBorder())
00482                                         {
00483                                                 inc=6;
00484                                                 break;
00485                                         }
00486                                         he.NextF();
00487                                         inc++;
00488                                 }
00489                                 if (inc!=6)
00490                                         Regular=false;
00491                                 if (inc!=6 && inc!=5)
00492                                         Semiregular=false;
00493                                 f->V(j)->SetS();
00494 
00495                         }
00496                         else
00497                                 f->V(j)->SetS();
00498                 }
00499                 if (Semiregular==false)
00500                         break;
00501 
00502         }
00503 
00504         if (Regular)
00505         {
00506                         fprintf(index, "<p> Type of Mesh: REGULAR</p>"); 
00507                   printf("\t Type of Mesh: REGULAR\n"); 
00508         }
00509         else if (Semiregular)
00510         {
00511                         fprintf(index, "<p> Type of Mesh: SEMIREGULAR</p>");
00512                   printf("\t Type of Mesh: SEMIREGULAR\n");
00513         }
00514         else 
00515         {
00516                 fprintf(index, "<p> Type of Mesh: IRREGULAR</p>"); 
00517           printf("\t Type of Mesh: IRREGULAR\n"); 
00518         }
00519 // ORIENTABLE E ORIENTED MESH
00520 
00521         bool Orientable=true;
00522         bool Oriented=true;
00523         if (!Manifold)
00524         {
00525                 fprintf(index, "<p> Orientable Mesh: NO</p>"); 
00526           printf( "\t Orientable Mesh: NO\n"); 
00527         }
00528         else
00529         {
00530                 for(f=m.face.begin();f!=m.face.end();++f)
00531                 {
00532                         (*f).ClearS();
00533                         (*f).ClearUserBit(0);
00534                 }
00535                 g=m.face.begin(); f=g; 
00536                 for(f=m.face.begin();f!=m.face.end();++f)
00537                 {
00538                         if (!(*f).IsS())
00539                         {
00540                                 (*f).SetS();
00541                                 sf.push(f);
00542                                 
00543                                 while (!sf.empty())
00544                                 {
00545                                         g=sf.top();
00546                                         sf.pop();
00547                                         for(j=0;j<3;++j)
00548                                         {
00549                                                 if( !(*g).IsBorder(j) )
00550                                                 {
00551                                                         he.Set(&(*g),0,g->V(0));
00552                                                         l=he.f->FFp(j);
00553                                                         he.Set(&(*g),j,g->V(j));                                                                
00554                                                         hei.Set(he.f->FFp(j),he.f->FFi(j), (he.f->FFp(j))->V(he.f->FFi(j)));
00555                                                         if( !(*g).IsUserBit(0) )
00556                                                         {
00557                                                                 if (he.v!=hei.v)    // bene
00558                                                                 {
00559                                                                         if ((*l).IsS() && (*l).IsUserBit(0))
00560                                                                         {
00561                                                                                 Orientable=false;
00562                                                                                 break;
00563                                                                         }
00564                                                                         else if (!(*l).IsS())
00565                                                                         {
00566                                                                                 (*l).SetS();
00567                                                                                 sf.push(l);
00568                                                                         }
00569                                                                 }       
00570                                                                 else if (!(*l).IsS())
00571                                                                 {
00572                                                                         Oriented=false;
00573                                                                         (*l).SetS();
00574                                                                         (*l).SetUserBit(0);
00575                                                                         sf.push(l);
00576                                                                 }
00577                                                                 else if ((*l).IsS() && !(*l).IsUserBit(0))
00578                                                                 {
00579                                                                         Orientable=false;
00580                                                                         break;
00581                                                                 }
00582                                                         }
00583                                                         else if (he.v==hei.v)    // bene
00584                                                         {
00585                                                                 if ((*l).IsS() && (*l).IsUserBit(0))
00586                                                                 {
00587                                                                         Orientable=false;
00588                                                                         break;
00589                                                                 }
00590                                                                 else if (!(*l).IsS())
00591                                                                 {
00592                                                                         (*l).SetS();
00593                                                                         sf.push(l);
00594                                                                 }
00595                                                         }       
00596                                                         else if (!(*l).IsS())
00597                                                         {
00598                                                                 Oriented=false;
00599                                                                 (*l).SetS();
00600                                                                 (*l).SetUserBit(0);
00601                                                                 sf.push(l);
00602                                                         }
00603                                                         else if ((*l).IsS() && !(*l).IsUserBit(0))
00604                                                         {
00605                                                                 Orientable=false;
00606                                                                 break;
00607                                                         }
00608                                                 }
00609                                         }
00610                                 }
00611                         }
00612                         if (!Orientable)
00613                                 break;
00614                 }
00615                 if (Orientable)
00616                 {
00617                                 fprintf(index, "<p> Orientable Mesh: YES</p>"); 
00618                           printf( "\t Orientable Mesh: YES\n"); 
00619                 }
00620                 else
00621                 {
00622                                 fprintf(index, "<p> Orientable Mesh: NO</p>"); 
00623                           printf( "\t Orientable Mesh: NO\n"); 
00624                 }
00625         }
00626         if (Oriented && Manifold)
00627         {
00628                         fprintf(index, "<p> Oriented Mesh: YES</p>"); 
00629                   printf( "\t Oriented Mesh: YES\n"); 
00630         }
00631         else
00632         {
00633                         fprintf(index, "<p> Oriented Mesh: NO</p>"); 
00634                   printf( "\t Oriented Mesh: NO\n"); 
00635         }
00636         int dv = DuplicateVertex(m);
00637         if(dv>0)
00638         {
00639                 fprintf(index, "<p> Duplicated vertices: %d</p>", dv); 
00640                 printf( "\t Duplicated vertices: %d\n",dv);
00641         }
00642         else
00643         {
00644                 fprintf(index, "<p> Duplicated vertices: NO</p>"); 
00645                 printf( "\t Duplicated vertices: NO\n");
00646         }
00647         // SELF INTERSECTION
00648 
00649         if (m.fn<300000)
00650         {
00651                 bool SelfInt=false;
00652                 for(f=m.face.begin();f!=m.face.end();++f)
00653                 {
00654                         for(g=++f , f--;g!=m.face.end();++g)
00655                         {
00656                                 if ((*f).FFp(0)!=&(*g) && (*f).FFp(1)!=&(*g) && (*f).FFp(2)!=&(*g) &&
00657                                         f->V(0)!=g->V(0) && f->V(0)!=g->V(1) && f->V(0)!=g->V(2) &&
00658                                         f->V(1)!=g->V(0) && f->V(1)!=g->V(1) && f->V(1)!=g->V(2) &&
00659                                         f->V(2)!=g->V(0) && f->V(2)!=g->V(1) && f->V(2)!=g->V(2))
00660                                 {
00661                                         if (NoDivTriTriIsect(f->V(0)->P(), f->V(1)->P(), f->V(2)->P(),g->V(0)->P(), g->V(1)->P(), g->V(2)->P()) )
00662                                                 SelfInt=true;
00663                                 }
00664                         }
00665                         if (SelfInt)
00666                                 break;                  
00667                 }
00668                 if (SelfInt)
00669                 {
00670                         fprintf(index, "<p> Self Intersection: YES</p>"); 
00671                         printf( "\t Self Intersection: YES\n");
00672                 }
00673                 else
00674                 {
00675                         fprintf(index, "<p> Self Intersection: NO</p>"); 
00676                          printf( "\t Self Intersection: NO\n"); 
00677                 }
00678         }
00679 
00680 
00681         fclose(index);
00682 }
00683 


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