trimesh_hole.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-2012                                           \/)\/    *
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<vcg/space/triangle3.h>
00025 #include<vcg/complex/complex.h>
00026 #include<vcg/complex/algorithms/hole.h>
00027 #include<vcg/complex/algorithms/local_optimization.h>
00028 #include<vcg/complex/algorithms/local_optimization/tri_edge_flip.h>
00029 #include<vcg/complex/algorithms/smooth.h>
00030 #include<vcg/complex/algorithms/refine.h>
00031 
00032 #include<vcg/complex/algorithms/update/selection.h>
00033 
00034 // topology computation
00035 #include<vcg/complex/algorithms/update/topology.h>
00036 #include <vcg/complex/algorithms/update/flag.h>
00037 #include <vcg/complex/algorithms/update/normal.h>
00038 
00039 // half edge iterators
00040 #include<vcg/simplex/face/pos.h>
00041 
00042 // input output
00043 #include <wrap/io_trimesh/import_ply.h>
00044 #include <wrap/io_trimesh/export_ply.h>
00045 
00046 using namespace vcg;
00047 using namespace std;
00048 
00049 class MyFace;
00050 class MyVertex;
00051 struct MyUsedTypes : public UsedTypes<  Use<MyVertex>           ::AsVertexType,
00052     Use<MyFace>                 ::AsFaceType>{};
00053 
00054 class MyVertex  : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark, vertex::Color4b >{};
00055 class MyFace    : public Face  < MyUsedTypes, face::VertexRef,face::FFAdj, face::Mark, face::BitFlags, face::Normal3f> {};
00056 
00057 class MyMesh : public tri::TriMesh< vector<MyVertex>, vector<MyFace > >{};
00058 
00059 //Delaunay
00060 class MyDelaunayFlip: public vcg::tri::TriEdgeFlip< MyMesh, MyDelaunayFlip > {
00061 public:
00062     typedef  vcg::tri::TriEdgeFlip< MyMesh,  MyDelaunayFlip > TEF;
00063     inline MyDelaunayFlip(  const TEF::PosType &p, int i,BaseParameterClass *pp) :TEF(p,i,pp){}
00064 };
00065 
00066 bool callback(int percent, const char *str) {
00067   cout << "str: " << str << " " << percent << "%\r";
00068   return true;
00069 }
00070 
00071 template <class MESH>
00072 bool NormalTest(typename face::Pos<typename MESH::FaceType> pos)
00073 {
00074     //giro intorno al vertice e controllo le normali
00075     typename MESH::ScalarType thr = 0.0f;
00076         typename MESH::CoordType NdP = vcg::TriangleNormal<typename MESH::FaceType>(*pos.f);
00077     typename MESH::CoordType tmp, oop, soglia = typename MESH::CoordType(thr,thr,thr);
00078     face::Pos<typename MESH::FaceType> aux=pos;
00079     do{
00080         aux.FlipF();
00081         aux.FlipE();
00082                 oop = Abs(tmp - ::vcg::TriangleNormal<typename MESH::FaceType>(*pos.f));
00083         if(oop < soglia )return false;
00084     }while(aux != pos && !aux.IsBorder());
00085 
00086     return true;
00087 }
00088 
00089 int main(int argc,char ** argv){
00090 
00091     if(argc<5)
00092     {
00093         printf(
00094             "\n     HoleFilling (" __DATE__ ")\n"
00095             "Visual Computing Group I.S.T.I. C.N.R.\n"
00096       "Usage: trimesh_hole #algorithm #size filein.ply fileout.ply \n"
00097             "#algorithm: \n"
00098             " 1) Trivial Ear \n"
00099             " 2) Minimum weight Ear \n"
00100             " 3) Selfintersection Ear \n"
00101             " 4) Minimum weight \n"
00102             );
00103         exit(0);
00104     }
00105 
00106     int algorithm = atoi(argv[1]);
00107     int holeSize  = atoi(argv[2]);
00108     if(algorithm < 0 && algorithm > 4)
00109     {
00110     printf("Error in algorithm's selection %i\n",algorithm);
00111         exit(0);
00112     }
00113 
00114     MyMesh m;
00115 
00116     if(tri::io::ImporterPLY<MyMesh>::Open(m,argv[3])!=0)
00117     {
00118         printf("Error reading file  %s\n",argv[2]);
00119         exit(0);
00120     }
00121 
00122     //update the face-face topology
00123     tri::UpdateTopology<MyMesh>::FaceFace(m);
00124     tri::UpdateNormal<MyMesh>::PerVertexPerFace(m);
00125     tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
00126   assert(tri::Clean<MyMesh>::IsFFAdjacencyConsistent(m));
00127 
00128     //compute the average of face area
00129     float AVG,sumA=0.0f;
00130     int numA=0,indice;
00131     indice = m.face.size();
00132     MyMesh::FaceIterator fi;
00133     for(fi=m.face.begin();fi!=m.face.end();++fi)
00134     {
00135             sumA += DoubleArea(*fi)/2;
00136             numA++;
00137             for(int ind =0;ind<3;++ind)
00138                 fi->V(ind)->InitIMark();
00139     }
00140     AVG=sumA/numA;
00141 
00142   //tri::Hole<MyMesh> holeFiller;
00143     switch(algorithm)
00144     {
00145   case 1:                       tri::Hole<MyMesh>::EarCuttingFill<tri::TrivialEar<MyMesh> >(m,holeSize,false);                          break;
00146   case 2:       tri::Hole<MyMesh>::EarCuttingFill<tri::MinimumWeightEar< MyMesh> >(m,holeSize,false,callback);          break;
00147   case 3:               tri::Hole<MyMesh>::EarCuttingIntersectionFill<tri::SelfIntersectionEar< MyMesh> >(m,holeSize,false);            break;
00148   case 4:               tri::Hole<MyMesh>::MinimumWeightFill(m,holeSize, false); tri::UpdateTopology<MyMesh>::FaceFace(m);      break;
00149     }
00150 
00151     tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
00152 
00153   assert(tri::Clean<MyMesh>::IsFFAdjacencyConsistent(m));
00154 
00155   printf("\nStart refinig...\n");
00156 
00157 /*start refining */
00158     MyMesh::VertexIterator vi;
00159     MyMesh::FaceIterator f;
00160     std::vector<MyMesh::FacePointer> vf;
00161     f =  m.face.begin();
00162     f += indice;
00163     for(; f != m.face.end();++f)
00164     {
00165         if(!f->IsD())
00166         {
00167             f->SetS();
00168         }
00169     }
00170 
00171     std::vector<MyMesh::FacePointer *> FPP;
00172     std::vector<MyMesh::FacePointer> added;
00173     std::vector<MyMesh::FacePointer>::iterator vfit;
00174     int i=1;
00175     printf("\n");
00176 
00177     for(f =  m.face.begin();f!=m.face.end();++f) if(!(*f).IsD())
00178     {
00179         if( f->IsS() )
00180         {
00181             f->V(0)->IsW();
00182             f->V(1)->IsW();
00183             f->V(2)->IsW();
00184         }
00185         else
00186         {
00187             f->V(0)->ClearW();
00188             f->V(1)->ClearW();
00189             f->V(2)->ClearW();
00190         }
00191     }
00192     BaseParameterClass pp;
00193                 vcg::LocalOptimization<MyMesh> Fs(m,&pp);
00194                 Fs.SetTargetMetric(0.0f);
00195                 Fs.Init<MyDelaunayFlip >();
00196                 Fs.DoOptimization();
00197 
00198 
00199     do
00200     {
00201         vf.clear();
00202         f =  m.face.begin();
00203         f += indice;
00204         for(; f != m.face.end();++f)
00205         {
00206             if(f->IsS())
00207             {
00208                 bool test= true;
00209                 for(int ind =0;ind<3;++ind)
00210                     f->V(ind)->InitIMark();
00211                 test = (DoubleArea<MyMesh::FaceType>(*f)/2) > AVG;
00212                 if(test)
00213                 {
00214                     vf.push_back(&(*f));
00215                 }
00216             }
00217         }
00218 
00219         //info print
00220     printf("\r Refining [%d] - > %d",i,int(vf.size()));
00221         i++;
00222 
00223         FPP.clear();
00224         added.clear();
00225 
00226         for(vfit = vf.begin(); vfit!=vf.end();++vfit)
00227         {
00228             FPP.push_back(&(*vfit));
00229         }
00230         int toadd= vf.size();
00231         MyMesh::FaceIterator f1,f2;
00232         f2 = tri::Allocator<MyMesh>::AddFaces(m,(toadd*2),FPP);
00233         MyMesh::VertexIterator vertp = tri::Allocator<MyMesh>::AddVertices(m,toadd);
00234         std::vector<MyMesh::FacePointer> added;
00235         added.reserve(toadd);
00236         vfit=vf.begin();
00237 
00238         for(int i = 0; i<toadd;++i,f2++,vertp++)
00239         {
00240             f1=f2;
00241             f2++;
00242             TriSplit<MyMesh,CenterPointBarycenter<MyMesh> >::Apply(vf[i],&(*f1),&(*f2),&(*vertp),CenterPointBarycenter<MyMesh>() );
00243             f1->SetS();
00244             f2->SetS();
00245             for(int itr=0;itr<3;itr++)
00246             {
00247                 f1->V(itr)->SetW();
00248                 f2->V(itr)->SetW();
00249             }
00250             added.push_back( &(*f1) );
00251             added.push_back( &(*f2) );
00252         }
00253 
00254         BaseParameterClass pp;
00255         vcg::LocalOptimization<MyMesh> FlippingSession(m,&pp);
00256         FlippingSession.SetTargetMetric(0.0f);
00257         FlippingSession.Init<MyDelaunayFlip >();
00258         FlippingSession.DoOptimization();
00259 
00260     }while(!vf.empty());
00261 
00262     vcg::LocalOptimization<MyMesh> Fiss(m,&pp);
00263     Fiss.SetTargetMetric(0.0f);
00264     Fiss.Init<MyDelaunayFlip >();
00265     Fiss.DoOptimization();
00266 
00267 /*end refining */
00268 
00269     tri::io::ExporterPLY<MyMesh>::Save(m,"PreSmooth.ply",false);
00270 
00271     int UBIT = MyMesh::VertexType::NewBitFlag();
00272     f =  m.face.begin();
00273     f += indice;
00274     for(; f != m.face.end();++f)
00275     {
00276         if(f->IsS())
00277         {
00278             for(int ind =0;ind<3;++ind){
00279                 if(NormalTest<MyMesh>(face::Pos<MyMesh::FaceType>(&(*f),ind )))
00280                 {
00281                     f->V(ind)->SetUserBit(UBIT);
00282                 }
00283             }
00284             f->ClearS();
00285         }
00286     }
00287 
00288     for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
00289     {
00290         if( vi->IsUserBit(UBIT) )
00291         {
00292             (*vi).SetS();
00293             vi->ClearUserBit(UBIT);
00294         }
00295     }
00296 
00297     tri::Smooth<MyMesh>::VertexCoordLaplacian(m,1,true);
00298 
00299     printf("\nCompleted. Saving....\n");
00300 
00301   tri::io::ExporterPLY<MyMesh>::Save(m,argv[4],false);
00302     return 0;
00303 }
00304 


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