直接从 OFF 文件构建 `Nef_polyhedron_3` 和从同一文件构建的 `Polyhedron_3` 构建之间的行为差异

问题描述 投票:0回答:1

在 CGAL 中,可以通过 加载

 OFF 文件直接构建 
Nef_polyhedron_3,或者通过 加载
相同的 OFF 文件构建 
Polyhedron_3,然后从中构造
Nef_polyhedron_3
.

一个执行前者的小例子:

#include "common.hpp"

int main(int argc, char ** argv)
{
  Nef_polyhedron nef_poly;
  std::ifstream is("test.off", std::ios::in);
  CGAL::OFF_to_nef_3(is, nef_poly);
  is.close();

  return 0;
}

执行后者的人:

#include "common.hpp"

int main(int argc, char ** argv)
{
  Polyhedron poly;
  std::ifstream is("test.off", std::ios::in);
  bool success = CGAL::IO::read_OFF(is, poly);
  is.close();
  assert(success);
  assert(poly.is_valid());
  assert(poly.is_closed());

  Nef_polyhedron nef_poly(poly); // <--- A (see below).

  return 0;
}

这里

common.hpp
包含:

#pragma once
#include <iostream>
#include <fstream>
#include <cassert>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Polyhedron_OFF_iostream.h>
#include <CGAL/OFF_to_nef_3.h>

using Exact_kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Polyhedron = CGAL::Polyhedron_3<Exact_kernel>;
using Surface_mesh = CGAL::Surface_mesh<Exact_kernel::Point_3>;
using Nef_polyhedron = CGAL::Nef_polyhedron_3<Exact_kernel>;

从文档中,我希望两者产生相同的 Nef 多面体(从数学上来说“相同”)。但是,我可以构造一些仅前一种方法有效的 OFF 文件,而后者则失败并显示

terminate called after throwing an instance of 'CGAL::Assertion_exception'
  what():  CGAL ERROR: assertion violation!
Expr: ss_circle.has_on(sp)
File: /usr/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h
Line: 253

在标记为

A
的位置。

这是展示该行为的 OFF:

OFF
5 5 10
-0.193282 0.100467 0.339231
-0.183855 0.102082 0.334972
-0.183473 0.103303 0.332011
-0.181318 0.104688 0.348585
0.000000 0.000000 0.000000
3 4 0 1
3 4 1 2
3 4 2 3
3 4 3 0
4 3 2 1 0

这是两种方法产生相同多面体的方法,正如我通常所期望的:

OFF
8 6 12
 1.0  0.0 1
 0.0  1.0 1
-1.0  0.0 1
 0.0 -1.0 1
 1.0  0.0 0.0
 0.0  1.0 0.0
-1.0  0.0 0.0
 0.0 -1.0 0.0
4 0 1 2 3
4 7 4 0 3
4 4 5 1 0
4 5 6 2 1
4 3 2 6 7

我认为我误解了这些类的 CGAL 文档中的某些内容。那到底是什么很明显吗?


作为附录,这里是断开的 OFF 边缘的简单可视化。那里没有发生什么太诡异的事情。橙色边是构成唯一非三角形曲面段边界的边。 Illustration of breaking OFF

c++ computational-geometry cgal
1个回答
0
投票

您提供的第一个 OFF 文件包含非平面 (

4 3 2 1 0
),无法通过函数
CGAL::IO::read_OFF(...)
进行处理。然而,这样的面孔可以通过更高级的函数
CGAL::OFF_to_nef_3(...)
来处理,该函数在其header中明确说明:

namespace CGAL {

/*!
\ingroup PkgNef3IOFunctions

This function creates a 3D Nef polyhedron from an OFF file which
is read from input stream `in`. The purpose of `OFF_to_nef_3`
is to create a Nef polyhedron from an OFF file that cannot be handled
by the `Nef_polyhedron_3` constructors. It handles double
coordinates while using a homogeneous kernel, non-coplanar facets,
surfaces with boundaries, self-intersecting surfaces, and single
facets. Every closed volume gets marked. The function returns the
number of facets it could not handle.

\sa `CGAL::Nef_polyhedron_3<Traits>`

*/
template<class Nef_polyhedron_3>
std::size_t OFF_to_nef_3(std::istream& in, Nef_polyhedron_3& N);

} /* namespace CGAL */

因此,如果您将此非平面分成两个三角形,则两个 OFF 处理函数都将能够处理修改后的 OFF 文件:

 OFF
5 6 0
-0.193282 0.100467 0.339231
-0.183855 0.102082 0.334972
-0.183473 0.103303 0.332011
-0.181318 0.104688 0.348585
0.000000 0.000000 0.000000
3 4 0 1
3 4 1 2
3 4 2 3
3 4 3 0
3 3 1 0
3 3 2 1
© www.soinside.com 2019 - 2024. All rights reserved.