a73c5e8954
VDE-002 (High): Fix submodule include path - All target_include_directories: CMAKE_SOURCE_DIR → BUILD_INTERFACE - Works as both standalone project and add_subdirectory() VDE-006 (High): Break vde_mesh ↔ vde_brep circular dependency - Move mesh-dependent code from brep to mesh module - vde_brep no longer links vde_mesh VDE-007 (Low): Add mirror() and mirror_about_plane() to transform.h VDE-008 (Low): Add convenience accessors to StlTriangle (.x()/.y()/.z()) VDE-009 (Medium): Full Doxygen docs for C API + examples/capi/basic_usage.cpp Pending: VDE-001/003/004/005/010 GCC compatibility (agent still running)
117 lines
3.5 KiB
C++
117 lines
3.5 KiB
C++
#pragma once
|
||
#include <string>
|
||
#include <vector>
|
||
#include "vde/foundation/math_types.h"
|
||
|
||
namespace vde::foundation {
|
||
|
||
/**
|
||
* @brief STL 三角形面片
|
||
*
|
||
* 表示一个 STL 三角形,包含法向量和三个顶点。
|
||
* 法向量应为单位向量,方向朝外(右手法则)。
|
||
*
|
||
* 除直接访问成员(v0, v1, v2)外,提供便捷分量访问方法,
|
||
* 无需通过 Point3D 的 .x()/.y()/.z() 间接获取。
|
||
*
|
||
* @ingroup foundation
|
||
*/
|
||
struct StlTriangle {
|
||
/// 面法向量(单位向量)
|
||
Vector3D normal;
|
||
/// 三个顶点(右手法则 CCW 顺序)
|
||
Point3D v0, v1, v2;
|
||
|
||
// ── 便捷分量访问:顶点 v0 ──
|
||
/// 顶点 v0 的 X 分量
|
||
[[nodiscard]] double v0x() const { return v0.x(); }
|
||
/// 顶点 v0 的 Y 分量
|
||
[[nodiscard]] double v0y() const { return v0.y(); }
|
||
/// 顶点 v0 的 Z 分量
|
||
[[nodiscard]] double v0z() const { return v0.z(); }
|
||
|
||
// ── 便捷分量访问:顶点 v1 ──
|
||
/// 顶点 v1 的 X 分量
|
||
[[nodiscard]] double v1x() const { return v1.x(); }
|
||
/// 顶点 v1 的 Y 分量
|
||
[[nodiscard]] double v1y() const { return v1.y(); }
|
||
/// 顶点 v1 的 Z 分量
|
||
[[nodiscard]] double v1z() const { return v1.z(); }
|
||
|
||
// ── 便捷分量访问:顶点 v2 ──
|
||
/// 顶点 v2 的 X 分量
|
||
[[nodiscard]] double v2x() const { return v2.x(); }
|
||
/// 顶点 v2 的 Y 分量
|
||
[[nodiscard]] double v2y() const { return v2.y(); }
|
||
/// 顶点 v2 的 Z 分量
|
||
[[nodiscard]] double v2z() const { return v2.z(); }
|
||
};
|
||
|
||
/**
|
||
* @brief 读取 STL 文件(自动检测格式)
|
||
*
|
||
* 通过检查文件头部的 80 字节判断二进制(含 triangle count)
|
||
* 还是 ASCII(以 "solid" 开头)格式,然后选择对应解析器。
|
||
*
|
||
* @param filepath STL 文件路径
|
||
* @return 三角形面片列表
|
||
*
|
||
* @throws std::runtime_error 若文件无法打开或格式无效
|
||
*
|
||
* @note 自动格式检测:二进制 STL 的 80 字节头后跟 4 字节三角形数量
|
||
* @note ASCII STL 以 "solid name" 开头
|
||
*
|
||
* @code{.cpp}
|
||
* auto tris = read_stl("part.stl");
|
||
* std::cout << "Triangles: " << tris.size() << "\n";
|
||
* @endcode
|
||
*
|
||
* @see write_stl, write_stl_ascii
|
||
* @ingroup foundation
|
||
*/
|
||
std::vector<StlTriangle> read_stl(const std::string& filepath);
|
||
|
||
/**
|
||
* @brief 写入二进制 STL 文件
|
||
*
|
||
* 以紧凑的二进制格式写出 STL 三角形列表。
|
||
* 二进制 STL 为业界标准交换格式,文件体积小、读写快。
|
||
*
|
||
* @param filepath 输出文件路径
|
||
* @param tris 三角形面片列表
|
||
*
|
||
* @note 二进制 STL 格式:80 字节头 + 4 字节三角形数 + 每三角形 50 字节
|
||
* @note 法向量在写入时自动归一化
|
||
*
|
||
* @code{.cpp}
|
||
* std::vector<StlTriangle> tris = // ...;
|
||
* write_stl("output.stl", tris); // 二进制,体积小
|
||
* @endcode
|
||
*
|
||
* @see read_stl, write_stl_ascii
|
||
* @ingroup foundation
|
||
*/
|
||
void write_stl(const std::string& filepath, const std::vector<StlTriangle>& tris);
|
||
|
||
/**
|
||
* @brief 写入 ASCII STL 文件
|
||
*
|
||
* 以人类可读的 ASCII 文本格式写出 STL,便于调试和手动编辑。
|
||
*
|
||
* @param filepath 输出文件路径
|
||
* @param tris 三角形面片列表
|
||
*
|
||
* @warning ASCII STL 文件体积约为二进制 STL 的 5-10 倍,不适合大规模网格
|
||
*
|
||
* @code{.cpp}
|
||
* std::vector<StlTriangle> tris = // ...;
|
||
* write_stl_ascii("debug.stl", tris); // 可读文本,便于调试
|
||
* @endcode
|
||
*
|
||
* @see read_stl, write_stl
|
||
* @ingroup foundation
|
||
*/
|
||
void write_stl_ascii(const std::string& filepath, const std::vector<StlTriangle>& tris);
|
||
|
||
} // namespace vde::foundation
|