Пример #1
0
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]);
    }
}
Пример #2
0
void DrawDust(MeshModel *base_mesh,MeshModel *cloud_mesh){
    if(tri::HasPerWedgeTexCoord(base_mesh->cm) && 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<Particle<CMeshO> > ph= tri::Allocator<CMeshO>::GetPerVertexAttribute<Particle<CMeshO> > (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());
    }
}
Пример #3
0
/**
This function compute the repulsion beetwen particles
@param MeshModel* b_m - base mesh
@param MeshModel* c_m - cloud of points
@param int k          - max number of particle to repulse
@param float l        - lenght of the step
@return nothing       - adhesion factor
*/
void ComputeRepulsion(MeshModel* b_m,MeshModel *c_m,int k,float l,Point3f g,float a){
    CMeshO::PerVertexAttributeHandle<Particle<CMeshO> > ph = Allocator<CMeshO>::GetPerVertexAttribute<Particle<CMeshO> >(c_m->cm,"ParticleInfo");
    MetroMeshVertexGrid v_grid;
    std::vector< Point3<float> > v_points;
    std::vector<CMeshO::VertexPointer> vp;
    std::vector<float> distances;
    v_grid.Set(c_m->cm.vert.begin(),c_m->cm.vert.end(),b_m->cm.bbox);
    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(unsigned int i=0;i<vp.size();i++){CMeshO::VertexPointer v = vp[i];
            if(v->P()!=vi->P() && !v->IsD() && !vi->IsD()){
                Ray3<float> 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);
            }
        }
    }
}
Пример #4
0
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;
    }

}
Пример #5
0
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();
  }
Пример #6
0
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);  
}
Пример #7
0
// The Real Core Function doing the actual mesh processing.
bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/)
{
    MeshModel* m=md.addNewMesh("",this->filterName(ID(filter)));
  switch(ID(filter))	 {
    case CR_TETRAHEDRON :
      vcg::tri::Tetrahedron<CMeshO>(m->cm);
      break;
    case CR_ICOSAHEDRON:
      vcg::tri::Icosahedron<CMeshO>(m->cm);
      break;
    case CR_DODECAHEDRON:
      vcg::tri::Dodecahedron<CMeshO>(m->cm);
      m->updateDataMask(MeshModel::MM_POLYGONAL);
      break;
    case CR_OCTAHEDRON:
      vcg::tri::Octahedron<CMeshO>(m->cm);
      break;
    case CR_TORUS:
    {
      float hRadius=par.getFloat("hRadius");
      float vRadius=par.getFloat("vRadius");
      int hSubdiv=par.getInt("hSubdiv");
      int vSubdiv=par.getInt("vSubdiv");
      vcg::tri::Torus(m->cm,hRadius,vRadius,hSubdiv,vSubdiv);
        break;
    }
  case CR_RANDOM_SPHERE:
    {
    CMeshO tt;

    int pointNum = par.getInt("pointNum");
    int oversamplingFactor =100;
    if(pointNum <= 100) oversamplingFactor = 1000;
    if(pointNum >= 10000) oversamplingFactor = 50;
    if(pointNum >= 100000) oversamplingFactor = 20;

    vcg::math::MarsenneTwisterRNG rng;
    vcg::tri::Allocator<CMeshO>::AddVertices(tt,pointNum*50);
    for(CMeshO::VertexIterator vi=tt.vert.begin();vi!=tt.vert.end();++vi)
      vcg::math::GeneratePointOnUnitSphereUniform(rng,vi->P());
    vcg::tri::UpdateBounding<CMeshO>::Box(tt);

    const float SphereArea = 4*M_PI;
    float poissonRadius = 2.0*sqrt((SphereArea / float(pointNum*2))/M_PI);

    std::vector<vcg::Point3f> poissonSamples;
    vcg::tri::TrivialSampler<CMeshO> pdSampler(poissonSamples);
    vcg::tri::SurfaceSampling<CMeshO, vcg::tri::TrivialSampler<CMeshO> >::PoissonDiskParam pp;

    vcg::tri::SurfaceSampling<CMeshO,vcg::tri::TrivialSampler<CMeshO> >::PoissonDiskPruning(pdSampler, tt, poissonRadius, pp);
    m->cm.Clear();
    vcg::tri::Allocator<CMeshO>::AddVertices(m->cm,poissonSamples.size());
    for(size_t i=0;i<poissonSamples.size();++i)
    {
      m->cm.vert[i].P()=poissonSamples[i];
      m->cm.vert[i].N()=m->cm.vert[i].P();
    }
  } break;

  case CR_SPHERE:
    {
        int rec = par.getInt("subdiv");
        float radius = par.getFloat("radius");
        m->cm.face.EnableFFAdjacency();
        m->updateDataMask(MeshModel::MM_FACEFACETOPO);
        assert(vcg::tri::HasPerVertexTexCoord(m->cm) == false);
        vcg::tri::Sphere<CMeshO>(m->cm,rec);

		for(CMeshO::VertexIterator vi = m->cm.vert.begin();vi!= m->cm.vert.end();++vi)
		  vi->P()=vi->P()*radius;

		break;
	}
	case CR_BOX:
	{
	  float sz=par.getFloat("size");
	  vcg::Box3f b(vcg::Point3f(1,1,1)*(sz/2),vcg::Point3f(1,1,1)*(-sz/2));
	  vcg::tri::Box<CMeshO>(m->cm,b);
			m->updateDataMask(MeshModel::MM_POLYGONAL);

      break;
    }
    case CR_CONE:
      float r0=par.getFloat("r0");
      float r1=par.getFloat("r1");
      float h=par.getFloat("h");
      int subdiv=par.getInt("subdiv");
      vcg::tri::Cone<CMeshO>(m->cm,r0,r1,h,subdiv);
      break;
   }
     vcg::tri::UpdateBounding<CMeshO>::Box(m->cm);
   vcg::tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFaceNormalized(m->cm);
    return true;
}