Ejemplo n.º 1
0
/*------------------------------------------------------------------------------*/
void GW_Mesh::IterateConnectedComponent_Face( GW_Face& start_face, FaceIterate_Callback pCallback )
{
	/* march on the voronoi diagram */
	T_FaceList FaceToProceed;
	FaceToProceed.push_back( &start_face );
	T_FaceMap FaceDone;
	FaceDone[ start_face.GetID() ] = &start_face;


	while( !FaceToProceed.empty() )
	{
		GW_Face* pFace = FaceToProceed.front();
		GW_ASSERT( pFace!=NULL );
		FaceToProceed.pop_front();

		/* cut the face */
		pCallback( *pFace );

		/* add neighbors */
		for( GW_U32 i=0; i<3; ++i )
		{
			GW_Face* pNewFace = pFace->GetFaceNeighbor(i);
			if( pNewFace!=NULL && FaceDone.find(pNewFace->GetID())==FaceDone.end() )
			{				
				FaceToProceed.push_back( pNewFace );
				FaceDone[ pNewFace->GetID() ] = pNewFace;	// so that it won't be added anymore
			}
		}
	}
}
Ejemplo n.º 2
0
/*------------------------------------------------------------------------------*/
void GW_Mesh::ReOrientMesh( GW_Face& start_face )
{
	/* march on the voronoi diagram */
	T_FaceList FaceToProceed;
	FaceToProceed.push_back( &start_face );
	T_FaceMap FaceDone;
	FaceDone[ start_face.GetID() ] = &start_face;


	while( !FaceToProceed.empty() )
	{
		GW_Face* pFace = FaceToProceed.front();
		GW_ASSERT( pFace!=NULL );
		FaceToProceed.pop_front();

		/* add neighbors */
		for( GW_U32 i=0; i<3; ++i )
		{
			GW_Vertex* pVertDir = pFace->GetVertex(i);	GW_ASSERT( pVertDir!=NULL );
			GW_Face* pNewFace = pFace->GetFaceNeighbor(*pVertDir);
			if( pNewFace!=NULL && FaceDone.find(pNewFace->GetID())==FaceDone.end() )
			{				
				/* find the two other vertices */
				GW_U32 i1 = (i+1)%3;
				GW_U32 i2 = (i+2)%3;
				GW_Vertex* pNewVert[3];
				pNewVert[0] = pFace->GetVertex(i2);						GW_ASSERT( pNewVert[0]!=NULL );
				pNewVert[1] = pFace->GetVertex(i1);						GW_ASSERT( pNewVert[1]!=NULL );
				pNewVert[2] = pNewFace->GetVertex(*pNewVert[0], *pNewVert[1]);	GW_ASSERT( pNewVert[2]!=NULL );
				GW_Face* pNeigh[3];
				pNeigh[0] = pNewFace->GetFaceNeighbor( *pNewVert[0] );
				pNeigh[1] = pNewFace->GetFaceNeighbor( *pNewVert[1] );
				pNeigh[2] = pNewFace->GetFaceNeighbor( *pNewVert[2] );
				/* reorient the face */
				pNewFace->SetVertex( *pNewVert[0], *pNewVert[1], *pNewVert[2] );
				pNewFace->SetFaceNeighbor( pNeigh[0], pNeigh[1], pNeigh[2] );
				FaceToProceed.push_back( pNewFace );
				FaceDone[ pNewFace->GetID() ] = pNewFace;	// so that it won't be added anymore
			}
		}
	}

	/* check for global orientation (just an heuristic) */
	GW_Face* pFace = this->GetFace(0);	GW_ASSERT( pFace!=NULL );
	GW_Vector3D v = pFace->GetVertex(0)->GetPosition() +
					pFace->GetVertex(1)->GetPosition() +
					pFace->GetVertex(2)->GetPosition();
	GW_Vector3D n = pFace->ComputeNormal();
	if( n*v<0 )
		this->FlipOrientation();
}
/*------------------------------------------------------------------------------*/
void GW_VoronoiMesh::BuildMesh( GW_GeodesicMesh& Mesh, GW_Bool bFixHole )
{
	/* Create Vornoi vertex and make the inverse map GeodesicVertex->VoronoiVertex */
	this->CreateVoronoiVertex();

#if 1	// simple method

	GW_OutputComment("Recomputing the whole Voronoi diagram.");
	GW_VoronoiMesh::PerformFastMarching( Mesh, BaseVertexList_ );

	/* find the faces */
	GW_OutputComment("Building the faces.");
	T_FaceMap FaceMap;	// to store the faces already built.
	for( GW_U32 i=0; i<Mesh.GetNbrFace(); ++i )
	{
		GW_Face* pFace = Mesh.GetFace(i);	GW_ASSERT( pFace!=NULL );
		GW_GeodesicVertex* pGeo[3];
		GW_GeodesicVertex* pFront[3];
		for( GW_U32 j=0; j<3; ++j )
		{
			pGeo[j] = (GW_GeodesicVertex*) pFace->GetVertex(j); GW_ASSERT( pGeo[j]!=NULL );
			pFront[j] = pGeo[j]->GetFront();
		}
		if( pFront[0]!=pFront[1] && pFront[1]!=pFront[2] && pFront[2]!=pFront[0] )
		{
			GW_U32 nID = GW_Vertex::ComputeUniqueId( *pFront[0], *pFront[1], *pFront[2] );
			if( FaceMap.find(nID)==FaceMap.end() )
			{
				/* create the face */
				GW_Face& Face = this->CreateNewFace();
				FaceMap[nID] = &Face;
				for( GW_U32 j=0; j<3; ++j )		// assign the vertices
				{
					GW_U32 nID = pFront[j]->GetID();
					GW_ASSERT( VoronoiVertexMap_.find(nID)!=VoronoiVertexMap_.end() );
					GW_VoronoiVertex* pVorVert = VoronoiVertexMap_[nID];	GW_ASSERT( pVorVert!=NULL );
					Face.SetVertex( *pVorVert, j );
				}
			}
		}
	}

#else

	GW_OutputComment("Computing voronoi diagrams.");
	/* perform once more a firestart to set up connectivity */		
	Mesh.RegisterNewDeadVertexCallbackFunction( GW_VoronoiMesh::FastMarchingCallbackFunction_MeshBuilding );
	Mesh.ResetGeodesicMesh();
	GW_VoronoiMesh::PerformFastMarching( Mesh, BaseVertexList_ );
	Mesh.RegisterNewDeadVertexCallbackFunction( NULL );

	/* build the faces */
	T_FaceMap FaceMap;	// to store the faces already built.

	GW_OutputComment("Building voronoi mesh faces.");
	for( IT_GeodesicVertexList it = BaseVertexList_.begin(); it!=BaseVertexList_.end(); ++it )
	{
		GW_GeodesicVertex* pVert0 = *it;
		GW_ASSERT( pVert0!=NULL );
		/* retrive the corresponding voronoi vertex */
		GW_VoronoiVertex* pVoronoiVert0 = GW_VoronoiMesh::GetVoronoiFromGeodesic( *pVert0 );
		GW_ASSERT( pVoronoiVert0!=NULL );
		for( IT_VoronoiVertexList itVoronoi1=pVoronoiVert0->BeginNeighborIterator(); itVoronoi1!=pVoronoiVert0->EndNeighborIterator(); ++itVoronoi1 )
		{
			GW_VoronoiVertex* pVoronoiVert1 = *itVoronoi1;
			GW_ASSERT( pVoronoiVert1!=NULL );
			GW_U32 nNumTriangle = 0;
			for( IT_VoronoiVertexList itVoronoi2=pVoronoiVert1->BeginNeighborIterator(); itVoronoi2!=pVoronoiVert1->EndNeighborIterator(); ++itVoronoi2 )
			{
				GW_VoronoiVertex* pVoronoiVert2 = *itVoronoi2;
				GW_ASSERT( pVoronoiVert2!=NULL );
				if( pVoronoiVert2!=pVoronoiVert0 && pVoronoiVert0->IsNeighbor(*pVoronoiVert2) )
				{
					/* yes, we find a triangle ! Test if it wasn't already constructed */
					GW_U32 nUniqueId = GW_Vertex::ComputeUniqueId( *pVoronoiVert0, *pVoronoiVert1, *pVoronoiVert2 );
					if( FaceMap.find(nUniqueId)==FaceMap.end() )
					{
						nNumTriangle++;
						GW_ASSERT( nNumTriangle<=2 );	// assert manifold structure
						/* this is the 1st time we encounter this face. */
						GW_Face* pFace = &Mesh.CreateNewFace();
						/* set up the face */
						pFace->SetVertex( *pVoronoiVert0, *pVoronoiVert1, *pVoronoiVert2 );
						FaceMap[nUniqueId] = pFace;
					}
				}
			}
		}
	}

#endif

	
	/* assign the faces */
	this->SetNbrFace( (GW_U32) FaceMap.size() );
	GW_U32 nNum = 0;
	for( IT_FaceMap it = FaceMap.begin(); it!=FaceMap.end(); ++it )
	{
		this->SetFace( nNum, it->second );
		nNum++;
	}
	/* rebuild connectivity */
	GW_OutputComment("Building connectivity.");
	this->BuildConnectivity();
	/* try to fill the holes */
	if( bFixHole )
	{
		GW_OutputComment("Fixing holes.");
		this->FixHole();
		/* re-rebuild connectivity */
		this->BuildConnectivity();
	}

}