Search code examples
c++meshcgal

Surface mesh - removing edge, loop goes in to infinite loop CGAL


i'm making slice function that removes part of mesh at y length. Problem starts when i try to delete removed face edges of a mesh, it goes in to infinite loop.

Where problem occours!

//removes edge - puts in infinite loop
BOOST_FOREACH(halfEdge_descriptor hed, halfedges_around_face(mesh.halfedge(fd), mesh)){
 edge_descriptor ed = mesh.edge(hed);
 mesh.remove_edge(ed);
}

When i iterate through, halfedges, it iterates as it should, but when i try to remove the halfedge, by converting to

remove_edge(Edge_index ed)

It goes in to infinite loop.

Anyone can explain why it does that, and how do i fix it?

Full Code!

void Mesh::slice(SurfaceMesh &mesh,  double lengthToCut){
  typedef SurfaceMesh::Vertex_index vertex_descriptor;
  typedef SurfaceMesh::Face_index face_descriptor;
  typedef SurfaceMesh::Halfedge_index halfEdge_descriptor;
  typedef SurfaceMesh::Edge_index edge_descriptor;
  double y = findMaxY(mesh) - lengthToCut; // length of a mesh
  //;oops over faces
  BOOST_FOREACH(face_descriptor fd, mesh.faces()){
    int verticesLargerThan = 0;
    //loops over vertices of face
    BOOST_FOREACH(vertex_descriptor vd,vertices_around_face(mesh.halfedge(fd), mesh)){
      if(CGAL::compare ( mesh.point(vd)[1],  y) == CGAL::LARGER){
        verticesLargerThan++;
        // if all vertices y coordinates are larger than double y, then removes face
        if(verticesLargerThan == 3){
          mesh.remove_face(fd);
          //mesh.remove_face(fd);
          int removedFaceCounter = 0;
          BOOST_FOREACH(face_descriptor rfd,faces_around_face(mesh.halfedge(fd), mesh)){
            if(mesh.is_removed(rfd)){
              removedFaceCounter++;
            }
            //remove all edges and vertices of face if face is not linked to any other face
            if(removedFaceCounter == 3){
              //removes edge - puts in infinite loop
              BOOST_FOREACH(halfEdge_descriptor hed, halfedges_around_face(mesh.halfedge(fd), mesh)){
                edge_descriptor ed = mesh.edge(hed);
                mesh.remove_edge(ed);
              }
              //removes vertice
              BOOST_FOREACH(vertex_descriptor rvd,vertices_around_face(mesh.halfedge(fd), mesh)){
                //removes vertice if its not linked to any face
                bool allFacesRemoved = true;
                BOOST_FOREACH(face_descriptor rfvd, faces_around_target(mesh.halfedge(fd), mesh)){

                  if(!mesh.is_removed(rfvd)){
                    allFacesRemoved = false;
                    break;
                  }
                }
                if(allFacesRemoved){
                  mesh.remove_vertex(rvd);
                }
              }
            }
          }
        }
      }
    }
  }

Solution

  • This is a classical mistake: removing elements you are iterating on. In this particular case, you are removing edges while iterating over edges of face. It is unlikely you'll find the initial edge to stop the iteration, thus the infinite loop.