c++meshcgalsurface3d-reconstruction

How to extract the underlying 2-manifold from a non-manifold by deleting "free faces"?


I'm trying to extract the underlying 2-manifold (closed surface) from a non-manifold mesh. I'm using CGAL for mesh manipulation.I want to achieve that by deleting 'free faces'.By free I mean, a face whose at least one edge is a boundary edge.Deleting a free face eventually may create new 'free faces'. I want to keep deleting them unless no face has boundary edge.For example, if I have a 2-sphere and a fin like structure attached to it, I want to get the 2-sphere by deleting all the faces of the fin.

In CGAL, I kept on iterating over the half-edges and if I get a half-edge whose opposite is_border, I delete the face incident(more precisely using make_hole(h)), to the half edge. I keep on iterating when no such deletion is possible.

typedef CGAL::Exact_predicates_inexact_constructions_kernel I;
typedef CGAL::Polyhedron_3<I> Polyhedron;
Polyhedron mesh;

//
int in_this_iter = 0;
    do {
        in_this_iter = 0;
        for (auto h = mesh.halfedges_begin(); h != mesh.halfedges_end(); h++) {
            //cout << e->is_border() << endl;

            if (h->opposite()->is_border() && !h->is_border()) {
                mesh.make_hole(h);
                /*CGAL::Euler::remove_face(h,mesh);
                *gives trouble*/
                in_this_iter++;
            }
            else if (h->is_border() && !h->opposite()->is_border()) {
                mesh.make_hole(h->opposite());

                in_this_iter++;
            }

        }
        //mesh.normalize_border();
        count = count + in_this_iter;
        std::cout << "Face Deleted in this iter: " << in_this_iter<<endl;
    } while (in_this_iter != 0);
    std::cout << "Face Deleted: " << count<<endl;

The structure I am testing is:

OFF
7 8 0
0.0 0.0 0.0
1.0 0.0 0.0
2.0 0.0 0.0
0.0 1.0 0.0
1.0 1.0 0.0
2.0 1.0 0.0
0.0 0.0 1.0
3 0 1 3
3 3 1 4
3 1 4 2
3 2 4 5
3 1 2 4
3 3 1 6
3 3 4 6
3 1 4 6

My algorithm does not delete any free face. But the ideal one should capture the 4 faces of tetrahedron deleting the others. P.S: Appreciate your help! And please forgive me if I didn't follow the decorum as this is my first post.


Solution

  • You should not modify the structure on which you are looping, as the results might be unexpected. Rather, you could simply do something like:

    Find all faces that have an halfedge on the border
    Put them in a stack
    while(stack not empty)
      take the face 'f' top of the stack
      if('f' is already tagged)
        continue
      else
        tag 'f' as "to_be_removed"
        add all neighboring faces that are not already tagged to the stack
    done
    Remove all faces that were tagged "to_be_removed"
    

    Note that this is roughly what the CGAL::PMP::connected_components functions are doing: they regroup all the faces of your structure in groups such that the faces of one group can all reach each other by walking from one face to another. What you could thus also do is to use these CGAL::PMP::connected_components functions to tag your faces in connected components, and then discard the connected components that do not form a closed mesh. You can find inspiration in the following function, whose goal is to split a given structure in independent connected components. This would be the first step of your code; your second step is then to just look whether the mesh is closed (CGAL::is_closed()) or not.