【问题标题】:Cgal surface mesh - connectivityCgal 表面网格 - 连通性
【发布时间】:2017-08-12 16:54:50
【问题描述】:

我有点困惑连接是如何工作的。 我正在尝试从网格中删除面,并调整连接性,删除未使用的边和顶点。 当我使用 mesh.is_valid() 时,它会显示连接问题

h1 前半边的完整性已损坏。 v0 的半边不是 传入的半边。顶点:迭代:1 vs number_of_vertices(): 5 个半边:迭代:2 vs number_of_halfedges():14 个面:迭代: 3 vs 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;
}

【问题讨论】:

  • 您能简要解释一下您的三个边缘操作中的每一个以及您背后的原因吗?
  • 首先我将每个半边设置为边框半边,将 set_vertex_halfedge 设置为边框半边,然后检查相对的半边是否为边框。如果相对的半边是边框,那么我删除边缘,如果不是,那么我将该半边的面设置为 null_face。之后,当我完成它时,我删除了脸。

标签: c++ mesh cgal


【解决方案1】:

使用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;

这不会产生验证错误,并确认操作后网格中少了一个面。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多