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 ); } }
// // 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 ); } }