2017-08-12 136 views
1

我有點困惑連接如何工作。 我想從網格中移除人臉,並調整連通性,移除未使用的邊和頂點。 當我使用mesh.is_valid()它顯示我的連接問題Cgal表面網格 - 連接

完整性H1以前半邊的損壞。 v0的Halfedge不是 傳入的halfedge。頂點:迭代:1對number_of_vertices(): 5 halfedges:迭代:2對number_of_halfedges():14面:迭代: 3比number_of_faces():3

代碼:

#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; 
} 
+0

你能簡單解釋一下你的三個邊緣操作和你背後的推理嗎? – Alex

+0

首先我將每個halfedge設置爲border halfedge,set_vertex_halfedge設置爲border halfedge,之後我檢查相對的halfedge是否是border。如果相反的halfedge是邊界,那麼我刪除邊緣,如果不是,那麼我將該halfedge的表面設置爲null_face。之後當我完成它時,我刪除臉。 – duufous

回答

2

使用Euler operationsremove_face功能。它會在幕後爲你「保持有效性」。歐拉操作對任何類型的值「Graph」都是「MutableFaceGraph的模型」。幸運的是,您的SurfaceMesh就是這樣的一個模型。

如果更換循環以下的(因爲你只想一個面是不必要的),你會看到它是如何工作的:

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; 

這不產生任何驗證錯誤,並確認有少一個在手術後面對網格。

+0

非常感謝,完美的作品 – duufous