Reputation: 21
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
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