/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * 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. * * * ****************************************************************************/ /**************************************************************************** History $Log: not supported by cvs2svn $ Revision 1.2 2005/01/03 16:13:09 rita_borgo Added Standard comments ****************************************************************************/ #include #include #include using namespace std; #include #include #include #include // mi sembra di averlo aggiunto! #include #include #include #include #include #include #include #include #include // loader #include #include "defs.h" using namespace vcg; using namespace face; class MyFace; class MyEdge; class MyVertex:public Vertex{}; class MyFace :public FaceAFAV{}; class MyMesh: public tri::TriMesh< std::vector, std::vector >{}; void OpenMesh(const char *filename, MyMesh &m) { int err = tri::io::Importer::Open(m,filename); if(err) { printf("Error in reading %s: '%s'\n",filename,tri::io::Importer::ErrorMsg(err)); exit(-1); } printf("read mesh `%s'\n", filename); } inline char* GetExtension(char* filename) { for(int i=strlen(filename)-1; i >= 0; i--) if(filename[i] == '.') break; if(i > 0) return &(filename[i+1]); else return NULL; } void main(int argc,char ** argv){ char *fmt; MyMesh m; //load the mesh //argv[1]=(char*)"c:\\checkup\\debug\\column1m.ply"; //argv[1] = "C:\\Documents and Settings\\Rita\\Desktop\\MeshReader\\trimeshinfo\\Debug\\prova0.ply"; // print program info printf("-------------------------------\n" " TriMeshInfo\n" " release date: "__DATE__"\n" "-------------------------------\n\n"); // load input meshes. if(argc <= 1) { printf(MSG_ERR_N_ARGS); exit(-1); } // load mesh M1. if(!(fmt = GetExtension(argv[1]))) { printf(MSG_ERR_UNKNOWN_FORMAT, fmt); exit(-1); } if(!_stricmp(FILE_EXT_PLY, fmt)) { printf("reading the mesh `%s'...", argv[1]); OpenMesh(argv[1],m); } else printf("done\n"); FILE * index; index = fopen((string(argv[1])+string("2.html")).c_str(),"w"); fprintf(index,"

TriMeshInfo: This is the result for %s

\n\n\n", argv[1]); fprintf(index,"

GENERAL INFO

\n\n"); fprintf(index,"

Number of vertices: %d

\n", m.vn); fprintf(index,"

Number of faces: %d

\n", m.fn); printf("Number of vertices: %d \n", m.vn); printf("Number of faces: %d \n", m.fn); if (m.Volume()!=0) { fprintf(index,"

Volume: %d

\n", m.Volume()); printf("Volume: %d \n", m.Volume()); } Color4b Color=m.C(); fprintf(index, "

Object color(4b): %f %f %f

\n\n", Color[0], Color[1], Color[2]); printf( "Object color(4b): %f %f %f \n\n", Color[0], Color[1], Color[2]); vcg::tri::UpdateTopology::FaceFace(m); // IS MANIFOLD MyMesh::FaceIterator f; MyMesh::FaceIterator g; vcg::face::Pos he; vcg::face::Pos hei; int j; int man=0; bool Manifold = true; MyMesh::FaceIterator prova; prova = m.face.end(); for(f=m.face.begin();f!=m.face.end();++f) { for (j=0;j<3;++j) { if(!IsManifold(*f,j)) { Manifold = false; f= m.face.end(); --f; j=3; } } } if (!Manifold) { fprintf(index, "

Manifold from lib gives: NO

"); printf( "Manifold from lib gives: NO\n"); } else { fprintf(index, "

Manifold from lib gives: YES

"); printf( "Manifold from lib gives: YES "); } // COUNT EDGES MyMesh::FaceIterator fi; int count_e = 0; bool counted=false; for(fi=m.face.begin();fi!=m.face.end();++fi) (*fi).ClearS(); for(fi=m.face.begin();fi!=m.face.end();++fi) { (*fi).SetS(); count_e +=3; for(int i=0; i<3; ++i) { if (IsManifold(*fi,i)) { if((*fi).FFp(i)->IsS()) count_e--; } else { hei.Set(&(*fi), i , fi->V(i)); he=hei; he.NextF(); while (he.f!=hei.f) { if (he.f->IsS()) { counted=true; break; } else { he.NextF(); } } if (counted) { count_e--; counted=false; } } } } fprintf(index, "

Number of edges: %d

\n", count_e); printf("Number of edges: %d \n", count_e); // DA QUI IN POI!!! // DEGENERATED FACES int count_fd = 0; for(fi=m.face.begin(); fi!=m.face.end();++fi) if((*fi).Area() == 0) count_fd++; fprintf(index, "

Number of degenerated faces: %d

\n", count_fd); printf("Number of degenerated faces: %d \n", count_fd); // UNREFERENCED VERTEX int count_uv = 0; MyMesh::VertexIterator v; int deleted = 0; for(v=m.vert.begin();v!=m.vert.end();++v) (*v).ClearV(); for(f=m.face.begin();f!=m.face.end();++f) for(j=0;j<3;++j) (*f).V(j)->SetV(); for(v=m.vert.begin();v!=m.vert.end();++v) if( !(*v).IsV() ) ++count_uv; fprintf(index,"

Number of unreferenced vertices: %d

\n",count_uv); printf("Number of unreferenced vertices: %d\n",count_uv); // HOLES COUNT for(f=m.face.begin();f!=m.face.end();++f) (*f).ClearS(); g=m.face.begin(); f=g; int BEdges=0; int numholes=0; if (Manifold) { for(f=g;f!=m.face.end();++f) { if(!(*f).IsS()) { for(j=0;j<3;j++) { if ((*f).IsBorder(j)) { BEdges++; if(!(IsManifold(*f,j))) { (*f).SetS(); hei.Set(&(*f),j,f->V(j)); he=hei; do { he.NextB(); he.f->SetS(); // BEdges++; } while (he.f!=hei.f); //BEdges--; numholes++; } } } } } } else { for(f=g;f!=m.face.end();++f) { for(j=0;j<3;j++) { if ((*f).IsBorder(j)) { BEdges++; } } } } if (Manifold) { fprintf(index, "

Number of holes: %d

\n

Number of border edges: %d

", numholes, BEdges); printf("Number of holes: %d \n", numholes, BEdges); printf("Number of border edges: %d\n", numholes, BEdges); } else { fprintf(index, "

Number of border edges: %d

", BEdges); printf("Number of border edges: %d\n", BEdges); } // CONNECTED COMPONENTS for(f=m.face.begin();f!=m.face.end();++f) (*f).ClearS(); g=m.face.begin(); f=g; int CountComp=0; int CountOrient=0; stack sf; MyMesh::FaceType *l; for(f=m.face.begin();f!=m.face.end();++f) { if (!(*f).IsS()) { (*f).SetS(); sf.push(f); while (!sf.empty()) { g=sf.top(); he.Set(&(*g),0,g->V(0)); sf.pop(); for(j=0;j<3;++j) if( !(*g).IsBorder(j) ) { l=he.f->FFp(j); if( !(*l).IsS() ) { (*l).SetS(); sf.push(l); } } } CountComp++; } } fprintf(index, "

Number of connected components: %d

", CountComp); printf("Number of connected components: %d\n", CountComp); if(CountComp ==1) { int eulero; //v-e+f eulero = (m.vn-count_uv)- (count_e+BEdges)+m.fn; if(Manifold) { int genus = (2-eulero)>>1; fprintf(index, "

Genus: %d

\n ", genus); printf( "Genus: %d \n ", genus); } } // REGULARITY bool Regular=true; bool Semiregular=true; int inc=0; for(v=m.vert.begin();v!=m.vert.end();++v) (*v).ClearS(); for(f=m.face.begin();f!=m.face.end();++f) { for (j=0; j<3; j++) { he.Set(&(*f),j,f->V(j)); if (!(*f).IsBorder(j) && !(*f).IsBorder((j+2)%3) && !f->V(j)->IsS()) { hei=he; inc=1; he.FlipE(); he.NextF(); while (he.f!=hei.f) { he.FlipE(); if (he.IsBorder()) { inc=6; break; } he.NextF(); inc++; } if (inc!=6) Regular=false; if (inc!=6 && inc!=5) Semiregular=false; f->V(j)->SetS(); } else f->V(j)->SetS(); } if (Semiregular==false) break; } if (Regular) { fprintf(index, "

Type of Mesh: REGULAR

"); printf("Type of Mesh: REGULAR\n"); } else if (Semiregular) { fprintf(index, "

Type of Mesh: SEMIREGULAR

"); printf("Type of Mesh: SEMIREGULAR\n"); } else { fprintf(index, "

Type of Mesh: IRREGULAR

"); printf("Type of Mesh: IRREGULAR\n"); } // ORIENTABLE E ORIENTED MESH bool Orientable=true; bool Oriented=true; if (!Manifold) { fprintf(index, "

Orientable Mesh: NO

"); printf( "Orientable Mesh: NO\n"); } else { for(f=m.face.begin();f!=m.face.end();++f) { (*f).ClearS(); (*f).ClearUserBit(0); } g=m.face.begin(); f=g; for(f=m.face.begin();f!=m.face.end();++f) { if (!(*f).IsS()) { (*f).SetS(); sf.push(f); while (!sf.empty()) { g=sf.top(); sf.pop(); for(j=0;j<3;++j) { if( !(*g).IsBorder(j) ) { he.Set(&(*g),0,g->V(0)); l=he.f->FFp(j); he.Set(&(*g),j,g->V(j)); hei.Set(he.f->FFp(j),he.f->FFi(j), (he.f->FFp(j))->V(he.f->FFi(j))); if( !(*g).IsUserBit(0) ) { if (he.v!=hei.v) // bene { if ((*l).IsS() && (*l).IsUserBit(0)) { Orientable=false; break; } else if (!(*l).IsS()) { (*l).SetS(); sf.push(l); } } else if (!(*l).IsS()) { Oriented=false; (*l).SetS(); (*l).SetUserBit(0); sf.push(l); } else if ((*l).IsS() && !(*l).IsUserBit(0)) { Orientable=false; break; } } else if (he.v==hei.v) // bene { if ((*l).IsS() && (*l).IsUserBit(0)) { Orientable=false; break; } else if (!(*l).IsS()) { (*l).SetS(); sf.push(l); } } else if (!(*l).IsS()) { Oriented=false; (*l).SetS(); (*l).SetUserBit(0); sf.push(l); } else if ((*l).IsS() && !(*l).IsUserBit(0)) { Orientable=false; break; } } } } } if (!Orientable) break; } if (Orientable) { fprintf(index, "

Orientable Mesh: YES

"); printf( "Orientable Mesh: YES\n"); } else { fprintf(index, "

Orientable Mesh: NO

"); printf( "Orientable Mesh: NO\n"); } } if (Oriented && Manifold) { fprintf(index, "

Oriented Mesh: YES

"); printf( "Oriented Mesh: YES\n"); } else { fprintf(index, "

Oriented Mesh: NO

"); printf( "Oriented Mesh: NO\n"); } // SELF INTERSECTION if (m.fn<300000) { bool SelfInt=false; for(f=m.face.begin();f!=m.face.end();++f) { for(g=++f , f--;g!=m.face.end();++g) { if ((*f).FFp(0)!=&(*g) && (*f).FFp(1)!=&(*g) && (*f).FFp(2)!=&(*g) && f->V(0)!=g->V(0) && f->V(0)!=g->V(1) && f->V(0)!=g->V(2) && f->V(1)!=g->V(0) && f->V(1)!=g->V(1) && f->V(1)!=g->V(2) && f->V(2)!=g->V(0) && f->V(2)!=g->V(1) && f->V(2)!=g->V(2)) { 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()) ) SelfInt=true; } } if (SelfInt) break; } if (SelfInt) { fprintf(index, "

Self Intersection: YES

"); printf( "Self Intersection: YES\n"); } else { fprintf(index, "

Self Intersection: NO

"); printf( "Self Intersection: NO\n"); } } fclose(index); }