【问题标题】:CGAL: Join coplanar Polyhedron facetsCGAL:加入共面多面体刻面
【发布时间】:2019-07-17 16:15:20
【问题描述】:

这个话题并不新鲜,但我找不到任何令人满意的解决方案。我有一个有效的多面体,它由纯三角形组成并且不是闭合的。现在我想合并共面的多面体,从而得到一个具有尽可能多的顶点的多面体小面。

我编写了一个迭代所有边的函数,并使用 join_facet() 以防对应的边是非边界的,而对面是共面的。这适用于简单的网格,但不适用于更复杂的网格。

如果您看一下图片,您会看到面是如何连接的(红色),这些面甚至不共享半边,而且根本不共面。我无法解释这一点,因为我首先要检查的是 halfedge 和 halfedge->opposite() 的面是否共面。

第二个问题是,如果我最终将共面多面体刻面与几个共同的半边连接起来。该问题已在here 中进行了描述。但目前还不清楚 join_facet() 在这种情况下做了什么。其他半边还会存在吗?这没问题,因为无论如何我都在迭代它们(如果它们不再存在,因为我的 Edge_iterator 仍然想要迭代它们,那将是一个更大的问题)。但是我该如何摆脱它们呢?

这是我的代码:

void mergeCoplanarFacets(Polyhedron *P_out) const {
  for (Polyhedron::Edge_iterator j = P_out->edges_begin(); j != P_out->edges_end(); ++j) {
    Polyhedron::Edge_iterator i = j; // copy necessary for iterator to work after removing halfedges
    if(i->is_border_edge()) { // if halfedge is border, there is no neighbor facet
      std::cout << "Border is edge" << std::endl;
      continue;
    }
    // check normals
    if(coplanar(i, i->opposite())) {
      std::cout << "Coplanar facet found" << std::endl;
      if(CGAL::circulator_size(i->opposite()->vertex_begin()) >= 3 && CGAL::circulator_size(i->vertex_begin()) >= 3) {
        std::cout << "Join facet " << i->facet()->id() << " with " << i->opposite()->facet()->id() << std::endl;
        P_out->join_facet(i);
      }
      else
        std::cerr << "Faces could not be joined" << std::endl;
    }
  }
bool MeshModel::coplanar(const Polyhedron::Halfedge_handle &h1, const Polyhedron::Halfedge_handle &h2) const {
  // check coplanarity of at least three points from the new triangle
  if (CGAL::coplanar(h1->vertex()->point(), h1->next()->vertex()->point(), h1->next()->next()->vertex()->point(), h2->vertex()->point())
      && CGAL::coplanar(h1->vertex()->point(), h1->next()->vertex()->point(), h1->next()->next()->vertex()->point(), h2->next()->vertex()->point())
      && CGAL::coplanar(h1->vertex()->point(), h1->next()->vertex()->point(), h1->next()->next()->vertex()->point(), h2->next()->next()->vertex()->point()))
        return true;
  else
    return false;
}

高度赞赏任何其他解决方案。

【问题讨论】:

  • halfedge 和 halfege->opposite() 总是共面的,它们共享两个相同的点并形成边缘。你的意思是 halfedge->face() 和 halfedge()->opposite()->face() 吗?
  • 只是一个错误的表述。在代码中,我实际上采用了相应的方面。

标签: cgal


【解决方案1】:

只要共面面集合的拓扑不是磁盘的拓扑,迭代连接面可能会导致问题。 我对此类任务的建议是识别所有共面补丁。对于每个这样的补丁,如果它不是拓扑圆盘,则使用约束三角剖分对其进行三角剖分。如果它是一个拓扑磁盘,你可以这样保持它或重新三角化它。请注意,您可能希望在补丁的边界上添加一个额外的步骤,以丢弃与其邻居共线的“2 度”顶点。

我有一些代码在做,我会看看我们能做些什么来公开发布它。

【讨论】:

  • 什么是“拓扑磁盘”?我不确定三角测量在这里有什么帮助,因为我想最终加入三角形而不是制作三角形。在我的例子中,由几个三角形组成的整面墙最终应该是一个有 4 个顶点的多面体。
  • 想象一个立方体,在一个面的中间有另一个较小的立方体。该面有 2 个半边的边界循环,您不能简单地加入(否则内部正方形将断开连接)。三角测量有助于保持连接。
  • 但由于这些是非共面面的边界半边,我什至不会尝试加入它们。在你的情况下,我应该得到一个“方形”戒指。我假设这两个立方体之间没有任何面(如果它们是连接的)。
  • 当然,但是你的脸上不知何故有一个洞,这不再有效。 HDS 可能对此很好,但 Polyhedron 则不然。
  • 只有当它是一个拓扑磁盘时才有可能,否则你需要另一个数据结构。
猜你喜欢
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多