CGAL:连接共面多面体面

时间:2019-07-17 16:15:20

标签: cgal

该主题不是新话题,但是我找不到任何令人满意的解决方案。我有一个有效的多面体,它由纯三角形组成并且没有闭合。现在,我想合并共面的小面,以形成一个多面体的小面,并根据需要添加尽可能多的顶点。

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

如果您查看图片,则可以看到如何连接(红色)甚至不共享半边且根本不共面的构面。我无法解释这一点,因为我要检查的第一件事是Halfedge和Halfedge-> opposite()的面是否共面。

Image

第二个问题是,如果我最终要加入具有多个常见半边的共面多面体面。已经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;
}

高度赞赏其他解决方案。

1 个答案:

答案 0 :(得分:0)

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

我有一些代码在做,我将看到如何公开发布它。