duufous
duufous

Reputation: 21

Cgal surface mesh - connectivity

I am bit confused how does connectivity work. I am trying to remove face from mesh, and adjust connectivity, remove unusued edges and vertices. When i use mesh.is_valid() it shows me connection problems

Integrity of previous halfedge of h1 corrupted. Halfedge of v0 is not an incoming halfedge. vertices: iterated: 1 vs number_of_vertices(): 5 halfedges: iterated: 2 vs number_of_halfedges(): 14 faces: iterated: 3 vs number_of_faces(): 3

Code:

#include <string>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <boost/foreach.hpp>
#include <iostream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Gmpq.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;

typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;
typedef Mesh::Halfedge_index halfedge_descriptor;
typedef Mesh::Edge_index edge_descriptor;

int main()
{
  Mesh mesh;
  vertex_descriptor v0 = mesh.add_vertex(K::Point_3(0,2,0));
  vertex_descriptor v1 = mesh.add_vertex(K::Point_3(2,2,0));
  vertex_descriptor v2 = mesh.add_vertex(K::Point_3(0,0,0));
  vertex_descriptor v3 = mesh.add_vertex(K::Point_3(2,0,0));
  vertex_descriptor v4 = mesh.add_vertex(K::Point_3(1,1,0));
  mesh.add_face(v3, v1, v4);
  mesh.add_face(v0, v4, v1);
  mesh.add_face(v0, v2, v4);
  mesh.add_face(v2, v3, v4);

 int counter = 0;
 std::vector <edge_descriptor> edg;
 BOOST_FOREACH(face_descriptor fd, mesh.faces()){
  if(counter == 0){
    halfedge_descriptor hed = mesh.halfedge(fd);
    halfedge_descriptor prev = mesh.prev(hed);
    halfedge_descriptor next = mesh.next(hed);

    mesh.set_vertex_halfedge_to_border_halfedge (next);
    mesh.set_vertex_halfedge_to_border_halfedge (prev);
    mesh.set_vertex_halfedge_to_border_halfedge (hed);

    if(mesh.is_border(mesh.opposite(next))){
      mesh.remove_edge(mesh.edge(next));
      std::cout << "Remove next halfedge " << next << std::endl;
    }else{
      mesh.set_face(next, mesh.null_face());
      std::cout << "sets next halfedge " << next << std::endl;
    }

    if(mesh.is_border(mesh.opposite(prev))){
      mesh.remove_edge(mesh.edge(prev));
      std::cout << "Remove prev halfedge " << prev << std::endl;
    }else{
      mesh.set_face(prev, mesh.null_face());
      std::cout << "sets prev halfedge " << prev << std::endl;
    }
    if(mesh.is_border(mesh.opposite(hed))){
      mesh.remove_edge(mesh.edge(hed));
      std::cout << "Remove Face halfedge " << hed << std::endl;
    }else{
      mesh.set_face(hed, mesh.null_face());
      std::cout << "sets Face halfedge " << hed << std::endl;
    }
    mesh.remove_face(fd);
    counter++;

    }
  }
  mesh.collect_garbage();
  mesh.is_valid();
  return 0;
}

Upvotes: 1

Views: 964

Answers (1)

Alex
Alex

Reputation: 790

Use the remove_face function of the Euler operations. It will "maintain the validity" behind the scenes for you. The Euler operations work on values of any type Graph that is "a model of" MutableFaceGraph. Fortunately, your SurfaceMesh is such a model.

If you replace your loop (which is unnecessary since you just want one face) with the following, you will see how it works:

int counter = 0;
BOOST_FOREACH(face_descriptor fd, mesh.faces()){
  counter++;
}
std::cout << counter << " faces" << std::endl;

CGAL::Euler::remove_face(mesh.halfedge(*mesh.faces().begin()), mesh );
mesh.collect_garbage();
mesh.is_valid();

counter = 0;
BOOST_FOREACH(face_descriptor fd, mesh.faces()){
  counter++;
}
std::cout << counter << " faces" << std::endl;

This produces no validation errors and confirms that there is one fewer face in the mesh after the operation.

Upvotes: 2

Related Questions