我正在 Linux 机器上测试 CGAL 库。作为测试的一部分,我想构建一个简单的立方体表面网格。
这是我的 Catch2 测试:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <catch2/catch_test_macros.hpp>
#include <cmath>
#include <fstream>
#include <iostream>
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Mesh = CGAL::Surface_mesh<Kernel::Point_3>;
// Function to create an approximate parametric sphere
Mesh create_mesh(double size) {
Mesh mesh;
// Cube.
// Define the 8 vertices of the cube
auto v0 = mesh.add_vertex(Kernel::Point_3(0, 0, 0));
auto v1 = mesh.add_vertex(Kernel::Point_3(size, 0, 0));
auto v2 = mesh.add_vertex(Kernel::Point_3(size, size, 0));
auto v3 = mesh.add_vertex(Kernel::Point_3(0, size, 0));
auto v4 = mesh.add_vertex(Kernel::Point_3(0, 0, size));
auto v5 = mesh.add_vertex(Kernel::Point_3(size, 0, size));
auto v6 = mesh.add_vertex(Kernel::Point_3(size, size, size));
auto v7 = mesh.add_vertex(Kernel::Point_3(0, size, size));
// Define the 6 faces of the cube (each face is a quadrilateral made of 2 triangles)
mesh.add_face(v0, v1, v2, v3); // Bottom
mesh.add_face(v4, v5, v6, v7); // Top
mesh.add_face(v0, v4, v7, v3); // Left
mesh.add_face(v1, v5, v6, v2); // Right
mesh.add_face(v0, v4, v5, v1); // Front
mesh.add_face(v3, v7, v6, v2); // Back
return mesh;
}
TEST_CASE("OBJ Export of Cube") {
const std::string filename = "test_output.obj";
// Remove file if it exists, to start fresh
std::remove(filename.c_str());
auto mesh = create_mesh(1);
// Use CGAL to save the combined mesh to OBJ format
CGAL::IO::write_OBJ(filename, mesh);
REQUIRE(std::ifstream(filename).good());
}
令我惊讶的是,这个立方体并不完整。立方体的 OBJ 文件中仅写入两个面。我不明白这一点。我做错了什么?
这是
test_output.obj
文件:
# file written from a CGAL tool in Wavefront obj format
# 8 vertices
# 16 halfedges
# 2 facets
# 8 vertices
# ------------------------------------------
v 0 0 0
v 1 0 0
v 1 1 0
v 0 1 0
v 0 0 1
v 1 0 1
v 1 1 1
v 0 1 1
# 2 facets
# ------------------------------------------
f 1 2 3 4
f 5 6 7 8
# End of Wavefront obj format #
你们的脸部朝向不兼容。一些
add_face()
调用实际上并没有添加任何新面孔。
类
CGAL::Surface_mesh
是表示多边形网格的半边数据结构。面按顶点的顺序定向。多边形网格必须是流形的,因此不能有两个具有相同(有向)半边的多边形网格。这是你的情况,例如你的“底”和“后”面以及 v2 --> v3。
这是一个可能的解决方案,面朝外:
// Define the 6 faces of the cube (each face is a quadrilateral made of 2 triangles)
mesh.add_face(v0, v3, v2, v1); // Bottom
mesh.add_face(v4, v5, v6, v7); // Top
mesh.add_face(v0, v4, v7, v3); // Left
mesh.add_face(v1, v2, v6, v5); // Right
mesh.add_face(v0, v1, v5, v4); // Front
mesh.add_face(v3, v7, v6, v2); // Back
您就得到了预期的结果(6张脸)。
请注意,
add_face()
有一个返回值(人脸索引),您可以使用它来检查您的人脸是否已正确添加,因为如果无法添加人脸,它会返回null_face()
。请参阅文档:https://doc.cgal.org/latest/Surface_mesh/classCGAL_1_1Surface__mesh.html#af45a68e4c8a0fcb7c4fd899185824cae。