在 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 边缘的简单可视化。那里没有发生什么太诡异的事情。橙色边是构成唯一非三角形曲面段边界的边。
您提供的第一个 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