예제 #1
0
void findOutsideSegment( Triangulation &t, Face_handle fh, int currentSegment, int commingFromIndex, int &outsideSegment )
{

	// if the face is an infinite face
	// then we know the outside segment which is the
	// current segment
	if( t.is_infinite(fh) )
	{
		if( (outsideSegment != -1)&&(outsideSegment != currentSegment) )
			printf( "error : different outsideSegments detected during triangulation (edgeloop not closed?)\n" );
		outsideSegment = currentSegment;
		return;
	}

	// if there is already a segment identifier, then we know that
	// the face has already been visited
	if( fh->info() != -1 )
		return;

	fh->info() = currentSegment;

	for( int i=0; i<3; ++i )
	{
		// get edge associated with the index i
		std::pair<Face_handle, int> edge = std::make_pair( fh, i );

		if( i == commingFromIndex )
			continue;
		

		// if the edge is a constrained edge, then we know this is the border
		if(t.is_constrained(edge))
		{
			//...and we have to pass a madified currentSegment value
			findOutsideSegment( t, fh->neighbor(i), (currentSegment+1)%2, t.mirror_index( fh, i), outsideSegment );
		}else
			//...else we recurse and leave the currentSegment value untouched
			findOutsideSegment( t, fh->neighbor(i), currentSegment, t.mirror_index( fh, i), outsideSegment );
	}
}
예제 #2
0
//
// Retriangulates a hole within the mesh. The hole is specified through an edgeloop(closed sequence of edges).
// In addition an optional number of points can be specified which will be included in the triangulation.
//
void MeshEx::retriangulateHole( std::vector<MeshEx::Edge *> &boundaryEdges, std::map<MeshEx::Vertex *, math::Vec2f> &boundaryVertexProjections, std::vector<std::pair<math::Vec3f, math::Vec2f> > &interiorPoints )
{
	std::map<Vertex_handle, MeshEx::Vertex*>                                 vertexMap; // used to map cgal vertex_handles to vertices
	std::vector<MeshEx::Edge *>                                                  edges; // this vector will hold all edges which were involved (for faster edge search)


	// algorithm:
	// - prepare data
	//		- find all boundary vertices
	// - prepare CGAL constrained triangulation
	//		- insert boundary vertices into triangulation and build mapping from Triangulation vertices to MeshEx::Vertices
	//		- use the boundary edges as constrained edges
	//		- insert points into triangulation from interiorPoints and build mapping from Triangulation vertices to MeshEx::Vertices
	// - extract triangulation results
	//		- ?


	// prepare algorithm ----------------------------------------------------------

	/*
	// obsolete since we get the boundary vertices with the boundaryVertexProjections
	// find boundary vertices
	for( std::vector<MeshEx::Edge *>::iterator it = boundaryEdges.begin(); it != boundaryEdges.end(); ++it )
	{
		MeshEx::Edge *e = *it;
		boundaryVertices.push_back( e->v1 );
		boundaryVertices.push_back( e->v2 );
	}
	// remove duplicate entries
	std::sort( boundaryVertices.begin(), boundaryVertices.end() );
	boundaryVertices.erase( std::unique( boundaryVertices.begin(), boundaryVertices.end() ), boundaryVertices.end() );
	*/
	
	// algorithm ------------------------------------------------------------------
	Triangulation t;

	// constrain triangulation with the boundary edges

	// iterate over all boundary vertices
	for( std::map<MeshEx::Vertex *, math::Vec2f>::iterator it = boundaryVertexProjections.begin(); it != boundaryVertexProjections.end(); ++it )
	{
		MeshEx::Vertex *v = it->first;

		// add boundary vertex to triangulation
		Vertex_handle vh = t.insert( Point( it->second.x, it->second.y ) );

		// we dont need to create the vertex
		vertexMap[vh] = v;
	}


	// iterate over all boundary edges
	for( std::vector<MeshEx::Edge *>::iterator it = boundaryEdges.begin(); it != boundaryEdges.end(); ++it )
	{
		MeshEx::Edge *e = *it;

		Vertex_handle v1, v2;


		bool v1_found  = false;
		bool v2_found  = false;
		// find vertex_handles for the given edge vertices
		for( std::map<Vertex_handle, MeshEx::Vertex*>::iterator vmit = vertexMap.begin(); vmit != vertexMap.end(); ++vmit )
		{
			if( e->v1 == vmit->second )
			{
				v1 = vmit->first;
				v1_found = true;
			}
			if( e->v2 == vmit->second )
			{
				v2 = vmit->first;
				v2_found = true;
			}
		}

		// add constrainedge to the triangulation
		t.insert_constraint( v1, v2 );

		// add edge to the list of created/existing edges
		edges.push_back( e );
	}

	// add additional and optional interior points
	for( std::vector<std::pair<math::Vec3f, math::Vec2f> >::iterator it = interiorPoints.begin(); it != interiorPoints.end(); ++it )
	{
		// update triangulation
		Vertex_handle v = t.insert( Point( it->second.x, it->second.y ) );

		// insertion may return a vertex which already exists (when the position is the same)
		if( vertexMap.find( v ) == vertexMap.end() )
			// create according MeshEx::Vertex and keep mapping to the CGAL vertices
			vertexMap[v] = createVertex( it->first );
	}


	// extract results and create triangles ----------------------------------------

	// now we have the triangulation of the convex hull of the whole problem, now we
	// have to find the faces which are inside the polygon - we mark each face with a
	// segment(inside or outside) property and by finding a face which is adjacent to
	// a infinite face, we find the segment which is outside


	// we employ some floodfilling scheme
	for( Triangulation::Finite_faces_iterator it = t.finite_faces_begin(); it != t.finite_faces_end(); ++it )
		// reset info to -1
		it->info() = -1;

	int outsideSegment = -1;
	findOutsideSegment( t, t.finite_faces_begin(), 0, -1, outsideSegment );

	if( outsideSegment == -1 )
		printf( "error : outsideSegment not found during triangulation\n" );

	for( Triangulation::Finite_faces_iterator it = t.finite_faces_begin(); it != t.finite_faces_end(); ++it )
		if( (it->info() == -1) && (!t.is_infinite(it)) )
			printf( "triangle not touched!\n" );

	// iterate over all faces of the triangulation and create edges/triangles
	for( Triangulation::Finite_faces_iterator it = t.finite_faces_begin(); it != t.finite_faces_end(); ++it )
	{
		Face_handle fh = it;

		// we are only interested in interior triangles
		if( fh->info() == outsideSegment )
			continue;

		MeshEx::Vertex *v0, *v1, *v2;

		v0 = vertexMap[ fh->vertex(0) ];
		v1 = vertexMap[ fh->vertex(1) ];
		v2 = vertexMap[ fh->vertex(2) ];

		MeshEx::Edge *e0, *e1, *e2;

		e0 = e1 = e2 = 0;

		// look for the edges in the edge vector
		for( std::vector<MeshEx::Edge*>::iterator eit = edges.begin(); eit != edges.end(); ++eit )
		{
			MeshEx::Edge *e = *eit;

			if( e->contains(v0) && e->contains(v1) )
				e0 = e;
			else
			if( e->contains(v1) && e->contains(v2) )
				e1 = e;
			else
			if( e->contains(v2) && e->contains(v0) )
				e2 = e;
		}

		// create the edges which could not be found
		if( !e0 )
		{
			e0 = createEdge( v0, v1 );
			edges.push_back(e0);
		}
		if( !e1 )
		{
			e1 = createEdge( v1, v2 );
			edges.push_back(e1);
		}
		if( !e2 )
		{
			e2 = createEdge( v2, v0 );
			edges.push_back(e2);
		}

		// create triangle
		MeshEx::Triangle *tri = createTriangle( v0, v1, v2, e0, e1, e2 );
	}
}