From 556bc2a07e919267da7175c3e2b831a077bf33e3 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Fri, 27 May 2011 00:34:11 +0000 Subject: [PATCH] Code Cleaning and Commenting Implementation of functions in dirt_utils.h moved to dirt_utils.cpp Added velocity vector to Structure particle.h Better handled Particle Vector information in move particle some warnings removed useless functions removed various bug fixes --- src/fgt/filter_dirt/dirt_utils.h | 688 ++-------------------------- src/fgt/filter_dirt/filter_dirt.cpp | 158 +++---- src/fgt/filter_dirt/filter_dirt.h | 54 +-- src/fgt/filter_dirt/filter_dirt.pro | 2 +- src/fgt/filter_dirt/particle.h | 25 +- 5 files changed, 145 insertions(+), 782 deletions(-) diff --git a/src/fgt/filter_dirt/dirt_utils.h b/src/fgt/filter_dirt/dirt_utils.h index 38129997d..c1a7da5d1 100644 --- a/src/fgt/filter_dirt/dirt_utils.h +++ b/src/fgt/filter_dirt/dirt_utils.h @@ -60,7 +60,6 @@ using namespace vcg; using namespace tri; - typedef GridStaticPtr MetroMeshFaceGrid; typedef GridStaticPtr MetroMeshVertexGrid; typedef FaceTmark MarkerFace; @@ -70,667 +69,34 @@ typedef FaceTmark MarkerFace; -/** -*/ - -bool CheckFallPosition(CMeshO::FacePointer f,Point3f g,float a){ - Point3f n=f->N(); - if(a>1) return false; - if(acos(n.dot(g)/(n.Norm()*g.Norm()))<((PI/2)*(1-a))) return true; - return false; -}; - -float GetElapsedTime(CMeshO::CoordType p1,CMeshO::CoordType p2, CMeshO::CoordType p3, float t,float l){ - float d1= Distance(p1,p2); - float d2= Distance(p2,p3); - if(d1+d2==0) return 0; - //float remainig_time= - return (d1/(d1+d2))*t; -}; - -void ComputeParticlesVelocityAndTime(CMeshO::CoordType o_p,CMeshO::CoordType n_p,CMeshO::FacePointer f,CMeshO::CoordType dir,float l,float m,float o_v,float &t,float &n_v){ - - Point3f n=f->N(); - float b=n[0]*dir[0]+n[1]*dir[1]+n[2]*dir[2]; - float distance=Distance(o_p,n_p); - Point3f force; - force[0]=dir[0]-b*n[0]; - force[1]=dir[1]-b*n[1]; - force[2]=dir[2]-b*n[2]; - if(force.Norm()==0){ - t=1; - n_v=0; - return; - } - float acceleration=(force/m).Norm(); - float velocity=math::Sqrt(pow(o_v,2)+(2*acceleration*distance)); - float time; - time=(velocity-o_v)/acceleration; - - t=time; - n_v=velocity; -}; - -/** -@def Generate random barycentric coordinates - -@return a triple of barycentric coordinates -*/ -CMeshO::CoordType RandomBaricentric(){ - - CMeshO::CoordType interp; - static math::MarsenneTwisterRNG rnd; - interp[1] = rnd.generate01(); - interp[2] = rnd.generate01(); - - if(interp[1] + interp[2] > 1.0){ - interp[1] = 1.0 - interp[1]; - interp[2] = 1.0 - interp[2]; - } - - assert(interp[1] + interp[2] <= 1.0); - interp[0]=1.0-(interp[1] + interp[2]); - return interp; -}; -/** -@def This funcion calculate the cartesian coordinates of a point given from its barycentric coordinates - -@param Point3f bc - barycentric coordinates of the point -@param FacePointer f - pointer to the face - -@return cartesian coordinates of the point -*/ - -CMeshO::CoordType fromBarCoords(Point3f bc,CMeshO::FacePointer f){ - - CMeshO::CoordType p; - Point3f p0=f->P(0); - Point3f p1=f->P(1); - Point3f p2=f->P(2); - p=f->P(0)*bc[0]+f->P(1)*bc[1]+f->P(2)*bc[2]; - return p; -}; - -CMeshO::CoordType getBaricenter(CMeshO::FacePointer f){ - Point3f bc; - bc[0]=0.33f; - bc[1]=0.33f; - bc[2]=1-bc[0]-bc[1]; - CMeshO::CoordType pc=fromBarCoords(bc,f); - return pc; -}; - -/** -@def Given a Face and a point that lies on a edge of that face return a position slightly more internal to avoid -@param FacePointer f - a pointer to the face -@param int e - index of an edge - -@return a point in the face f near the edge e -*/ - -CMeshO::CoordType GetSafePosition(CMeshO::CoordType p,CMeshO::FacePointer f){ - CMeshO::CoordType safe_p; - Point3f bc; - bc[0]=0.33f; - bc[1]=0.33f; - bc[2]=1-bc[0]-bc[1]; - CMeshO::CoordType pc=fromBarCoords(bc,f); - Ray3 ray=Ray3(p,pc); - ray.Normalize(); - Line3f line; - Point3f p1=pc-p; - safe_p=p+p1*0.02; - return safe_p; -}; - - -/** -@def Verify if a point lies on a face - -@param Point3f p - Coordinates of the point -@param FacePointer f - Pointer to the face - -@return true if point p is on face f, false elsewhere. -*/ -bool IsOnFace(Point3f p, CMeshO::FacePointer f){ - //Compute vectors - Point3f a=f->V(0)->P(); - Point3f b=f->V(2)->P(); - Point3f c=f->V(1)->P(); - - - Point3f v0 = c-a; - Point3f v1 = b-a; - Point3f v2 = p-a; - - // Compute dot products - float dot00 = v0.dot(v0); - float dot01 = v0.dot(v1); - float dot02 = v0.dot(v2); - float dot11 = v1.dot(v1); - float dot12 = v1.dot(v2); - - // Compute barycentric coordinates - float invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - float u = (dot11 * dot02 - dot01 * dot12) * invDenom; - float v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - // Check if point is in triangle - if(math::Abs(u)<0) u=0; - if(math::Abs(v)<0) v=0; - return (u >= 0) && (v >= 0) && (u + v <=1); -}; -/** -@def Simulate the movement of a point, affected by a force "dir" on a face. - -@param CoordType p - coordinates of the point -@param CoordType v - velocity of the particle -@param float m - mass of the particle -@param FaceType face - pointer to the face -@param CoordType dir - direction of the force -@param float l - length of the movement -@param float t - time step - -@return new coordinates of the point -*/ -CMeshO::CoordType StepForward(CMeshO::CoordType p,float v,float m,CMeshO::FacePointer &face,CMeshO::CoordType dir,float l,float t=1){ - Point3f new_pos; - Point3f n= face->N(); - float a=n[0]*dir[0]+n[1]*dir[1]+n[2]*dir[2]; - - Point3f f; - Point3f vel; - //Compute force component along the face - f[0]=dir[0]-a*n[0]; - f[1]=dir[1]-a*n[1]; - f[2]=dir[2]-a*n[2]; - - if(f.Norm()!=0){ - vel=f/f.Norm(); - vel=vel*v; - }else{ - vel[0]=0; - vel[1]=0; - vel[2]=0; - } - new_pos=p+(vel*t+(f/m)*pow(t,2)*0.5)*l; - return new_pos; -}; - -void DrawDust(MeshModel *base_mesh,MeshModel *cloud_mesh){ - if(base_mesh->cm.HasPerWedgeTexCoord() && base_mesh->cm.textures.size()>0){ - QImage img; - QFileInfo text_file=QFileInfo(base_mesh->cm.textures[0].c_str()); - img.load(base_mesh->cm.textures[0].c_str()); - QPainter painter(&img); - float w=img.width(); - float h=img.height(); - painter.setPen(Qt::black); - painter.setBrush(Qt::SolidPattern); - base_mesh->updateDataMask(MeshModel::MM_WEDGTEXCOORD); - CMeshO::PerVertexAttributeHandle > ph= tri::Allocator::GetPerVertexAttribute > (cloud_mesh->cm,std::string("ParticleInfo")); - CMeshO::VertexIterator vi; - for(vi=cloud_mesh->cm.vert.begin();vi!=cloud_mesh->cm.vert.end();++vi){ - CMeshO::FacePointer f=ph[vi].face; - TexCoord2f t0=f->WT(0); - TexCoord2f t1=f->WT(1); - TexCoord2f t2=f->WT(2); - Point2f p0=Point2f(t0.U()*w,h-t0.V()*h); - Point2f p1=Point2f(t1.U()*w,h-t1.V()*h); - Point2f p2=Point2f(t2.U()*w,h-t2.V()*h); - Point3f bc; - Point2f dbc; - InterpolationParameters(*f,vi->P(),bc); - dbc=p0*bc[0]+p1*bc[1]+p2*bc[2]; - painter.drawPoint(dbc[0],dbc[1]); - } - QString path=QDir::currentPath()+"/dirt_texture.png"; - img.save(path,"PNG"); - base_mesh->cm.textures.clear(); - base_mesh->cm.textures.push_back(path.toStdString()); - } -}; - - -void ColorizeMesh(MeshModel* m){ - CMeshO::FaceIterator fi; - float color; - 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::VertexFromFace(m->cm); -}; - - -/** -@def Compute the intersection of the segment from p1 to p2 and the face f - -@param CoordType p1 - position of the first point -@param Coordtype p2 - position of the second poin -@param Facepointer f - pointer to the face -@param CoordType int_point - intersection point this is a return parameter for the function. -@param FacePointer face - pointer to the new face - -@return the intersection edge index if there is an intersection -1 elsewhere -Step -*/ -int ComputeIntersection(CMeshO::CoordType p1,CMeshO::CoordType p2,CMeshO::FacePointer &f,CMeshO::FacePointer &new_f,CMeshO::CoordType &int_point){ - - CMeshO::CoordType v0=f->V(0)->P(); - CMeshO::CoordType v1=f->V(1)->P(); - CMeshO::CoordType v2=f->V(2)->P(); - float dist[3]; - Point3f int_points[3]; - dist[0]=PSDist(p2,v0,v1,int_points[0]); - dist[1]=PSDist(p2,v1,v2,int_points[1]); - dist[2]=PSDist(p2,v2,v0,int_points[2]); - int edge=-1; - if(dist[0]V(edge)->P())V((edge+1) % 3)->P())) v=f->V(edge); - else v=f->V((edge+1) % 3); - vcg::face::Pos p(f,edge,v); - new_f=f->FFp(edge); - if(new_f==f) return -1; - - if(Distance(int_points[edge],v->P())cm.face.begin();fi!=m->cm.face.end();++fi){ - d=k/s+(1+k/s)*pow(fi->N().dot(u),s); - fi->Q()=d; - } -}; - -/** -@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 eh=vcg::tri::Allocator::AddPerFaceAttribute(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 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 ray=Ray3(p_c,fi->N()); - di=0; - face=0; - face=f_grid.DoRay,MarkerFace>(RSectFunct,markerFunctor,ray,1000,di); - - if(di!=0){ - xi=xi+(dh/(dh-di)); - - } - } - exp=1-(xi/n_ray); - eh[fi]=exp; - - } -}; - - -void ComputeParticlesFallsPosition(MeshModel* cloud_mesh,MeshModel* base_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 RSectFunct; - CMeshO::PerVertexAttributeHandle > ph= tri::Allocator::GetPerVertexAttribute >(cloud_mesh->cm,"ParticleInfo"); - std::vector ToDelVec; - for(vi=cloud_mesh->cm.vert.begin();vi!=cloud_mesh->cm.vert.end();++vi){ - Particle info=ph[vi]; - if((*vi).IsS()){ - Point3f p_c=vi->P()+info.face->N().normalized()*0.1; - Ray3 ray=Ray3(p_c,dir); - float di; - CMeshO::FacePointer new_f=f_grid.DoRay,MarkerFace>(RSectFunct,markerFunctor,ray,base_mesh->cm.bbox.Diag(),di); - if(new_f!=0){ - ph[vi].face=new_f; - float min_dist; - Point3f prj; - vcg::Triangle3 triangle(new_f->P(0),new_f->P(1),new_f->P(2)); - float dist; - float u; - float v; - float t; - IntersectionRayTriangle(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(int i=0;iIsD()) Allocator::DeleteVertex(cloud_mesh->cm,*ToDelVec[i]); - } -}; - - - -/** -@def This funcion - -@param -@param -@param - -@return ? -*/ -bool GenerateParticles(MeshModel* m,std::vector &cpv,/*std::vector< Particle > &dpv,*/int d,float threshold){ - - //Handler - CMeshO::PerFaceAttributeHandle eh=vcg::tri::Allocator::GetPerFaceAttribute(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; - int n_dust=0; - - for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ - 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;iP(0)*p[0]+fi->P(1)*p[1]+fi->P(2)*p[2]; - cpv.push_back(n_p); - /*Particle part; - part.face=&(*fi); - part.bar_coord=p; - dpv.push_back(part); - */ - } - - fi->Q()=n_dust; - - } - - - return true; -}; - - -/** - -*/ -void associateParticles(MeshModel* b_m,MeshModel* c_m,float &m,float &v){ - MetroMeshFaceGrid unifGridFace; - Point3f closestPt; - CMeshO::PerVertexAttributeHandle > ph= tri::Allocator::AddPerVertexAttribute > (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 PDistFunct; - for(vi=c_m->cm.vert.begin();vi!=c_m->cm.vert.end();++vi){ - Particle* part = new Particle(); - part->face=unifGridFace.GetClosest(PDistFunct,markerFunctor,vi->P(),dist_upper_bound,dist,closestPt); - part->face->Q()=part->face->Q()+1; - part->mass=m; - part->velocity=v; - ph[vi]=*part; - } - -}; - - -/** -@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::CompactFaceVector(m->cm); - tri::Clean::RemoveUnreferencedVertex(m->cm); - tri::Clean::RemoveDuplicateVertex(m->cm); - tri::Allocator::CompactVertexVector(m->cm); - - tri::UpdateFlags::FaceClear(m->cm); - //update Mesh - m->cm.vert.EnableVFAdjacency(); - m->cm.face.EnableVFAdjacency(); - tri::UpdateTopology::FaceFace(m->cm); - tri::UpdateTopology::VertexFace(m->cm); - tri::UpdateNormals::PerFaceNormalized(m->cm); - tri::UpdateFlags::FaceProjection(m->cm); - - CMeshO::FaceIterator fi; - for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){ - fi->Q()=0; - } -}; - -/** -@def This function move a particle over the mesh -*/ -void MoveParticle(Particle &info,CMeshO::VertexPointer p,float l,int t,Point3f dir,Point3f g,float a){ - if(CheckFallPosition(info.face,g,a)){ - p->SetS(); - return; - } - float time=t; - - Point3f new_pos; - Point3f current_pos; - Point3f int_pos; - CMeshO::FacePointer current_face=info.face; - CMeshO::FacePointer new_face; - new_face=current_face; - current_pos=p->P(); - new_pos=StepForward(current_pos,info.velocity,info.mass,current_face,g+dir,l,time); - while(!IsOnFace(new_pos,current_face)){ - int edge=ComputeIntersection(current_pos,new_pos,current_face,new_face,int_pos); - if(edge!=-1){ - Point3f n = new_face->N(); - if(CheckFallPosition(new_face,g,a)) p->SetS(); - float new_velocity=0; - //ComputeParticlesVelocityAndTime(current_pos,int_pos,info.face,dir,l,info.mass,info.velocity,elapsed_time,new_velocity); - info.velocity=new_velocity; - float elapsed_time=GetElapsedTime(current_pos,int_pos,new_pos,time,l); - time=time-elapsed_time; - current_pos=int_pos; - current_face->Q()+=elapsed_time*5; - current_face=new_face; - new_pos=int_pos; - if(time>0){ - if(p->IsS()) break; - new_pos=StepForward(current_pos,info.velocity,info.mass,current_face,g+dir,l,time); - } - current_face->C()=Color4b::Green;//Just Debug!!!! - }else{ - //We are on a border - new_pos=int_pos; - current_face=new_face; - p->SetS(); - break; - } - } - //current_face->Q()+=1; - //Point3f n = ->N(); - //if(acos(n.dot(dir)/(n.Norm()*dir.Norm()))<(m_angle)) p->SetS(); - //float new_velocity; - //float elapsed_time; - //ComputeParticlesVelocityAndTime(current_pos,int_pos,info.face,dir,l,info.mass,info.velocity,elapsed_time,new_velocity); - //current_face->Q()=current_face->Q()+1; - p->P()=new_pos; - //info.velocity=new_velocity; - info.face=current_face; -}; - - - - -/** -@def This function compute the repulsion beetwen particles - -@param MeshModel* c_m - cloud of points -@param int k - max number of particle to repulse - -@return nothing -*/ -void ComputeRepulsion(MeshModel* b_m,MeshModel *c_m,int k,float l,Point3f g,float a){ - CMeshO::PerVertexAttributeHandle > ph = Allocator::GetPerVertexAttribute >(c_m->cm,"ParticleInfo"); - MetroMeshVertexGrid v_grid; - std::vector> v_points; - std::vector vp; - std::vector distances; - - v_grid.Set(c_m->cm.vert.begin(),c_m->cm.vert.end(),b_m->cm.bbox); - - Point3f bc ; - CMeshO::VertexIterator vi; - - for(vi=c_m->cm.vert.begin();vi!=c_m->cm.vert.end();++vi){ - vcg::tri::GetKClosestVertex(c_m->cm,v_grid,k,vi->P(),EPSILON,vp,distances,v_points); - for(int i=0;iP()!=vi->P() && !v->IsD() && !vi->IsD()){ - Ray3 ray(vi->P(),fromBarCoords(RandomBaricentric(),ph[vp[i]].face)); - ray.Normalize(); - Point3f dir=ray.Direction(); - dir.Normalize(); - MoveParticle(ph[vp[i]],vp[i],0.01,1,dir,g,a); - } - } - } - - }; - - -/** -@def This function simulate the movement of the cloud mesh, it requires that every point is associated with a Particle data structure - -@param MeshModel cloud - Mesh of points -@param Point3f force - Direction of the force -@param float l - Lenght of the movementstep -@param float t - Time Step - -@return nothing -*/ -void MoveCloudMeshForward(MeshModel *cloud,MeshModel *base,Point3f g,Point3f force,float l,float a,float t,int r_step){ - - CMeshO::PerVertexAttributeHandle > ph = Allocator::GetPerVertexAttribute >(cloud->cm,"ParticleInfo"); - CMeshO::VertexIterator vi; - for(vi=cloud->cm.vert.begin();vi!=cloud->cm.vert.end();++vi) - if(!vi->IsD()) MoveParticle(ph[vi],&*vi,l,t,force,g,a); - - - //Handle falls Particle - ComputeParticlesFallsPosition(cloud,base,g); - //Compute Particles Repulsion - for(int i=0;i &cpv,int d,float threshold); + + +void ColorizeMesh(MeshModel* m); +void DrawDust(MeshModel *base_mesh,MeshModel *cloud_mesh); +void ComputeNormalDustAmount(MeshModel* m,CMeshO::CoordType u,float k,float s); +void ComputeSurfaceExposure(MeshModel* m,int r,int n_ray); +void ComputeParticlesFallsPosition(MeshModel* cloud_mesh,MeshModel* base_mesh,CMeshO::CoordType dir); +void associateParticles(MeshModel* b_m,MeshModel* c_m,float &m,float &v,CMeshO::CoordType g); +void prepareMesh(MeshModel* m); +void MoveParticle(Particle &info,CMeshO::VertexPointer p,float l,int t,Point3f dir,Point3f g,float a); +void ComputeRepulsion(MeshModel* b_m,MeshModel *c_m,int k,float l,Point3f g,float a); +void MoveCloudMeshForward(MeshModel *cloud,MeshModel *base,Point3f g,Point3f force,float l,float a,float t,int r_step); #endif // DIRT_UTILS_H diff --git a/src/fgt/filter_dirt/filter_dirt.cpp b/src/fgt/filter_dirt/filter_dirt.cpp index 393393c15..2581298ce 100644 --- a/src/fgt/filter_dirt/filter_dirt.cpp +++ b/src/fgt/filter_dirt/filter_dirt.cpp @@ -70,16 +70,16 @@ QString FilterDirt::filterName(FilterIDType filterId) const case FP_DIRT:{ return QString("Dust Accumulation"); break; - } + } case FP_CLOUD_MOVEMENT: - { + { return QString("Points Cloud Movement"); break; - } + } default:{ assert(0); return QString("error"); break; - } + } } } @@ -87,13 +87,13 @@ QString FilterDirt::filterInfo(FilterIDType filterId) const { switch (filterId) { case FP_DIRT:{ - return QString("Simulate dust accumulation over the mesh"); - break; - } + return QString("Simulate dust accumulation over the mesh generating a cloud of points lying on the current mesh"); + break; + } case FP_CLOUD_MOVEMENT:{ - return QString("Simulate the movement of a points cloud over a mesh"); - break; - } + return QString("Simulate the movement of a points cloud over a mesh"); + break; + } default: assert(0); return QString("error"); break; @@ -102,30 +102,30 @@ QString FilterDirt::filterInfo(FilterIDType filterId) const void FilterDirt::initParameterSet(QAction* filter,MeshDocument &md, RichParameterSet &par){ - switch(ID(filter)){ + switch(ID(filter)){ case FP_DIRT:{ - par.addParam(new RichPoint3f("dust_dir",Point3f(0,1,0),"Direction","Direction of the dust source")); - par.addParam(new RichInt("nparticles",3,"particles","Max Number of Dust Particles to Generate Per Face")); - par.addParam(new RichFloat("slippiness",1,"s","The surface slippines")); - par.addParam(new RichFloat("adhesion",0.2,"k","Factor to model the general adhesion")); - par.addParam(new RichBool("draw_texture",false,"Draw Dust","")); - par.addParam(new RichBool("colorize_mesh",false,"Map to Color","")); - break; - } + par.addParam(new RichPoint3f("dust_dir",Point3f(0,1,0),"Direction","Direction of the dust source")); + par.addParam(new RichInt("nparticles",3,"max particles x face","Max Number of Dust Particles to Generate Per Face")); + par.addParam(new RichFloat("slippiness",1,"s","The surface slippines(large s means less sticky)")); + par.addParam(new RichFloat("adhesion",0.2,"k","Factor to model the general adhesion")); + par.addParam(new RichBool("draw_texture",false,"Draw Dust","create a new texture saved in dirt_texture.png")); + // par.addParam(new RichBool("colorize_mesh",false,"Map to Color","Color the mesh with colors based on the movement of the particle")); + break; + } case FP_CLOUD_MOVEMENT:{ - par.addParam(new RichPoint3f("gravity_dir",Point3f(0,-1,0),"g","Direction of gravity")); - par.addParam(new RichPoint3f("force_dir",Point3f(0,0,0),"Force","Direction of the force acting on the points cloud")); - par.addParam(new RichInt("steps",1,"s","Simulation Steps")); - par.addParam(new RichDynamicFloat("adhesion", 1.0f, 0.0f, 1.0f,"Adhesion","Factor to model the general adhesion.")); - par.addParam(new RichFloat("velocity",0,"v","Initial velocity of the particle")); - par.addParam(new RichFloat("mass",1,"m","Mass of the particle")); - par.addParam(new RichBool("colorize_mesh",false,"Map to Color","")); - break; - } + par.addParam(new RichPoint3f("gravity_dir",Point3f(0,-1,0),"g","Direction of gravity")); + par.addParam(new RichPoint3f("force_dir",Point3f(0,0,0),"force","Direction of the force acting on the points cloud")); + par.addParam(new RichInt("steps",1,"s","Simulation Steps")); + par.addParam(new RichDynamicFloat("adhesion", 1.0f, 0.0f, 1.0f,"adhesion","Factor to model the general adhesion.")); + par.addParam(new RichFloat("velocity",0,"v","Initial velocity of the particle")); + par.addParam(new RichFloat("mass",1,"m","Mass of the particle")); + par.addParam(new RichBool("colorize_mesh",false,"Map to Color","Color the mesh with colors based on the movement of the particle")); + break; + } default:{ break; - } + } } } @@ -141,18 +141,19 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet case FP_DIRT:{ /*Get Parameters*/ + Point3f dir=par.getPoint3f("dust_dir"); float s=par.getFloat("slippiness"); float k=par.getFloat("adhesion"); bool draw=par.getBool("draw_texture"); - bool colorize=par.getBool("colorize_mesh"); + //bool colorize=par.getBool("colorize_mesh"); int n_p=par.getInt("nparticles"); MeshModel* currMM=md.mm(); if (currMM->cm.fn==0) { - errorMessage = "This filter requires a mesh with some faces, it does not work on PointSet"; - return false; + errorMessage = "This filter requires a mesh with some faces, it does not work on PointSet"; + return false; } if(draw && !currMM->cm.HasPerWedgeTexCoord()){ @@ -161,42 +162,41 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet } - vector dust_points; - vector > dust_particles; - + vector dust_points; prepareMesh(currMM); - ComputeNormalDustAmount(currMM,dir,k,s); - ComputeSurfaceExposure(currMM,1,1); - GenerateParticles(currMM,dust_points,/*dust_particles,*/n_p,0.6); + if(cb) (*cb)(10,"Computing Dust Amount..."); + ComputeNormalDustAmount(currMM,dir,k,s); + if(cb) (*cb)(30,"Computing Mesh Exposure..."); + + ComputeSurfaceExposure(currMM,1,1); + + if(cb) (*cb)(50,"Generating Particles..."); + + GenerateParticles(currMM,dust_points,/*dust_particles,*/n_p,0.6); MeshModel* dmm=md.addNewMesh("","dust_mesh"); dmm->cm.Clear(); - tri::Allocator::AddVertices(dmm->cm,dust_points.size()); - //CMeshO::PerVertexAttributeHandle > ph= tri::Allocator::AddPerVertexAttribute > (dmm->cm,std::string("ParticleInfo")); CMeshO::VertexIterator vi; vector::iterator dvi=dust_points.begin(); - //std::vector< Particle >::iterator dpi=dust_particles.begin(); - + if(cb) (*cb)(70,"Creating cloud Mesh..."); for(vi=dmm->cm.vert.begin();vi!=dmm->cm.vert.end();++vi){ vi->P()=(*dvi); - // ph[vi]=(*dpi); ++dvi; - // ++dpi; } if(draw) DrawDust(currMM,dmm); - if(colorize) ColorizeMesh(currMM); + //if(colorize) ColorizeMesh(currMM); + - break; - } + } case FP_CLOUD_MOVEMENT:{ - if(md.size()!=2){ - errorMessage="This filter requires two mesh"; - return false; - } + if(md.size()!=2){ + errorMessage="This filter requires two mesh"; + return false; + } MeshModel* base_mesh=md.getMesh(0); if(base_mesh->cm.fn==0){ @@ -209,40 +209,40 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet errorMessage="The filter requires that the second mesh is a Point Set"; return false; } - - //Get Parameters + + //Get Parameters Point3f dir=par.getPoint3f("force_dir"); Point3f g=par.getPoint3f("gravity_dir"); - float adhesion =par.getDynamicFloat("adhesion"); - float l=base_mesh->cm.bbox.Diag()*0.01; //mm()->cm.bbox.Diag(); - float v=par.getFloat("velocity"); + float adhesion =par.getDynamicFloat("adhesion"); + float l=base_mesh->cm.bbox.Diag()*0.01; //mm()->cm.bbox.Diag(); + float v=par.getFloat("velocity"); float m=par.getFloat("mass"); - int s=par.getInt("steps"); - bool colorize=par.getBool("colorize_mesh"); + int s=par.getInt("steps"); + bool colorize=par.getBool("colorize_mesh"); if(!HasPerVertexAttribute(cloud_mesh->cm,"ParticleInfo")){ - prepareMesh(base_mesh); + prepareMesh(base_mesh); //Associate every point to a mesh and a Particle to every point - associateParticles(base_mesh,cloud_mesh,m,v); + associateParticles(base_mesh,cloud_mesh,m,v,g); } - - //Move Cloud Mesh + + //Move Cloud Mesh float frac=100/s; - for(int i=0;i v_attrNames; - std::vector v_attrValue; - //std::vector f_attrNames; - //std:: vector f_attrValue; - std::vector > vhandlers; - //std::vector > fhandlers; + Q_OBJECT + Q_INTERFACES(MeshFilterInterface) +protected: + double x,y,z,nx,ny,nz,r,g,b,q,rad; + //double x0,y0,z0,x1,y1,z1,x2,y2,z2,nx0,ny0,nz0,nx1,ny1,nz1,nx2,ny2,nz2,r0,g0,b0,r1,g1,b1,r2,g2,b2,q0,q1,q2; + double v,f,v0i,v1i,v2i; + std::vector v_attrNames; + std::vector v_attrValue; + //std::vector f_attrNames; + //std:: vector f_attrValue; + std::vector > vhandlers; + //std::vector > fhandlers; - public: - enum {FP_DIRT,FP_CLOUD_MOVEMENT} ; - - FilterDirt(); - ~FilterDirt(){}; +public: + enum {FP_DIRT,FP_CLOUD_MOVEMENT} ; - virtual QString filterName(FilterIDType filter) const; - virtual QString filterInfo(FilterIDType filter) const; - virtual int getRequirements(QAction *); - virtual bool autoDialog(QAction *) {return true;} - virtual void initParameterSet(QAction* filter,MeshModel &,RichParameterSet &){}; - virtual void initParameterSet(QAction *,MeshDocument &/*m*/, RichParameterSet & /*parent*/); - virtual bool applyFilter(QAction* filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb); - virtual bool applyFilter(QAction * /*filter */, MeshModel &, RichParameterSet & /*parent*/, vcg::CallBackPos *) { assert(0); return false;} ; - virtual int postCondition(QAction*) const; - virtual FilterClass getClass(QAction *); + FilterDirt(); + ~FilterDirt(){}; + + virtual QString filterName(FilterIDType filter) const; + virtual QString filterInfo(FilterIDType filter) const; + virtual int getRequirements(QAction *); + virtual bool autoDialog(QAction *) {return true;} + // virtual void initParameterSet(QAction* filter,MeshModel &,RichParameterSet &){}; + virtual void initParameterSet(QAction *,MeshDocument &/*m*/, RichParameterSet & /*parent*/); + virtual bool applyFilter(QAction* filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb); + virtual bool applyFilter(QAction * /*filter */, MeshModel &, RichParameterSet & /*parent*/, vcg::CallBackPos *) { assert(0); return false;} ; + virtual int postCondition(QAction*) const; + virtual FilterClass getClass(QAction *); }; diff --git a/src/fgt/filter_dirt/filter_dirt.pro b/src/fgt/filter_dirt/filter_dirt.pro index c6387961e..784c4b0fb 100644 --- a/src/fgt/filter_dirt/filter_dirt.pro +++ b/src/fgt/filter_dirt/filter_dirt.pro @@ -5,5 +5,5 @@ HEADERS = filter_dirt.h \ dirt_utils.h \ $$VCGDIR/vcg/complex/trimesh/point_sampling.h -SOURCES = filter_dirt.cpp +SOURCES = filter_dirt.cpp dirt_utils.cpp TARGET = filter_dirt diff --git a/src/fgt/filter_dirt/particle.h b/src/fgt/filter_dirt/particle.h index 22d426412..f2874a5ec 100644 --- a/src/fgt/filter_dirt/particle.h +++ b/src/fgt/filter_dirt/particle.h @@ -40,14 +40,14 @@ class Particle{ public: Particle(){ - mass=1.0f; - velocity=0; - face=0; + mass=1.0f; + velocity=0; + face=0; } Particle(float m,float v){ - mass=m; - vel=v; + mass=m; + velocity=v; } ~Particle(){ @@ -55,15 +55,12 @@ public: } public: - FacePointer face; - CoordType bar_coord;/*To delete?*/ - float mass; - //CoordType velocity; - float velocity; - //float velocity; - float ad_coeff;/*Adhesion Coefficient*/ - // Position History - //std::vector pos_his; + FacePointer face; + CoordType bar_coord;/*To delete?*/ + float mass; + float velocity; + float ad_coeff;/*Adhesion Coefficient*/ + CoordType v; };