CGAL:添加功能失败
CGAL: adding features fails
任务
很简单:我想创建一个四面体网格并向其添加几个特征。
例子
作为输入,获取可以在 CGAL-4.11/examples/Mesh_3/data
中找到的文件 cube.off
。我想添加的特征(只是立方体的十二条边)保存在 cube.edges
:
2 -1 -1 -1 -1 1 -1
2 -1 -1 -1 1 -1 -1
2 -1 -1 -1 -1 -1 1
2 -1 1 -1 1 1 -1
2 -1 1 -1 -1 1 1
2 1 1 -1 1 -1 -1
2 1 1 -1 1 1 1
2 1 -1 -1 1 -1 1
2 -1 -1 1 -1 1 1
2 -1 -1 1 1 -1 1
2 -1 1 1 1 1 1
2 1 1 1 1 -1 1
代码的MWE:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Polyhedral_complex_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
// From CGAL-4.11/examples/Mesh_3 but for simplicity copied to the current folder.
#include "read_polylines.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_complex_mesh_domain_3<K> Mesh_domain;
typedef CGAL::Sequential_tag Concurrency_tag;
typedef CGAL::Mesh_triangulation_3<Mesh_domain,CGAL::Default,Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
typedef K::Point_3 Point;
typedef std::vector<std::vector<Point> > Polylines;
int main()
{
// Read the (one) patch.
std::vector<Polyhedron> patches(1);
std::ifstream input("cube.off");
input >> patches[0];
const std::pair<int, int> incident_subdomains[] = { std::make_pair(1,0) };
Mesh_domain domain(patches.begin(), patches.end(), incident_subdomains, incident_subdomains+1);
// Read the features.
std::string feature_edges="cube.edges";
Polylines polylines;
read_polylines<Point>(feature_edges.c_str(), polylines);
domain.add_features(polylines.begin(), polylines.end());
// Create the mesh.
Mesh_criteria criteria(CGAL::parameters::edge_size = 0.25);
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
// Write it (if it hasn't crashed before).
std::ofstream medit_file("out.mesh");
c3t3.output_to_medit(medit_file, false, true);
}
这(当使用选项 -DCGAL_MESH_3_VERBOSE
编译时)崩溃并显示以下错误消息:
Start volume scan...Scanning triangulation for bad cells (sequential)... terminate called after throwing an instance of 'CGAL::Assertion_exception'
what(): CGAL ERROR: assertion violation!
Expr: patch_id > 0 && std::size_t(patch_id) < patch_id_to_polyhedron_id.size()
File: /yatmp/scr1/ya10813/cgal-install/include/CGAL/Polyhedral_complex_mesh_domain_3.h
Line: 457
Aborted
问题
我错过了什么?它必须是非常基本的东西。 CGAL 是一个非常可靠的库,可以很好地处理复杂数据;我不相信一个有 12 条边的立方体足以阻止它。
我也试过的东西
当我用 domain.detect_features();
替换行 domain.add_features(polylines.begin(), polylines.end());
时,程序正确终止。令人困惑的部分是,检测到的特征 完全是 我要添加的特征(我知道是因为我在 Mesh_domain_with_polyline_features_3
中创建了一个函数,它为我打印了边缘;如果需要我可以在这里分享。
当我使用 Polyhedral_mesh_domain_with_features_3
而不是 Polyhedral_complex_mesh_domain_3
时,程序正确终止。这些特征似乎保留在生成的几何体中。然而,它只是一个补丁(out.mesh
中的所有三角形都有相同的最后一个数字,而在这种情况下我希望它们的数字为 0 到 11)。 编辑: 要实现这一点,必须使用 detect_features();
而不是 add_features(...);
或将域拆分为补丁并让 CGAL 从中创建复合体。感谢@lrineau 的澄清。
我也试过先把域分成几个补丁。然而,随后补丁的边界发生了变化。 编辑: 保留它们的一种方法是将补丁边界添加为特征。
反转表面的方向(并在 incident_subdomains
中交换 0
和 1
):没有可见的变化。
更改 cube.edges
中特征线的顺序:无明显变化。
与旧版 Boost 的链接:无明显变化。
class Polyhedral_complex_mesh_domain_3
is a new class added one year ago in CGAL-4.11。你得到的问题是没有调用domain.detect_features()
就从来没有测试过,代码有一个bug:数据成员patch_id_to_polyhedron_id
只填入了detect_features()
。这解释了为什么当您调用 detect_features()
而不是 add_features(..)
.
时它会起作用
编辑:我今天修复了那个错误,请参阅PR #3393 of CGAL。修复将在未来的错误修复版本 CGAL-4.12.2 和 CGAL-4.13.1 中。
任务
很简单:我想创建一个四面体网格并向其添加几个特征。
例子
作为输入,获取可以在 CGAL-4.11/examples/Mesh_3/data
中找到的文件 cube.off
。我想添加的特征(只是立方体的十二条边)保存在 cube.edges
:
2 -1 -1 -1 -1 1 -1
2 -1 -1 -1 1 -1 -1
2 -1 -1 -1 -1 -1 1
2 -1 1 -1 1 1 -1
2 -1 1 -1 -1 1 1
2 1 1 -1 1 -1 -1
2 1 1 -1 1 1 1
2 1 -1 -1 1 -1 1
2 -1 -1 1 -1 1 1
2 -1 -1 1 1 -1 1
2 -1 1 1 1 1 1
2 1 1 1 1 -1 1
代码的MWE:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Polyhedral_complex_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
// From CGAL-4.11/examples/Mesh_3 but for simplicity copied to the current folder.
#include "read_polylines.h"
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_complex_mesh_domain_3<K> Mesh_domain;
typedef CGAL::Sequential_tag Concurrency_tag;
typedef CGAL::Mesh_triangulation_3<Mesh_domain,CGAL::Default,Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
typedef K::Point_3 Point;
typedef std::vector<std::vector<Point> > Polylines;
int main()
{
// Read the (one) patch.
std::vector<Polyhedron> patches(1);
std::ifstream input("cube.off");
input >> patches[0];
const std::pair<int, int> incident_subdomains[] = { std::make_pair(1,0) };
Mesh_domain domain(patches.begin(), patches.end(), incident_subdomains, incident_subdomains+1);
// Read the features.
std::string feature_edges="cube.edges";
Polylines polylines;
read_polylines<Point>(feature_edges.c_str(), polylines);
domain.add_features(polylines.begin(), polylines.end());
// Create the mesh.
Mesh_criteria criteria(CGAL::parameters::edge_size = 0.25);
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);
// Write it (if it hasn't crashed before).
std::ofstream medit_file("out.mesh");
c3t3.output_to_medit(medit_file, false, true);
}
这(当使用选项 -DCGAL_MESH_3_VERBOSE
编译时)崩溃并显示以下错误消息:
Start volume scan...Scanning triangulation for bad cells (sequential)... terminate called after throwing an instance of 'CGAL::Assertion_exception'
what(): CGAL ERROR: assertion violation!
Expr: patch_id > 0 && std::size_t(patch_id) < patch_id_to_polyhedron_id.size()
File: /yatmp/scr1/ya10813/cgal-install/include/CGAL/Polyhedral_complex_mesh_domain_3.h
Line: 457
Aborted
问题
我错过了什么?它必须是非常基本的东西。 CGAL 是一个非常可靠的库,可以很好地处理复杂数据;我不相信一个有 12 条边的立方体足以阻止它。
我也试过的东西
当我用
domain.detect_features();
替换行domain.add_features(polylines.begin(), polylines.end());
时,程序正确终止。令人困惑的部分是,检测到的特征 完全是 我要添加的特征(我知道是因为我在Mesh_domain_with_polyline_features_3
中创建了一个函数,它为我打印了边缘;如果需要我可以在这里分享。当我使用
Polyhedral_mesh_domain_with_features_3
而不是Polyhedral_complex_mesh_domain_3
时,程序正确终止。这些特征似乎保留在生成的几何体中。然而,它只是一个补丁(out.mesh
中的所有三角形都有相同的最后一个数字,而在这种情况下我希望它们的数字为 0 到 11)。 编辑: 要实现这一点,必须使用detect_features();
而不是add_features(...);
或将域拆分为补丁并让 CGAL 从中创建复合体。感谢@lrineau 的澄清。我也试过先把域分成几个补丁。然而,随后补丁的边界发生了变化。 编辑: 保留它们的一种方法是将补丁边界添加为特征。
反转表面的方向(并在
incident_subdomains
中交换0
和1
):没有可见的变化。更改
cube.edges
中特征线的顺序:无明显变化。与旧版 Boost 的链接:无明显变化。
class Polyhedral_complex_mesh_domain_3
is a new class added one year ago in CGAL-4.11。你得到的问题是没有调用domain.detect_features()
就从来没有测试过,代码有一个bug:数据成员patch_id_to_polyhedron_id
只填入了detect_features()
。这解释了为什么当您调用 detect_features()
而不是 add_features(..)
.
编辑:我今天修复了那个错误,请参阅PR #3393 of CGAL。修复将在未来的错误修复版本 CGAL-4.12.2 和 CGAL-4.13.1 中。