void ComputeParticlesFallsPosition(MeshModel* base_mesh,MeshModel* cloud_mesh,CMeshO::CoordType dir){ CMeshO::VertexIterator vi; MetroMeshFaceGrid f_grid; f_grid.Set(base_mesh->cm.face.begin(),base_mesh->cm.face.end()); MarkerFace markerFunctor; markerFunctor.SetMesh(&(base_mesh->cm)); RayTriangleIntersectionFunctor<false> RSectFunct; CMeshO::PerVertexAttributeHandle<Particle<CMeshO> > ph= tri::Allocator<CMeshO>::GetPerVertexAttribute<Particle<CMeshO> >(cloud_mesh->cm,"ParticleInfo"); std::vector<CMeshO::VertexPointer> ToDelVec; for(vi=cloud_mesh->cm.vert.begin();vi!=cloud_mesh->cm.vert.end();++vi){ Particle<CMeshO> info=ph[vi]; if((*vi).IsS()){ Point3f p_c=vi->P()+info.face->N().normalized()*0.1; Ray3<float> ray=Ray3<float>(p_c,dir); float di; CMeshO::FacePointer new_f=f_grid.DoRay<RayTriangleIntersectionFunctor<false>,MarkerFace>(RSectFunct,markerFunctor,ray,base_mesh->cm.bbox.Diag(),di); if(new_f!=0){ ph[vi].face=new_f; float u; float v; float t; IntersectionRayTriangle<float>(ray,new_f->P(0),new_f->P(1),new_f->P(2),t,u,v); Point3f bc(1-u-v,u,v); vi->P()=fromBarCoords(bc,new_f); vi->ClearS(); new_f->C()=Color4b::Red; }else{ ToDelVec.push_back(&*vi); } } } for(unsigned int i=0;i<ToDelVec.size();i++){ if(!ToDelVec[i]->IsD()) Allocator<CMeshO>::DeleteVertex(cloud_mesh->cm,*ToDelVec[i]); } }
/** @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; } }
void associateParticles(MeshModel* b_m,MeshModel* c_m,float &m,float &v,CMeshO::CoordType g){ MetroMeshFaceGrid unifGridFace; Point3f closestPt; CMeshO::PerVertexAttributeHandle<Particle<CMeshO> > ph= tri::Allocator<CMeshO>::AddPerVertexAttribute<Particle<CMeshO> > (c_m->cm,std::string("ParticleInfo")); unifGridFace.Set(b_m->cm.face.begin(),b_m->cm.face.end()); MarkerFace markerFunctor; markerFunctor.SetMesh(&(b_m->cm)); float dist=1; float dist_upper_bound=dist; CMeshO::VertexIterator vi; vcg::face::PointDistanceBaseFunctor<CMeshO::ScalarType> PDistFunct; for(vi=c_m->cm.vert.begin();vi!=c_m->cm.vert.end();++vi){ Particle<CMeshO>* part = new Particle<CMeshO>(); CMeshO::FacePointer f=unifGridFace.GetClosest(PDistFunct,markerFunctor,vi->P(),dist_upper_bound,dist,closestPt); part->face=f; part->face->Q()=part->face->Q()+1; part->mass=m; part->velocity=v; part->v=getVelocityComponent(v,f,g); ph[vi]=*part; } }
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(); }