Beispiel #1
0
int main(int ,char ** ){

	MyMesh m;

	//generate a mesh
	vcg::tri::Icosahedron(m);

	//update the face-face topology 
	vcg::tri::UpdateTopology<MyMesh>::FaceFace(m);

  // Now for each face the F() members are meaningful
  
  if(face::IsBorder(m.face[0],0)) printf("Edge 0 of face 0 is a border\n");
                       else printf("Edge 0 of face 0 is NOT a border\n"); // always this path!

  vcg::face::FFDetach<MyFace>(m.face[0],0);  // Detach the face [0] from the mesh
  vcg::face::FFDetach<MyFace>(m.face[0],1);
  vcg::face::FFDetach<MyFace>(m.face[0],2);

  if(face::IsBorder(m.face[0],0)) printf("Edge 0 of face 0 is a border\n"); // always this path!
                       else printf("Edge 0 of face 0 is NOT a border\n"); 

  m.face[0].SetD(); // deleting face [0] (i.e. marked as deleted) 


	// declare an iterator on the mesh
	vcg::face::Pos<MyMesh::FaceType> he, hei;

  // Now a simple search and trace of all the border of the mesh
  MyMesh::FaceIterator fi; 
  UnMarkAll(m);
  int BorderEdgeNum=0;
  int HoleNum=0;
  for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
			{	
				for(int j=0;j<3;j++)
				{
          if ( face::IsBorder(*fi,j) && tri::IsMarked(m,&*fi))
            {
              tri::Mark(m,&*fi);
              hei.Set(&*fi,j,fi->V(j));
							he=hei;
							do
							{
                BorderEdgeNum++;	
								he.NextB(); // next edge along a border 
                tri::Mark(m,he.f);
       				}
							while (he.f!=hei.f);
							HoleNum++;
            }			
				}
			}
		
  printf("Mesh has %i holes and %i border edges\n",HoleNum,BorderEdgeNum);
  return 0;
}
int main(int argc,char ** argv){

	if(argc<5)
	{
		printf(
			"\n     HoleFilling ("__DATE__")\n"
			"Visual Computing Group I.S.T.I. C.N.R.\n"
      "Usage: trimesh_hole #algorithm #size filein.ply fileout.ply \n"
			"#algorithm: \n"
			" 1) Trivial Ear \n"
			" 2) Minimum weight Ear \n"
			" 3) Selfintersection Ear \n"
			" 4) Minimum weight \n"
			);
		exit(0);
	}

	int algorithm = atoi(argv[1]);
	int holeSize  = atoi(argv[2]);
	if(algorithm < 0 && algorithm > 4)
	{
    printf("Error in algorithm's selection %i\n",algorithm);
		exit(0);
	}

	MyMesh m;

	if(tri::io::ImporterPLY<MyMesh>::Open(m,argv[3])!=0)
	{
		printf("Error reading file  %s\n",argv[2]);
		exit(0);
	}

	//update the face-face topology 
	tri::UpdateTopology<MyMesh>::FaceFace(m);
	tri::UpdateNormals<MyMesh>::PerVertexPerFace(m);
	tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
  assert(tri::Clean<MyMesh>::IsFFAdjacencyConsistent(m));
	
	//compute the average of face area
	float AVG,sumA=0.0f;
	int numA=0,indice;
	indice = m.face.size();
	MyMesh::FaceIterator fi;
	for(fi=m.face.begin();fi!=m.face.end();++fi)
	{
			sumA += DoubleArea(*fi)/2;
			numA++;
			for(int ind =0;ind<3;++ind)
				fi->V(ind)->InitIMark();
	}
	AVG=sumA/numA;
	
  //tri::Hole<MyMesh> holeFiller;
	switch(algorithm)
	{
  case 1:			tri::Hole<MyMesh>::EarCuttingFill<tri::TrivialEar<MyMesh> >(m,holeSize,false);                	        break;
  case 2:   	tri::Hole<MyMesh>::EarCuttingFill<tri::MinimumWeightEar< MyMesh> >(m,holeSize,false,callback);          break;
  case 3: 		tri::Hole<MyMesh>::EarCuttingIntersectionFill<tri::SelfIntersectionEar< MyMesh> >(m,holeSize,false);		break;
  case 4: 		tri::Hole<MyMesh>::MinimumWeightFill(m,holeSize, false); tri::UpdateTopology<MyMesh>::FaceFace(m);      break;
	}
 
	tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
  
  assert(tri::Clean<MyMesh>::IsFFAdjacencyConsistent(m));
	
  printf("\nStart refinig...\n");

/*start refining */
	MyMesh::VertexIterator vi;
	MyMesh::FaceIterator f;
	std::vector<MyMesh::FacePointer> vf;
	f =  m.face.begin();
	f += indice;
	for(; f != m.face.end();++f)
	{
		if(!f->IsD())
		{
			f->SetS();
		}
	}

	std::vector<MyMesh::FacePointer *> FPP;
	std::vector<MyMesh::FacePointer> added;
	std::vector<MyMesh::FacePointer>::iterator vfit;
	int i=1;
	printf("\n");

	for(f =  m.face.begin();f!=m.face.end();++f) if(!(*f).IsD())
	{
		if( f->IsS() )
		{ 
			f->V(0)->IsW();
			f->V(1)->IsW();
			f->V(2)->IsW();
		}
		else
		{
			f->V(0)->ClearW();
			f->V(1)->ClearW();
			f->V(2)->ClearW();
		}
	}
	BaseParameterClass pp;
				vcg::LocalOptimization<MyMesh> Fs(m,&pp);
				Fs.SetTargetMetric(0.0f);
				Fs.Init<MyDelaunayFlip >();
				Fs.DoOptimization();

		
	do
	{
		vf.clear();
		f =  m.face.begin();
		f += indice;
		for(; f != m.face.end();++f)
		{
			if(f->IsS())
			{
				bool test= true;
				for(int ind =0;ind<3;++ind)
					f->V(ind)->InitIMark();
				test = (DoubleArea<MyMesh::FaceType>(*f)/2) > AVG;
				if(test)
				{
					vf.push_back(&(*f));
				}
			}
		}

		//info print 
    printf("\r Refining [%d] - > %d",i,int(vf.size()));
		i++;

		FPP.clear();
		added.clear();

		for(vfit = vf.begin(); vfit!=vf.end();++vfit)
		{
			FPP.push_back(&(*vfit));
		}
		int toadd= vf.size();
		MyMesh::FaceIterator f1,f2;
		f2 = tri::Allocator<MyMesh>::AddFaces(m,(toadd*2),FPP);
		MyMesh::VertexIterator vertp = tri::Allocator<MyMesh>::AddVertices(m,toadd);
		std::vector<MyMesh::FacePointer> added;
		added.reserve(toadd);
		vfit=vf.begin();

		for(int i = 0; i<toadd;++i,f2++,vertp++)
		{
			f1=f2;
			f2++;
			TriSplit<MyMesh,CenterPoint<MyMesh> >(vf[i],&(*f1),&(*f2),&(*vertp),CenterPoint<MyMesh>() );
			f1->SetS();
			f2->SetS();
			for(int itr=0;itr<3;itr++)
			{
				f1->V(itr)->SetW();
				f2->V(itr)->SetW();
			}
			added.push_back( &(*f1) );
			added.push_back( &(*f2) );
		}

		BaseParameterClass pp;
		vcg::LocalOptimization<MyMesh> FlippingSession(m,&pp);
		FlippingSession.SetTargetMetric(0.0f);
		FlippingSession.Init<MyDelaunayFlip >();
		FlippingSession.DoOptimization();
		
	}while(!vf.empty());

	vcg::LocalOptimization<MyMesh> Fiss(m,&pp);
	Fiss.SetTargetMetric(0.0f);
	Fiss.Init<MyDelaunayFlip >();
	Fiss.DoOptimization();

/*end refining */

	tri::io::ExporterPLY<MyMesh>::Save(m,"PreSmooth.ply",false);

	int UBIT = MyMesh::VertexType::LastBitFlag();
	f =  m.face.begin();
	f += indice;
	for(; f != m.face.end();++f)
	{
		if(f->IsS())
		{
			for(int ind =0;ind<3;++ind){
				if(NormalTest<MyMesh>(face::Pos<MyMesh::FaceType>(&(*f),ind )))
				{
					f->V(ind)->SetUserBit(UBIT);
				}
			}
			f->ClearS();
		}
	}

	for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
	{
		if( vi->IsUserBit(UBIT) )
		{ 
			(*vi).SetS();
			vi->ClearUserBit(UBIT);
		}
	}

	tri::Smooth<MyMesh>::VertexCoordLaplacian(m,1,true);

	printf("\nCompleted. Saving....\n");
  
  tri::io::ExporterPLY<MyMesh>::Save(m,argv[4],false);
	return 0;
}