static void make_mesh( MeshModel & m, MeshEP * mesh ) { for( CMeshO::FaceIterator i = m.cm.face.begin(); i < m.cm.face.end(); i++ ) { FaceEP f; f.V( 0 ) = i->V( 0 ); f.V( 1 ) = i->V( 1 ); f.V( 2 ) = i->V( 2 ); f.ImportData( *i ); mesh->face.push_back( f ); } mesh->bbox = m.cm.bbox; vcg::tri::UpdateComponentEP<MeshEP>::Set( *mesh ); }
int SnapVertexBorder(CMeshO &m, float threshold, vcg::CallBackPos * cb) { tri::Allocator<CMeshO>::CompactVertexVector(m); tri::Allocator<CMeshO>::CompactFaceVector(m); tri::UpdateTopology<CMeshO>::FaceFace(m); tri::UpdateFlags<CMeshO>::FaceBorderFromFF(m); tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m); tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFaceNormalized(m); typedef GridStaticPtr<CMeshO::FaceType, CMeshO::ScalarType > MetroMeshFaceGrid; MetroMeshFaceGrid unifGridFace; typedef tri::FaceTmark<CMeshO> MarkerFace; MarkerFace markerFunctor; vcg::face::PointDistanceBaseFunctor<CMeshO::ScalarType> PDistFunct; tri::UpdateFlags<CMeshO>::FaceClearV(m); unifGridFace.Set(m.face.begin(),m.face.end()); markerFunctor.SetMesh(&m); int faceFound; int K = 20; Point3f startPt; float maxDist = m.bbox.Diag()/20; vector<Point3f> splitVertVec; vector<CMeshO::FacePointer> splitFaceVec; vector<int> splitEdgeVec; for(CMeshO::VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD() && (*vi).IsB()) { int percPos = (tri::Index(m,*vi) *100) / m.vn; cb(percPos,"Snapping vertices"); vector<CMeshO::FacePointer> faceVec; vector<float> distVec; vector<Point3f> pointVec; Point3f u; startPt = (*vi).P(); faceFound = unifGridFace.GetKClosest(PDistFunct,markerFunctor, K, startPt,maxDist, faceVec, distVec, pointVec); CMeshO::FacePointer bestFace = 0; float localThr, bestDist = std::numeric_limits<float>::max(); Point3f bestPoint; int bestEdge; // qDebug("Found %i face for vertex %i",faceFound,vi-m.vert.begin()); for(int i=0;i<faceFound;++i) { const float epsilonSmall = 1e-5; const float epsilonBig = 1e-2; CMeshO::FacePointer fp=faceVec[i]; InterpolationParameters(*fp,fp->cN(),pointVec[i],u); // qDebug(" face %i face for vertex %5.3f %5.3f %5.3f dist %5.3f (%c %c %c)",fp-&*m.face.begin(),u[0],u[1],u[2],distVec[i],IsBorder(*fp,0)?'b':' ',IsBorder(*fp,1)?'b':' ',IsBorder(*fp,2)?'b':' '); for(int j=0;j<3;++j) { if(IsBorder(*fp,j) && !fp->IsV()) { if( u[(j+0)%3] > epsilonBig && u[(j+1)%3] > epsilonBig && u[(j+2)%3] < epsilonSmall ) { if(distVec[i] < bestDist) { bestDist=distVec[i]; //bestPoint=pointVec[i]; bestPoint=(*vi).cP(); bestFace=fp; bestEdge=j; } } } } } // end for each faceFound if(bestFace) localThr = threshold*Distance(bestFace->P0(bestEdge),bestFace->P1(bestEdge)); if(bestDist < localThr && !bestFace->IsV()) { bestFace->SetV(); (*vi).C()= Color4b::Blue; //bestFace->C()=Color4b::LightBlue; (*vi).SetS(); splitVertVec.push_back(bestPoint); splitEdgeVec.push_back(bestEdge); splitFaceVec.push_back(bestFace); } } tri::Allocator<CMeshO>::PointerUpdater<CMeshO::FacePointer> pu; CMeshO::VertexIterator firstVert = tri::Allocator<CMeshO>::AddVertices(m,splitVertVec.size()); CMeshO::FaceIterator firstface = tri::Allocator<CMeshO>::AddFaces(m,splitVertVec.size(),pu); // // ^ ^ // / \ / | \ . // / \ / | \ . // / \ / | \ . // / fp \ / | \ . // / \ / fp | ff \ . // V0 ------------------V2 V0 -------fv---------V2 // i for(size_t i=0;i<splitVertVec.size();++i) { firstVert->P() = splitVertVec[i]; int eInd = splitEdgeVec[i]; CMeshO::FacePointer fp = splitFaceVec[i]; pu.Update(fp); firstface->V(0) = &*firstVert; firstface->V(1) = fp->V2(eInd); firstface->V(2) = fp->V0(eInd); // firstface->C()=Color4b::LightBlue; fp->V0(eInd) = &*firstVert; ++firstface; ++firstVert; } tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFaceNormalized(m); return splitVertVec.size(); }