diff --git a/apps/sample/trimesh_hole/trimesh_hole.cpp b/apps/sample/trimesh_hole/trimesh_hole.cpp index 7de1e3bf..b9c717e1 100644 --- a/apps/sample/trimesh_hole/trimesh_hole.cpp +++ b/apps/sample/trimesh_hole/trimesh_hole.cpp @@ -5,10 +5,13 @@ #include #include #include -#include -//#include +#include +#include #include +#include +#include +#include // topology computation #include @@ -18,7 +21,7 @@ // half edge iterators #include -#include + // input output #include @@ -38,28 +41,37 @@ class MyFace : public FaceSimp2 < MyVertex, MyEdge, MyFace, face::VertexRef, class MyMesh : public tri::TriMesh< vector, vector >{}; - - -/* -//for coplanar mesh -class MyTriEdgeFlip: public vcg::tri::PlanarEdgeFlip< MyMesh, MyTriEdgeFlip > { - public: - typedef vcg::tri::PlanarEdgeFlip< MyMesh, MyTriEdgeFlip > TEF; - inline MyTriEdgeFlip( const TEF::PosType &p, int i) :TEF(p,i){} -}; -/*/ //Delaunay -class MyTriEdgeFlip: public vcg::tri::TriEdgeFlip< MyMesh, MyTriEdgeFlip > { - public: - typedef vcg::tri::TriEdgeFlip< MyMesh, MyTriEdgeFlip > TEF; - inline MyTriEdgeFlip( const TEF::PosType &p, int i) :TEF(p,i){} +class MyDelaunayFlip: public vcg::tri::TriEdgeFlip< MyMesh, MyDelaunayFlip > { +public: + typedef vcg::tri::TriEdgeFlip< MyMesh, MyDelaunayFlip > TEF; + inline MyDelaunayFlip( const TEF::PosType &p, int i) :TEF(p,i){} }; -//*/ + bool callback(int percent, const char *str) { cout << "str: " << str << " " << percent << "%\r"; return true; } +template +bool NormalTest(typename face::Pos pos) +{ + //giro intorno al vertice e controllo le normali + float accum=0; + MESH::ScalarType thr = 0.0f; + MESH::CoordType NdP = Normal(*pos.f); + MESH::CoordType tmp, oop, soglia = MESH::CoordType(thr,thr,thr); + face::Pos aux=pos; + do{ + aux.FlipF(); + aux.FlipE(); + oop = Abs(tmp - Normal(*pos.f)); + if(oop < soglia )return false; + }while(aux != pos && !aux.IsBorder()); + + return true; +} + int main(int argc,char ** argv){ if(argc<5) @@ -93,33 +105,184 @@ int main(int argc,char ** argv){ exit(0); } - //update the face-face topology tri::UpdateTopology::FaceFace(m); tri::UpdateNormals::PerVertexPerFace(m); tri::UpdateFlags::FaceBorderFromFF(m); assert(tri::Clean::IsFFAdjacencyConsistent(m)); - + //compute the average of face area + float AVG,sumA=0.0f; + int numA=0,indice; + indice = m.face.size(); + MyMesh::FaceIterator fi; + for(fi=m.face.begin();fi!=m.face.end();++fi) + { + sumA += DoubleArea(*fi)/2; + numA++; + for(int ind =0;ind<3;++ind) + fi->V(ind)->InitIMark(); + } + AVG=sumA/numA; + tri::Hole holeFiller; switch(algorithm) { case 1: tri::Hole::EarCuttingFill >(m,holeSize,false); break; case 2: tri::Hole::EarCuttingFill >(m,holeSize,false,callback); break; case 3: tri::Hole::EarCuttingIntersectionFill >(m,holeSize,false); break; - case 4: tri::Hole::MinimumWeightFill(m,holeSize, false); break; + case 4: tri::Hole::MinimumWeightFill(m,holeSize, false); tri::UpdateTopology::FaceFace(m); break; } - printf("\nCompleted. Saving...\n"); - assert(tri::Clean::IsFFAdjacencyConsistent(m)); - tri::io::ExporterPLY::Save(m,argv[4],false); - printf("\nStart flipping...\n"); - - vcg::LocalOptimization FlippingSession(m); - FlippingSession.SetTargetMetric(-0.000000000001f);// - FlippingSession.Init(); - FlippingSession.DoOptimization(); - tri::io::ExporterPLY::Save(m,"out2.ply",vcg::tri::io::Mask::IOM_VERTCOLOR); + + tri::UpdateFlags::FaceBorderFromFF(m); + assert(tri::Clean::IsFFAdjacencyConsistent(m)); + + printf("\nStart refinig...\n"); + +/*start refining */ + MyMesh::VertexIterator vi; + MyMesh::FaceIterator f; + std::vector vf; + f = m.face.begin(); + f += indice; + for(; f != m.face.end();++f) + { + if(!f->IsD()) + { + f->SetS(); + } + } + + std::vector FPP; + std::vector added; + std::vector::iterator vfit; + int i=1; + printf("\n"); + + for(f = m.face.begin();f!=m.face.end();++f) if(!(*f).IsD()) + { + if( f->IsS() ) + { + f->V(0)->IsW(); + f->V(1)->IsW(); + f->V(2)->IsW(); + } + else + { + f->V(0)->ClearW(); + f->V(1)->ClearW(); + f->V(2)->ClearW(); + } + } + vcg::LocalOptimization Fs(m); + Fs.SetTargetMetric(0.0f); + Fs.Init(); + Fs.DoOptimization(); + + + do + { + vf.clear(); + f = m.face.begin(); + f += indice; + for(; f != m.face.end();++f) + { + if(f->IsS()) + { + bool test= true; + for(int ind =0;ind<3;++ind) + f->V(ind)->InitIMark(); + test = (DoubleArea(*f)/2) > AVG; + if(test) + { + vf.push_back(&(*f)); + } + } + } + + //info print + printf("\r Raffino [%d] - > %d",i,vf.size()); + i++; + + FPP.clear(); + added.clear(); + + for(vfit = vf.begin(); vfit!=vf.end();++vfit) + { + FPP.push_back(&(*vfit)); + } + int toadd= vf.size(); + MyMesh::FaceIterator f1,f2; + f2 = tri::Allocator::AddFaces(m,(toadd*2),FPP); + MyMesh::VertexIterator vertp = tri::Allocator::AddVertices(m,toadd); + std::vector added; + added.reserve(toadd); + vfit=vf.begin(); + + for(int i = 0; i >(vf[i],&(*f1),&(*f2),&(*vertp),CenterPoint() ); + f1->SetS(); + f2->SetS(); + for(int itr=0;itr<3;itr++) + { + f1->V(itr)->SetW(); + f2->V(itr)->SetW(); + } + added.push_back( &(*f1) ); + added.push_back( &(*f2) ); + } + + vcg::LocalOptimization FlippingSession(m); + FlippingSession.SetTargetMetric(0.0f); + FlippingSession.Init(); + FlippingSession.DoOptimization(); + + }while(!vf.empty()); + + vcg::LocalOptimization Fiss(m); + Fiss.SetTargetMetric(0.0f); + Fiss.Init(); + Fiss.DoOptimization(); + +/*end refining */ + + tri::io::ExporterPLY::Save(m,"PreSmooth.ply",false); + + int UBIT = MyMesh::VertexType::LastBitFlag(); + f = m.face.begin(); + f += indice; + for(; f != m.face.end();++f) + { + if(f->IsS()) + { + for(int ind =0;ind<3;++ind){ + if(NormalTest(face::Pos(&(*f),ind ))) + { + f->V(ind)->SetUserBit(UBIT); + } + } + f->ClearS(); + } + } + + for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + { + if( vi->IsUserBit(UBIT) ) + { + (*vi).SetS(); + vi->ClearUserBit(UBIT); + } + } + + LaplacianSmooth(m,1,true); + + printf("\nCompleted. Saving....\n"); + + tri::io::ExporterPLY::Save(m,argv[4],false); return 0; }