/** @def This function initialize the mesh m in order to respect some prerequisites of the filter @param MeshModel* m - Pointer to the Mesh @return nothing */ void prepareMesh(MeshModel* m){ m->updateDataMask(MeshModel::MM_FACEFACETOPO); m->updateDataMask(MeshModel::MM_FACEMARK); m->updateDataMask(MeshModel::MM_FACECOLOR); m->updateDataMask(MeshModel::MM_VERTQUALITY); m->updateDataMask(MeshModel::MM_FACEQUALITY); m->updateDataMask(MeshModel::MM_FACENORMAL); tri::UnMarkAll(m->cm); //clean Mesh tri::Allocator<CMeshO>::CompactFaceVector(m->cm); tri::Clean<CMeshO>::RemoveUnreferencedVertex(m->cm); tri::Clean<CMeshO>::RemoveDuplicateVertex(m->cm); tri::Allocator<CMeshO>::CompactVertexVector(m->cm); tri::UpdateFlags<CMeshO>::FaceClear(m->cm); //update Mesh m->cm.vert.EnableVFAdjacency(); m->cm.face.EnableVFAdjacency(); tri::UpdateTopology<CMeshO>::FaceFace(m->cm); tri::UpdateTopology<CMeshO>::VertexFace(m->cm); tri::UpdateNormal<CMeshO>::PerFaceNormalized(m->cm); CMeshO::FaceIterator fi; for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ fi->Q()=0; } }
/** @def Compute the Normal Dust Amount Function per face of a Mesh m @param m MeshModel @param u CoordType dust direction @param k float @param s float @return nothing */ void ComputeNormalDustAmount(MeshModel* m,CMeshO::CoordType u,float k,float s){ CMeshO::FaceIterator fi; float d; for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ d=k/s+(1+k/s)*pow(fi->N().dot(u),s); fi->Q()=d; } }
void ColorizeMesh(MeshModel* m){ CMeshO::FaceIterator fi; float dirtiness; for(fi = m->cm.face.begin(); fi != m->cm.face.end(); ++fi){ dirtiness=fi->Q(); if(dirtiness==0){ fi->C()=Color4b(255,255,255,0); }else{ if(dirtiness>255) fi->C()=Color4b(0,0,0,0); else fi->C()=Color4b(255-dirtiness,255-dirtiness,255-dirtiness,0); } } tri::UpdateColor<CMeshO>::PerVertexFromFace(m->cm); }
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 ); }
// Core Function doing the actual mesh processing. bool RangeMapPlugin::applyFilter(QAction *filter, MeshDocument &m, FilterParameterSet & par, vcg::CallBackPos *cb) { CMeshO::FaceIterator fi; switch(ID(filter)) { case FP_SELECTBYANGLE : { bool usecam = par.getBool("usecamera"); Point3f viewpoint = par.getPoint3f("viewpoint"); // if usecamera but mesh does not have one if( usecam && !m.mm()->hasDataMask(MeshModel::MM_CAMERA) ) { errorMessage = "Mesh has not a camera that can be used to compute view direction. Please set a view direction."; // text return false; } if(usecam) { viewpoint = m.mm()->cm.shot.GetViewPoint(); } // angle threshold in radians float limit = cos( math::ToRad(par.getDynamicFloat("anglelimit")) ); Point3f viewray; for(fi=m.mm()->cm.face.begin();fi!=m.mm()->cm.face.end();++fi) if(!(*fi).IsD()) { viewray = viewpoint - Barycenter(*fi); viewray.Normalize(); if((viewray.dot((*fi).N().Normalize())) < limit) fi->SetS(); } } break; } return true; }
/** @def This function compute the Surface Exposure per face of a Mesh m @param MeshModel* m - Pointer to the new mesh @param int r - scaling factor @param int n_ray - number of rays emitted @return nothing */ void ComputeSurfaceExposure(MeshModel* m,int r,int n_ray){ CMeshO::PerFaceAttributeHandle<float> eh=vcg::tri::Allocator<CMeshO>::AddPerFaceAttribute<float>(m->cm,std::string("exposure")); float dh=1.2; float exp=0; float di=0; float xi=0; CMeshO::FacePointer face; CMeshO::CoordType p_c; MetroMeshFaceGrid f_grid; f_grid.Set(m->cm.face.begin(),m->cm.face.end()); MarkerFace markerFunctor; markerFunctor.SetMesh(&(m->cm)); RayTriangleIntersectionFunctor<false> RSectFunct; CMeshO::FaceIterator fi; for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ xi=0; eh[fi]=0; for(int i=0;i<n_ray;i++){ //For every f_face get the central point p_c=fromBarCoords(RandomBaricentric(),&*fi); //Create a ray with p_c as origin and direction N p_c=p_c+NormalizedNormal(*fi)*0.1; Ray3<float> ray=Ray3<float>(p_c,fi->N()); di=0; face=0; face=f_grid.DoRay<RayTriangleIntersectionFunctor<false>,MarkerFace>(RSectFunct,markerFunctor,ray,1000,di); if(di!=0){ xi=xi+(dh/(dh-di)); } } exp=1-(xi/n_ray); eh[fi]=exp; } }
/** @def This funcion @param @param @param @return ? */ bool GenerateParticles(MeshModel* m,std::vector<CMeshO::CoordType> &cpv,/*std::vector< Particle<CMeshO> > &dpv,*/int d,float threshold){ //Handler CMeshO::PerFaceAttributeHandle<float> eh=vcg::tri::Allocator<CMeshO>::GetPerFaceAttribute<float>(m->cm,std::string("exposure")); CMeshO::FaceIterator fi; CMeshO::CoordType p; cpv.clear(); //dpv.clear(); float r=1; float a0=0; float a=0; float a1=0; for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ int n_dust=0; a1=a0+r*eh[fi]; if(a1<0) a=0; if(a1>1) a=1; if(a1>=0 && a1<=1) a=a1; if(eh[fi]==1) a=1; else a=0; n_dust=(int)d*fi->Q()*a; for(int i=0;i<n_dust;i++){ p=RandomBaricentric(); CMeshO::CoordType n_p; n_p=fi->P(0)*p[0]+fi->P(1)*p[1]+fi->P(2)*p[2]; cpv.push_back(n_p); } fi->Q()=n_dust; } return true; }
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(); }
segMesh::segMesh(MeshModel *model) : image() { CMeshO::VertexIterator vi; CMeshO::FaceIterator fi; int i = 0; double x1, y1, z1, dx, dy, dz; for(vi=model->cm.vert.begin();vi!=model->cm.vert.end();++vi) { Point3f p = vi->P(); x1 = (double)p[0]; y1 = (double)p[1]; z1 = (double)p[2]; if (!i){ minx = maxx = x1; miny = maxy = y1; minz = maxz = z1; } else { if (x1 < minx) minx = x1; if (x1 > maxx) maxx = x1; if (y1 < miny) miny = y1; if (y1 > maxy) maxy = y1; if (z1 < minz) minz = z1; if (z1 > maxz) maxz = z1; } i++; } dx = maxx - minx; dy = maxy - miny; dz = maxz - minz; norm = max(dx,max(dy,dz)); qDebug("Points: %d", i); pix = new struct point[number = w = i]; h = 1; i = 0; x = new int[number]; y = new int[number]; for(vi=model->cm.vert.begin();vi!=model->cm.vert.end();++vi) { Point3f p = vi->P(); pix[i].x = (double)p[0]; pix[i].y = (double)p[1]; pix[i].z = (double)p[2]; pix[i].n = 0; pix[i].valid = 1; pix[i].boundary = NO_BOUND; x[i] = (int)(256 * (pix[i].x - minx) / dx); y[i] = (int)(256 * (pix[i].y - miny) / dy); i++; } i = 0; const CMeshO::VertexType * v0 = &(model->cm.vert[0]); for(fi=model->cm.face.begin();fi!=model->cm.face.end();++fi) { uint a = int(fi->cV(0) - v0); uint b = int(fi->cV(1) - v0); uint c = int(fi->cV(2) - v0); add_neighbour(a,0,b); add_neighbour(a,0,c); add_neighbour(b,0,a); add_neighbour(b,0,c); add_neighbour(c,0,a); add_neighbour(c,0,b); i++; } mesh = model; qDebug("Triangles: %d", i); }