From 06de5d8b1e5e19e4528861e7b24c5935245e3a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=82=E4=B9=8B=E9=92=B3?= Date: Mon, 27 Jul 2026 15:00:57 +0800 Subject: [PATCH] docs: finalize API-REFERENCE for v1.0.0 Replace 6942-line auto-generated reference with concise 150-line manual. Modules index, code examples, Doxygen link. --- docs/reference/API-REFERENCE.md | 7032 +------------------------------ 1 file changed, 111 insertions(+), 6921 deletions(-) diff --git a/docs/reference/API-REFERENCE.md b/docs/reference/API-REFERENCE.md index 4386c67..436729a 100644 --- a/docs/reference/API-REFERENCE.md +++ b/docs/reference/API-REFERENCE.md @@ -1,6942 +1,132 @@ # ViewDesignEngine API 参考手册 -> 版本 3.2.0 | 76 个头文件 - - -## 基础模块 (`vde::foundation`) - - -### `error_codes.h` - -**全局错误码枚举** -`enum class ErrorCode : int32_t {` - - - -### `exact_predicates.h` - -**二维定向测试结果** -`enum class Orientation { Clockwise, CounterClockwise, Collinear }` - - -**圆测试结果** -`enum class CircleTest { Inside, On, Outside }` - - -**自适应精度二维定向测试(Shewchuk 算法)** -`Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个点 | -| `b` | 第二个点 | -| `c` | 第三个点 | - -**返回**: Orientation::Collinear 若三点共线 -> Delaunay 三角剖分、凸包计算等几何算法的核心原语 - -**参见**: `orient_3d, in_circle` - - -**自适应精度三维定向测试** -`Orientation orient_3d(const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个点 | -| `b` | 第二个点 | -| `c` | 第三个点 | -| `d` | 第四个点(测试点) | - -**返回**: Orientation::Collinear 若四点共面 -> 三维 Delaunay 剖分和凸包计算的核心原语 - -**参见**: `orient_2d, in_circle` - - -**自适应精度圆内测试(In-Circle Test)** -`CircleTest in_circle(const Point2D& a, const Point2D& b,` - -| 参数 | 说明 | -|------|------| -| `a` | 三角形第一个顶点 | -| `b` | 三角形第二个顶点 | -| `c` | 三角形第三个顶点 | -| `d` | 待测试点 | - -**返回**: CircleTest::Outside 若 d 在三角形外接圆外部 -> Delaunay 三角剖分的空圆性质检查核心原语 - -**参见**: `orient_2d, orient_3d` - - -**自适应双精度谓词后端(默认)** - - -**二维定向测试** -`static exact::Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c) {` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三个二维点 | - -**返回**: 定向结果 - -**参见**: `exact::orient_2d` - - -**三维定向测试** -`static exact::Orientation orient_3d(const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c,d` | 四个三维点 | - -**返回**: 定向结果 - -**参见**: `exact::orient_3d` - - -**圆内测试** -`static exact::CircleTest in_circle(const Point2D& a, const Point2D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三角形三顶点 | -| `d` | 待测试点 | - -**返回**: 圆测试结果 - -**参见**: `exact::in_circle` - - - -### `exact_predicates_gmp.h` - -**GMP 精确算术谓词后端** -`struct GmpExact {` -> 仅在定义了 VDE_USE_GMP 宏且链接了 GMP 库时可用 - - -**精确有理数二维定向测试** -`static Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c) {` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个点 | -| `b` | 第二个点 | -| `c` | 第三个点 | - -**返回**: 定向结果(保证正确,无舍入误差) - -**参见**: `GmpExact::orient_3d, GmpExact::in_circle` - - -**精确有理数三维定向测试** -`static Orientation orient_3d(const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 定义平面的三点 | -| `d` | 待测试点 | - -**返回**: 定向结果(零误差) - -**参见**: `GmpExact::orient_2d` - - -**精确有理数圆内测试** -`static CircleTest in_circle(const Point2D& a, const Point2D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三角形三顶点 | -| `d` | 待测试点 | - -**返回**: 圆测试结果(零误差) - -**参见**: `GmpExact::orient_2d` - - - -### `format_utils.h` - -**以 CAD 级别精度格式化双精度浮点数** -`inline std::string fmt_double(double v, int precision = 12) {` - -| 参数 | 说明 | -|------|------| -| `v` | 要格式化的双精度数 | -| `precision` | 有效数字位数(默认 12) | - -**返回**: 格式化后的字符串,如 "1.234567890123e+02" -> 总是确保指数部分带符号(如 "e+00" 而非 "e00"),便于解析器统一处理 - -**参见**: `fmt_iges_real, fmt_point` - - -**IGES 格式实数输出** -`inline std::string fmt_iges_real(double v, int /*precision*/ = 12) {` - -| 参数 | 说明 | -|------|------| -| `v` | 要格式化的双精度数 | - -**返回**: IGES 格式字符串,如 "3.141592653590D+00" - -**参见**: `fmt_double` - - -**格式化三维点为逗号分隔字符串** -`inline std::string fmt_point(const core::Point3D& p, bool use_d = false) {` - -| 参数 | 说明 | -|------|------| -| `p` | 三维点 | -| `use_d` | 若为 true,使用 IGES 风格 D 指数标记 | - -**返回**: 逗号分隔的坐标字符串 - -**参见**: `fmt_double, fmt_iges_real` - - -**将字符串填充到恰好 72 个字符** -`inline std::string pad72(const std::string& s) {` - -| 参数 | 说明 | -|------|------| -| `s` | 输入字符串 | - -**返回**: 恰好 72 字符的字符串(不足右侧补空格,超出截断) - -**参见**: `format_iges_line` - - -**格式化 IGES 段落行** -`inline std::string format_iges_line(const std::string& data, char section_char, int seq) {` - -| 参数 | 说明 | -|------|------| -| `data` | 数据内容(最多 72 字符,超出截断) | -| `section_char` | 段落标识符(如 'P' 参数段, 'D' 目录段) | -| `seq` | 行序号(1-based) | - -**返回**: 完整 IGES 行(含换行符),共 81 字符 - -**参见**: `pad72` - - - -### `interval.h` - -**双精度区间算术类** - - -**从单值构造精确区间(退化为点)** -`Interval(double v) : lo(v), hi(v) {}` - -| 参数 | 说明 | -|------|------| -| `v` | 区间值,[v, v] | - - -**从上下界构造区间** -`Interval(double l, double h) : lo(std::min(l,h)), hi(std::max(l,h)) {}` - -| 参数 | 说明 | -|------|------| -| `l` | 下界 | -| `h` | 上界 | - - -**区间中点** -`[[nodiscard]] double mid() const { return (lo + hi) * 0.5; }` - -**返回**: (lo + hi) / 2 - - -**区间宽度** -`[[nodiscard]] double width() const { return hi - lo; }` - -**返回**: hi - lo - - -**判断区间是否包含给定值** -`[[nodiscard]] bool contains(double v) const { return lo <= v && v <= hi; }` - -| 参数 | 说明 | -|------|------| -| `v` | 测试值 | - -**返回**: true 若 lo ≤ v ≤ hi - - -**判断区间是否足够窄(收敛)** -`[[nodiscard]] bool is_exact(double eps = 1e-12) const { return width() < eps; }` - -| 参数 | 说明 | -|------|------| -| `eps` | 宽度阈值(默认 1e-12) | - -**返回**: true 若区间宽度 < eps - - -**判断两个区间是否有重叠** -`[[nodiscard]] bool overlaps(const Interval& o) const {` - -| 参数 | 说明 | -|------|------| -| `o` | 另一个区间 | - -**返回**: true 若存在公共点 - - -**确定性区间比较** -`[[nodiscard]] int cmp(const Interval& o) const {` - -| 参数 | 说明 | -|------|------| -| `o` | 另一个区间 | - -**返回**: 0 若区间重叠,无法确定 - - -**区间加法** -`Interval operator+(const Interval& o) const {` - -**返回**: [this.lo + o.lo, this.hi + o.hi] - - -**区间减法** -`Interval operator-(const Interval& o) const {` - -**返回**: [this.lo - o.hi, this.hi - o.lo](保守估计) - - -**区间乘法** -`Interval operator*(const Interval& o) const {` - -**返回**: [min(a*c,a*d,b*c,b*d), max(a*c,a*d,b*c,b*d)] - - -**区间除法** -`Interval operator/(const Interval& o) const {` - -**返回**: 结果区间或 [-∞, +∞](除数为零区间) - - -**区间平方根** -`[[nodiscard]] Interval sqrt() const {` - -**返回**: [sqrt(max(0, lo)), sqrt(max(0, hi))] - - -**从双精度值创建区间(含舍入误差带)** -`static Interval from_double(double v, double error = 0) {` - -| 参数 | 说明 | -|------|------| -| `v` | 中心值 | -| `error` | 误差半径(默认 0) | - -**返回**: [v - error, v + error] - - -**从坐标值创建区间(含 ULP 误差带)** -`static Interval from_coord(double v) {` - -| 参数 | 说明 | -|------|------| -| `v` | 坐标值 | - -**返回**: 包含浮点舍入误差的区间 - - -**二维定向行列式的区间验证** -`inline Interval orient_2d_interval(double ax, double ay, double bx, double by, double cx, double cy) {` - -| 参数 | 说明 | -|------|------| -| `ax,ay` | 点 a 的坐标 | -| `bx,by` | 点 b 的坐标 | -| `cx,cy` | 点 c 的坐标 | - -**返回**: 行列式的区间值 - -**参见**: `orient_2d_verified` - - -**使用区间算术验证 orient_2d 结果** -`inline int orient_2d_verified(double ax, double ay, double bx, double by, double cx, double cy) {` - -| 参数 | 说明 | -|------|------| -| `ax,ay` | 点 a 的坐标 | -| `bx,by` | 点 b 的坐标 | -| `cx,cy` | 点 c 的坐标 | - -**返回**: 1 确认 CounterClockwise - -**参见**: `orient_2d_interval, Interval::cmp` - - - -### `io_gltf.h` - -**glTF 2.0 导出选项** -`struct GltfOptions {` - - -**导出网格为 glTF 2.0 / GLB 格式** -`bool write_gltf(const std::string& filepath, const mesh::HalfedgeMesh& mesh,` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径(.glb 或 .gltf) | -| `mesh` | 要导出的半边网格 | -| `options` | 导出选项(格式、法线、颜色等) | - -**返回**: false 导出失败(文件无法创建等) -> 生成的 glTF 符合 2.0 规范,兼容 Blender、three.js、Unreal Engine 等工具 - -**参见**: `write_brep_gltf, GltfOptions` - - -**导出 B-Rep 模型为 GLB 格式(通过面片化)** -`bool write_brep_gltf(const std::string& filepath, const brep::BrepModel& model,` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径(建议 .glb) | -| `model` | 要导出的 B-Rep 模型 | -| `tessellation_res` | 每条边的离散段数(默认 32),越大越精确 | - -**返回**: false 导出失败 - -**参见**: `write_gltf` - - - -### `io_obj.h` - -**OBJ 文件解析结果数据结构** -`struct ObjMeshData {` - - -**每个面的顶点索引列表(0-based)** -`std::vector> faces` - - -**每个面的纹理坐标索引列表(0-based)** -`std::vector> face_texcoords` - - -**每个面的法线索引列表(0-based)** -`std::vector> face_normals` - - -**每个面对应的材质名称** -`std::vector face_materials` - - -**读取 Wavefront OBJ 文件** -`ObjMeshData read_obj(const std::string& filepath)` - -| 参数 | 说明 | -|------|------| -| `filepath` | OBJ 文件路径 | - -**返回**: 解析后的 ObjMeshData -> 不解析 MTL 材质文件,仅记录 usemtl 指令中的材质名称 -> 面索引在内部转换为 0-based;若文件中使用相对索引(负值),自动转换为正向 - -**参见**: `write_obj, ObjMeshData` - - -**写入 Wavefront OBJ 文件** -`void write_obj(const std::string& filepath, const ObjMeshData& data)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径 | -| `data` | 要写出的网格数据 | -> 输出的面索引为 1-based(OBJ 标准) - -**参见**: `read_obj` - - - -### `io_ply.h` - -**读取 PLY 文件(Stanford Polygon Format)** -`mesh::HalfedgeMesh read_ply(const std::string& filepath)` - -| 参数 | 说明 | -|------|------| -| `filepath` | PLY 文件路径 | - -**返回**: 解析后的半边网格 -> 自动检测文件头部 magic number 判断 ASCII / 二进制格式 -> 二进制格式仅支持小端序(little-endian) -> 返回类型为 HalfedgeMesh,内部自动建立半边拓扑 - -**参见**: `write_ply` - - -**写入 PLY 文件(ASCII 格式)** -`void write_ply(const std::string& filepath, const mesh::HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径 | -| `mesh` | 要导出的半边网格 | -> 输出的 PLY 为 ASCII 编码,易于人工阅读和编辑 -> 若需要二进制输出以提高性能,请使用 BinarySerializer - -**参见**: `read_ply, BinarySerializer` - - - -### `io_stl.h` - -**STL 三角形面片** -`struct StlTriangle {` - - -**读取 STL 文件(自动检测格式)** -`std::vector read_stl(const std::string& filepath)` - -| 参数 | 说明 | -|------|------| -| `filepath` | STL 文件路径 | - -**返回**: 三角形面片列表 -> 自动格式检测:二进制 STL 的 80 字节头后跟 4 字节三角形数量 -> ASCII STL 以 "solid name" 开头 - -**参见**: `write_stl, write_stl_ascii` - - -**写入二进制 STL 文件** -`void write_stl(const std::string& filepath, const std::vector& tris)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径 | -| `tris` | 三角形面片列表 | -> 二进制 STL 格式:80 字节头 + 4 字节三角形数 + 每三角形 50 字节 -> 法向量在写入时自动归一化 - -**参见**: `read_stl, write_stl_ascii` - - -**写入 ASCII STL 文件** -`void write_stl_ascii(const std::string& filepath, const std::vector& tris)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径 | -| `tris` | 三角形面片列表 | - -**参见**: `read_stl, write_stl` - - - -### `math_types.h` - -**通用 N 维点类型(使用 Eigen 列向量)** -`template ` - - -**通用 N 维向量类型(与 Point 相同的列向量表示)** -`template ` - - -**基础模块提供 VDE 引擎的核心基础设施:** -`/** @} */ // end of foundation group` - - - -### `memory_pool.h` - -**固定块大小的内存池** -`template ` -> 内存池不调用对象的构造函数/析构函数,仅管理原始内存 -> 适合 POD 类型或通过 placement new 手动管理生命周期的类型 - - -**构造内存池** -`explicit MemoryPool(size_t chunk_size = 1024) : chunk_size_(chunk_size) {}` - -| 参数 | 说明 | -|------|------| -| `chunk_size` | 每个内存块可容纳的对象数(默认 1024) | - - -**析构内存池,释放所有已分配的内存块** -`~MemoryPool() { for (auto* p : chunks_) ::operator delete(p); }` - - -**从池中分配 n 个 T 对象的内存** -`T* allocate(size_t n = 1) {` - -| 参数 | 说明 | -|------|------| -| `n` | 对象数量(当前未使用,保留用于 API 兼容) | - -**返回**: 指向未初始化内存的指针 - - -**将内存归还到池中** -`void deallocate(T* p, size_t = 1) {` - -| 参数 | 说明 | -|------|------| -| `p` | 之前从 allocate() 获取的指针 | - - -**分配一个新的内存块并初始化空闲链表** -`void allocate_chunk() {` - - - -### `predicates.h` - -**统一谓词接口 — 编译时选择 GMP 或自适应双精度后端** -`struct Predicates {` - - -**二维定向测试** -`static exact::Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c) {` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三点 | - -**返回**: 定向结果 - - -**三维定向测试** -`static exact::Orientation orient_3d(const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c,d` | 四点 | - -**返回**: 定向结果 - - -**圆内测试** -`static exact::CircleTest in_circle(const Point2D& a, const Point2D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三角形三顶点 | -| `d` | 测试点 | - -**返回**: 圆测试结果 - - -**二维定向测试便捷封装** -`inline exact::Orientation orient(const Point2D& a, const Point2D& b, const Point2D& c) {` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三个二维点 | - -**返回**: Orientation::Clockwise / CounterClockwise / Collinear - - -**三维定向测试便捷封装** -`inline exact::Orientation orient(const Point3D& a, const Point3D& b, const Point3D& c, const Point3D& d) {` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 定义平面的三点 | -| `d` | 测试点 | - -**返回**: Orientation::Clockwise / CounterClockwise / Collinear - - -**圆内测试便捷封装** -`inline exact::CircleTest in_circle(const Point2D& a, const Point2D& b, const Point2D& c, const Point2D& d) {` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三角形三顶点 | -| `d` | 测试点 | - -**返回**: CircleTest::Inside / On / Outside - - - -### `serializer.h` - -**二进制序列化格式的网格数据结构** -`struct SerializedMesh {` - - -**二进制序列化器** -> 该格式专为 VDE 内部快速读写设计,不适用于跨平台数据交换 -> 使用 glTF/OBJ/STL 进行外部交换,此格式用于本地缓存 - - -**序列化网格到二进制缓冲区** -`static std::vector serialize(const mesh::HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 要序列化的半边网格 | - -**返回**: 压缩后的二进制数据(含文件头) - - -**从二进制缓冲区反序列化网格** -`static mesh::HalfedgeMesh deserialize(const std::vector& data)` - -| 参数 | 说明 | -|------|------| -| `data` | 之前由 serialize() 生成的二进制数据 | - -**返回**: 恢复的半边网格 - - -**序列化并写入文件** -`static bool write_file(const std::string& path, const mesh::HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `path` | 输出文件路径 | -| `mesh` | 要保存的半边网格 | - -**返回**: false 文件创建失败 - -**参见**: `read_file` - - -**从文件读取并反序列化** -`static mesh::HalfedgeMesh read_file(const std::string& path)` - -| 参数 | 说明 | -|------|------| -| `path` | VDE 二进制格式文件路径 | - -**返回**: 恢复的半边网格 - -**参见**: `write_file` - - -**VDE 二进制文件魔数:"VDEGEOM\0"** - - -**VDE 二进制格式当前版本号** - - - -### `tolerance.h` - -**分层容差管理类** - - -**构造容差对象** -`Tolerance(double absolute = 1e-6, double relative = 1e-8,` - -| 参数 | 说明 | -|------|------| -| `absolute` | 绝对容差,默认 1e-6 | -| `relative` | 相对容差,默认 1e-8 | -| `angular` | 角度容差(弧度),默认 1e-8 | -| `snapping` | 吸附容差,默认 1e-4 | - - -**判断两点是否相等(基于绝对容差)** -`bool points_equal(const Eigen::MatrixXd& a, const Eigen::MatrixXd& b) const {` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个点(Eigen 矩阵) | -| `b` | 第二个点(Eigen 矩阵) | - -**返回**: true 若两点的欧氏距离 < absolute_ - - -**判断值是否接近零** -`template ` - -| 参数 | 说明 | -|------|------| -| `value` | 测试值 | - -**返回**: true 若 |value| < absolute_ - - -**混合容差相等判断** -`template ` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个值 | -| `b` | 第二个值 | - -**返回**: true 若两值在容差范围内相等 - - -**收紧容差** -`Tolerance tighten(double factor = 0.1) const {` - -| 参数 | 说明 | -|------|------| -| `factor` | 收紧因子(默认 0.1) | - -**返回**: 收紧后的新容差对象 - - -**放宽容差** -`Tolerance relax(double factor = 10.0) const {` - -| 参数 | 说明 | -|------|------| -| `factor` | 放宽因子(默认 10.0) | - -**返回**: 放宽后的新容差对象 - - -**合并两个容差,取更严格的(更小的)** -`static Tolerance min(const Tolerance& a, const Tolerance& b) {` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个容差 | -| `b` | 第二个容差 | - -**返回**: 每项取 min 的新容差 - - -**获取全局容差实例** -`static Tolerance& global() { return global_; }` - -**返回**: 全局容差的引用 - - -**设置全局容差** -`static void set_global(const Tolerance& tol) { global_ = tol; }` - -| 参数 | 说明 | -|------|------| -| `tol` | 新的全局容差 | -> 推荐使用 ToleranceScope 进行临时修改,确保自动恢复 - - -**局部容差作用域(RAII)** - - -**进入新的容差作用域** -`explicit ToleranceScope(const Tolerance& tol) : previous_(Tolerance::global()) {` - -| 参数 | 说明 | -|------|------| -| `tol` | 此作用域内使用的容差 | - - -**退出容差作用域,恢复之前的全局容差** -`~ToleranceScope() { Tolerance::set_global(previous_); }` - - - -## 核心几何 (`vde::core`) - - -### `aabb.h` - -**轴对齐包围盒(AABB)** -`template ` -> 初始状态为空(min = +∞, max = -∞),需要通过 expand() 初始化 - - -**构造空包围盒** -`AABB() : min_(Point3D::Constant(std::numeric_limits::max())),` - - -**从两个角点构造包围盒** -`AABB(const Point3D& min, const Point3D& max) : min_(min), max_(max) {}` - -| 参数 | 说明 | -|------|------| -| `min` | 最小角点 | -| `max` | 最大角点 | - - -**扩展包围盒以包含给定点** -`void expand(const Point3D& p) {` - -| 参数 | 说明 | -|------|------| -| `p` | 要包含的点 | - - -**扩展包围盒以包含另一个 AABB** -`void expand(const AABB& other) {` - -| 参数 | 说明 | -|------|------| -| `other` | 另一个包围盒 | - - -**包围盒中心点** -`[[nodiscard]] Point3D center() const { return (min_ + max_) * 0.5; }` - -**返回**: (min + max) / 2 - - -**包围盒对角线向量(从 min 到 max)** -`[[nodiscard]] Vector3D extent() const { return max_ - min_; }` - -**返回**: max - min - - -**包围盒表面积** -`[[nodiscard]] T surface_area() const {` - -**返回**: 2 * (dx*dy + dy*dz + dz*dx) - - -**包围盒体积** -`[[nodiscard]] T volume() const {` - -**返回**: dx * dy * dz - - -**测试点是否在包围盒内部(含边界)** -`[[nodiscard]] bool contains(const Point3D& p) const {` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | - -**返回**: true 若 min ≤ p ≤ max(各分量) - - -**测试两个包围盒是否相交(含边界接触)** -`[[nodiscard]] bool intersects(const AABB& other) const {` - -| 参数 | 说明 | -|------|------| -| `other` | 另一个包围盒 | - -**返回**: true 若存在交集 - - - -### `convex_hull.h` - -**二维凸包计算(Graham Scan 算法)** -`std::vector convex_hull_2d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入点集(至少 3 个不共线点) | - -**返回**: 凸包顶点序列(逆时针排列),不含共线的中间点 -> 自动过滤共线点,返回严格的凸包顶点 -> 若所有点共线,返回两个端点 - -**参见**: `convex_hull_3d, Polygon2D::convex_hull_2d` - - -**三维凸包计算(QuickHull 算法)** -`std::vector> convex_hull_3d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入点集(至少 4 个不共面点) | - -**返回**: 凸包三角形列表,每个三角形三顶点按逆时针排列(从外部观察) -> 返回的三角形法线方向朝外 -> 共面/退化点被自动丢弃 - -**参见**: `convex_hull_2d` - - - -### `distance.h` - -**两点之间的欧氏距离** -`double distance(const Point3D& a, const Point3D& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个点 | -| `b` | 第二个点 | - -**返回**: ||b - a|| - - -**点到直线的距离** -`double distance(const Point3D& p, const Line3D& line)` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | -| `line` | 直线 | - -**返回**: 垂直距离 - - -**点到线段的距离** -`double distance(const Point3D& p, const Segment3D& seg)` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | -| `seg` | 线段 | - -**返回**: 最短距离 - - -**点到平面的距离** -`double distance(const Point3D& p, const Plane& plane)` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | -| `plane` | 平面 | - -**返回**: 绝对垂直距离 - -**参见**: `Plane::signed_distance` - - -**点到三角形的距离** -`double distance(const Point3D& p, const Triangle& tri)` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | -| `tri` | 三角形 | - -**返回**: 最短距离 - - -**点到包围盒的距离** -`double distance(const Point3D& p, const AABB& box)` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | -| `box` | 包围盒 | - -**返回**: 最短距离(内部点返回 0) - - -**两条线段之间的最短距离** -`double distance(const Segment3D& a, const Segment3D& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一条线段 | -| `b` | 第二条线段 | - -**返回**: 最短距离(若相交则为 0) - - -**两条直线之间的最短距离** -`double distance(const Line3D& a, const Line3D& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一条直线 | -| `b` | 第二条直线 | - -**返回**: 最短距离 - - -**两个包围盒之间的最短距离** -`double distance(const AABB& a, const AABB& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个包围盒 | -| `b` | 第二个包围盒 | - -**返回**: 最短距离 - - -**两个三角形之间的最短距离** -`double distance(const Triangle& a, const Triangle& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个三角形 | -| `b` | 第二个三角形 | - -**返回**: 最短距离(若相交则为 0) - - -**三角形上距给定点最近的点** -`Point3D closest_point(const Point3D& p, const Triangle& tri)` - -| 参数 | 说明 | -|------|------| -| `p` | 查询点 | -| `tri` | 三角形 | - -**返回**: 三角形上距离 p 最近的点 - - -**线段上距给定点最近的点** -`Point3D closest_point(const Point3D& p, const Segment3D& seg)` - -| 参数 | 说明 | -|------|------| -| `p` | 查询点 | -| `seg` | 线段 | - -**返回**: 线段上距离 p 最近的点(可能为端点) - - -**包围盒上距给定点最近的点** -`Point3D closest_point(const Point3D& p, const AABB& box)` - -| 参数 | 说明 | -|------|------| -| `p` | 查询点 | -| `box` | 包围盒 | - -**返回**: 包围盒边界上(或内部)距离 p 最近的点 - - -**平面上距给定点最近的点(正交投影)** -`Point3D closest_point(const Point3D& p, const Plane& plane)` - -| 参数 | 说明 | -|------|------| -| `p` | 查询点 | -| `plane` | 平面 | - -**返回**: 点 p 在平面上的正交投影 - -**参见**: `Plane::project` - - - -### `icp.h` - -**ICP(迭代最近点)配准结果** -`struct ICPResult {` - - -**配准后的均方根误差** -`double rms_error` - - -**迭代最近点(ICP)刚体点云配准** -`[[nodiscard]] ICPResult icp_register(const std::vector& source,` - -| 参数 | 说明 | -|------|------| -| `source` | 源点云(将被移动) | -| `target` | 目标点云(固定参考) | -| `max_iter` | 最大迭代次数(默认 50) | -| `tolerance` | 收敛容差:相邻两次 RMS 变化的阈值(默认 1e-6) | - -**返回**: 配准结果,包含最终变换和误差 -> source 和 target 点数可以不同 -> 初始对齐越好,收敛越快;若初始偏差太大,可能收敛到局部最优 - - - -### `line.h` - -**三维无限直线** -`template ` - - -**从原点和方向构造直线** -`Line3D(const Point3D& origin, const Vector3D& direction)` - -| 参数 | 说明 | -|------|------| -| `origin` | 直线上一点 | -| `direction` | 方向向量(自动归一化) | - - -**参数方程求点** -`[[nodiscard]] Point3D point_at(T t) const { return origin_ + direction_ * t; }` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | - -**返回**: origin + direction * t - - -**三维线段** -`template ` - - -**从两个端点构造线段** -`Segment3D(const Point3D& p0, const Point3D& p1) : p0_(p0), p1_(p1) {}` - -| 参数 | 说明 | -|------|------| -| `p0` | 起点 | -| `p1` | 终点 | - - -**方向向量(未归一化)** -`[[nodiscard]] Vector3D direction() const { return p1_ - p0_; }` - -**返回**: p1 - p0 - - -**线段长度** -`[[nodiscard]] T length() const { return direction().norm(); }` - -**返回**: ||p1 - p0|| - - -**三维射线** -`template ` - - -**从原点和方向构造射线** -`Ray3D(const Point3D& origin, const Vector3D& direction)` - -| 参数 | 说明 | -|------|------| -| `origin` | 射线起点 | -| `direction` | 方向向量(自动归一化) | - - -**参数方程求点(t ≥ 0)** -`[[nodiscard]] Point3D point_at(T t) const { return origin_ + direction_ * t; }` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值(应为非负) | - -**返回**: origin + direction * t - - - -### `plane.h` - -**三维平面** -`template ` - - -**从点和法线构造平面** -`Plane(const Point3D& point, const Vector3D& normal)` - -| 参数 | 说明 | -|------|------| -| `point` | 平面上一点 | -| `normal` | 法向量(自动归一化) | - - -**从三点构造平面** -`Plane(const Point3D& a, const Point3D& b, const Point3D& c)` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 平面上不共线的三点(右手定则决定法线方向) | - - -**获取平面方程常数 d** -`[[nodiscard]] T d() const { return d_; }` - -**返回**: d 值 - - -**有向点到平面距离** -`[[nodiscard]] T signed_distance(const Point3D& p) const { return normal_.dot(p) + d_; }` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | - -**返回**: normal · p + d - - -**绝对点到平面距离** -`[[nodiscard]] T distance(const Point3D& p) const { return std::abs(signed_distance(p)); }` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | - -**返回**: |signed_distance(p)| - - -**点在平面上的正交投影** -`[[nodiscard]] Point3D project(const Point3D& p) const {` - -| 参数 | 说明 | -|------|------| -| `p` | 原点 | - -**返回**: 投影点(满足在平面上且连线垂直于平面) - - - -### `point.h` - -**核心模块提供 VDE 引擎的几何操作 API:** - - -**通用 N 维点类型(重新导出,便于 core 模块使用)** -`template ` - - -**通用 N 维向量类型(重新导出)** -`template ` - - - -### `polygon.h` - -**二维平面多边形** -> 内部假设简单多边形(无自交),非简单多边形的行为未定义 -> 所有几何计算基于(假设的)XY 平面 - - -**从顶点列表构造多边形** -`explicit Polygon2D(std::vector vertices) : vertices_(std::move(vertices)) {}` - -| 参数 | 说明 | -|------|------| -| `vertices` | 顶点序列(逆时针或顺时针均可) | - - -**有向面积(Shoelace 公式)** -`[[nodiscard]] double signed_area() const` - -**返回**: 有向面积 - - -**绝对面积** -`[[nodiscard]] double area() const { return std::abs(signed_area()); }` - -**返回**: |signed_area()| - - -**周长(各边长之和)** -`[[nodiscard]] double perimeter() const` - -**返回**: 总边长 - - -**面积加权质心** -`[[nodiscard]] Point2D centroid() const` - -**返回**: 质心坐标 - - -**二维轴对齐包围盒** -`[[nodiscard]] AABB bounding_box() const` - -**返回**: 包围盒 - - -**点包含测试(射线法)** -`[[nodiscard]] bool contains(const Point2D& p) const` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点 | - -**返回**: true 若点在多边形内部或边界上 -> 边界上的点也返回 true - - -**多边形是否为逆时针方向** -`[[nodiscard]] bool is_ccw() const { return signed_area() > 0; }` - -**返回**: signed_area() > 0 - - -**Douglas-Peucker 简化** -`[[nodiscard]] Polygon2D simplify(double tolerance) const` - -| 参数 | 说明 | -|------|------| -| `tolerance` | 允许的最大偏差 | - -**返回**: 简化后的新多边形 - -**参见**: `triangulate` - - -**耳切法三角剖分(Ear Clipping)** -`[[nodiscard]] std::vector> triangulate() const` - -**返回**: 三角形列表,每个元素为 {i, j, k} 表示顶点索引 -> 时间复杂度 O(n²),适用于顶点数 < 1000 的多边形 - -**参见**: `simplify` - - -**Andrew's Monotone Chain 二维凸包** -`static Polygon2D convex_hull_2d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入点集 | - -**返回**: 凸包多边形(CCW,不含共线中间点) - -**参见**: `convex_hull_2d` - - - -### `transform.h` - -**三维仿射变换类型** -`using Transform3D = Eigen::Transform` - - -**创建平移变换** -`inline Transform3D translate(const Vector3D& v) {` - -| 参数 | 说明 | -|------|------| -| `v` | 平移向量 | - -**返回**: 平移变换矩阵 - - -**创建平移变换(分量形式)** -`inline Transform3D translate(double x, double y, double z) {` - -| 参数 | 说明 | -|------|------| -| `x` | X 方向位移 | -| `y` | Y 方向位移 | -| `z` | Z 方向位移 | - -**返回**: 平移变换矩阵 - - -**创建旋转变换(轴-角表示)** -`inline Transform3D rotate(const Vector3D& axis, double angle_rad) {` - -| 参数 | 说明 | -|------|------| -| `axis` | 旋转轴(自动归一化) | -| `angle_rad` | 旋转角度(弧度) | - -**返回**: 旋转变换矩阵 - - -**绕 X 轴旋转** -`inline Transform3D rotate_x(double rad) { return rotate(Vector3D::UnitX(), rad); }` - -| 参数 | 说明 | -|------|------| -| `rad` | 旋转角度(弧度) | - -**返回**: 旋转变换矩阵 - - -**绕 Y 轴旋转** -`inline Transform3D rotate_y(double rad) { return rotate(Vector3D::UnitY(), rad); }` - -| 参数 | 说明 | -|------|------| -| `rad` | 旋转角度(弧度) | - -**返回**: 旋转变换矩阵 - - -**绕 Z 轴旋转** -`inline Transform3D rotate_z(double rad) { return rotate(Vector3D::UnitZ(), rad); }` - -| 参数 | 说明 | -|------|------| -| `rad` | 旋转角度(弧度) | - -**返回**: 旋转变换矩阵 - - -**创建非均匀缩放变换** -`inline Transform3D scale(double sx, double sy, double sz) {` - -| 参数 | 说明 | -|------|------| -| `sx` | X 方向缩放因子 | -| `sy` | Y 方向缩放因子 | -| `sz` | Z 方向缩放因子 | - -**返回**: 缩放变换矩阵 -> 非均匀缩放可能导致法线方向不准确;使用场景中应考虑法线变换 = (M^{-1})^T - - -**创建均匀缩放变换** -`inline Transform3D scale(double s) { return scale(s, s, s); }` - -| 参数 | 说明 | -|------|------| -| `s` | 各方向统一的缩放因子 | - -**返回**: 缩放变换矩阵 - - - -### `triangle.h` - -**三维三角形** -`template ` - - -**从三个顶点构造三角形** -`Triangle(const Point3D& v0, const Point3D& v1, const Point3D& v2)` - -| 参数 | 说明 | -|------|------| -| `v0` | 第一个顶点 | -| `v1` | 第二个顶点 | -| `v2` | 第三个顶点 | - - -**获取第 i 个顶点** -`[[nodiscard]] const Point3D& v(int i) const { return v_[i]; }` - -| 参数 | 说明 | -|------|------| -| `i` | 顶点索引(0, 1, 2) | - -**返回**: 顶点引用 - - -**三角形单位法向量** -`[[nodiscard]] Vector3D normal() const {` - -**返回**: 单位法向量 -> 若三角形退化(面积为零),返回零向量 - - -**三角形面积** -`[[nodiscard]] T area() const {` - -**返回**: 0.5 * ||(v1 - v0) × (v2 - v0)|| - - -**三角形质心(几何中心)** -`[[nodiscard]] Point3D centroid() const {` - -**返回**: (v0 + v1 + v2) / 3 - - -**重心坐标包含测试** -`[[nodiscard]] bool contains(const Point3D& p) const {` - -| 参数 | 说明 | -|------|------| -| `p` | 测试点(三维空间中的任意点) | - -**返回**: true 若投影点在三角形内部或边界上 -> 该测试等效于三维点在三角形上的包含测试(先投影再测试) - - - -### `voronoi.h` - -**Voronoi 单元格** -`struct VoronoiCell {` - - -**单元格边界顶点(按逆时针顺序排列)** -`std::vector vertices` - - -**单元格边界边** -`std::vector> edges` - - -**二维 Voronoi 图生成(通过 Delaunay 对偶图)** -`std::vector voronoi_2d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入点集(站点) | - -**返回**: 每个站点对应的 VoronoiCell 列表(顺序与输入一致) -> 对于凸包边界上的站点,对应的 Voronoi 单元格无界,顶点不完全闭合 -> 内部使用 Delaunay 三角剖分作为中间步骤 - - +> v1.0.0-rc.1 · 11 模块 · 完整 API 文档见 [Doxygen](api/html/index.html) + +## 模块索引 + +| 模块 | 命名空间 | 核心类/函数 | +|------|---------|-----------| +| **foundation** | `vde::foundation` | `ToleranceConfig`, `import_step_file`, `export_step_file` | +| **core** | `vde::core` | `Point3D`, `Vector3D`, `AABB3D`, `Tool`, `ObjectPool` | +| **curves** | `vde::curves` | `NurbsCurve`, `NurbsSurface`, `sweep_surface`, `loft_surface` | +| **mesh** | `vde::mesh` | `HalfedgeMesh`, `marching_cubes`, `tetrahedral_mesh` | +| **spatial** | `vde::spatial` | `BVH`, `Octree`, `KDTree`, `RTree` | +| **boolean** | `vde::boolean` | `boolean_union_2d`, `mesh_union` | +| **collision** | `vde::collision` | `gjk_intersect`, `ray_intersect_triangle` | +| **brep** | `vde::brep` | `BrepModel`, `make_box`, `brep_union`, `validate` | +| **sdf** | `vde::sdf` | `SdfNode`, `evaluate`, `sdf_to_mesh` | +| **sketch** | `vde::sketch` | `ConstraintSolver` | +| **capi** | `vde::capi` | C API `vde_*` 函数 | + +## 基础类型 (`vde::core`) + +```cpp +// 3D 点 +Point3D p(1.0, 2.0, 3.0); +double x = p.x(), y = p.y(), z = p.z(); + +// 3D 向量 +Vector3D v = p2 - p1; +double len = v.norm(); +Vector3D n = v.normalized(); +double dot = a.dot(b); +Vector3D cross = a.cross(b); + +// 包围盒 +AABB3D box(p_min, p_max); +box.expand(point); +bool hit = box.intersects(other); +auto center = box.center(); +``` + +## B-Rep 建模 (`vde::brep`) + +```cpp +// 创建 +auto box = make_box(2, 3, 4); +auto cyl = make_cylinder(1.5, 6, 32); +auto sphere = make_sphere(2, 32, 16); + +// 布尔 +auto result = brep_union(a, b); +auto result = brep_intersection(a, b); +auto result = brep_difference(a, b); + +// 修复 +heal_topology(body); +auto report = validate(body); // ValidationReport + +// 直接建模 +push_pull(body, face_id, 5.0); +tweak_face(body, face_id, 2.0); + +// 转换 +auto mesh = body.to_mesh(0.01); // HalfedgeMesh +auto bb = body.bounds(); // AABB3D +size_t n = body.num_faces(); +const auto& f = body.face(id); +``` ## 曲线曲面 (`vde::curves`) +```cpp +// 求值 +Point3D p = surf.evaluate(u, v); +Vector3D n = surf.normal(u, v); -### `bezier_curve.h` +// 分析 +auto cmap = curvature_map(surf, 64, 64); +auto cont = surface_continuity(a, b, edge); -**任意阶 Bézier 曲线** +// 生成 +auto swept = sweep_surface(profile, path); +auto lofted = loft_surface(sections); +auto netted = net_surface(u_curves, v_curves); +``` +## 网格 (`vde::mesh`) -**构造 Bézier 曲线** -`explicit BezierCurve(std::vector control_points)` +```cpp +// 简化 +auto simplified = simplify_mesh(mesh, 0.5); -| 参数 | 说明 | -|------|------| -| `control_points` | 控制点序列,点数 = degree + 1,最少 2 个 | -> 控制点数量决定了曲线阶次;点数越多,曲线越灵活但计算越昂贵 +// MC +auto mesh = marching_cubes(sdf, bounds, 64); +// FEA +auto tets = tetrahedral_mesh(body, TetraParams{}); +auto hex = mapped_hex_mesh(body, src, tgt); +``` -**在参数 t 处求值曲线点** -`[[nodiscard]] Point3D evaluate(double t) const` +## 格式 IO (`vde::foundation`) -| 参数 | 说明 | -|------|------| -| `t` | 参数值,范围 [0, 1] | +```cpp +// STEP +auto body = import_step_file("input.step"); +export_step_file(body, "output.step"); -**返回**: 曲线上对应 t 的点坐标 -> 使用 de Casteljau 递推算法,O(n²) 复杂度 +// IGES +auto body = import_iges_file("input.igs"); +// 工业格式 +auto body = import_parasolid_xt("model.x_t"); +auto body = import_acis_sat("model.sat"); +auto body = import_jt("model.jt"); +``` -**在参数 t 处求导数** -`[[nodiscard]] Vector3D derivative(double t, int order = 1) const` +## CAM (`vde::core`) -| 参数 | 说明 | -|------|------| -| `t` | 参数值,范围 [0, 1] | -| `order` | 导数阶数,1 = 一阶(切向量),2 = 二阶(曲率相关) | +```cpp +Tool tool{ToolType::ENDMILL, 10.0, 4, 50.0}; -**返回**: 导数向量 -> 高阶导数通过降阶 Bézier 曲线计算: +auto rough = roughing_toolpath(body, tool, {}); +auto finish = finishing_toolpath(body, tool, {}); +auto drill = drilling_toolpath(points, tool, {5, 10}); +FanucPost post; +auto gcode = post.generate(toolpath); +``` -**曲线阶次** -`[[nodiscard]] int degree() const { return static_cast(cp_.size()) - 1; }` - -**返回**: 阶次 = 控制点数 - 1 - - -**参数定义域** -`[[nodiscard]] std::pair domain() const { return {0.0, 1.0}; }` - -**返回**: 固定为 [0, 1] - - -**控制点访问** -`[[nodiscard]] const std::vector& control_points() const { return cp_; }` - -**返回**: 控制点向量的只读引用 - - -**在 t 处将曲线一分为二** -`[[nodiscard]] std::pair split(double t) const` - -| 参数 | 说明 | -|------|------| -| `t` | 分割参数,范围 [0, 1] | - -**返回**: 左段 + 右段两条 Bézier 曲线 -> 使用 de Casteljau 分割算法,分割点为三角阵的对角线 - - -**升阶操作** -`[[nodiscard]] BezierCurve degree_elevate(int times = 1) const` - -| 参数 | 说明 | -|------|------| -| `times` | 升阶次数,≥ 1 | - -**返回**: 升阶后的 Bézier 曲线(控制点数增加 times,形状不变) -> 通过反复应用公式 P_i' = i/(n+1) P_{i-1} + (1 - i/(n+1)) P_i - -**参见**: `split` - - - -### `bezier_surface.h` - -**Bézier 张量积曲面** - - -**构造 Bézier 曲面** -`BezierSurface(std::vector> control_grid)` - -| 参数 | 说明 | -|------|------| -| `control_grid` | 控制点网格,grid[i][j] 对应 u 方向第 i 个、v 方向第 j 个控制点 | -> grid 必须矩整(所有行等长);grid.size() = degree_u+1, grid[0].size() = degree_v+1 - - -**求曲面点 S(u,v)** -`[[nodiscard]] Point3D evaluate(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数,范围 [0, 1] | -| `v` | v 参数,范围 [0, 1] | - -**返回**: 曲面上对应 (u,v) 的 3D 坐标 -> 张量积求值:先按 v 方向对每行做 de Casteljau,再沿 u 方向对结果做一次 - - -**u 方向偏导数 ∂S/∂u** -`[[nodiscard]] Vector3D derivative_u(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: u 方向切向量 -> 通过降阶 Bézier 曲线计算:对 v 求值后沿 u 求导 - - -**v 方向偏导数 ∂S/∂v** -`[[nodiscard]] Vector3D derivative_v(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: v 方向切向量 - - -**单位法向量 N(u,v) = (∂S/∂u × ∂S/∂v) / |…|** -`[[nodiscard]] Vector3D normal(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: 归一化法向量(指向曲面的特选侧) -> 当两个偏导数平行时返回零向量(奇异点) - - -**u 向阶次** -`[[nodiscard]] int degree_u() const { return static_cast(cp_.size()) - 1; }` - -**返回**: u 方向阶次(控制点行数 - 1) - - -**v 向阶次** -`[[nodiscard]] int degree_v() const { return static_cast(cp_[0].size()) - 1; }` - -**返回**: v 方向阶次(控制点列数 - 1) - - -**一维 de Casteljau 求值(内部辅助)** -`[[nodiscard]] Point3D de_casteljau(double t, const std::vector& pts) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数 | -| `pts` | 一维控制点序列 | - -**返回**: 求值结果 - - - -### `bspline_curve.h` - -**B 样条曲线(非有理、均匀/非均匀节点)** - - -**构造 B 样条曲线** -`BSplineCurve(std::vector control_points,` - -| 参数 | 说明 | -|------|------| -| `control_points` | n+1 个控制点 | -| `knots` | 节点向量,必须为非递减序列 | -| `degree` | 阶次 p | -> 节点数量 = 控制点数 + 阶次 + 1;clamped 端点多重度为 p+1 - - -**在参数 t 处求值曲线点** -`[[nodiscard]] Point3D evaluate(double t) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值,必须在 domain() 范围内 | - -**返回**: 曲线上对应 t 的点坐标 -> 使用 de Boor(Cox-de Boor)递推算法 - - -**在参数 t 处求导数** -`[[nodiscard]] Vector3D derivative(double t, int order = 1) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | -| `order` | 导数阶数,1 = 一切向量 | - -**返回**: 导数向量 -> B 样条导数公式: - - -**曲线阶次** -`[[nodiscard]] int degree() const { return degree_; }` - -**返回**: 阶次 p - - -**参数定义域** -`[[nodiscard]] std::pair domain() const` - -**返回**: 有效参数范围 [knots[p], knots[n+1]] - - -**控制点访问** -`[[nodiscard]] const std::vector& control_points() const { return cp_; }` - -**返回**: 控制点数组只读引用 - - -**节点向量访问** -`[[nodiscard]] const std::vector& knots() const { return knots_; }` - -**返回**: 节点向量只读引用 - - -**查找 t 所在的节点区间** -`[[nodiscard]] int find_span(double t) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | - -**返回**: 节点区间索引 i 满足 knots[i] ≤ t < knots[i+1] -> 使用二分查找,O(log n);求值和基函数的前置步骤 - - -**在 t 处求非零基函数值** -`[[nodiscard]] std::vector basis_functions(double t, int span = -1) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | -| `span` | 节点区间索引,-1 表示自动查找 | - -**返回**: N_{span-p}(t), ..., N_{span}(t) 共 p+1 个值 -> 仅返回 p+1 个非零基函数;用于端点求值及插值 - -**参见**: `find_span` - - -**在 t 处求非零基函数的一阶导数** -`[[nodiscard]] std::vector basis_derivatives(double t, int span = -1) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | -| `span` | 节点区间索引,-1 表示自动查找 | - -**返回**: dN_{span-p}/du, ..., dN_{span}/du 共 p+1 个值 -> B 样条基函数导数递推: - -**参见**: `basis_functions` - - - -### `bspline_surface.h` - -**B 样条张量积曲面(非有理)** - - -**构造 B 样条曲面** -`BSplineSurface(std::vector> control_grid,` - -| 参数 | 说明 | -|------|------| -| `control_grid` | (nu+1)×(nv+1) 控制点网格 | -| `knots_u` | u 向节点向量,长度 = nu + pu + 1 | -| `knots_v` | v 向节点向量,长度 = nv + pv + 1 | -| `degree_u` | u 向阶次 pu | -| `degree_v` | v 向阶次 pv | - - -**求曲面点 S(u,v)** -`[[nodiscard]] Point3D evaluate(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: 曲面上的 3D 点 -> 张量积分解:先行后列(或先列后行)做两次 B 样条求值 - - -**u 向偏导数 ∂S/∂u** -`[[nodiscard]] Vector3D derivative_u(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: u 向切向量 - - -**v 向偏导数 ∂S/∂v** -`[[nodiscard]] Vector3D derivative_v(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: v 向切向量 - - -**单位法向量** -`[[nodiscard]] Vector3D normal(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: N(u,v) = (∂S/∂u × ∂S/∂v) / |…| - - -**u 向阶次** -`[[nodiscard]] int degree_u() const { return degree_u_; }` - -**返回**: pu - - -**v 向阶次** -`[[nodiscard]] int degree_v() const { return degree_v_; }` - -**返回**: pv - - -**u 向节点向量** -`[[nodiscard]] const std::vector& knots_u() const { return knots_u_; }` - -**返回**: 只读引用 - - -**v 向节点向量** -`[[nodiscard]] const std::vector& knots_v() const { return knots_v_; }` - -**返回**: 只读引用 - - - -### `nurbs_curve.h` - -**NURBS 曲线(Non-Uniform Rational B-Spline)** - - -**构造 NURBS 曲线** -`NurbsCurve(std::vector control_points, std::vector knots,` - -| 参数 | 说明 | -|------|------| -| `control_points` | 控制点序列 | -| `knots` | 节点向量 | -| `weights` | 权重序列,必须与 control_points 等长,各分量 > 0 | -| `degree` | 阶次 p | -> 所有权重必须 > 0 以保证分母不为零(非退化) - - -**在参数 t 处求值** -`[[nodiscard]] Point3D evaluate(double t) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | - -**返回**: 曲线上对应 t 的点坐标 -> 内部将 (w·P, w) 提升为齐次坐标的 B 样条,求值后投影回 3D - - -**在参数 t 处求导数** -`[[nodiscard]] Vector3D derivative(double t, int order = 1) const` - -| 参数 | 说明 | -|------|------| -| `t` | 参数值 | -| `order` | 导数阶数 | - -**返回**: 导数向量 -> 有理导数公式: - - -**曲线阶次** -`[[nodiscard]] int degree() const { return degree_; }` - -**返回**: p - - -**参数定义域** -`[[nodiscard]] std::pair domain() const` - -**返回**: [knots[degree], knots[n+1]] - - -**控制点访问** -`[[nodiscard]] const std::vector& control_points() const { return cp_; }` - -**返回**: 只读引用 - - -**权重访问** -`[[nodiscard]] const std::vector& weights() const { return weights_; }` - -**返回**: 只读引用 - - -**节点向量访问** -`[[nodiscard]] const std::vector& knots() const { return knots_; }` - -**返回**: 只读引用 - - - -### `nurbs_operations.h` - -**NURBS 曲面等距偏移** -`[[nodiscard]] NurbsSurface offset_surface(const NurbsSurface& surf, double distance)` - -| 参数 | 说明 | -|------|------| -| `surf` | 输入 NURBS 曲面 | -| `distance` | 偏移距离(正值 = 沿法向外,负值 = 向内) | - -**返回**: 偏移后的 NURBS 曲面(近似,阶次与原曲面相同) -> 这是几何近似,非精确偏移。对于大变曲率曲面,增大控制点数量 -> 偏移可能导致自交(distance 超过曲面局部曲率半径时) - -**参见**: `trim_surface blend_surfaces` - - -**NURBS 曲面参数域裁剪** -`[[nodiscard]] NurbsSurface trim_surface(const NurbsSurface& surf,` - -| 参数 | 说明 | -|------|------| -| `surf` | 输入曲面 | -| `u_min,u_max` | 裁剪后的 u 参数范围(必须在原 domain 内) | -| `v_min,v_max` | 裁剪后的 v 参数范围(必须在原 domain 内) | - -**返回**: 裁剪后的 NURBS 曲面 -> 裁剪是"软裁剪"——几何不变,仅改变参数化。如需"硬裁剪" - - -**两 NURBS 曲面沿边界边的过渡面** -`[[nodiscard]] NurbsSurface blend_surfaces(const NurbsSurface& surf_a,` - -| 参数 | 说明 | -|------|------| -| `surf_a` | 第一个曲面 | -| `surf_b` | 第二个曲面 | -| `edge_a` | surf_a 的边界边索引(0=u_min, 1=u_max, 2=v_min, 3=v_max) | -| `edge_b` | surf_b 的边界边索引(0=u_min, 1=u_max, 2=v_min, 3=v_max) | -| `blend_radius` | 过渡半径 | - -**返回**: 过渡 NURBS 曲面(在偏移边界曲线间的直纹面) -> 过渡面与原始曲面在边界处为 C⁰ 连续(非切线连续) - -**参见**: `ruled_surface` - - -**两 NURBS 曲线间的直纹面** -`[[nodiscard]] NurbsSurface ruled_surface(const NurbsCurve& curve_a,` - -| 参数 | 说明 | -|------|------| -| `curve_a` | 第一条曲线(v=0 边界) | -| `curve_b` | 第二条曲线(v=1 边界) | - -**返回**: 直纹 NURBS 曲面 -> 两条曲线需有兼容的阶次和节点结构(内部执行升阶和节点精化) - -**参见**: `coons_patch blend_surfaces` - - -**由四条边界曲线创建 Coons 曲面** -`[[nodiscard]] NurbsSurface coons_patch(const NurbsCurve& curve_u0,` - -| 参数 | 说明 | -|------|------| -| `curve_u0` | v=0 处边界(沿 u 方向) | -| `curve_u1` | v=1 处边界(沿 u 方向) | -| `curve_v0` | u=0 处边界(沿 v 方向) | -| `curve_v1` | u=1 处边界(沿 v 方向) | - -**返回**: Coons 曲面 -> 仅保证边界插值,不保证内部形状与设计意图一致 - -**参见**: `ruled_surface` - - -**沿方向向量拉伸 NURBS 曲线为曲面** -`[[nodiscard]] NurbsSurface extrude_curve(const NurbsCurve& curve,` - -| 参数 | 说明 | -|------|------| -| `curve` | 截面曲线 | -| `direction` | 拉伸方向(内部归一化) | -| `length` | 拉伸长度 | - -**返回**: 拉伸 NURBS 曲面 - - -**提取 NURBS 曲面的等参边界曲线** -`[[nodiscard]] NurbsCurve extract_boundary_curve(const NurbsSurface& surf, int edge)` - -| 参数 | 说明 | -|------|------| -| `surf` | 输入曲面 | -| `edge` | 边界索引:0=u_min, 1=u_max, 2=v_min, 3=v_max | - -**返回**: 指定边界上的 NURBS 曲线 -> 边界曲线继承原曲面该方向的阶次和节点向量 - - - -### `nurbs_surface.h` - -**NURBS 张量积曲面** - - -**构造 NURBS 曲面** -`NurbsSurface(std::vector> control_grid,` - -| 参数 | 说明 | -|------|------| -| `control_grid` | 控制点网格 | -| `knots_u` | u 向节点向量 | -| `knots_v` | v 向节点向量 | -| `weights` | 权重网格,维度与 control_grid 一致,所有值 > 0 | -| `degree_u` | u 向阶次 | -| `degree_v` | v 向阶次 | - - -**求曲面点 S(u,v)** -`[[nodiscard]] Point3D evaluate(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: 曲面上对应 (u,v) 的 3D 点 - - -**u 向偏导数** -`[[nodiscard]] Vector3D derivative_u(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: ∂S/∂u - - -**v 向偏导数** -`[[nodiscard]] Vector3D derivative_v(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: ∂S/∂v - - -**单位法向量** -`[[nodiscard]] Vector3D normal(double u, double v) const` - -| 参数 | 说明 | -|------|------| -| `u` | u 参数 | -| `v` | v 参数 | - -**返回**: N(u,v) = normalize(∂S/∂u × ∂S/∂v) - - -**u 向阶次** -`[[nodiscard]] int degree_u() const { return degree_u_; }` - -**返回**: pu - - -**v 向阶次** -`[[nodiscard]] int degree_v() const { return degree_v_; }` - -**返回**: pv - - -**控制点数量** -`[[nodiscard]] std::array num_control_points() const {` - -**返回**: {nu+1, nv+1},即网格的行数和列数 - - -**u 向节点向量** -`[[nodiscard]] const std::vector& knots_u() const { return knots_u_; }` - -**返回**: 只读引用 - - -**v 向节点向量** -`[[nodiscard]] const std::vector& knots_v() const { return knots_v_; }` - -**返回**: 只读引用 - - -**控制点网格访问** -`[[nodiscard]] const std::vector>& control_points() const { return cp_; }` - -**返回**: 只读引用 - - -**权重网格访问** -`[[nodiscard]] const std::vector>& weights() const { return weights_; }` - -**返回**: 只读引用 - - -**由两条 NURBS 曲线创建直纹面** -`static NurbsSurface ruled(const NurbsCurve& c1, const NurbsCurve& c2)` - -| 参数 | 说明 | -|------|------| -| `c1` | 起始曲线(v=0 边界) | -| `c2` | 终止曲线(v=1 边界) | - -**返回**: 直纹 NURBS 曲面 -> 两条曲线需具有兼容的阶次和节点结构(内部做升阶和节点精化对齐) - -**参见**: `blend_surfaces ruled_surface` - - -**由截面曲线旋转生成旋转曲面** -`static NurbsSurface revolve(const NurbsCurve& profile, const Point3D& axis_origin,` - -| 参数 | 说明 | -|------|------| -| `profile` | 截面 NURBS 曲线 | -| `axis_origin` | 旋转轴上一点 | -| `axis_dir` | 旋转轴方向 | -| `angle_rad` | 旋转角度(弧度),≤ 2π | - -**返回**: 旋转 NURBS 曲面 -> 使用 NURBS 表示圆弧的权重方案;完整旋转生成闭曲面 - - -**将 NURBS 曲面三角化** -`[[nodiscard]] std::pair, std::vector>>` - -| 参数 | 说明 | -|------|------| -| `res_u` | u 方向采样分辨率 | -| `res_v` | v 方向采样分辨率 | - -**返回**: {顶点数组, 三角形索引数组},每个三角形为 {i0,i1,i2} -> 生成 res_u×res_v 均匀网格,每个单元格拆为两个三角形 - -**参见**: `tessellate` - - - -### `tessellation.h` - -**均匀参数化曲面三角化** -`std::pair, std::vector>>` - -| 参数 | 说明 | -|------|------| -| `eval` | 曲面求值函数 eval(u,v) -> Point3D,参数 (u,v) ∈ [0,1]×[0,1] | -| `res_u` | u 方向子分段数(≥ 1) | -| `res_v` | v 方向子分段数(≥ 1) | - -**返回**: {顶点数组, 三角形索引数组},三角形为 {i0,i1,i2} -> 总顶点数 = (res_u+1)×(res_v+1),三角形数 = 2×res_u×res_v - -**参见**: `adaptive_tessellate` - - -**自适应曲面三角化** -`std::pair, std::vector>>` - -| 参数 | 说明 | -|------|------| -| `eval` | 曲面求值函数 eval(u,v) -> Point3D | -| `normal_fn` | 单位法向函数 normal_fn(u,v) -> Vector3D | -| `min_res` | 初始每向子分段数(≥ 1),默认 2 | -| `max_depth` | 最大递归深度,限制总面数,默认 6 | -| `angle_threshold_deg` | 法向角度偏差阈值(度),默认 5.0 | - -**返回**: {顶点数组, 三角形索引数组} -> 最终面数上限约为 2·min_res²·4^max_depth(实际远小于此上限) - -**参见**: `tessellate` - - - -## 网格处理 (`vde::mesh`) - - -### `alpha_shapes.h` - -**Alpha Shapes 点云表面重建** -`TetrahedronMesh alpha_shapes(const std::vector& points, double alpha)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入 3D 点云 | -| `alpha` | α 半径阈值,通常取平均点间距的 1~3 倍 | - -**返回**: TetrahedronMesh 保留的四面体网格 - -**参见**: `alpha_shapes_surface delaunay_3d` - - -**将 Alpha Shapes 四面体网格的表面提取为三角形网格** -`std::pair, std::vector>>` - -| 参数 | 说明 | -|------|------| -| `tet_mesh` | Alpha Shapes 输出的四面体网格 | - -**返回**: {顶点数组, 三角形索引数组} -> 表面三角形法向指向四面体外部(右手定则) - -**参见**: `alpha_shapes` - - - -### `cdt_2d.h` - -**约束 Delaunay 三角化(CDT)** -`DelaunayResult constrained_delaunay_2d(` - -| 参数 | 说明 | -|------|------| -| `points` | 输入 2D 点集 | -| `constraints` | 约束边列表,每项为 {起点索引, 终点索引} | - -**返回**: DelaunayResult 含约束边的三角化结果 -> 约束边不能相交(否则行为未定义);自相交约束需先分割交点 - -**参见**: `delaunay_2d` - - - -### `delaunay_2d.h` - -**2D Delaunay 三角化结果** -`struct DelaunayResult {` - - -**2D Delaunay 三角化(Bowyer-Watson 增量算法)** -`DelaunayResult delaunay_2d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入 2D 点集(至少 3 个不共线点) | - -**返回**: DelaunayResult 三角化结果 -> 时间复杂度:平均 O(n log n),最坏 O(n²) - -**参见**: `constrained_delaunay_2d` - - - -### `delaunay_3d.h` - -**四面体网格结构** -`struct TetrahedronMesh {` - - -**3D Delaunay 四面体化(Bowyer-Watson 增量算法)** -`TetrahedronMesh delaunay_3d(const std::vector& points)` - -| 参数 | 说明 | -|------|------| -| `points` | 输入 3D 点集(至少 4 个不共面点) | - -**返回**: TetrahedronMesh 四面体网格 -> 时间复杂度与 2D 类似:平均 O(n log n),最坏 O(n²) -> 输出包括内部和边界四面体;通过 alpha_shapes 可提取表面 - -**参见**: `alpha_shapes` - - - -### `geodesic.h` - -**热方法(Heat Method)计算测地距离** -`std::vector geodesic_distance(const HalfedgeMesh& mesh,` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | -| `sources` | 源顶点索引列表(距离为 0 的顶点) | -| `t` | 时间步长,< 0 时自动设为平均边长平方 | - -**返回**: 每顶点到最近源点的测地距离 -> 要求网格为连通流形;时间步长 t 越小精度越高但数值越不稳定 - - - -### `halfedge_mesh.h` - -**半边数据结构元素** -`struct Halfedge {` - - -**面元素** -`struct Face {` - - -**半边数据结构三角网格** - - -**清空所有数据** -`void clear()` - - -**添加顶点** -`int add_vertex(const Point3D& p)` - -| 参数 | 说明 | -|------|------| -| `p` | 3D 坐标 | - -**返回**: 新顶点的索引(0-based) - - -**添加面** -`int add_face(const std::vector& vertex_indices)` - -| 参数 | 说明 | -|------|------| -| `vertex_indices` | 按逆时针顺序排列的顶点索引(至少 3 个) | - -**返回**: 新面的索引,失败返回 -1 -> 自动创建/查找半边并设置对侧关系;面法向遵循右手定则 - - -**从三角形列表批量构建半边形网格** -`void build_from_triangles(const std::vector& verts,` - -| 参数 | 说明 | -|------|------| -| `verts` | 顶点位置数组 | -| `tris` | 三角形索引数组,每个 {i0,i1,i2} | -> 等价于反复调用 add_vertex + add_face,但内部做批处理优化 - - -**顶点数量** -`[[nodiscard]] size_t num_vertices() const { return vertices_.size(); }` - -**返回**: vertices_ 大小 - - -**面数量** -`[[nodiscard]] size_t num_faces() const { return faces_.size(); }` - -**返回**: faces_ 大小 - - -**边数量** -`[[nodiscard]] size_t num_edges() const { return halfedges_.size() / 2; }` - -**返回**: halfedges_.size() / 2 - - -**访问顶点** -`[[nodiscard]] const Point3D& vertex(size_t idx) const { return vertices_[idx]; }` - -| 参数 | 说明 | -|------|------| -| `idx` | 顶点索引,0 ≤ idx < num_vertices() | - -**返回**: 顶点坐标只读引用 - - -**访问面** -`[[nodiscard]] const Face& face(size_t idx) const { return faces_[idx]; }` - -| 参数 | 说明 | -|------|------| -| `idx` | 面索引 | - -**返回**: Face 只读引用 - - -**访问半边** -`[[nodiscard]] const Halfedge& halfedge(size_t idx) const { return halfedges_[idx]; }` - -| 参数 | 说明 | -|------|------| -| `idx` | 半边索引 | - -**返回**: Halfedge 只读引用 - - -**更新顶点位置** -`void set_vertex(size_t idx, const Point3D& p) { vertices_[idx] = p; normals_dirty_ = true; }` - -| 参数 | 说明 | -|------|------| -| `idx` | 顶点索引 | -| `p` | 新坐标 | -> 标记法向缓存为脏,下次查询时重新计算 - - -**获取面的所有顶点索引(按环绕顺序)** -`[[nodiscard]] std::vector face_vertices(int fi) const` - -| 参数 | 说明 | -|------|------| -| `fi` | 面索引 | - -**返回**: 顶点索引序列 - - -**获取顶点的邻面索引环** -`[[nodiscard]] std::vector vertex_faces(int vi) const` - -| 参数 | 说明 | -|------|------| -| `vi` | 顶点索引 | - -**返回**: 所有以 vi 为顶点的面索引 - - -**是否为边界半边** -`[[nodiscard]] bool is_boundary_edge(int hei) const { return halfedges_[hei].face_index < 0; }` - -| 参数 | 说明 | -|------|------| -| `hei` | 半边索引 | - -**返回**: 没有所属面时为 true - - -**是否为边界顶点** -`[[nodiscard]] bool is_boundary_vertex(int vi) const` - -| 参数 | 说明 | -|------|------| -| `vi` | 顶点索引 | - -**返回**: 邻接任何边界半边时为 true - - -**面法向(几何法向,非归一化?由实现决定)** -`[[nodiscard]] Vector3D face_normal(int fi) const` - -| 参数 | 说明 | -|------|------| -| `fi` | 面索引 | - -**返回**: (v1-v0)×(v2-v0) 归一化结果 - - -**顶点法向(邻面法向的面积加权平均)** -`[[nodiscard]] Vector3D vertex_normal(int vi) const` - -| 参数 | 说明 | -|------|------| -| `vi` | 顶点索引 | - -**返回**: 归一化顶点法向 - - -**重新计算所有面法向和顶点法向** -`void update_normals()` -> 修改顶点位置后自动标记脏位,调用此方法触发重新计算 - - -**网格包围盒** -`[[nodiscard]] AABB3D bounds() const` - -**返回**: AABB3D 轴对齐包围盒 - - -**面迭代器范围(支持 for-range)** - - -**顶点单邻环迭代器** - - -**获取所有面范围(range-based for 支持)** -`[[nodiscard]] FaceRange faces_range() const` - -**返回**: FaceRange 对象 - - -**获取顶点的 1-ring 邻域迭代器** -`[[nodiscard]] VertexOneRing vertex_one_ring(int vi) const` - -| 参数 | 说明 | -|------|------| -| `vi` | 顶点索引 | - -**返回**: VertexOneRing 对象 - - -**查找或创建半边 (v0→v1)** -`int find_or_create_edge(int v0, int v1)` - -| 参数 | 说明 | -|------|------| -| `v0` | 起点顶点索引 | -| `v1` | 终点顶点索引 | - -**返回**: 半边索引 - - - -### `marching_cubes.h` - -**Marching Cubes 输出网格** -`struct MCMesh {` - - -**Marching Cubes 等值面提取** -`MCMesh marching_cubes(const std::function& f,` - -| 参数 | 说明 | -|------|------| -| `f` | 标量场函数 f(x,y,z) → double | -| `iso_level` | 等值面值(默认 0) | -| `bmin` | 包围盒最小角 | -| `bmax` | 包围盒最大角 | -| `resolution` | 每轴采样分辨率(≥ 1),总网格 = resolution³ 个立方体 | - -**返回**: MCMesh 三角形网格 -> 使用经典的 256 查表法(Lorensen & Cline 1987) - -**参见**: `sdf_sphere sdf_box` - - -**SDF 球体函数** -`inline double sdf_sphere(double x, double y, double z, double cx, double cy, double cz, double r) {` - -| 参数 | 说明 | -|------|------| -| `x,y,z` | 采样点坐标 | -| `cx,cy,cz` | 球心坐标 | -| `r` | 半径 | - -**返回**: 有符号距离:内部 < 0,表面 = 0,外部 > 0 - - -**SDF 立方体函数(轴对齐,中心在原点)** -`inline double sdf_box(double x, double y, double z, double hx, double hy, double hz) {` - -| 参数 | 说明 | -|------|------| -| `x,y,z` | 采样点坐标 | -| `hx,hy,hz` | 半边长 | - -**返回**: 有符号距离 - - -**SDF 平滑并集(Smooth Union)** - -| 参数 | 说明 | -|------|------| -| `d1,d2` | 两个 SDF 值 | -| `k` | 平滑宽度(> 0),值越大过渡越平滑 | - -**返回**: 混合后的 SDF 值 - - -**SDF 平滑差集(Smooth Subtraction)** -`inline double sdf_smooth_subtraction(double d1, double d2, double k) {` - -| 参数 | 说明 | -|------|------| -| `d1,d2` | 两个 SDF 值 | -| `k` | 平滑宽度(> 0) | - -**返回**: 混合后的 SDF 值 - - - -### `mesh_boolean.h` - -**布尔运算类型(CSG 组合)** -`enum class BooleanOp {` - - -**三角网格布尔运算** -`HalfedgeMesh mesh_boolean(const HalfedgeMesh& a, const HalfedgeMesh& b, BooleanOp op)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个三角网格(必须为封闭流形) | -| `b` | 第二个三角网格(必须为封闭流形) | -| `op` | 布尔运算类型 | - -**返回**: 结果三角网格 -> 要求输入网格为封闭流形(watertight),否则分类不可靠 - - - -### `mesh_curvature.h` - -**离散曲率计算结果** -`struct CurvatureResult {` - - -**离散曲率计算(Cotan 公式,Meyer et al. 2003)** -`CurvatureResult compute_curvature(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | - -**返回**: CurvatureResult 每顶点曲率 -> 要求网格为流形;边界顶点曲率使用近似公式 - - - -### `mesh_parameterize.h` - -**Tutte 参数化(调和参数化)** -`[[nodiscard]] std::vector tutte_parameterization(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格(需含边界) | - -**返回**: 每顶点 UV 坐标(Point2D),顺序与 mesh 顶点一致 -> 网格必须有边界(开网格);闭曲面需先切割为拓扑圆盘 - -**参见**: `lscm_parameterization` - - -**LSCM(Least Squares Conformal Maps)参数化** -`[[nodiscard]] std::vector lscm_parameterization(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | - -**返回**: 每顶点 UV 坐标(Point2D) -> 简化实现,不包含完整 Lévy 论文中所有的退化处理 - -**参见**: `tutte_parameterization` - - - -### `mesh_quality.h` - -**三角网格质量指标** -`struct MeshQuality {` - - -**评估三角网格质量** -`MeshQuality evaluate_mesh_quality(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | - -**返回**: MeshQuality 质量指标汇总 - - -**四面体网格质量指标** -`struct TetQuality {` - - -**评估三角网格作为四面体边界的质量** -`TetQuality evaluate_tet_quality(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 封闭三角网格(volume boundary) | - -**返回**: TetQuality 四面体质量指标 -> 这不是真正的四面体网格质量评估——仅用于表面网格的代理指标 - - -**单元类型枚举** -`enum class ElementType {` - - -**通用单元质量指标** -`struct ElemQuality {` - - -**按单元类型分派的网格质量评估** -`ElemQuality evaluate_element_quality(const HalfedgeMesh& mesh, ElementType type)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格 | -| `type` | 单元类型 | - -**返回**: ElemQuality 质量指标 -> 目前仅 Tri 和 Tet 完整实现;Quad / Hex 返回 stub(全零) - - -**详细质量报告** -`struct QualityReport {` - - -**生成三角网格的完整质量报告** -`QualityReport mesh_quality_report(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | - -**返回**: QualityReport 完整质量报告 - - -**生成四面体网格的完整质量报告** -`QualityReport mesh_quality_report_tet(const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 封闭三角网格 | - -**返回**: QualityReport 完整质量报告 - - -**三角形归一化 Jacobian** -`double tri_scaled_jacobian(const Point3D& a, const Point3D& b, const Point3D& c)` - -| 参数 | 说明 | -|------|------| -| `a,b,c` | 三角形三个顶点 | - -**返回**: 归一化 Jacobian [-1, 1] - - -**四面体归一化 Jacobian** -`double tet_scaled_jacobian(const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `a,b,c,d` | 四面体四个顶点 | - -**返回**: 归一化 Jacobian [0, 1] - - - -### `mesh_repair.h` - -**网格修复选项** -`struct RepairOptions {` - - -**自动网格修复** -`HalfedgeMesh repair_mesh(const HalfedgeMesh& mesh, const RepairOptions& opts = {})` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格(可能有缺陷) | -| `opts` | 修复选项(默认全部启用) | - -**返回**: 修复后的网格 -> 修复为启发式算法,不保证 100% 成功;孔洞过大或非流形边可能仍有残留问题 - - - -### `mesh_simplify.h` - -**网格简化选项** -`struct SimplifyOptions {` - - -**QEM(Quadric Error Metrics)网格简化** -`HalfedgeMesh simplify_mesh(const HalfedgeMesh& mesh, const SimplifyOptions& opts = {})` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | -| `opts` | 简化选项 | - -**返回**: 简化后的网格 -> preserve_boundary 模式下,边界边通过惩罚项(大代价)被保护 - - - -### `mesh_smooth.h` - -**网格光顺方法** -`enum class SmoothMethod {` - - -**网格光顺参数** -`struct SmoothOptions {` - - -**网格光顺(通用分发器)** -`HalfedgeMesh smooth_mesh(const HalfedgeMesh& mesh, const SmoothOptions& opts = {})` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入三角网格 | -| `opts` | 光顺选项 | - -**返回**: 光顺后的网格(顶点位置更新,拓扑不变) - - -**标准拉普拉斯光顺** -`HalfedgeMesh smooth_laplacian(const HalfedgeMesh& mesh, int iterations, double lambda)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格 | -| `iterations` | 迭代次数 | -| `lambda` | 步长系数 (0, 1] | - -**返回**: 光顺后的网格 -> 迭代过多会导致网格坍塌;对于体积关键的应用优先选 Taubin 或 HC - -**参见**: `smooth_taubin smooth_hc_laplacian` - - -**Taubin λ|μ 光顺(体积保持)** -`HalfedgeMesh smooth_taubin(const HalfedgeMesh& mesh, int iterations, double lambda, double mu)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格 | -| `iterations` | 完整 λ/μ 循环次数 | -| `lambda` | 正步系数 (0, 1] | -| `mu` | 负步系数,需满足 mu < 0 且 |mu| > lambda | - -**返回**: 光顺后的网格 -> 典型值:λ = 0.5, μ = -0.53;|mu| 过大可能导致不稳定振荡 - - -**HC 拉普拉斯光顺(Humphrey's Classes)** -`HalfedgeMesh smooth_hc_laplacian(const HalfedgeMesh& mesh, const SmoothOptions& opts = {})` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格 | -| `opts` | 光顺选项(使用 hc_alpha 和 hc_beta 字段) | - -**返回**: 光顺后的网格 - - -**双边网格滤波** -`HalfedgeMesh smooth_bilateral(const HalfedgeMesh& mesh, const SmoothOptions& opts = {})` - -| 参数 | 说明 | -|------|------| -| `mesh` | 输入网格 | -| `opts` | 光顺选项(使用 bilateral_ 前缀字段) | - -**返回**: 光顺后的网格 - - - -## 空间索引 (`vde::spatial`) - - -### `bvh.h` - -**包围盒层次结构 (Bounding Volume Hierarchy)** - - -**BVH 构建分裂策略** -`enum class BVHSplitStrategy {` - - -**< 按最长轴中点分裂** -`Equal, /**< 按数量均等分裂 */` - - -**< 按数量均等分裂** -`SAH /**< Surface Area Heuristic — 最小化射线击中概率期望 */` - - -**< Surface Area Heuristic — 最小化射线击中概率期望** -`}` - - -**BVH 构建选项** -`struct BVHBuildOptions {` - - -**< 分裂策略** -`int leaf_size = 4; /**< 叶节点最大图元数 */` - - -**< 叶节点最大图元数** -`int max_depth = 64; /**< 树的最大深度 */` - - -**< 树的最大深度** -`}` - - -**包围盒层次结构 — 三角形网格加速结构** - -**参见**: `SpatialIndex, Octree, KDTree, RTree` - - -**构造 BVH 并指定构建选项** -`explicit BVH(const BVHBuildOptions& opts = {}) : opts_(opts) {}` - -| 参数 | 说明 | -|------|------| -| `opts` | 构建选项(分裂策略、叶节点大小、最大深度) | - - -**清除已有数据并重建 BVH** -`void build(const std::vector& tris) override` - -| 参数 | 说明 | -|------|------| -| `tris` | 三角形数组 | - - -**插入单个三角形** -`void insert(const Triangle3D& tri) override` - -| 参数 | 说明 | -|------|------| -| `tri` | 要插入的三角形 | - - -**删除三角形** -`bool remove(const Triangle3D& tri) override` - -| 参数 | 说明 | -|------|------| -| `tri` | 要删除的三角形 | - -**返回**: 删除成功返回 true - - -**AABB 范围查询** -`std::vector query_range(const AABB3D& range) const override` - -| 参数 | 说明 | -|------|------| -| `range` | 查询包围盒 | - -**返回**: 与 range 相交的三角形列表 - - -**K 近邻查询** -`std::vector query_knn(const Point3D& point, size_t k) const override` - -| 参数 | 说明 | -|------|------| -| `point` | 查询点 | -| `k` | 返回数量 | - -**返回**: 最近的 k 个三角形 - - -**射线查询:返回所有命中的三角形** -`std::vector query_ray(const Ray3Dd& ray) const override` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 按命中顺序排列的三角形列表 - - -**清空 BVH 树和所有三角形** -`void clear() override` - - -**三角形数量** -`size_t size() const override { return primitives_.size(); }` - -**返回**: 当前索引的三角形总数 - - -**射线最近命中查询结果** -`struct HitResult {` - - -**< 沿射线的参数 t** -`Triangle3D tri; /**< 命中的三角形 */` - - -**< 命中的三角形** -`Point3D point; /**< 命中点的世界坐标 = origin + t * dir */` - - -**< 命中点的世界坐标 = origin + t * dir** -`}` - - -**射线最近命中查询** -`std::optional query_ray_nearest(const Ray3Dd& ray) const` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 最近命中结果(若无命中则返回空) -> 比 query_ray() 更高效,仅返回最近命中 - - -**BVH 节点** -`struct Node {` - - -**< 节点的包围盒(所有子节点/图元的并集)** -`int left = -1; /**< 左子节点索引,叶节点为 -1 */` - - -**< 左子节点索引,叶节点为 -1** -`int right = -1; /**< 右子节点索引,叶节点为 -1 */` - - -**< 右子节点索引,叶节点为 -1** -`int first_prim = 0; /**< 叶节点第一个图元的索引 */` - - -**< 叶节点第一个图元的索引** -`int prim_count = 0; /**< 叶节点图元数量 */` - - -**< 叶节点图元数量** -`/** @brief 判断是否为叶节点 */` - - -**判断是否为叶节点** -`bool leaf() const { return left < 0; }` - - -**< 节点数组(根节点为 nodes_[0])** -`std::vector primitives_; /**< 图元数组 */` - - -**< 图元数组** -`BVHBuildOptions opts_; /**< 构建选项 */` - - -**< 构建选项** -`/**` - - -**递归构建 BVH 子树** -`void build_recursive(int node, int first, int count, int depth)` - -| 参数 | 说明 | -|------|------| -| `node` | 当前节点索引 | -| `first` | 图元范围的起始索引 | -| `count` | 图元数量 | -| `depth` | 当前递归深度 | - - -**计算 SAH 分裂代价** -`double sah_cost(int n_left, int n_right, const AABB3D& left, const AABB3D& right) const` - -| 参数 | 说明 | -|------|------| -| `n_left` | 左子树图元数 | -| `n_right` | 右子树图元数 | -| `left` | 左子树包围盒 | -| `right` | 右子树包围盒 | - -**返回**: SAH 代价估值 - - - -### `kd_tree.h` - -**k-d 树 (K-Dimensional Tree) 空间划分结构** - - -**k-d 树空间索引** -`template ` -> k-d 树在维度约 2~6 时效率最佳。三维场景中, - -**参见**: `SpatialIndex, BVH, Octree` - - -**批量构建 k-d 树** -`void build(const std::vector& items) override` - -| 参数 | 说明 | -|------|------| -| `items` | 待索引的对象数组 | - - -**插入单个对象** -`void insert(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待插入的空间对象 | - - -**删除对象** -`bool remove(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待删除的空间对象 | - -**返回**: 删除成功返回 true - - -**范围查询** -`std::vector query_range(const AABB3D& range) const override` - -| 参数 | 说明 | -|------|------| -| `range` | 查询包围盒 | - -**返回**: 与 range 相交的对象列表 - - -**K 近邻查询** -`std::vector query_knn(const Point3D& point, size_t k) const override` - -| 参数 | 说明 | -|------|------| -| `point` | 查询点 | -| `k` | 返回数量 | - -**返回**: 最近的 k 个对象 - - -**射线查询** -`std::vector query_ray(const Ray3Dd& ray) const override` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 与射线相交的对象列表 - - -**清空 k-d 树** -`void clear() override` - - -**对象数量** -`size_t size() const override { return items_.size(); }` - -**返回**: 当前索引的对象总数 - - -**k-d 树节点** -`struct Node {` - - -**< 节点包围盒** -`int item_idx = -1; /**< 叶节点对应的对象索引(-1 表示内部节点) */` - - -**< 叶节点对应的对象索引(-1 表示内部节点)** -`int split_axis = 0; /**< 分裂轴:0=x, 1=y, 2=z */` - - -**< 分裂轴:0=x, 1=y, 2=z** -`int left = -1; /**< 左子节点索引 */` - - -**< 左子节点索引** -`int right = -1; /**< 右子节点索引 */` - - -**< 右子节点索引** -`}` - - -**< 对象数组** -`std::vector nodes_; /**< 节点数组 */` - - -**< 节点数组** -`int root_ = -1; /**< 根节点索引 */` - - -**< 根节点索引** -`/**` - - -**获取对象代表位置(用于空间排序)** -`static Point3D get_position(const T& item)` - -| 参数 | 说明 | -|------|------| -| `item` | 空间对象 | - -**返回**: 对象的三维代表点 - - -**获取对象的轴对齐包围盒** -`static AABB3D get_aabb(const T& item)` - -| 参数 | 说明 | -|------|------| -| `item` | 空间对象 | - -**返回**: 包围盒 - - -**判断对象是否与射线相交** -`static bool ray_hits_item(const T& item, const Ray3Dd& ray)` - -| 参数 | 说明 | -|------|------| -| `item` | 空间对象 | -| `ray` | 查询射线 | - -**返回**: 相交返回 true - - -**递归构建 k-d 树** -`int build_recursive(int start, int end)` - -| 参数 | 说明 | -|------|------| -| `start` | items_ 中当前范围起始索引 | -| `end` | items_ 中当前范围结束索引 | - -**返回**: 新节点的索引 - - -**递归范围查询** -`void query_range_recursive(int node_idx, const AABB3D& range,` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `range` | 查询包围盒 | -| `result` | 累积结果 | - - -**递归射线查询** -`void query_ray_recursive(int node_idx, const Ray3Dd& ray,` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `ray` | 查询射线 | -| `result` | 累积结果 | - - - -### `octree.h` - -**八叉树 (Octree) 空间划分结构** - - -**八叉树空间索引** -`template ` -> 适用于体积数据、粒子系统、空间哈希等场景。 - -**参见**: `SpatialIndex, BVH, KDTree` - - -**构造八叉树** -`explicit Octree(int max_depth = 8, int max_items = 16)` - -| 参数 | 说明 | -|------|------| -| `max_depth` | 最大递归深度(默认 8,对应 256³ 分辨率) | -| `max_items` | 节点剖分前可容纳的最大对象数(默认 16) | - - -**批量构建八叉树** -`void build(const std::vector& items) override` - -| 参数 | 说明 | -|------|------| -| `items` | 待索引的对象数组 | - - -**增量插入对象** -`void insert(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待插入的空间对象 | - - -**删除对象** -`bool remove(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待删除的空间对象 | - -**返回**: 删除成功返回 true;对象不存在返回 false - - -**范围查询** -`std::vector query_range(const AABB3D& range) const override` - -| 参数 | 说明 | -|------|------| -| `range` | 查询包围盒 | - -**返回**: 与 range 相交的对象列表 - - -**K 近邻查询** -`std::vector query_knn(const Point3D& point, size_t k) const override` - -| 参数 | 说明 | -|------|------| -| `point` | 查询点 | -| `k` | 返回数量 | - -**返回**: 最近的 k 个对象 - - -**射线查询** -`std::vector query_ray(const Ray3Dd& ray) const override` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 按命中顺序排列的相交对象列表 - - -**清空八叉树** -`void clear() override` - - -**当前索引中的对象数量** -`size_t size() const override` - -**返回**: 对象总数 - - -**递归插入对象到指定节点** -`void insert_recursive(int node_idx, const T& item, int depth)` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 目标节点索引 | -| `item` | 待插入的对象 | -| `depth` | 当前递归深度 | - - -**递归剖分节点** -`void subdivide_recursive(int node_idx, int depth)` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `depth` | 当前深度 | - - -**递归范围查询** -`void query_range_recursive(int node_idx, const AABB3D& range,` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `range` | 查询包围盒 | -| `result` | 累积结果 | - - -**递归射线查询** -`void query_ray_recursive(int node_idx, const Ray3Dd& ray,` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `ray` | 查询射线 | -| `result` | 累积结果 | - - -**获取对象空间位置(用于剖分分配)** -`static Point3D get_position(const T& item)` - -| 参数 | 说明 | -|------|------| -| `item` | 空间对象 | - -**返回**: 对象的代表点 - - -**< 八叉树内部数据** -`int max_depth_; /**< 最大递归深度 */` - - -**< 最大递归深度** -`int max_items_; /**< 节点剖分阈值 */` - - -**< 节点剖分阈值** -`}` - - - -### `r_tree.h` - -**R 树 (R-Tree) 动态空间索引** - - -**R 树节点** -`template ` - - -**< 节点包围盒(子节点/对象 MBR 的并集)** -`bool is_leaf = true; /**< 是否为叶节点 */` - - -**< 是否为叶节点** -`std::vector children; /**< 内部节点:子节点索引列表 */` - - -**< 内部节点:子节点索引列表** -`std::vector item_indices; /**< 叶节点:对象索引列表 */` - - -**< 叶节点:对象索引列表** -`size_t parent = static_cast(-1); /**< 父节点索引 */` - - -**< 父节点索引** -`}` - - -**R 树动态空间索引** -`template ` -> R 树在动态场景(如编辑中的几何体)中比 BVH 更合适。 - -**参见**: `SpatialIndex, BVH, RStarTree` - - -**批量构建 R 树** -`void build(const std::vector& items) override` - -| 参数 | 说明 | -|------|------| -| `items` | 待索引的对象数组 | - - -**增量插入对象** -`void insert(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待插入的空间对象 | - - -**删除对象** -`bool remove(const T& item) override` - -| 参数 | 说明 | -|------|------| -| `item` | 待删除的空间对象 | - -**返回**: 删除成功返回 true - - -**范围查询** -`std::vector query_range(const AABB3D& range) const override` - -| 参数 | 说明 | -|------|------| -| `range` | 查询包围盒 | - -**返回**: 与 range 相交的对象列表 - - -**K 近邻查询** -`std::vector query_knn(const Point3D& point, size_t k) const override` - -| 参数 | 说明 | -|------|------| -| `point` | 查询点 | -| `k` | 返回数量 | - -**返回**: 最近的 k 个对象 - - -**射线查询** -`std::vector query_ray(const Ray3Dd& ray) const override` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 与射线相交的对象列表 - - -**清空 R 树** -`void clear() override` - - -**对象数量** -`size_t size() const override { return count_; }` - -**返回**: 当前索引的对象总数 - - -**R 树节点总数** -`size_t node_count() const { return nodes_.size(); }` - -**返回**: 内部节点 + 叶节点数量 - - -**递归范围查询** -`void query_range_recursive(size_t node_idx, const AABB3D& range,` - -| 参数 | 说明 | -|------|------| -| `node_idx` | 当前节点索引 | -| `range` | 查询包围盒 | -| `result` | 累积结果 | - - -**< 对象数组** -`std::vector item_bounds_; /**< 对象包围盒数组 */` - - -**< 对象包围盒数组** -`std::vector> nodes_; /**< R 树节点数组 */` - - -**< R 树节点数组** -`size_t root_idx_ = 0; /**< 根节点索引 */` - - -**< 根节点索引** -`size_t count_ = 0; /**< 对象计数 */` - - -**< 对象计数** -`}` - - - -### `spatial_index.h` - -**空间索引抽象基类** - - -**空间索引抽象基类** -`template ` -> 本类为纯虚接口,不可直接实例化 - - -**批量构建索引** -`virtual void build(const std::vector& items) = 0` - -| 参数 | 说明 | -|------|------| -| `items` | 待索引的对象数组 | - - -**插入单个对象** -`virtual void insert(const T& item) = 0` - -| 参数 | 说明 | -|------|------| -| `item` | 待插入的空间对象 | - - -**删除单个对象** -`virtual bool remove(const T& item) = 0` - -| 参数 | 说明 | -|------|------| -| `item` | 待删除的空间对象 | - -**返回**: true 删除成功;false 对象不存在 - - -**范围查询:返回与 AABB 相交的所有对象** -`virtual std::vector query_range(const AABB3D& range) const = 0` - -| 参数 | 说明 | -|------|------| -| `range` | 查询的轴对齐包围盒 | - -**返回**: 与 range 相交的对象列表 - - -**K 近邻查询:返回距 point 最近的 k 个对象** -`virtual std::vector query_knn(const Point3D& point, size_t k) const = 0` - -| 参数 | 说明 | -|------|------| -| `point` | 查询点 | -| `k` | 需要返回的对象数量 | - -**返回**: 按距离升序排列的 k 个最近对象 - - -**射线查询:返回与射线相交的所有对象** -`virtual std::vector query_ray(const Ray3Dd& ray) const = 0` - -| 参数 | 说明 | -|------|------| -| `ray` | 查询射线 | - -**返回**: 按命中距离升序排列的相交对象列表 - - -**清空索引中所有数据** -`virtual void clear() = 0` - - -**当前索引中的对象数量** -`virtual size_t size() const = 0` - -**返回**: 对象计数 - - - -## 布尔运算 (`vde::boolean`) - - -### `boolean_2d.h` - -**二维多边形布尔运算** - - -**布尔运算类型** -`enum class BooleanOp {` - - -**< 并集 A ∪ B** -`Intersection, /**< 交集 A ∩ B */` - - -**< 交集 A ∩ B** -`Difference, /**< 差集 A − B */` - - -**< 差集 A − B** -`SymDiff /**< 对称差 (A − B) ∪ (B − A) */` - - -**< 对称差 (A − B) ∪ (B − A)** -`}` - - -**二维多边形布尔运算** -`std::vector boolean_2d(const Polygon2D& a, const Polygon2D& b, BooleanOp op)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个多边形 | -| `b` | 第二个多边形 | -| `op` | 布尔操作类型 | - -**返回**: 结果多边形列表(可能有多个分离的组件) -> 当前版本优化了凸多边形路径。对于带孔洞或自交的 - -**参见**: `BooleanOp, mesh_boolean, polygon_offset` - - - -### `boolean_mesh.h` - -**三维网格布尔运算** - - -**网格并集 A ∪ B** -`HalfedgeMesh mesh_union(const HalfedgeMesh& a, const HalfedgeMesh& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | - -**返回**: A ∪ B 的合并网格 - -**参见**: `mesh_intersection, mesh_difference, is_point_inside_mesh` - - -**网格交集 A ∩ B** -`HalfedgeMesh mesh_intersection(const HalfedgeMesh& a, const HalfedgeMesh& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | - -**返回**: A ∩ B 的交集网格 -> 结果体积为两网格公共区域 - -**参见**: `mesh_union, mesh_difference` - - -**网格差集 A − B** -`HalfedgeMesh mesh_difference(const HalfedgeMesh& a, const HalfedgeMesh& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | - -**返回**: A − B 的差集网格 -> 结果中来自 B 的面片会被翻转法线以保持内-外一致性 - -**参见**: `mesh_union, mesh_intersection, mesh_sym_diff` - - -**网格对称差 (A − B) ∪ (B − A)** -`HalfedgeMesh mesh_sym_diff(const HalfedgeMesh& a, const HalfedgeMesh& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | - -**返回**: 对称差网格 - -**参见**: `mesh_difference, mesh_union` - - -**用网格 B 裁剪网格 A** -`HalfedgeMesh clip_mesh(const HalfedgeMesh& a, const HalfedgeMesh& b,` - -| 参数 | 说明 | -|------|------| -| `a` | 待裁剪网格 | -| `b` | 裁剪体网格 | -| `invert_b` | 若为 true,将 B 的内外判定取反(裁剪外部) | - -**返回**: 裁剪后的网格(仅包含 A 的面片) - -**参见**: `mesh_difference, is_point_inside_mesh` - - -**翻转网格所有面片的法线方向** -`HalfedgeMesh invert_mesh(const HalfedgeMesh& m)` - -| 参数 | 说明 | -|------|------| -| `m` | 原始网格 | - -**返回**: 法线翻转后的网格 - -**参见**: `mesh_difference` - - -**合并两个网格** -`HalfedgeMesh merge_meshes(const HalfedgeMesh& a, const HalfedgeMesh& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | - -**返回**: 包含 A 和 B 全部顶点和面片的合并网格 -> 不处理重叠区域;仅做纯几何拼接 - -**参见**: `mesh_union(做布尔合并)` - - -**网格布尔运算统一接口** -`HalfedgeMesh mesh_boolean(const HalfedgeMesh& a, const HalfedgeMesh& b, BooleanOp op)` - -| 参数 | 说明 | -|------|------| -| `a` | 网格 A | -| `b` | 网格 B | -| `op` | 布尔操作类型 | - -**返回**: 结果网格 - -**参见**: `BooleanOp, mesh_union, mesh_intersection, mesh_difference, mesh_sym_diff` - - -**判断三维点是否在封闭网格内部** -`bool is_point_inside_mesh(const core::Point3D& p, const HalfedgeMesh& mesh)` - -| 参数 | 说明 | -|------|------| -| `p` | 待判定点 | -| `mesh` | 封闭网格 | - -**返回**: 点在网格内部返回 true -> 网格必须是封闭(水密)的,否则结果不可靠。 - -**参见**: `clip_mesh, mesh_difference` - - - -### `polygon_offset.h` - -**多边形等距偏移 (Polygon Offset / Inset)** - - -**多边形等距偏移** -`std::vector polygon_offset(const Polygon2D& poly, double distance)` - -| 参数 | 说明 | -|------|------| -| `poly` | 原始多边形 | -| `distance` | 偏移距离(正=外扩,负=内缩) | - -**返回**: 偏移后的多边形列表(内缩或自交可能产生多个碎片) -> 使用直骨架近似而非精确圆弧偏移,转角处为斜角连接。 - -**参见**: `boolean_2d` - - - -## 碰撞检测 (`vde::collision`) - - -### `gjk.h` - -**GJK (Gilbert–Johnson–Keerthi) 碰撞检测算法** - - -**支撑函数类型** -`using SupportFunc = std::function` - - -**GJK 完整检测结果** -`struct GJKResult {` - - -**< 两凸体是否相交** -`double distance; /**< 最近距离(不相交时 >0,相交时为 0) */` - - -**< 最近距离(不相交时 >0,相交时为 0)** -`Point3D point_a; /**< 形状 A 上的最近点 */` - - -**< 形状 A 上的最近点** -`Point3D point_b; /**< 形状 B 上的最近点 */` - - -**< 形状 B 上的最近点** -`}` - - -**GJK 相交检测(仅判断是否碰撞)** -`bool gjk_intersect(const SupportFunc& shape_a, const SupportFunc& shape_b)` - -| 参数 | 说明 | -|------|------| -| `shape_a` | 形状 A 的支撑函数 | -| `shape_b` | 形状 B 的支撑函数 | - -**返回**: 相交返回 true - -**参见**: `gjk_distance, gjk_full, SupportFunc` - - -**GJK 最近距离查询** -`double gjk_distance(const SupportFunc& shape_a, const SupportFunc& shape_b)` - -| 参数 | 说明 | -|------|------| -| `shape_a` | 形状 A 的支撑函数 | -| `shape_b` | 形状 B 的支撑函数 | - -**返回**: 最近距离(相交时返回 0),始终 ≥ 0 - -**参见**: `gjk_intersect, gjk_full` - - -**GJK 完整检测:碰撞状态、距离、最近点对** -`GJKResult gjk_full(const SupportFunc& shape_a, const SupportFunc& shape_b)` - -| 参数 | 说明 | -|------|------| -| `shape_a` | 形状 A 的支撑函数 | -| `shape_b` | 形状 B 的支撑函数 | - -**返回**: GJKResult 包含碰撞状态、距离、最近点对 -> 对于连续碰撞检测 (CCD) 或需要分离向量的场景, - -**参见**: `gjk_intersect, gjk_distance` - - - -### `ray_intersect.h` - -**射线求交工具集** - - -**射线-三角形求交结果** -`struct RayTriResult {` - - -**< 沿射线的参数:hit_point = origin + t * dir** -`double u, v; /**< 三角形重心坐标:hit_point = (1−u−v)*v0 + u*v1 + v*v2 */` - - -**< 三角形重心坐标:hit_point = (1−u−v)*v0 + u*v1 + v*v2** -`Point3D point; /**< 命中点的世界坐标 */` - - -**< 命中点的世界坐标** -`}` - - -**射线-三角形求交(Möller-Trumbore 算法)** -`std::optional ray_triangle_intersect(` - -| 参数 | 说明 | -|------|------| -| `origin` | 射线起点 | -| `dir` | 射线方向(需归一化以获得正确 t 值) | -| `tri` | 三角形 | - -**返回**: 命中返回 RayTriResult;未命中返回空 - -**参见**: `ray_mesh_intersect` - - -**射线-三角形求交(Ray3Dd 重载)** -`inline std::optional ray_triangle_intersect(` - -| 参数 | 说明 | -|------|------| -| `ray` | 射线 | -| `tri` | 三角形 | - -**返回**: 命中返回 RayTriResult;未命中返回空 - -**参见**: `ray_triangle_intersect(origin, dir, tri)` - - -**射线-AABB 求交(slab 方法)** -`bool ray_aabb_intersect(const Ray3Dd& ray, const AABB3D& box,` - -| 参数 | 说明 | -|------|------| -| `ray` | 射线 | -| `box` | 轴对齐包围盒 | -| `tmin_out` | [输出] 进入包围盒的参数 t | -| `tmax_out` | [输出] 离开包围盒的参数 t | - -**返回**: 命中返回 true -> 常用于 BVH 遍历节点的快速 rejection test - -**参见**: `ray_triangle_intersect` - - -**射线-球体求交结果** -`struct RaySphereResult {` - - -**< 命中参数(通常取较小的 t)** -`Point3D point; /**< 命中点世界坐标 */` - - -**< 命中点世界坐标** -`}` - - -**射线-球体求交(解析法)** -`std::optional ray_sphere_intersect(` - -| 参数 | 说明 | -|------|------| -| `origin` | 射线起点 | -| `dir` | 射线方向 | -| `center` | 球心 | -| `radius` | 球半径 | - -**返回**: 命中返回 RaySphereResult(最近交点);未命中返回空 - -**参见**: `ray_sphere_intersect(ray, center, radius)` - - -**射线-球体求交(Ray3Dd 重载)** -`inline std::optional ray_sphere_intersect(` - -| 参数 | 说明 | -|------|------| -| `ray` | 射线 | -| `center` | 球心 | -| `radius` | 球半径 | - -**返回**: 命中返回 RaySphereResult;未命中返回空 - - -**射线-平面求交** -`std::optional ray_plane_intersect(` - -| 参数 | 说明 | -|------|------| -| `origin` | 射线起点 | -| `dir` | 射线方向 | -| `plane_point` | 平面上一点 | -| `plane_normal` | 平面法线(需归一化以获得正确 t) | - -**返回**: 命中返回参数 t;未命中(平行或反向)返回空 - - -**射线-平面求交(Ray3Dd 重载)** -`inline std::optional ray_plane_intersect(` - -| 参数 | 说明 | -|------|------| -| `ray` | 射线 | -| `plane_point` | 平面上一点 | -| `plane_normal` | 平面法线 | - -**返回**: 命中返回参数 t;未命中返回空 - - -**射线-网格求交(暴力遍历)** -`std::optional ray_mesh_intersect(` - -| 参数 | 说明 | -|------|------| -| `origin` | 射线起点 | -| `dir` | 射线方向 | -| `triangles` | 三角形列表 | - -**返回**: 最近命中结果;无命中返回空 -> 对于大型网格建议配合 BVH 使用: - -**参见**: `ray_tri_intersect.h, query_ray_nearest (BVH)` - - -**射线-网格求交(Ray3Dd 重载)** -`inline std::optional ray_mesh_intersect(` - -| 参数 | 说明 | -|------|------| -| `ray` | 射线 | -| `triangles` | 三角形列表 | - -**返回**: 最近命中结果;无命中返回空 - - - -### `sat.h` - -**SAT (Separating Axis Theorem) 碰撞检测** - - -**SAT 凸多面体相交检测** -`bool sat_intersect(const std::vector& verts_a,` - -| 参数 | 说明 | -|------|------| -| `verts_a` | 多面体 A 的顶点数组 | -| `faces_a` | 多面体 A 的面索引数组(每个面为 {v0, v1, v2}) | -| `verts_b` | 多面体 B 的顶点数组 | -| `faces_b` | 多面体 B 的面索引数组 | - -**返回**: 相交返回 true -> 适用于任意凸多面体。对于胶囊/球等光滑形状,GJK 更合适。 - -**参见**: `gjk_intersect, tri_tri_intersect` - - - -### `tri_intersect.h` - -**三角形-三角形 / 三角形-AABB 相交检测** - - -**三角形-三角形相交检测(布尔测试)** -`bool tri_tri_intersect(const Triangle3D& t1, const Triangle3D& t2)` - -| 参数 | 说明 | -|------|------| -| `t1` | 三角形 1 | -| `t2` | 三角形 2 | - -**返回**: 相交返回 true - -**参见**: `tri_tri_intersect_detailed, sat_intersect` - - -**三角形-三角形相交线段** -`struct TriTriIntersection {` - - -**< 是否相交** -`Point3D p0; /**< 交点段起点 */` - - -**< 交点段起点** -`Point3D p1; /**< 交点段终点 */` - - -**< 交点段终点** -`}` - - -**三角形-三角形详细相交检测** -`TriTriIntersection tri_tri_intersect_detailed(const Triangle3D& t1,` - -| 参数 | 说明 | -|------|------| -| `t1` | 三角形 1 | -| `t2` | 三角形 2 | - -**返回**: TriTriIntersection:相交标志 + 交点段端点 -> 共面情况交集段可能退化为单点(p0 == p1) - -**参见**: `tri_tri_intersect` - - -**三角形-AABB 快速相交测试** -`bool tri_aabb_overlap(const Triangle3D& tri, const AABB3D& box)` - -| 参数 | 说明 | -|------|------| -| `tri` | 三角形 | -| `box` | 轴对齐包围盒 | - -**返回**: 相交返回 true -> AABB 碰撞比三角剖分后的三角-三角检测更高效, - -**参见**: `tri_tri_intersect, ray_aabb_intersect` - - - -## B-Rep建模 (`vde::brep`) - - -### `assembly.h` - -**装配体节点** -`struct AssemblyNode {` - - -**装配体** -`struct Assembly {` - - - -### `brep.h` - -**边界表示(B-Rep)核心数据结构** - - -**边曲线类型枚举** -`enum class CurveType { Line, Circle, Bezier, BSpline, Nurbs }` - - -**拓扑顶点** -`struct TopoVertex {` - - -**拓扑边** -`struct TopoEdge {` - - -**拓扑环(Loop)** -`struct TopoLoop {` - - -**拓扑面** -`struct TopoFace {` - - -**拓扑壳** -`struct TopoShell {` - - -**拓扑体** -`struct TopoBody {` - - -**B-Rep 模型** - -**参见**: `brep_validate.h 验证`, `modeling.h 高层建模 API`, `brep_boolean.h 布尔运算` - - -**添加顶点** -`int add_vertex(const Point3D& p)` - -| 参数 | 说明 | -|------|------| -| `p` | 顶点坐标 | - -**返回**: 新顶点的 ID - - -**添加直线边** -`int add_edge(int v0, int v1)` - -| 参数 | 说明 | -|------|------| -| `v0` | 起点顶点 ID | -| `v1` | 终点顶点 ID | - -**返回**: 新边的 ID - - -**添加曲线边** -`int add_edge(int v0, int v1, const curves::NurbsCurve& curve)` - -| 参数 | 说明 | -|------|------| -| `v0` | 起点顶点 ID | -| `v1` | 终点顶点 ID | -| `curve` | 边的几何曲线 | - -**返回**: 新边的 ID - - -**添加环** -`int add_loop(const std::vector& edges, bool outer = true)` - -| 参数 | 说明 | -|------|------| -| `edges` | 环中边的 ID 序列(顺序连接) | -| `outer` | true = 外环, false = 内环 | - -**返回**: 新环的 ID - - -**添加面** -`int add_face(int surface_id, const std::vector& loops)` - -| 参数 | 说明 | -|------|------| -| `surface_id` | 关联曲面 ID | -| `loops` | 环 ID 列表 | - -**返回**: 新面的 ID - - -**添加壳** -`int add_shell(const std::vector& faces, bool closed = true)` - -| 参数 | 说明 | -|------|------| -| `faces` | 面 ID 列表 | -| `closed` | 是否为封闭壳 | - -**返回**: 新壳的 ID - - -**添加体** -`int add_body(const std::vector& shells, const std::string& name = "")` - -| 参数 | 说明 | -|------|------| -| `shells` | 壳 ID 列表 | -| `name` | 体名称 | - -**返回**: 新体的 ID - - -**添加 NURBS 曲面** -`int add_surface(const curves::NurbsSurface& surf)` - -| 参数 | 说明 | -|------|------| -| `surf` | NURBS 曲面定义 | - -**返回**: 新曲面的 ID - - -**顶点数量** -`[[nodiscard]] size_t num_vertices() const { return vertices_.size(); }` - - -**边数量** -`[[nodiscard]] size_t num_edges() const { return edges_.size(); }` - - -**面数量** -`[[nodiscard]] size_t num_faces() const { return faces_.size(); }` - - -**体数量** -`[[nodiscard]] size_t num_bodies() const { return bodies_.size(); }` - - -**曲面数量** -`[[nodiscard]] size_t num_surfaces() const { return surfaces_.size(); }` - - -**按数组索引访问顶点** -`[[nodiscard]] const TopoVertex& vertex(int id) const { return vertices_[id]; }` - - -**按唯一 ID 访问顶点(适用于边数据中的 ID 引用)** -`[[nodiscard]] const TopoVertex& vertex_by_id(int id) const` - - -**按数组索引访问边** -`[[nodiscard]] const TopoEdge& edge(int id) const { return edges_[id]; }` - - -**按数组索引访问面** -`[[nodiscard]] const TopoFace& face(int id) const { return faces_[id]; }` - - -**按数组索引访问曲面** -`[[nodiscard]] const curves::NurbsSurface& surface(int id) const { return surfaces_[id]; }` - - -**按唯一 ID 访问环** -`[[nodiscard]] const TopoLoop& loop_by_id(int id) const` - - -**获取所有环的只读引用** -`[[nodiscard]] const std::vector& all_loops() const { return loops_; }` - - -**计算模型的轴对齐包围盒** -`[[nodiscard]] core::AABB3D bounds() const` - -**返回**: 包围盒(AABB) - - -**检查模型有效性(快速版本)** -`[[nodiscard]] bool is_valid() const` - -**返回**: true 如果模型通过基本检查 - -**参见**: `validate() 完整验证(水密性、方向一致性等)` - - -**将 B-Rep 模型 tessellate 为三角网格** -`[[nodiscard]] mesh::HalfedgeMesh to_mesh(double deflection = 0.01) const` - -| 参数 | 说明 | -|------|------| -| `deflection` | 弦高误差(控制 tessellation 精度,默认 0.01) | - -**返回**: HalfedgeMesh 三角网格 -> deflection 越小网格越精细,但三角形数量显著增加。 - - -**获取面的所有边** -`[[nodiscard]] std::vector face_edges(int face_id) const` - -| 参数 | 说明 | -|------|------| -| `face_id` | 面 ID | - -**返回**: 边 ID 列表(去重) - - -**获取边的所有相邻面** -`[[nodiscard]] std::vector edge_faces(int edge_id) const` - -| 参数 | 说明 | -|------|------| -| `edge_id` | 边 ID | - -**返回**: 相邻面 ID 列表 - - -**获取顶点的所有相邻边** -`[[nodiscard]] std::vector vertex_edges(int vertex_id) const` - -| 参数 | 说明 | -|------|------| -| `vertex_id` | 顶点 ID | - -**返回**: 相邻边 ID 列表 - - - -### `brep_boolean.h` - -**B-Rep 级别的布尔运算** - - -**B-Rep 布尔并集: A ∪ B** -`[[nodiscard]] BrepModel brep_union(const BrepModel& a, const BrepModel& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个 B-Rep 实体 | -| `b` | 第二个 B-Rep 实体 | - -**返回**: 新的 B-Rep 实体(a ∪ b) - -**参见**: `brep_intersection 交集`, `brep_difference 差集` - - -**B-Rep 布尔交集: A ∩ B** -`[[nodiscard]] BrepModel brep_intersection(const BrepModel& a, const BrepModel& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 第一个 B-Rep 实体 | -| `b` | 第二个 B-Rep 实体 | - -**返回**: 新的 B-Rep 实体(a ∩ b) - -**参见**: `brep_union 并集`, `brep_difference 差集` - - -**B-Rep 布尔差集: A \ B** -`[[nodiscard]] BrepModel brep_difference(const BrepModel& a, const BrepModel& b)` - -| 参数 | 说明 | -|------|------| -| `a` | 被减实体 A | -| `b` | 减去实体 B | - -**返回**: 新的 B-Rep 实体(a \ b) - -**参见**: `brep_union 并集`, `brep_intersection 交集` - - - -### `brep_validate.h` - -**B-Rep 模型综合验证** - - -**B-Rep 模型的综合验证结果** -`struct ValidationResult {` - - -**是否通过所有必要检查** -`bool valid = true` - - -**错误信息列表(导致 valid = false)** -`std::vector errors` - - -**警告信息列表(不影响 valid)** -`std::vector warnings` - - -**水密性比率:恰好有 2 个相邻面的边的比例(1.0 = 完美水密)** -`double watertightness = 1.0` - - -**无自交比率:不与其他面内部相交的面对比例(1.0 = 无自交)** -`double self_intersection_free = 1.0` - - -**最短边的长度(用于检测退化边)** -`double min_edge_length = std::numeric_limits::max()` - - -**最长边的长度(用于检测超长边)** -`double max_edge_length = 0.0` - - -**非流形边数(相邻面 ≠ 2 的边)** -`size_t non_manifold_edges = 0` - - -**悬挂边数(无相邻面的边)** -`size_t dangling_edges = 0` - - -**方向不一致的面数** -`size_t inconsistent_orientations = 0` - - -**总边数** -`size_t total_edges = 0` - - -**总面数** -`size_t total_faces = 0` - - -**对 BrepModel 执行综合验证** -`[[nodiscard]] ValidationResult validate(const BrepModel& body)` - -| 参数 | 说明 | -|------|------| -| `body` | 待验证的 B-Rep 模型 | - -**返回**: ValidationResult 包含所有检查结果的详细报告 -> 自交检测是最昂贵的检查项(O(n²) 面对数), - -**参见**: `BrepModel::is_valid() 快速有效性检查(无详细报告)` - - - -### `iges_export.h` - -**IGES 文件导出(版本 5.3)** - - -**将 B-Rep 体导出为 IGES 格式字符串(版本 5.3)** -`[[nodiscard]] std::string export_iges(const std::vector& bodies)` - -| 参数 | 说明 | -|------|------| -| `bodies` | B-Rep 体列表 | - -**返回**: IGES 5.3 格式字符串 - -**参见**: `export_iges_file 直接写入文件`, `export_step STEP 格式导出` - - -**将 B-Rep 体导出为 IGES 文件** -`void export_iges_file(const std::string& filepath, const std::vector& bodies)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径(建议扩展名 .igs 或 .iges) | -| `bodies` | B-Rep 体列表 | - -**参见**: `export_iges 获取字符串输出` - - - -### `iges_import.h` - -**IGES 文件导入(ANSI Y14.26M)** - - -**IGES 导入错误码** -`enum class IgesError {` - - -**从文件导入 IGES** -`[[nodiscard]] std::vector import_iges(const std::string& filepath)` - -| 参数 | 说明 | -|------|------| -| `filepath` | .igs 或 .iges 文件路径 | - -**返回**: B-Rep 体列表 -> IGES 格式较为宽松,不同 CAD 系统的实现差异很大。 - -**参见**: `import_iges_from_string 从字符串导入`, `iges_last_error 获取错误码` - - -**从字符串导入 IGES(用于测试)** -`[[nodiscard]] std::vector import_iges_from_string(const std::string& data)` - -| 参数 | 说明 | -|------|------| -| `data` | IGES 文件完整内容(字符串形式) | - -**返回**: B-Rep 体列表 - -**参见**: `import_iges 从文件导入` - - -**获取最近一次 IGES 导入的错误码** -`[[nodiscard]] IgesError iges_last_error()` - -**返回**: IgesError 枚举值 - -**参见**: `iges_last_error_message 获取可读描述` - - -**获取最近一次 IGES 导入的可读错误描述** -`[[nodiscard]] const std::string& iges_last_error_message()` - -**返回**: 错误描述字符串 - -**参见**: `iges_last_error 获取枚举错误码` - - - -### `modeling.h` - -**高层 B-Rep 建模 API** - - -**沿方向挤出平面轮廓** -`[[nodiscard]] BrepModel extrude(const curves::NurbsCurve& profile, const Vector3D& dir)` - -| 参数 | 说明 | -|------|------| -| `profile` | 轮廓曲线(必须位于一个平面内) | -| `dir` | 挤出方向向量(其长度决定挤出距离) | - -**返回**: 挤出后的 B-Rep 实体 - -**参见**: `revolve 旋转扫掠`, `sweep 沿任意路径扫掠` - - -**绕轴旋转平面轮廓** -`[[nodiscard]] BrepModel revolve(const curves::NurbsCurve& profile,` - -| 参数 | 说明 | -|------|------| -| `profile` | 轮廓曲线(通常位于轴的半平面中) | -| `axis_origin` | 旋转轴上的一个点 | -| `axis_dir` | 旋转轴方向(单位向量) | -| `angle_rad` | 旋转角度(弧度,默认 2π = 完整的旋转体) | - -**返回**: 旋转后的 B-Rep 实体 - -**参见**: `extrude 线性挤出`, `make_sphere 直接创建球体` - - -**沿任意路径扫掠轮廓** -`[[nodiscard]] BrepModel sweep(const curves::NurbsCurve& profile,` - -| 参数 | 说明 | -|------|------| -| `profile` | 截面轮廓(需位于路径起点的垂直平面内) | -| `path` | 扫掠路径曲线 | - -**返回**: 扫掠后的 B-Rep 实体 -> 路径曲率过大处可能出现自交,需要控制路径的光滑性。 - -**参见**: `extrude 直线挤出`, `revolve 旋转扫掠` - - -**在两个或多个轮廓曲线之间放样** -`[[nodiscard]] BrepModel loft(const std::vector& profiles)` - -| 参数 | 说明 | -|------|------| -| `profiles` | 轮廓曲线列表(至少 2 条) | - -**返回**: 放样后的 B-Rep 实体 - -**参见**: `extrude 单轮廓挤出` - - -**创建立方体** -`[[nodiscard]] BrepModel make_box(double w, double h, double d)` - -| 参数 | 说明 | -|------|------| -| `w` | 宽度(X 方向),必须 > 0 | -| `h` | 高度(Y 方向),必须 > 0 | -| `d` | 深度(Z 方向),必须 > 0 | - -**返回**: 实心立方体 B-Rep - -**参见**: `make_cylinder 圆柱体`, `make_sphere 球体` - - -**创建圆柱体** -`[[nodiscard]] BrepModel make_cylinder(double radius, double height, int segments = 32)` - -| 参数 | 说明 | -|------|------| -| `radius` | 截面半径,必须 > 0 | -| `height` | 总高度,沿 Y 轴从 -h/2 到 +h/2 | -| `segments` | 截面分段数(边数,默认 32) | - -**返回**: 实心圆柱体 B-Rep -> segments 越大圆柱越光滑,但面和边数增加。 - -**参见**: `make_box 立方体`, `make_sphere 球体` - - -**创建球体** -`[[nodiscard]] BrepModel make_sphere(double radius, int segments_u = 32, int segments_v = 16)` - -| 参数 | 说明 | -|------|------| -| `radius` | 球半径,必须 > 0 | -| `segments_u` | 经度方向分段数(默认 32) | -| `segments_v` | 纬度方向分段数(默认 16) | - -**返回**: 实心球体 B-Rep - -**参见**: `make_cylinder 圆柱体` - - -**对边做圆角处理** -`[[nodiscard]] BrepModel fillet(const BrepModel& body, int edge_id, double radius)` - -| 参数 | 说明 | -|------|------| -| `body` | 输入实体 | -| `edge_id` | 要倒圆的边 ID | -| `radius` | 圆角半径,必须 > 0 | - -**返回**: 圆角后的新实体 -> 圆角半径不能超过相邻面的最小宽度,否则会产生自交。 -> 只支持恒定半径圆角。变半径圆角尚未实现。 - -**参见**: `chamfer 倒角`, `shell 抽壳` - - -**对边做倒角** -`[[nodiscard]] BrepModel chamfer(const BrepModel& body, int edge_id, double distance)` - -| 参数 | 说明 | -|------|------| -| `body` | 输入实体 | -| `edge_id` | 要倒角的边 ID | -| `distance` | 倒角距离(从原边沿两个面各偏移的距离) | - -**返回**: 倒角后的新实体 - -**参见**: `fillet 圆角` - - -**抽壳(挖空实体)** -`[[nodiscard]] BrepModel shell(const BrepModel& body, int face_id, double thickness)` - -| 参数 | 说明 | -|------|------| -| `body` | 输入实心实体 | -| `face_id` | 要移除的面 ID(形成开口),-1 表示封闭壳(不开口) | -| `thickness` | 壁厚(正值 = 向外偏移,负值 = 向内偏移) | - -**返回**: 抽壳后的新实体 -> 壁厚不应超过实体最小尺寸的一半。 -> 当 face_id = -1 时,结果是一个封闭的壳(中空但没有开口)。 - -**参见**: `fillet 圆角` - - - -### `step_export.h` - -**STEP 文件导出(ISO 10303-214)** - - -**将 B-Rep 体导出为 STEP AP214 字符串** -`[[nodiscard]] std::string export_step(const std::vector& bodies)` - -| 参数 | 说明 | -|------|------| -| `bodies` | B-Rep 体列表(每个体对应一个 PRODUCT) | - -**返回**: STEP AP214 格式字符串 -> 输出包含所有必要的 ISO 10303-21 头部信息。 - -**参见**: `export_step_file 直接写入文件`, `export_iges IGES 格式导出` - - -**将 B-Rep 体导出为 STEP 文件** -`void export_step_file(const std::string& filepath, const std::vector& bodies)` - -| 参数 | 说明 | -|------|------| -| `filepath` | 输出文件路径(建议扩展名 .step 或 .stp) | -| `bodies` | B-Rep 体列表 | - -**参见**: `export_step 获取字符串输出` - - - -### `step_import.h` - -**STEP 文件导入(ISO 10303)** - - -**STEP 导入错误码** -`enum class StepError {` - - -**从文件导入 STEP(AP203/AP214)** -`[[nodiscard]] std::vector import_step(const std::string& filepath)` - -| 参数 | 说明 | -|------|------| -| `filepath` | .step 或 .stp 文件路径 | - -**返回**: B-Rep 体列表(每个文件中的 PRODUCT 一个) -> 大型 STEP 文件(> 100 MB)可能需要数秒到数十秒进行解析。 - -**参见**: `import_step_from_string 从内存字符串导入(测试用)`, `step_last_error 获取错误码` - - -**从字符串导入 STEP(用于测试和嵌入式场景)** -`[[nodiscard]] std::vector import_step_from_string(const std::string& step_data)` - -| 参数 | 说明 | -|------|------| -| `step_data` | 完整的 STEP 文件内容(字符串形式) | - -**返回**: B-Rep 体列表 - -**参见**: `import_step 从文件导入` - - -**获取最近一次 STEP 导入的错误码** -`[[nodiscard]] StepError step_last_error()` - -**返回**: StepError 枚举值 - -**参见**: `step_last_error_message 获取可读的错误描述` - - -**获取最近一次 STEP 导入的可读错误描述** -`[[nodiscard]] const std::string& step_last_error_message()` - -**返回**: 错误描述字符串(如 "Missing entity reference #42") - -**参见**: `step_last_error 获取枚举错误码` - - - -## SDF隐式建模 (`vde::sdf`) - - -### `sdf_gradient.h` - -**SDF 梯度计算(数值微分、解析梯度、链式法则)** - - -**SDF 的空间梯度(中心差分近似)** -`[[nodiscard]] inline Vector3D gradient(` - -| 参数 | 说明 | -|------|------| -| `f` | SDF 函数(接受 Point3D 参数) | -| `p` | 求值点 | -| `h` | 差分步长(默认 1e-6) | - -**返回**: 梯度向量 ∇f(p) -> 步长太小会导致舍入误差主导,太大导致截断误差主导。 -> 对于含不连续性的 SDF(如 sharp CSG),有限差分可能在边界产生错误梯度。 - -**参见**: `evaluate_with_gradient 一次性获取值和梯度` - - -**前向模梯度结果: SDF 值 + 梯度** -`struct GradResult {` - - -**同时计算 SDF 值和梯度的便捷函数** -`[[nodiscard]] inline GradResult evaluate_with_gradient(` - -| 参数 | 说明 | -|------|------| -| `f` | SDF 函数 | -| `p` | 求值点 | -| `h` | 差分步长 | - -**返回**: value + grad 结构 - -**参见**: `gradient 仅计算梯度` - - -**球体 SDF 对半径的参数梯度 ∂f/∂r** -`[[nodiscard]] inline double sphere_radius_gradient(const Point3D& p, double radius, double h = 1e-6)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 球体半径 | -| `h` | 差分步长(默认 1e-6) | - -**返回**: ∂f/∂radius -> 对于球体,解析梯度为 -1(球面上),但此函数提供与实现无关的数值验证。 - -**参见**: `sphere_param_grad 封装版本` - - -**长方体 SDF 对各轴半尺寸的参数梯度 ∂f/∂extent[i]** -`[[nodiscard]] inline double box_extent_gradient(const Point3D& p, const Point3D& extents,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `extents` | 半边长 | -| `axis` | 轴索引: 0=x, 1=y, 2=z | -| `h` | 差分步长 | - -**返回**: ∂f/∂extent[axis] - -**参见**: `box_param_grad 封装版本` - - -**圆环 SDF 对主半径的参数梯度 ∂f/∂major_r** -`[[nodiscard]] inline double torus_major_gradient(const Point3D& p, double major_r, double minor_r,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `major_r` | 主半径 | -| `minor_r` | 副半径 | -| `h` | 差分步长 | - -**返回**: 参数梯度 - - -**圆环 SDF 对副半径的参数梯度 ∂f/∂minor_r** -`[[nodiscard]] inline double torus_minor_gradient(const Point3D& p, double major_r, double minor_r,` - -**返回**: 参数梯度 - - -**圆柱 SDF 对高度的参数梯度 ∂f/∂height** -`[[nodiscard]] inline double cylinder_height_gradient(const Point3D& p, double radius, double height,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 圆柱半径 | -| `height` | 圆柱高度 | -| `h` | 差分步长 | - -**返回**: 参数梯度 - - -**圆柱 SDF 对半径的参数梯度 ∂f/∂radius** -`[[nodiscard]] inline double cylinder_radius_gradient(const Point3D& p, double radius, double height,` - -**返回**: 参数梯度 - - -**球体 SDF 的解析梯度** -`[[nodiscard]] inline Vector3D sphere_gradient_analytic(const Point3D& p, double /*radius*/)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 球半径(当前未使用,保留以保持接口一致) | - -**返回**: 解析梯度(单位向量) -> 在表面上 (|p| = radius),梯度即为外法向量。 - - -**长方体 SDF 的解析梯度** -`[[nodiscard]] inline Vector3D box_gradient_analytic(const Point3D& p, const Point3D& half_extents)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `half_extents` | 半边长 | - -**返回**: 解析梯度 - - -**圆环 SDF 的解析梯度** -`[[nodiscard]] inline Vector3D torus_gradient_analytic(const Point3D& p, double major_r, double minor_r)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `major_r` | 主半径 | -| `minor_r` | 副半径 | - -**返回**: 解析梯度 - - -**无限圆柱(沿 Y 轴)的解析梯度** -`[[nodiscard]] inline Vector3D cylinder_gradient_analytic(const Point3D& p, double /*radius*/)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 圆柱半径(未使用,保留接口一致) | - -**返回**: 解析梯度 - - -**平面的解析梯度** -`[[nodiscard]] inline Vector3D plane_gradient_analytic(const Vector3D& normal)` - -| 参数 | 说明 | -|------|------| -| `normal` | 单位法向量 | - -**返回**: 梯度(等于 normal) -> 这是最简单的解析梯度,因为平面 SDF 是线性的。 - - -**胶囊体 SDF 的解析梯度** -`[[nodiscard]] inline Vector3D capsule_gradient_analytic(const Point3D& p,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `a` | 线段起点 | -| `b` | 线段终点 | -| `radius` | 扫掠球半径 | - -**返回**: 解析梯度 - - -**并集操作后的梯度传递** -`[[nodiscard]] inline Vector3D chain_union(const Vector3D& grad_a, const Vector3D& grad_b,` - -| 参数 | 说明 | -|------|------| -| `grad_a` | 子对象 A 的梯度 | -| `grad_b` | 子对象 B 的梯度 | -| `d1` | A 的 SDF 值 | -| `d2` | B 的 SDF 值 | - -**返回**: 合并后的梯度 - -**参见**: `chain_smooth_union 避免不连续的平滑版本` - - -**交集操作后的梯度传递** -`[[nodiscard]] inline Vector3D chain_intersection(const Vector3D& grad_a, const Vector3D& grad_b,` - -**返回**: 合并后的梯度 - - -**差集操作后的梯度传递** -`[[nodiscard]] inline Vector3D chain_difference(const Vector3D& grad_a, const Vector3D& grad_b,` - -| 参数 | 说明 | -|------|------| -| `grad_a` | 子对象 A 的梯度 | -| `grad_b` | 子对象 B 的梯度 | -| `d1` | f_A | -| `d2` | f_B | - -**返回**: 合并后的梯度 - - -**平滑并集操作的梯度传递(含完整链式法则)** -`[[nodiscard]] inline Vector3D chain_smooth_union(const Vector3D& grad_a, const Vector3D& grad_b,` - -| 参数 | 说明 | -|------|------| -| `grad_a` | 子对象 A 的梯度 | -| `grad_b` | 子对象 B 的梯度 | -| `d1` | f_A | -| `d2` | f_B | -| `k` | 混合参数 | - -**返回**: 平滑合并后的梯度 - -**参见**: `op_smooth_union 对应的平滑并集 SDF 操作`, `chain_union 硬切换版本` - - -**平移变换后的梯度传递(梯度不变)** -`[[nodiscard]] inline GradResult chain_translate(const GradResult& child_result, const Point3D& /*offset*/)` - -| 参数 | 说明 | -|------|------| -| `child_result` | 变换空间中的子对象求值结果 | -| `offset` | 平移量(仅接口保留) | - -**返回**: 相同梯度 - - -**绕 Y 轴旋转后的梯度传递** -`[[nodiscard]] inline GradResult chain_rotate(const GradResult& child_result, double angle_rad)` - -| 参数 | 说明 | -|------|------| -| `child_result` | 旋转后坐标系中的子对象求值 | -| `angle_rad` | 旋转角度 | - -**返回**: 世界坐标系的梯度 - -**参见**: `op_rotate 对应的域变形操作` - - -**非均匀缩放后的梯度传递** -`[[nodiscard]] inline GradResult chain_scale(const GradResult& child_result, const Point3D& factors)` - -| 参数 | 说明 | -|------|------| -| `child_result` | 缩放后坐标系中的子对象求值 | -| `factors` | 缩放因子 | - -**返回**: 世界坐标系的梯度 -> 缩放后梯度不再是单位长度,除非是均匀缩放。 - - -**扭曲变换后的梯度传递(含完整雅可比)** -`[[nodiscard]] inline GradResult chain_twist(const GradResult& child_result,` - -| 参数 | 说明 | -|------|------| -| `child_result` | 扭曲空间中的子对象求值 | -| `amount` | 单位高度的旋转量 | -| `p` | 原始采样点 | - -**返回**: 世界坐标系的梯度 - -**参见**: `op_twist 对应的域变形操作`, `chain_rotate 不含 Y 依赖的简化旋转梯度传递` - - -**周期重复后的梯度传递(梯度不变)** -`[[nodiscard]] inline GradResult chain_repeat(const GradResult& child_result,` - -| 参数 | 说明 | -|------|------| -| `child_result` | 中心晶格内的子对象求值 | -| `cell` | 晶格尺寸(仅接口保留) | -| `p` | 原始采样点(仅接口保留) | - -**返回**: 相同梯度 - - -**参数梯度结构体** -`struct ParamGrad {` - -**参见**: `sphere_param_grad, box_param_grad, cylinder_param_grad` - - -**球体所有参数的梯度(当前仅 radius 有意义)** -`[[nodiscard]] inline ParamGrad sphere_param_grad(const Point3D& p, double radius, double h = 1e-6)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 球体半径 | -| `h` | 差分步长 | - -**返回**: 参数梯度(仅 d_radius 非零) - -**参见**: `sphere_radius_gradient 底层数值差分` - - -**长方体所有参数的梯度** -`[[nodiscard]] inline ParamGrad box_param_grad(const Point3D& p, const Point3D& half_extents,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `half_extents` | 半边长 | -| `h` | 差分步长 | - -**返回**: 参数梯度(d_extents 分量填充) - -**参见**: `box_extent_gradient 底层数值差分` - - -**圆柱所有参数的梯度** -`[[nodiscard]] inline ParamGrad cylinder_param_grad(const Point3D& p, double radius, double height,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 圆柱半径 | -| `height` | 圆柱高度 | -| `h` | 差分步长 | - -**返回**: 参数梯度(d_radius, d_height 填充) - - - -### `sdf_operations.h` - -**SDF 布尔运算、修饰算子与域变形** - - -**布尔并集: A ∪ B** -`[[nodiscard]] inline double op_union(double d1, double d2) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 第一个对象的 SDF 值 | -| `d2` | 第二个对象的 SDF 值 | - -**返回**: 并集的 SDF 值 - -**参见**: `op_smooth_union 带平滑过渡的并集`, `op_intersection 交集` - - -**布尔交集: A ∩ B** -`[[nodiscard]] inline double op_intersection(double d1, double d2) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 第一个对象的 SDF 值 | -| `d2` | 第二个对象的 SDF 值 | - -**返回**: 交集的 SDF 值 - -**参见**: `op_smooth_intersection 带平滑过渡的交集` - - -**布尔差集: A \ B** -`[[nodiscard]] inline double op_difference(double d1, double d2) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 被减对象 A 的 SDF 值 | -| `d2` | 减去对象 B 的 SDF 值 | - -**返回**: 差集的 SDF 值 - -**参见**: `op_smooth_difference 带平滑过渡的差集` - - -**平滑并集(带混合过渡)** -`[[nodiscard]] inline double op_smooth_union(double d1, double d2, double k) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 第一个对象的 SDF 值 | -| `d2` | 第二个对象的 SDF 值 | -| `k` | 混合强度参数(> 0 时平滑过渡;≤ 0 时退化为普通并集) | - -**返回**: 平滑混合后的 SDF 值 -> 多项式混合是函数 f(x)=x 在 [0,k] 区间的平滑近似。在 d1=d2 处,f 向下偏移 k/4。 - -**参见**: `op_union 无平滑的标准并集`, `op_smooth_intersection 平滑交集`, `op_smooth_difference 平滑差集` - - -**平滑交集(带混合过渡)** -`[[nodiscard]] inline double op_smooth_intersection(double d1, double d2, double k) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 第一个对象的 SDF 值 | -| `d2` | 第二个对象的 SDF 值 | -| `k` | 混合强度参数 | - -**返回**: 平滑混合后的 SDF 值 - -**参见**: `op_intersection 无平滑的标准交集`, `op_smooth_union 平滑并集` - - -**平滑差集(带混合过渡)** -`[[nodiscard]] inline double op_smooth_difference(double d1, double d2, double k) {` - -| 参数 | 说明 | -|------|------| -| `d1` | 被减对象 A 的 SDF 值 | -| `d2` | 减去对象 B 的 SDF 值 | -| `k` | 混合强度参数 | - -**返回**: 平滑混合后的 SDF 值 - -**参见**: `op_difference 无平滑的标准差集`, `op_smooth_union 平滑并集` - - -**圆角偏移: 将等值面向外扩展 r 单位** -`[[nodiscard]] inline double op_round(double d, double r) {` - -| 参数 | 说明 | -|------|------| -| `d` | SDF 值 | -| `r` | 偏移距离(正值 = 膨胀,负值 = 收缩) | - -**返回**: 偏移后的 SDF 值 - -**参见**: `op_onion 壳层修饰`, `round_box 特例化的圆角立方体` - - -**洋葱皮/壳层修饰: 取绝对值后减去厚度** -`[[nodiscard]] inline double op_onion(double d, double thickness) {` - -| 参数 | 说明 | -|------|------| -| `d` | SDF 值 | -| `thickness` | 壳层半厚度,必须 > 0 | - -**返回**: 壳层的 SDF 值 - -**参见**: `op_round 圆角偏移` - - -**无限重复(周期复制)** -`[[nodiscard]] inline Point3D op_repeat(const Point3D& p, const Point3D& cell) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `cell` | 晶格尺寸 (cx, cy, cz),各分量必须 > 0 才生效 | - -**返回**: 映射到中心晶格内的点 -> 边界处 SDF 可能不连续,需要确保各晶格间映射是连续的。 - - -**镜像对称(X=0 平面),可选偏移** -`[[nodiscard]] inline Point3D op_mirror_x(const Point3D& p, double offset = 0.0) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `offset` | 镜像平面沿 X 轴的偏移量(默认 0 = X=0 平面) | - -**返回**: 映射到镜像半空间的点 - -**参见**: `op_mirror_y YZ 平面镜像`, `op_mirror_z XY 平面镜像` - - -**镜像对称(Y=0 平面)** -`[[nodiscard]] inline Point3D op_mirror_y(const Point3D& p) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | - -**返回**: 映射到上半空间的点 - - -**镜像对称(Z=0 平面)** -`[[nodiscard]] inline Point3D op_mirror_z(const Point3D& p) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | - -**返回**: 映射到前半空间的点 - - -**空间平移(逆变换)** -`[[nodiscard]] inline Point3D op_translate(const Point3D& p, const Point3D& offset) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `offset` | 平移量(对象正向移动的方向) | - -**返回**: 逆平移后的采样点 - -**参见**: `op_rotate 旋转变换`, `op_scale 缩放变换` - - -**绕 Y 轴旋转(逆变换)** -`[[nodiscard]] inline Point3D op_rotate(const Point3D& p, double angle_rad) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `angle_rad` | 旋转角度(弧度),正值 = 逆时针(从上往下看) | - -**返回**: 逆旋转后的采样点 - -**参见**: `op_twist 绕 Y 轴的扭曲变换`, `op_bend 弯曲变换` - - -**非均匀缩放(逆变换)** -`[[nodiscard]] inline Point3D op_scale(const Point3D& p, const Point3D& s) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `s` | 各轴缩放因子 (sx, sy, sz),均必须 ≠ 0 | - -**返回**: 缩放后的采样点 - -**参见**: `op_translate 平移(等距变换)`, `op_rotate 旋转(等距变换)` - - -**绕 Y 轴的扭曲变换** -`[[nodiscard]] inline Point3D op_twist(const Point3D& p, double amount) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `amount` | 单位高度上的旋转量(弧度/单位长度) | - -**返回**: 扭曲后的采样点 - -**参见**: `op_rotate 恒定角度旋转`, `op_bend 弯曲变换` - - -**弯曲变换(绕 Z 轴弯曲 XZ 平面)** -`[[nodiscard]] inline Point3D op_bend(const Point3D& p, double k) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `k` | 弯曲曲率参数(k 越大弯曲越剧烈) | - -**返回**: 弯曲后的采样点 - -**参见**: `op_cheap_bend 简化版弯曲(仅绕 X 轴)`, `op_twist 扭曲变换` - - -**拉伸/压扁域变形(消除拉伸方向上的内部体积)** -`[[nodiscard]] inline Point3D op_elongate(const Point3D& p, const Point3D& h) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `h` | 各轴的拉伸阈值 (hx, hy, hz),均 ≥ 0 | - -**返回**: 变形后的采样点 - -**参见**: `op_repeat 周期重复` - - -**简化弯曲变换(绕 X 轴弯曲 YZ 平面)** -`[[nodiscard]] inline Point3D op_cheap_bend(const Point3D& p, double k) {` - -| 参数 | 说明 | -|------|------| -| `p` | 原始采样点 | -| `k` | 弯曲曲率参数 | - -**返回**: 弯曲后的采样点 -> 使用场景:不需要精确物理弯曲,仅需视觉效果时优先用此函数以节省计算。 - -**参见**: `op_bend 完整弯曲变换` - - -**正弦波位移扰动** -`[[nodiscard]] inline double op_displace(double d, const Point3D& p,` - -| 参数 | 说明 | -|------|------| -| `d` | 原始 SDF 值 | -| `p` | 采样点(用于扰动计算) | -| `amplitude` | 扰动幅值 | -| `frequency` | 空间频率 | - -**返回**: 扰动后的 SDF 值 - - - -### `sdf_optimize.h` - -**基于梯度的 SDF 形状优化** - - -**优化结果** -`struct OptimizeResult {` - - -**损失函数类型** -`using LossFn = std::function&)>` - -**参见**: `fit_to_point_cloud 使用该类型的内置实现` - - -**将参数化形状拟合到目标点云** -`[[nodiscard]] OptimizeResult fit_to_point_cloud(` - -| 参数 | 说明 | -|------|------| -| `initial` | 初始形状(sphere, box, cylinder 等),其参数将被优化 | -| `target_points` | 目标点云(表面采样点) | -| `learning_rate` | 梯度下降步长(默认 0.01) | -| `max_iterations` | 最大迭代次数(默认 100) | - -**返回**: 优化结果(含优化后的形状和收敛信息) -> 损失函数为 L = mean(|sdf(p_i)|),即点到表面的平均绝对距离。 -> initial 的共享子节点不会被复制——返回的 optimize_shape 共享未修改的子树。 - -**参见**: `fit_surface_to_points 类似但仅最小化 |sdf| 而非有符号距离`, `fit_to_sdf 拟合到另一个 SDF` - - -**将形状表面移动到目标采样点** -`[[nodiscard]] OptimizeResult fit_surface_to_points(` - -| 参数 | 说明 | -|------|------| -| `initial` | 初始形状 | -| `surface_points` | 目标表面点 | -| `learning_rate` | 学习率 | -| `max_iterations` | 最大迭代次数 | - -**返回**: 优化结果 - -**参见**: `fit_to_point_cloud 更通用的点云拟合(可包含内部/外部点)` - - -**拟合一个 SDF 形状以匹配另一个目标 SDF** -`[[nodiscard]] OptimizeResult fit_to_sdf(` - -| 参数 | 说明 | -|------|------| -| `source` | 被优化的参数化形状 | -| `target_sdf` | 目标 SDF 函数 | -| `bmin` | 采样网格最小角点 | -| `bmax` | 采样网格最大角点 | -| `grid_resolution` | 采样网格分辨率(默认 16) | -| `learning_rate` | 学习率 | -| `max_iterations` | 最大迭代次数 | - -**返回**: 优化结果 - -**参见**: `fit_to_point_cloud 拟合到点云` - - -**通过平移解决两个形状之间的穿透** -`[[nodiscard]] bool resolve_collision(` - -| 参数 | 说明 | -|------|------| -| `shape_a` | 形状 A(原地修改) | -| `shape_b` | 形状 B(原地修改) | -| `step_size` | 每次迭代的平移步长(默认 0.1) | -| `max_iterations` | 最大迭代次数(默认 50) | - -**返回**: true 如果碰撞被成功解决;false 如果在迭代次数内未能解决 - -**参见**: `penetration_depth 估算穿透深度` - - -**估算两个形状之间的最小穿透距离** -`[[nodiscard]] double penetration_depth(` - -| 参数 | 说明 | -|------|------| -| `shape_a` | 形状 A | -| `shape_b` | 形状 B | -| `bmin` | 公共包围盒最小角点 | -| `bmax` | 公共包围盒最大角点 | -| `samples` | 蒙地卡罗采样数(默认 1000) | - -**返回**: 最大穿透深度(负值表示不重叠时的最小间距) - -**参见**: `resolve_collision 解决穿透` - - -**计算形状表面上点的可及性分数** -`[[nodiscard]] double accessibility(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `p` | 表面点(应满足 |sdf(p)| < ε) | -| `direction` | 接近方向 | -| `hemisphere_samples` | 半球采样光线数量(默认 64) | - -**返回**: 可及性分数 [0, 1] -> 采样数越多越精确,但线性增加计算量。 - -**参见**: `find_accessible_point 找到最大可及性的表面点` - - -**找到给定接近方向下具有最大可及性的表面点** -`[[nodiscard]] Point3D find_accessible_point(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `approach_dir` | 接近方向(如工具接近方向) | -| `bmin` | 搜索包围盒最小角点 | -| `bmax` | 搜索包围盒最大角点 | -| `grid_res` | 搜索网格分辨率(默认 32) | - -**返回**: 最大可及性的表面点 - -**参见**: `accessibility 单点可及性计算` - - -**检测形状在给定方向上的反射对称性** -`[[nodiscard]] double symmetry_score(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `bmin` | 包围盒最小角点 | -| `bmax` | 包围盒最大角点 | -| `plane_normal` | 反射平面的法向量 | -| `plane_offset` | 反射平面的偏移量(沿法向量方向,默认 0) | -| `samples` | 采样点对数(默认 1000) | - -**返回**: 对称性分数 [0, 1](0 = 完全不对称,1 = 完美对称) - -**参见**: `find_symmetry_plane 自动寻找最佳对称平面` - - -**对称检测结果** -`struct SymmetryResult {` - - -**自动找到形状的最佳反射对称平面** -`[[nodiscard]] SymmetryResult find_symmetry_plane(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `bmin` | 包围盒最小角点 | -| `bmax` | 包围盒最大角点 | -| `samples` | 每个候选方向的采样数(默认 1000) | - -**返回**: 最佳对称平面及其分数 - -**参见**: `symmetry_score 给定方向的对称性检测` - - -**通过蒙地卡罗法估算隐式形状的体积** -`[[nodiscard]] double estimate_volume(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `bmin` | 采样包围盒最小角点 | -| `bmax` | 采样包围盒最大角点 | -| `samples` | 蒙地卡罗采样数(默认 10000) | - -**返回**: 近似体积 -> 精度与 √samples 成正比。10000 采样 ≈ 1% 相对误差。 -> 包围盒应尽可能紧致以减小方差。 - -**参见**: `center_of_mass 蒙地卡罗质心估算` - - -**通过蒙地卡罗法估算形状的质心** -`[[nodiscard]] Point3D center_of_mass(` - -| 参数 | 说明 | -|------|------| -| `shape` | SDF 形状 | -| `bmin` | 采样包围盒最小角点 | -| `bmax` | 采样包围盒最大角点 | -| `samples` | 蒙地卡罗采样数(默认 10000) | - -**返回**: 近似质心坐标 - -**参见**: `estimate_volume 体积估算` - - -**SDF 树中可变参数的引用** -`struct ParamRef {` - - -**从叶节点收集所有可变数值参数** -`[[nodiscard]] std::vector collect_params(SdfNodePtr& root)` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 树根节点(可写引用,因为参数将被原地修改) | - -**返回**: 可变参数引用列表 - -**参见**: `numerical_gradient 计算损失对参数的数值梯度` - - -**计算标量损失对收集到的参数的数值梯度** -`[[nodiscard]] std::vector numerical_gradient(` - -| 参数 | 说明 | -|------|------| -| `params` | collect_params() 返回的参数引用列表 | -| `loss_fn` | 损失函数(无参数的可调用对象) | -| `eps` | 差分步长(默认 1e-6) | - -**返回**: 梯度向量 grad_loss,grad_loss[i] = ∂loss / ∂params[i].value - -**参见**: `collect_params 收集参数`, `GradientDescent 梯度下降优化器` - - -**固定学习率的简单梯度下降优化器** - - -**构造优化器** -`explicit GradientDescent(double lr) : lr_(lr) {}` - -| 参数 | 说明 | -|------|------| -| `lr` | 学习率(步长因子) | - - -**执行单步梯度下降** -`double step(std::vector& params,` - -| 参数 | 说明 | -|------|------| -| `params` | 参数向量(原地修改) | -| `grad_fn` | 梯度计算函数,签名为 | - -**返回**: 当前损失值 - - -**设置学习率** -`void set_learning_rate(double lr) { lr_ = lr; }` - - -**获取学习率** -`[[nodiscard]] double learning_rate() const { return lr_; }` - - -**获取当前迭代次数** -`[[nodiscard]] int iteration() const { return iteration_; }` - - - -### `sdf_primitives.h` - -**有符号距离函数(SDF)基础图元** -> 所有图元假设未施加变换——坐标系原点即图元中心/基点。 - - -**球体的 SDF** -`[[nodiscard]] inline double sphere(const Point3D& p, double radius) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点(三维坐标) | -| `radius` | 球半径,必须 > 0 | - -**返回**: 有符号距离 -> 球位于原点。如需其他位置,使用 op_translate 对采样点做反向平移。 - -**参见**: `ellipsoid 各轴半径不同的椭球`, `cylinder 沿 Y 轴的圆柱` - - -**轴对齐立方体的 SDF** -`[[nodiscard]] inline double box(const Point3D& p, const Point3D& half_extents) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `half_extents` | 半边长 (hx, hy, hz),均必须 ≥ 0 | - -**返回**: 有符号距离 - -**参见**: `round_box 带圆角的盒子`, `wedge 对角切割的半盒子` - - -**圆角立方体的 SDF** -`[[nodiscard]] inline double round_box(const Point3D& p, const Point3D& half_extents, double r) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `half_extents` | 半边长 (hx, hy, hz) | -| `r` | 圆角半径,必须 < min(half_extents) 否则整体形态改变 | - -**返回**: 有符号距离 - -**参见**: `box 无圆角的长方体`, `op_round 对任意 SDF 做圆角偏移` - - -**圆环面的 SDF** -`[[nodiscard]] inline double torus(const Point3D& p, double major_radius, double minor_radius) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `major_radius` | 主半径(环的半径),必须 > 0 | -| `minor_radius` | 副半径(管的粗细),必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `link 双环连接体(两个并行圆环的组合)` - - -**胶囊体的 SDF** -`[[nodiscard]] inline double capsule(const Point3D& p, const Point3D& a, const Point3D& b, double radius) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `a` | 线段起点 | -| `b` | 线段终点 | -| `radius` | 扫掠球半径,必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `cylinder 两端平头的圆柱(非球形端盖)` - - -**带平端盖的圆柱体 SDF** -`[[nodiscard]] inline double cylinder(const Point3D& p, double radius, double height) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 圆柱截面半径,必须 > 0 | -| `height` | 圆柱总高度(从 -h/2 到 +h/2),必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `capsule 两端球形端盖的圆柱`, `infinite_cylinder 无限长圆柱`, `cone 圆锥台` - - -**平面的 SDF** -`[[nodiscard]] inline double plane(const Point3D& p, const Vector3D& normal, double offset) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `normal` | 单位法向量(必须已归一化) | -| `offset` | 沿法向量正方向的偏移量 | - -**返回**: 有符号距离 - -**参见**: `wedge 两个平面+盒子的组合(对角切割)` - - -**椭球体的 SDF(有界梯度近似)** -`[[nodiscard]] inline double ellipsoid(const Point3D& p, const Point3D& radii) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radii` | 半轴长 (rx, ry, rz),均必须 > 0 | - -**返回**: 有符号距离(近似) -> 当三个半径相等时退化为球体,此时使用 sphere() 更精确高效。 -> 当点到原点距离远大于最大半径时,近似精度下降。 - -**参见**: `sphere 精确球体(rx=ry=rz 时的特例)` - - -**正六棱柱的 SDF** -`[[nodiscard]] inline double hex_prism(const Point3D& p, double radius, double height) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `radius` | 六边形外接圆半径(中心到顶点),必须 > 0 | -| `height` | 挤出总高度(±h/2 沿 Y 轴),必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `extrusion_bounded 通用 bounded extrusion 算子` - - -**无限长圆柱的 SDF** -`[[nodiscard]] inline double infinite_cylinder(const Point3D& p, const Vector3D& axis, double radius) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `axis` | 圆柱轴线方向(必须归一化,|axis| = 1) | -| `radius` | 截面半径,必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `cylinder 有限长圆柱(带平端盖)` - - -**楔形体的 SDF** -`[[nodiscard]] inline double wedge(const Point3D& p, double w, double h, double d) {` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `w` | 宽度(X 方向) | -| `h` | 高度(Y 方向) | -| `d` | 深度(Z 方向) | - -**返回**: 有符号距离 - -**参见**: `box 完整立方体`, `plane 独立平面 SDF` - - -**二维 SDF 沿 Z 轴的无限挤出** -`[[nodiscard]] inline double extrusion(const Point3D& /*p*/, double sdf_2d) {` - -| 参数 | 说明 | -|------|------| -| `p` | 三维采样点(仅 x,y 分量被隐式使用——通过 sdf_2d 参数间接) | -| `sdf_2d` | 预计算的二维 SDF 值(在 (p.x, p.y) 处求值) | - -**返回**: 三维有符号距离(等于 sdf_2d) -> p 参数仅保持接口一致,实际不影响结果。 -> 对于有限长度的挤出,使用 extrusion_bounded()。 - -**参见**: `extrusion_bounded 有限长度的挤出`, `revolution 二维轮廓绕 Y 轴旋转` - - -**二维 SDF 的有限长度挤出** -`[[nodiscard]] inline double extrusion_bounded(const Point3D& p, double sdf_2d, double half_height) {` - -| 参数 | 说明 | -|------|------| -| `p` | 三维采样点 | -| `sdf_2d` | 预计算的二维 SDF 值(在 (p.x, p.y) 处求值) | -| `half_height` | 挤出半高度(Z 方向),必须 ≥ 0 | - -**返回**: 有符号距离 - -**参见**: `extrusion 无限挤出`, `hex_prism 六棱柱(特例化 bounded extrusion 实现)` - - -**二维轮廓绕 Y 轴的旋转体 SDF** -`[[nodiscard]] inline double revolution(const Point3D& /*p*/, double sdf_2d, double /*offset*/) {` - -| 参数 | 说明 | -|------|------| -| `p` | 三维采样点(接口保留,不直接使用) | -| `sdf_2d` | 预计算的二维 SDF(在 (√(pₓ²+p𝓏²)-offset, p.y) 处求值) | -| `offset` | 径向偏移量(从 Y 轴的起点距离) | - -**返回**: 有符号距离 - -**参见**: `torus 圆环(revolution 的特例:截面为圆)` - - -**圆锥台的 SDF(非内联实现)** -`[[nodiscard]] double cone(const Point3D& p, double angle_rad, double height)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `angle_rad` | 半锥角(弧度),决定底面半径 | -| `height` | 锥体总高度,必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `cylinder 半锥角为 0 时的退化情况`, `infinite_cone 无限圆锥` - - -**三角棱柱的 SDF(非内联实现)** -`[[nodiscard]] double triangular_prism(const Point3D& p, const Point3D& a, const Point3D& b,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `a` | 三角形顶点 A(XY 平面内) | -| `b` | 三角形顶点 B(XY 平面内) | -| `c` | 三角形顶点 C(XY 平面内) | -| `height` | 挤出总高度(沿 Z 轴),必须 > 0 | - -**返回**: 有符号距离 - -**参见**: `wedge 直角三角形楔形体` - - -**双环链接体的 SDF(非内联实现)** -`[[nodiscard]] double link(const Point3D& p, double length, double major_r, double minor_r)` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `length` | 两个环心沿 X 轴的距离 | -| `major_r` | 每个环的主半径(环的半径) | -| `minor_r` | 每个环的管半径(截面的粗细) | - -**返回**: 有符号距离 - -**参见**: `torus 单个圆环` - - -**无限圆锥的 SDF(非内联实现)** -`[[nodiscard]] double infinite_cone(const Point3D& p, const Point3D& apex,` - -| 参数 | 说明 | -|------|------| -| `p` | 采样点 | -| `apex` | 锥顶位置 | -| `axis` | 锥轴方向(必须归一化),锥体沿此方向扩展 | -| `angle_rad` | 半锥角(弧度) | - -**返回**: 有符号距离 - -**参见**: `cone 有限高圆锥台` - - - -### `sdf_to_mesh.h` - -**SDF 到三角网格的转换** - - -**将 SDF 表达式树转换为三角网格** -`[[nodiscard]] mesh::MCMesh sdf_to_mesh(const SdfNodePtr& root,` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 表达式树的根节点 | -| `resolution` | 每轴的网格分辨率(例如 64 表示 64³ 体素网格) | -| `iso_level` | 等值面水平(0.0 = 隐式表面) | - -**返回**: 包含顶点和三角形索引的 MCMesh -> 分辨率推荐为 2 的幂(32, 64, 128, 256)以获得最佳缓存性能。 -> 对于大尺寸但细节少的几何体,使用较低的 resolution 即可获得光滑结果。 - -**参见**: `sdf_to_mesh_lambda Lambda 版本的 SDF 转网格(Python 友好)`, `estimate_bbox 包围盒估算` - - -**将 Lambda SDF 函数转换为三角网格** -`[[nodiscard]] mesh::MCMesh sdf_to_mesh_lambda(` - -| 参数 | 说明 | -|------|------| -| `f` | SDF 函数,签名为 double(double x, double y, double z) → 有符号距离 | -| `bmin` | 采样包围盒最小角点 | -| `bmax` | 采样包围盒最大角点 | -| `resolution` | 每轴分辨率 | -| `iso_level` | 等值面水平(默认 0.0) | - -**返回**: MCMesh 三角网格 - -**参见**: `sdf_to_mesh 基于 SDF 树的网格转换` - - - -### `sdf_torch.h` - -**SDF 批量求值与梯度计算(CPU 后端)** - - -**在批处理模式下求值 SDF** -`void evaluate_batch(const SdfNodePtr& root,` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 表达式树根节点 | -| `points` | 点数组,length = 3·n,x,y,z 交替存储 | -| `n` | 点数 | -| `distances` | 输出数组,length = n,写入有符号距离值 | - -**参见**: `evaluate 单点求值`, `gradient_batch 批量梯度计算` - - -**在批处理模式下求值 SDF 的空间梯度** -`void gradient_batch(const SdfNodePtr& root,` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 表达式树根节点 | -| `points` | 点数组,length = 3·n | -| `n` | 点数 | -| `gradients` | 输出数组,length = 3·n,x,y,z 梯度分量交替存储 | - -**参见**: `evaluate_batch 批量距离求值`, `evaluate_with_gradient_batch 同时获取距离和梯度(减少重复采样)` - - -**一次遍历同时求值 SDF 值和梯度** -`void evaluate_with_gradient_batch(const SdfNodePtr& root,` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 表达式树根节点 | -| `points` | 点数组,length = 3·n | -| `n` | 点数 | -| `distances` | 输出距离数组,length = n | -| `gradients` | 输出梯度数组,length = 3·n | -> 对于大量点的场景(n > 1000),推荐使用本函数以获得 ~2× 速度提升。 - -**参见**: `evaluate_batch 仅求距离`, `gradient_batch 仅求梯度` - - - -### `sdf_tree.h` - -**SDF 表达式树结构** - - -**CSG 树的所有节点类型** -`enum class SdfOp : uint8_t {` - -**参见**: `SdfParams 对应的参数结构` - - -**SDF 节点参数联合体** -`struct SdfParams {` - - -**SDF 表达式树节点** -> 树是不可变的——节点创建后 op 和子节点关系不变,但 params 可被外部修改以支持参数优化。 - - -**创建球体节点** -`static SdfNodePtr sphere(double r)` - - -**创建轴对齐长方体节点** -`static SdfNodePtr box(const Point3D& half_extents)` - - -**创建圆角长方体节点** -`static SdfNodePtr round_box(const Point3D& half_extents, double r)` - - -**创建圆柱体节点** -`static SdfNodePtr cylinder(double r, double h)` - - -**创建圆环体节点** -`static SdfNodePtr torus(double major_r, double minor_r)` - - -**创建胶囊体节点** -`static SdfNodePtr capsule(const Point3D& a, const Point3D& b, double r)` - - -**创建圆锥台节点** -`static SdfNodePtr cone(double angle_rad, double h)` - - -**创建平面节点** -`static SdfNodePtr plane(const Vector3D& normal, double offset)` - - -**创建椭球体节点** -`static SdfNodePtr ellipsoid(const Point3D& radii)` - - -**创建三角棱柱节点** -`static SdfNodePtr triangular_prism(double h)` - - -**创建六棱柱节点** -`static SdfNodePtr hex_prism(double h)` - - -**创建双环链接节点** -`static SdfNodePtr link(double r, double length, double thickness)` - - -**创建楔形体节点** -`static SdfNodePtr wedge(const Point3D& extents)` - - -**创建并集节点: A ∪ B** -`static SdfNodePtr op_union(SdfNodePtr a, SdfNodePtr b)` - - -**创建交集节点: A ∩ B** -`static SdfNodePtr op_intersection(SdfNodePtr a, SdfNodePtr b)` - - -**创建差集节点: A \ B** -`static SdfNodePtr op_difference(SdfNodePtr a, SdfNodePtr b)` - - -**创建平滑并集节点** -`static SdfNodePtr smooth_union(SdfNodePtr a, SdfNodePtr b, double k)` - - -**创建平滑交集节点** -`static SdfNodePtr smooth_intersection(SdfNodePtr a, SdfNodePtr b, double k)` - - -**创建平滑差集节点** -`static SdfNodePtr smooth_difference(SdfNodePtr a, SdfNodePtr b, double k)` - - -**创建圆角偏移节点** -`static SdfNodePtr round(SdfNodePtr child, double r)` - - -**创建壳层修饰节点** -`static SdfNodePtr onion(SdfNodePtr child, double thickness)` - - -**创建周期重复节点** -`static SdfNodePtr repeat(SdfNodePtr child, const Point3D& cell)` - - -**创建 X 镜像节点** -`static SdfNodePtr mirror_x(SdfNodePtr child)` - - -**创建 Y 镜像节点** -`static SdfNodePtr mirror_y(SdfNodePtr child)` - - -**创建 Z 镜像节点** -`static SdfNodePtr mirror_z(SdfNodePtr child)` - - -**创建平移节点** -`static SdfNodePtr translate(SdfNodePtr child, const Point3D& offset)` - - -**创建旋转节点(绕 Y 轴)** -`static SdfNodePtr rotate(SdfNodePtr child, double angle_rad)` - - -**创建缩放节点** -`static SdfNodePtr scale(SdfNodePtr child, const Point3D& factors)` - - -**创建扭曲节点** -`static SdfNodePtr twist(SdfNodePtr child, double amount)` - - -**创建弯曲节点** -`static SdfNodePtr bend(SdfNodePtr child, double amount)` - - -**创建拉伸节点** -`static SdfNodePtr elongate(SdfNodePtr child, const Point3D& h)` - - -**创建简化弯曲节点** -`static SdfNodePtr cheap_bend(SdfNodePtr child, double amount)` - - -**创建位移扰动节点** -`static SdfNodePtr displace(SdfNodePtr child, double amplitude, double frequency)` - - -**前序遍历所有节点** -`template ` - - -**前序遍历(const 版本)** -`template ` - -**参见**: `visit(Fn&&)` - - -**构造 SDF 节点** -`explicit SdfNode(SdfOp o) : op(o) {}` - -| 参数 | 说明 | -|------|------| -| `o` | 操作类型 | - - -**在空间点 p 处求值 SDF 树** -`[[nodiscard]] double evaluate(const SdfNodePtr& root, const Point3D& p)` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 表达式树的根节点 | -| `p` | 世界空间中的采样点 | - -**返回**: 有符号距离(负 = 内部,零 = 表面,正 = 外部) - -**参见**: `estimate_bounds 估计树的包围盒` - - -**估算 SDF 树的包围半尺寸** -`[[nodiscard]] Point3D estimate_bounds(const SdfNodePtr& root, double margin = 1.0)` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 树的根节点 | -| `margin` | 额外安全边距(默认 1.0) | - -**返回**: 包围半边长 (hx, hy, hz) -> 变形节点(旋转/弯曲/扭曲等)会使包围盒放大,以保守估计覆盖变形后区域。 - -**参见**: `estimate_bbox 完整 AABB 结果` - - -**SDF 树的包围盒(AABB)** -`struct SdfBBox {` - - -**估算 SDF 树的完整轴对齐包围盒** -`[[nodiscard]] SdfBBox estimate_bbox(const SdfNodePtr& root, double margin = 1.0)` - -| 参数 | 说明 | -|------|------| -| `root` | SDF 树的根节点 | -| `margin` | 额外安全边距 | - -**返回**: AABB 包围盒 - - - -## 草图约束 (`vde::sketch`) - - -### `constraint_solver.h` - -**草图点元素** -`struct SketchPoint {` - - -**草图线段元素** -`struct SketchLine {` - - -**草图圆元素** -`struct SketchCircle {` - - -**约束类型枚举** -`enum class ConstraintType {` - - -**约束实例** -`struct Constraint {` - - -**求解器返回结果** -`struct SolverResult {` - - -**二维几何约束求解器** - - -**添加自由点** -`int add_point(double x, double y, bool fixed = false)` - -| 参数 | 说明 | -|------|------| -| `x` | X 坐标 | -| `y` | Y 坐标 | -| `fixed` | 是否固定(true 则排除变量) | - -**返回**: 点 ID - - -**添加线段** -`int add_line(int p0, int p1)` - -| 参数 | 说明 | -|------|------| -| `p0` | 起点 ID | -| `p1` | 终点 ID | - -**返回**: 线段 ID - - -**添加圆** -`int add_circle(int center, double radius)` - -| 参数 | 说明 | -|------|------| -| `center` | 圆心点 ID | -| `radius` | 半径 | - -**返回**: 圆 ID - - -**添加约束** -`void add_constraint(ConstraintType type, const std::vector& elements, double val = 0.0)` - -| 参数 | 说明 | -|------|------| -| `type` | 约束类型 | -| `elements` | 约束涉及的元素 ID 列表 | -| `val` | 约束值(距离、角度等),默认 0 | -> 不同类型 elements 的语义: - - -**标记点为固定(硬约束)** -`void fix_point(int pid) {` - -| 参数 | 说明 | -|------|------| -| `pid` | 点 ID | -> 固定点不参与变量优化,从自由度中排除 - - -**执行约束求解** -`[[nodiscard]] SolverResult solve(int max_iter = 100, double tol = 1e-8)` - -| 参数 | 说明 | -|------|------| -| `max_iter` | 最大 Gauss-Newton 迭代次数,默认 100 | -| `tol` | 收敛容差(梯度范数 < tol 时停止),默认 1e-8 | - -**返回**: SolverResult 求解结果 -> 收敛判断:||J^T r|| < tol -> 欠约束时(DOF > 0)解不唯一;过约束时(DOF < 0)为最小二乘解 - - -**计算自由度** -`[[nodiscard]] int degrees_of_freedom() const` - -**返回**: DOF = 2·N_free - Σ(约束方程数) -> DOF < 0 时系统过约束,求解器仍然工作但解非精确满足所有约束 - - -**当前点集访问** -`[[nodiscard]] const std::vector& points() const { return points_; }` - -**返回**: SketchPoint 数组只读引用 - - -**查询点坐标** -`[[nodiscard]] Point2D get_point(int id) const` - -| 参数 | 说明 | -|------|------| -| `id` | 点 ID | - -**返回**: Point2D 当前坐标 - - -**将求解器变量向量同步回 points_(用于 Jacobian 数值计算)** -`void sync_from_vars(const double* vars, int nv)` - -| 参数 | 说明 | -|------|------| -| `vars` | 变量数组(长度为 2·N_free) | -| `nv` | 变量数 | - - -**评估单个约束的残差值** -`double eval_constraint(const Constraint& c) const` - -| 参数 | 说明 | -|------|------| -| `c` | 约束 | - -**返回**: 残差(方程 → 0 表示约束满足) - - -**计算单个约束的方程数** -`int count_equations(const Constraint& c) const` - -| 参数 | 说明 | -|------|------| -| `c` | 约束 | - -**返回**: Coincident/Fixed → 2,其余 → 1 - - -**填充 Jacobian 矩阵中对应约束 ci 的行** -`void fill_jacobian_rows(const Constraint& c, int ci,` - -| 参数 | 说明 | -|------|------| -| `c` | 约束 | -| `ci` | 约束索引 | -| `row_map` | 方程行映射 | -| `J_data` | Jacobian 矩阵数据(行优先) | -| `nv` | 变量数 | -| `stride` | 行跨度 | - - - -## C API (`vde::capi`) - - -### `vde_capi.h` - -**ViewDesignEngine C API — 跨语言边界接口** -`extern "C" {` - -**参见**: `vde.h C++ 等价接口` - - -**引擎上下文句柄 — 管理错误状态和内部资源** -`typedef struct VdeContext* VdeHandle` - - -**三角网格句柄 — 顶点+面集合** -`typedef struct VdeMesh* VdeMeshHandle` - - -**参数曲线句柄 — NURBS 曲线** -`typedef struct VdeCurve* VdeCurveHandle` - - -**约束求解器句柄 — 二维草图约束** -`typedef struct VdeSolver* VdeSolverHandle` - - -**B-Rep 实体句柄 — 边界表示模型** -`typedef struct VdeBody* VdeBodyHandle` - - -**创建 ViewDesignEngine 上下文** -`VdeHandle vde_create(void)` - -**返回**: 新的引擎句柄,不需要时通过 vde_destroy() 释放 - -**参见**: `vde_destroy 释放上下文` - - -**销毁引擎上下文** -`void vde_destroy(VdeHandle ctx)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | - -**参见**: `vde_create` - - -**获取引擎版本字符串** -`const char* vde_version(void)` - -**返回**: 语义版本号字符串(如 "0.5.0"),静态生命周期,无需释放 - - -**获取最后一次操作的错误描述** -`const char* vde_last_error(VdeHandle ctx)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | - -**返回**: 错误描述字符串(上下文的内部缓冲区,静态生命周期) -> 每次新的失败操作会覆盖此描述。成功操作不会清除它。 - - -**从文件加载三角网格** -`VdeMeshHandle vde_load_mesh(VdeHandle ctx, const char* path)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `path` | 文件路径(UTF-8 编码) | - -**返回**: 网格句柄,失败时返回 NULL(通过 vde_last_error() 获取原因) - -**参见**: `vde_mesh_free 释放网格`, `vde_save_mesh 保存网格` - - -**将三角网格保存为文件** -`int vde_save_mesh(VdeHandle ctx, VdeMeshHandle mesh, const char* path, const char* format)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `mesh` | 网格句柄 | -| `path` | 输出文件路径 | -| `format` | 输出格式(当前仅 "obj" 有效) | - -**返回**: 成功返回 1,失败返回 0 - -**参见**: `vde_load_mesh 加载网格` - - -**获取网格的顶点数量** -`size_t vde_mesh_num_vertices(VdeMeshHandle mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 网格句柄(必须有效且非 NULL) | - -**返回**: 顶点数 - -**参见**: `vde_mesh_num_faces 面数` - - -**获取网格的三角面数量** -`size_t vde_mesh_num_faces(VdeMeshHandle mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 网格句柄 | - -**返回**: 面数 - -**参见**: `vde_mesh_num_vertices 顶点数` - - -**获取指定索引的顶点坐标** -`void vde_mesh_get_vertex(VdeMeshHandle mesh, size_t idx,` - -| 参数 | 说明 | -|------|------| -| `mesh` | 网格句柄 | -| `idx` | 顶点索引 [0, num_vertices) | -| `out_x` | [out] 顶点 X 坐标 | -| `out_y` | [out] 顶点 Y 坐标 | -| `out_z` | [out] 顶点 Z 坐标 | - - -**获取网格的轴对齐包围盒** -`void vde_mesh_get_bounds(VdeMeshHandle mesh,` - -| 参数 | 说明 | -|------|------| -| `mesh` | 网格句柄 | -| `out_min_x` | [out] 最小 X 坐标 | -| `out_min_y` | [out] 最小 Y 坐标 | -| `out_min_z` | [out] 最小 Z 坐标 | -| `out_max_x` | [out] 最大 X 坐标 | -| `out_max_y` | [out] 最大 Y 坐标 | -| `out_max_z` | [out] 最大 Z 坐标 | - - -**释放网格句柄及其资源** -`void vde_mesh_free(VdeMeshHandle mesh)` - -| 参数 | 说明 | -|------|------| -| `mesh` | 网格句柄 | - - -**网格简化** -`VdeMeshHandle vde_mesh_simplify(VdeHandle ctx, VdeMeshHandle mesh, double target_ratio)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `mesh` | 输入网格句柄(不修改输入) | -| `target_ratio` | 目标简化比率 [0, 1](0 = 不变,1 = 最大简化) | - -**返回**: 简化后的新网格句柄 - -**参见**: `vde_mesh_smooth 网格平滑` - - -**网格平滑(Laplacian 或 Taubin 平滑)** -`VdeMeshHandle vde_mesh_smooth(VdeHandle ctx, VdeMeshHandle mesh, int iterations)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `mesh` | 输入网格句柄 | -| `iterations` | 平滑迭代次数 | - -**返回**: 平滑后的新网格句柄 - -**参见**: `vde_mesh_simplify 网格简化` - - -**网格布尔运算** -`VdeMeshHandle vde_mesh_boolean(VdeHandle ctx, VdeMeshHandle a, VdeMeshHandle b, int operation)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `a` | 网格 A | -| `b` | 网格 B | -| `operation` | 布尔操作类型: 0 = 并集, 1 = 交集, 2 = 差集 (A \ B) | - -**返回**: 布尔结果的新网格句柄 - - -**创建 Bézier 曲线** -`VdeCurveHandle vde_curve_create_bezier(VdeHandle ctx, const double* control_points,` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `control_points` | 控制点数组,每 3 个 double 表示一个三维点 (x,y,z) | -| `num_points` | 控制点数量(次数 = num_points - 1) | -| `dim` | 维度(固定为 3) | - -**返回**: 曲线句柄 - -**参见**: `vde_curve_evaluate 求值`, `vde_curve_free 释放` - - -**在参数 t 处求值曲线** -`void vde_curve_evaluate(VdeCurveHandle curve, double t,` - -| 参数 | 说明 | -|------|------| -| `curve` | 曲线句柄 | -| `t` | 参数值 [0, 1] | -| `out_x` | [out] 曲线上点的 X 坐标 | -| `out_y` | [out] 曲线上点的 Y 坐标 | -| `out_z` | [out] 曲线上点的 Z 坐标 | - - -**获取曲线的次数** -`int vde_curve_degree(VdeCurveHandle curve)` - -| 参数 | 说明 | -|------|------| -| `curve` | 曲线句柄 | - -**返回**: 曲线次数 - - -**释放曲线句柄** -`void vde_curve_free(VdeCurveHandle curve)` - -| 参数 | 说明 | -|------|------| -| `curve` | 曲线句柄 | - - -**两球体碰撞检测(GJK 算法)** -`int vde_collision_gjk_spheres(VdeHandle ctx,` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `cx1,` | cy1, cz1 第一个球体的球心坐标 | -| `r1` | 第一个球体的半径 | -| `cx2,` | cy2, cz2 第二个球体的球心坐标 | -| `r2` | 第二个球体的半径 | - -**返回**: 碰撞返回 1,不碰撞返回 0 - -**参见**: `vde_collision_ray_mesh 射线-网格相交` - - -**射线与网格的最近交点查询** -`int vde_collision_ray_mesh(VdeHandle ctx, VdeMeshHandle mesh,` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `mesh` | 目标网格句柄 | -| `ox,` | oy, oz 射线起点 | -| `dx,` | dy, dz 射线方向(无需归一化) | -| `out_t` | [out] 交点参数 t(沿射线的距离) | -| `out_x,` | out_y, out_z [out] 交点坐标 | - -**返回**: 命中返回 1,未命中返回 0 - -**参见**: `vde_collision_gjk_spheres GJK 球体碰撞` - - -**创建二维约束求解器** -`VdeSolverHandle vde_solver_create(void)` - -**返回**: 求解器句柄 - -**参见**: `vde_solver_free 释放` - - -**向求解器添加点** -`int vde_solver_add_point(VdeSolverHandle solver, double x, double y, int fixed)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `x` | 初始 X 坐标 | -| `y` | 初始 Y 坐标 | -| `fixed` | 固定点标记(1 = 固定不移动) | - -**返回**: 点的 ID(用于后续约束引用) - -**参见**: `vde_solver_add_line 添加线段` - - -**向求解器添加线段(由两个点定义)** -`int vde_solver_add_line(VdeSolverHandle solver, int p0, int p1)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `p0` | 起点 ID | -| `p1` | 终点 ID | - -**返回**: 线段的 ID - -**参见**: `vde_solver_add_point 添加点`, `vde_solver_add_horizontal 添加水平约束`, `vde_solver_add_vertical 添加垂直约束` - - -**添加距离约束(两点之间)** -`void vde_solver_add_distance_constraint(VdeSolverHandle solver, int p0, int p1, double d)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `p0` | 第一个点的 ID | -| `p1` | 第二个点的 ID | -| `d` | 目标距离(必须 > 0) | - -**参见**: `vde_solver_add_horizontal 水平约束` - - -**添加水平约束(线段水平)** -`void vde_solver_add_horizontal(VdeSolverHandle solver, int line_id)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `line_id` | 线段 ID | - -**参见**: `vde_solver_add_vertical 垂直约束`, `vde_solver_add_line 添加线段` - - -**添加垂直约束(线段垂直)** -`void vde_solver_add_vertical(VdeSolverHandle solver, int line_id)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `line_id` | 线段 ID | - -**参见**: `vde_solver_add_horizontal 水平约束` - - -**求解约束系统** -`int vde_solver_solve(VdeSolverHandle solver, int max_iter, double tol)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `max_iter` | 最大迭代次数 | -| `tol` | 收敛容差 | - -**返回**: 收敛返回 1,未收敛返回 0 - -**参见**: `vde_solver_get_point 获取求解后的点坐标` - - -**获取求解后的点坐标** -`void vde_solver_get_point(VdeSolverHandle solver, int idx, double* out_x, double* out_y)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | -| `idx` | 点 ID | -| `out_x` | [out] 求解后 X 坐标 | -| `out_y` | [out] 求解后 Y 坐标 | - - -**释放求解器句柄** -`void vde_solver_free(VdeSolverHandle solver)` - -| 参数 | 说明 | -|------|------| -| `solver` | 求解器句柄 | - - -**创建实心立方体 B-Rep** -`VdeBodyHandle vde_body_create_box(VdeHandle ctx, double w, double h, double d)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `w` | 宽度(X 方向),> 0 | -| `h` | 高度(Y 方向),> 0 | -| `d` | 深度(Z 方向),> 0 | - -**返回**: B-Rep 实体句柄 - -**参见**: `vde_body_create_cylinder 圆柱体`, `vde_body_create_sphere 球体` - - -**创建实心圆柱体 B-Rep** -`VdeBodyHandle vde_body_create_cylinder(VdeHandle ctx, double r, double h, int segs)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `r` | 截面半径,> 0 | -| `h` | 总高度(从 -h/2 到 +h/2) | -| `segs` | 截面分段数(边数) | - -**返回**: B-Rep 实体句柄 - -**参见**: `vde_body_create_box 立方体` - - -**创建球体 B-Rep** -`VdeBodyHandle vde_body_create_sphere(VdeHandle ctx, double r, int su, int sv)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `r` | 球半径,> 0 | -| `su` | 经度方向分段数 | -| `sv` | 纬度方向分段数 | - -**返回**: B-Rep 实体句柄 - - -**将 B-Rep 实体转换为三角网格** -`VdeMeshHandle vde_body_to_mesh(VdeHandle ctx, VdeBodyHandle body, double deflection)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `body` | B-Rep 实体句柄 | -| `deflection` | 弦高误差(越小 = 越精细,推荐 0.01) | - -**返回**: 三角网格句柄 - -**参见**: `vde_body_free 释放 B-Rep 实体` - - -**释放 B-Rep 实体句柄** -`void vde_body_free(VdeBodyHandle body)` - -| 参数 | 说明 | -|------|------| -| `body` | B-Rep 实体句柄 | - - -**将网格序列化为二进制字节流** -`size_t vde_serialize_mesh(VdeHandle ctx, VdeMeshHandle mesh, uint8_t** out_data)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `mesh` | 网格句柄 | -| `out_data` | [out] 指向序列化字节数组的指针 | - -**返回**: 字节数 -> 输出的缓冲区由库管理,调用方不得直接 free/delete。 - -**参见**: `vde_deserialize_mesh 反序列化`, `vde_free_buffer 释放序列化缓冲区` - - -**从二进制字节流反序列化为网格** -`VdeMeshHandle vde_deserialize_mesh(VdeHandle ctx, const uint8_t* data, size_t len)` - -| 参数 | 说明 | -|------|------| -| `ctx` | 引擎上下文句柄 | -| `data` | 序列化数据缓冲区 | -| `len` | 数据长度(字节数) | - -**返回**: 反序列化后的网格句柄 - -**参见**: `vde_serialize_mesh 序列化` - - -**释放由 vde_serialize_mesh 分配的缓冲区** -`void vde_free_buffer(uint8_t* ptr)` - -| 参数 | 说明 | -|------|------| -| `ptr` | 由 vde_serialize_mesh 返回的缓冲区指针 | +--- +> 完整 API 文档请查看 [Doxygen HTML](api/html/index.html)