Files
ViewDesignEngine/docs/API-REFERENCE.md
T
茂之钳 7219791685
CI / Build & Test (push) Failing after 16m49s
CI / Release Build (push) Failing after 1m31s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
docs: Markdown API reference (6942 lines, 76 headers)
2026-07-24 11:58:54 +00:00

163 KiB
Raw Blame History

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(ac,ad,bc,bd), max(ac,ad,bc,bd)]

区间除法
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<std::vector<int>> faces

每个面的纹理坐标索引列表(0-based)
std::vector<std::vector<int>> face_texcoords

每个面的法线索引列表(0-based
std::vector<std::vector<int>> face_normals

每个面对应的材质名称
std::vector<std::string> 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<StlTriangle> 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<StlTriangle>& 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<StlTriangle>& tris)

参数 说明
filepath 输出文件路径
tris 三角形面片列表

参见: read_stl, write_stl

math_types.h

通用 N 维点类型(使用 Eigen 列向量)
template <typename T, size_t Dim>

通用 N 维向量类型(与 Point 相同的列向量表示)
template <typename T, size_t Dim>

基础模块提供 VDE 引擎的核心基础设施:
/** @} */ // end of foundation group

memory_pool.h

固定块大小的内存池
template <typename T>

内存池不调用对象的构造函数/析构函数,仅管理原始内存
适合 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<uint8_t> serialize(const mesh::HalfedgeMesh& mesh)

参数 说明
mesh 要序列化的半边网格

返回: 压缩后的二进制数据(含文件头)

从二进制缓冲区反序列化网格
static mesh::HalfedgeMesh deserialize(const std::vector<uint8_t>& 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 <typename T>

参数 说明
value 测试值

返回: true 若 |value| < absolute_

混合容差相等判断
template <typename T>

参数 说明
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 <typename T>

初始状态为空(min = +∞, max = -∞),需要通过 expand() 初始化

构造空包围盒
AABB() : min_(Point3D::Constant(std::numeric_limits<T>::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 * (dxdy + dydz + 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<Point2D> convex_hull_2d(const std::vector<Point2D>& points)

参数 说明
points 输入点集(至少 3 个不共线点)

返回: 凸包顶点序列(逆时针排列),不含共线的中间点

自动过滤共线点,返回严格的凸包顶点
若所有点共线,返回两个端点

参见: convex_hull_3d, Polygon2D::convex_hull_2d

三维凸包计算(QuickHull 算法)
std::vector<std::array<Point3D, 3>> convex_hull_3d(const std::vector<Point3D>& 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<double>& line)

参数 说明
p 测试点
line 直线

返回: 垂直距离

点到线段的距离
double distance(const Point3D& p, const Segment3D<double>& seg)

参数 说明
p 测试点
seg 线段

返回: 最短距离

点到平面的距离
double distance(const Point3D& p, const Plane<double>& plane)

参数 说明
p 测试点
plane 平面

返回: 绝对垂直距离

参见: Plane::signed_distance

点到三角形的距离
double distance(const Point3D& p, const Triangle<double>& tri)

参数 说明
p 测试点
tri 三角形

返回: 最短距离

点到包围盒的距离
double distance(const Point3D& p, const AABB<double>& box)

参数 说明
p 测试点
box 包围盒

返回: 最短距离(内部点返回 0

两条线段之间的最短距离
double distance(const Segment3D<double>& a, const Segment3D<double>& b)

参数 说明
a 第一条线段
b 第二条线段

返回: 最短距离(若相交则为 0

两条直线之间的最短距离
double distance(const Line3D<double>& a, const Line3D<double>& b)

参数 说明
a 第一条直线
b 第二条直线

返回: 最短距离

两个包围盒之间的最短距离
double distance(const AABB<double>& a, const AABB<double>& b)

参数 说明
a 第一个包围盒
b 第二个包围盒

返回: 最短距离

两个三角形之间的最短距离
double distance(const Triangle<double>& a, const Triangle<double>& b)

参数 说明
a 第一个三角形
b 第二个三角形

返回: 最短距离(若相交则为 0

三角形上距给定点最近的点
Point3D closest_point(const Point3D& p, const Triangle<double>& tri)

参数 说明
p 查询点
tri 三角形

返回: 三角形上距离 p 最近的点

线段上距给定点最近的点
Point3D closest_point(const Point3D& p, const Segment3D<double>& seg)

参数 说明
p 查询点
seg 线段

返回: 线段上距离 p 最近的点(可能为端点)

包围盒上距给定点最近的点
Point3D closest_point(const Point3D& p, const AABB<double>& box)

参数 说明
p 查询点
box 包围盒

返回: 包围盒边界上(或内部)距离 p 最近的点

平面上距给定点最近的点(正交投影)
Point3D closest_point(const Point3D& p, const Plane<double>& plane)

参数 说明
p 查询点
plane 平面

返回: 点 p 在平面上的正交投影

参见: Plane::project

icp.h

ICP(迭代最近点)配准结果
struct ICPResult {

配准后的均方根误差
double rms_error

迭代最近点(ICP)刚体点云配准
[[nodiscard]] ICPResult icp_register(const std::vector<Point3D>& source,

参数 说明
source 源点云(将被移动)
target 目标点云(固定参考)
max_iter 最大迭代次数(默认 50
tolerance 收敛容差:相邻两次 RMS 变化的阈值(默认 1e-6)

返回: 配准结果,包含最终变换和误差

source 和 target 点数可以不同
初始对齐越好,收敛越快;若初始偏差太大,可能收敛到局部最优

line.h

三维无限直线
template <typename T>

从原点和方向构造直线
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 <typename T>

从两个端点构造线段
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 <typename T>

从原点和方向构造射线
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 <typename T>

从点和法线构造平面
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 <typename T, size_t Dim>

通用 N 维向量类型(重新导出)
template <typename T, size_t Dim>

polygon.h

二维平面多边形

内部假设简单多边形(无自交),非简单多边形的行为未定义
所有几何计算基于(假设的)XY 平面

从顶点列表构造多边形
explicit Polygon2D(std::vector<Point2D> 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<double> 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<std::array<int, 3>> triangulate() const

返回: 三角形列表,每个元素为 {i, j, k} 表示顶点索引

时间复杂度 O(n²),适用于顶点数 < 1000 的多边形

参见: simplify

Andrew's Monotone Chain 二维凸包
static Polygon2D convex_hull_2d(const std::vector<Point2D>& points)

参数 说明
points 输入点集

返回: 凸包多边形(CCW,不含共线中间点)

参见: convex_hull_2d

transform.h

三维仿射变换类型
using Transform3D = Eigen::Transform<double, 3, Eigen::Affine>

创建平移变换
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 <typename T>

从三个顶点构造三角形
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<Point2D> vertices

单元格边界边
std::vector<std::array<int, 2>> edges

二维 Voronoi 图生成(通过 Delaunay 对偶图)
std::vector<VoronoiCell> voronoi_2d(const std::vector<Point2D>& points)

参数 说明
points 输入点集(站点)

返回: 每个站点对应的 VoronoiCell 列表(顺序与输入一致)

对于凸包边界上的站点,对应的 Voronoi 单元格无界,顶点不完全闭合
内部使用 Delaunay 三角剖分作为中间步骤

曲线曲面 (vde::curves)

bezier_curve.h

任意阶 Bézier 曲线

构造 Bézier 曲线
explicit BezierCurve(std::vector<Point3D> control_points)

参数 说明
control_points 控制点序列,点数 = degree + 1,最少 2 个

控制点数量决定了曲线阶次;点数越多,曲线越灵活但计算越昂贵

在参数 t 处求值曲线点
[[nodiscard]] Point3D evaluate(double t) const

参数 说明
t 参数值,范围 [0, 1]

返回: 曲线上对应 t 的点坐标

使用 de Casteljau 递推算法,O(n²) 复杂度

在参数 t 处求导数
[[nodiscard]] Vector3D derivative(double t, int order = 1) const

参数 说明
t 参数值,范围 [0, 1]
order 导数阶数,1 = 一阶(切向量),2 = 二阶(曲率相关)

返回: 导数向量

高阶导数通过降阶 Bézier 曲线计算:

曲线阶次
[[nodiscard]] int degree() const { return static_cast<int>(cp_.size()) - 1; }

返回: 阶次 = 控制点数 - 1

参数定义域
[[nodiscard]] std::pair<double, double> domain() const { return {0.0, 1.0}; }

返回: 固定为 [0, 1]

控制点访问
[[nodiscard]] const std::vector<Point3D>& control_points() const { return cp_; }

返回: 控制点向量的只读引用

在 t 处将曲线一分为二
[[nodiscard]] std::pair<BezierCurve, BezierCurve> 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<std::vector<Point3D>> 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<int>(cp_.size()) - 1; }

返回: u 方向阶次(控制点行数 - 1

v 向阶次
[[nodiscard]] int degree_v() const { return static_cast<int>(cp_[0].size()) - 1; }

返回: v 方向阶次(控制点列数 - 1

一维 de Casteljau 求值(内部辅助)
[[nodiscard]] Point3D de_casteljau(double t, const std::vector<Point3D>& pts) const

参数 说明
t 参数
pts 一维控制点序列

返回: 求值结果

bspline_curve.h

B 样条曲线(非有理、均匀/非均匀节点)

构造 B 样条曲线
BSplineCurve(std::vector<Point3D> control_points,

参数 说明
control_points n+1 个控制点
knots 节点向量,必须为非递减序列
degree 阶次 p

节点数量 = 控制点数 + 阶次 + 1;clamped 端点多重度为 p+1

在参数 t 处求值曲线点
[[nodiscard]] Point3D evaluate(double t) const

参数 说明
t 参数值,必须在 domain() 范围内

返回: 曲线上对应 t 的点坐标

使用 de BoorCox-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<double, double> domain() const

返回: 有效参数范围 [knots[p], knots[n+1]]

控制点访问
[[nodiscard]] const std::vector<Point3D>& control_points() const { return cp_; }

返回: 控制点数组只读引用

节点向量访问
[[nodiscard]] const std::vector<double>& 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<double> 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<double> 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<std::vector<Point3D>> 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<double>& knots_u() const { return knots_u_; }

返回: 只读引用

v 向节点向量
[[nodiscard]] const std::vector<double>& knots_v() const { return knots_v_; }

返回: 只读引用

nurbs_curve.h

NURBS 曲线(Non-Uniform Rational B-Spline

构造 NURBS 曲线
NurbsCurve(std::vector<Point3D> control_points, std::vector<double> 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<double, double> domain() const

返回: [knots[degree], knots[n+1]]

控制点访问
[[nodiscard]] const std::vector<Point3D>& control_points() const { return cp_; }

返回: 只读引用

权重访问
[[nodiscard]] const std::vector<double>& weights() const { return weights_; }

返回: 只读引用

节点向量访问
[[nodiscard]] const std::vector<double>& 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<std::vector<Point3D>> 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<int, 2> num_control_points() const {

返回: {nu+1, nv+1},即网格的行数和列数

u 向节点向量
[[nodiscard]] const std::vector<double>& knots_u() const { return knots_u_; }

返回: 只读引用

v 向节点向量
[[nodiscard]] const std::vector<double>& knots_v() const { return knots_v_; }

返回: 只读引用

控制点网格访问
[[nodiscard]] const std::vector<std::vector<Point3D>>& control_points() const { return cp_; }

返回: 只读引用

权重网格访问
[[nodiscard]] const std::vector<std::vector<double>>& 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<Point3D>, std::vector<std::array<int,3>>>

参数 说明
res_u u 方向采样分辨率
res_v v 方向采样分辨率

返回: {顶点数组, 三角形索引数组},每个三角形为 {i0,i1,i2}

生成 res_u×res_v 均匀网格,每个单元格拆为两个三角形

参见: tessellate

tessellation.h

均匀参数化曲面三角化
std::pair<std::vector<Point3D>, std::vector<std::array<int, 3>>>

参数 说明
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<Point3D>, std::vector<std::array<int, 3>>>

参数 说明
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<Point3D>& points, double alpha)

参数 说明
points 输入 3D 点云
alpha α 半径阈值,通常取平均点间距的 1~3 倍

返回: TetrahedronMesh 保留的四面体网格

参见: alpha_shapes_surface delaunay_3d

将 Alpha Shapes 四面体网格的表面提取为三角形网格
std::pair<std::vector<Point3D>, std::vector<std::array<int,3>>>

参数 说明
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<Point2D>& 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<Point3D>& points)

参数 说明
points 输入 3D 点集(至少 4 个不共面点)

返回: TetrahedronMesh 四面体网格

时间复杂度与 2D 类似:平均 O(n log n),最坏 O(n²)
输出包括内部和边界四面体;通过 alpha_shapes 可提取表面

参见: alpha_shapes

geodesic.h

热方法(Heat Method)计算测地距离
std::vector<double> 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<int>& vertex_indices)

参数 说明
vertex_indices 按逆时针顺序排列的顶点索引(至少 3 个)

返回: 新面的索引,失败返回 -1

自动创建/查找半边并设置对侧关系;面法向遵循右手定则

从三角形列表批量构建半边形网格
void build_from_triangles(const std::vector<Point3D>& 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<int> face_vertices(int fi) const

参数 说明
fi 面索引

返回: 顶点索引序列

获取顶点的邻面索引环
[[nodiscard]] std::vector<int> 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<double(double,double,double)>& 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<Point2D> tutte_parameterization(const HalfedgeMesh& mesh)

参数 说明
mesh 输入三角网格(需含边界)

返回: 每顶点 UV 坐标(Point2D),顺序与 mesh 顶点一致

网格必须有边界(开网格);闭曲面需先切割为拓扑圆盘

参见: lscm_parameterization

LSCMLeast Squares Conformal Maps)参数化
[[nodiscard]] std::vector<Point2D> 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 {

QEMQuadric 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 且

返回: 光顺后的网格

典型值:λ = 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<Triangle3D>& tris) override

参数 说明
tris 三角形数组

插入单个三角形
void insert(const Triangle3D& tri) override

参数 说明
tri 要插入的三角形

删除三角形
bool remove(const Triangle3D& tri) override

参数 说明
tri 要删除的三角形

返回: 删除成功返回 true

AABB 范围查询
std::vector<Triangle3D> query_range(const AABB3D& range) const override

参数 说明
range 查询包围盒

返回: 与 range 相交的三角形列表

K 近邻查询
std::vector<Triangle3D> query_knn(const Point3D& point, size_t k) const override

参数 说明
point 查询点
k 返回数量

返回: 最近的 k 个三角形

射线查询:返回所有命中的三角形
std::vector<Triangle3D> 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<HitResult> 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<Triangle3D> 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 <typename T>

k-d 树在维度约 2~6 时效率最佳。三维场景中,

参见: SpatialIndex, BVH, Octree

批量构建 k-d 树
void build(const std::vector<T>& items) override

参数 说明
items 待索引的对象数组

插入单个对象
void insert(const T& item) override

参数 说明
item 待插入的空间对象

删除对象
bool remove(const T& item) override

参数 说明
item 待删除的空间对象

返回: 删除成功返回 true

范围查询
std::vector<T> query_range(const AABB3D& range) const override

参数 说明
range 查询包围盒

返回: 与 range 相交的对象列表

K 近邻查询
std::vector<T> query_knn(const Point3D& point, size_t k) const override

参数 说明
point 查询点
k 返回数量

返回: 最近的 k 个对象

射线查询
std::vector<T> 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<Node> 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 <typename T>

适用于体积数据、粒子系统、空间哈希等场景。

参见: 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<T>& items) override

参数 说明
items 待索引的对象数组

增量插入对象
void insert(const T& item) override

参数 说明
item 待插入的空间对象

删除对象
bool remove(const T& item) override

参数 说明
item 待删除的空间对象

返回: 删除成功返回 true;对象不存在返回 false

范围查询
std::vector<T> query_range(const AABB3D& range) const override

参数 说明
range 查询包围盒

返回: 与 range 相交的对象列表

K 近邻查询
std::vector<T> query_knn(const Point3D& point, size_t k) const override

参数 说明
point 查询点
k 返回数量

返回: 最近的 k 个对象

射线查询
std::vector<T> 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 <typename T>

< 节点包围盒(子节点/对象 MBR 的并集)
bool is_leaf = true; /**< 是否为叶节点 */

< 是否为叶节点
std::vector<size_t> children; /**< 内部节点:子节点索引列表 */

< 内部节点:子节点索引列表
std::vector<size_t> item_indices; /**< 叶节点:对象索引列表 */

< 叶节点:对象索引列表
size_t parent = static_cast<size_t>(-1); /**< 父节点索引 */

< 父节点索引
}

R 树动态空间索引
template <typename T>

R 树在动态场景(如编辑中的几何体)中比 BVH 更合适。

参见: SpatialIndex, BVH, RStarTree

批量构建 R 树
void build(const std::vector<T>& items) override

参数 说明
items 待索引的对象数组

增量插入对象
void insert(const T& item) override

参数 说明
item 待插入的空间对象

删除对象
bool remove(const T& item) override

参数 说明
item 待删除的空间对象

返回: 删除成功返回 true

范围查询
std::vector<T> query_range(const AABB3D& range) const override

参数 说明
range 查询包围盒

返回: 与 range 相交的对象列表

K 近邻查询
std::vector<T> query_knn(const Point3D& point, size_t k) const override

参数 说明
point 查询点
k 返回数量

返回: 最近的 k 个对象

射线查询
std::vector<T> 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<AABB3D> item_bounds_; /**< 对象包围盒数组 */

< 对象包围盒数组
std::vector<RTreeNode<T>> nodes_; /**< R 树节点数组 */

< R 树节点数组
size_t root_idx_ = 0; /**< 根节点索引 */

< 根节点索引
size_t count_ = 0; /**< 对象计数 */

< 对象计数
}

spatial_index.h

空间索引抽象基类

空间索引抽象基类
template <typename T>

本类为纯虚接口,不可直接实例化

批量构建索引
virtual void build(const std::vector<T>& 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<T> query_range(const AABB3D& range) const = 0

参数 说明
range 查询的轴对齐包围盒

返回: 与 range 相交的对象列表

K 近邻查询:返回距 point 最近的 k 个对象
virtual std::vector<T> query_knn(const Point3D& point, size_t k) const = 0

参数 说明
point 查询点
k 需要返回的对象数量

返回: 按距离升序排列的 k 个最近对象

射线查询:返回与射线相交的所有对象
virtual std::vector<T> 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<Polygon2D> 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<Polygon2D> polygon_offset(const Polygon2D& poly, double distance)

参数 说明
poly 原始多边形
distance 偏移距离(正=外扩,负=内缩)

返回: 偏移后的多边形列表(内缩或自交可能产生多个碎片)

使用直骨架近似而非精确圆弧偏移,转角处为斜角连接。

参见: boolean_2d

碰撞检测 (vde::collision)

gjk.h

GJK (GilbertJohnsonKeerthi) 碰撞检测算法

支撑函数类型
using SupportFunc = std::function<Point3D(const Vector3D&)>

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 = (1uv)*v0 + u*v1 + v*v2 */

< 三角形重心坐标:hit_point = (1uv)v0 + uv1 + v*v2
Point3D point; /**< 命中点的世界坐标 */

< 命中点的世界坐标
}

射线-三角形求交(Möller-Trumbore 算法)
std::optional<RayTriResult> ray_triangle_intersect(

参数 说明
origin 射线起点
dir 射线方向(需归一化以获得正确 t 值)
tri 三角形

返回: 命中返回 RayTriResult;未命中返回空

参见: ray_mesh_intersect

射线-三角形求交(Ray3Dd 重载)
inline std::optional<RayTriResult> 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<RaySphereResult> ray_sphere_intersect(

参数 说明
origin 射线起点
dir 射线方向
center 球心
radius 球半径

返回: 命中返回 RaySphereResult(最近交点);未命中返回空

参见: ray_sphere_intersect(ray, center, radius)

射线-球体求交(Ray3Dd 重载)
inline std::optional<RaySphereResult> ray_sphere_intersect(

参数 说明
ray 射线
center 球心
radius 球半径

返回: 命中返回 RaySphereResult;未命中返回空

射线-平面求交
std::optional<double> ray_plane_intersect(

参数 说明
origin 射线起点
dir 射线方向
plane_point 平面上一点
plane_normal 平面法线(需归一化以获得正确 t

返回: 命中返回参数 t;未命中(平行或反向)返回空

射线-平面求交(Ray3Dd 重载)
inline std::optional<double> ray_plane_intersect(

参数 说明
ray 射线
plane_point 平面上一点
plane_normal 平面法线

返回: 命中返回参数 t;未命中返回空

射线-网格求交(暴力遍历)
std::optional<RayTriResult> ray_mesh_intersect(

参数 说明
origin 射线起点
dir 射线方向
triangles 三角形列表

返回: 最近命中结果;无命中返回空

对于大型网格建议配合 BVH 使用:

参见: ray_tri_intersect.h, query_ray_nearest (BVH)

射线-网格求交(Ray3Dd 重载)
inline std::optional<RayTriResult> ray_mesh_intersect(

参数 说明
ray 射线
triangles 三角形列表

返回: 最近命中结果;无命中返回空

sat.h

SAT (Separating Axis Theorem) 碰撞检测

SAT 凸多面体相交检测
bool sat_intersect(const std::vector<Point3D>& 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<int>& edges, bool outer = true)

参数 说明
edges 环中边的 ID 序列(顺序连接)
outer true = 外环, false = 内环

返回: 新环的 ID

添加面
int add_face(int surface_id, const std::vector<int>& loops)

参数 说明
surface_id 关联曲面 ID
loops 环 ID 列表

返回: 新面的 ID

添加壳
int add_shell(const std::vector<int>& faces, bool closed = true)

参数 说明
faces 面 ID 列表
closed 是否为封闭壳

返回: 新壳的 ID

添加体
int add_body(const std::vector<int>& 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<TopoLoop>& 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<int> face_edges(int face_id) const

参数 说明
face_id 面 ID

返回: 边 ID 列表(去重)

获取边的所有相邻面
[[nodiscard]] std::vector<int> edge_faces(int edge_id) const

参数 说明
edge_id 边 ID

返回: 相邻面 ID 列表

获取顶点的所有相邻边
[[nodiscard]] std::vector<int> 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<std::string> errors

警告信息列表(不影响 valid
std::vector<std::string> warnings

水密性比率:恰好有 2 个相邻面的边的比例(1.0 = 完美水密)
double watertightness = 1.0

无自交比率:不与其他面内部相交的面对比例(1.0 = 无自交)
double self_intersection_free = 1.0

最短边的长度(用于检测退化边)
double min_edge_length = std::numeric_limits<double>::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<BrepModel>& 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<BrepModel>& bodies)

参数 说明
filepath 输出文件路径(建议扩展名 .igs 或 .iges)
bodies B-Rep 体列表

参见: export_iges 获取字符串输出

iges_import.h

IGES 文件导入(ANSI Y14.26M

IGES 导入错误码
enum class IgesError {

从文件导入 IGES
[[nodiscard]] std::vector<BrepModel> import_iges(const std::string& filepath)

参数 说明
filepath .igs 或 .iges 文件路径

返回: B-Rep 体列表

IGES 格式较为宽松,不同 CAD 系统的实现差异很大。

参见: import_iges_from_string 从字符串导入, iges_last_error 获取错误码

从字符串导入 IGES(用于测试)
[[nodiscard]] std::vector<BrepModel> 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<curves::NurbsCurve>& 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<BrepModel>& 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<BrepModel>& bodies)

参数 说明
filepath 输出文件路径(建议扩展名 .step 或 .stp)
bodies B-Rep 体列表

参见: export_step 获取字符串输出

step_import.h

STEP 文件导入(ISO 10303

STEP 导入错误码
enum class StepError {

从文件导入 STEPAP203/AP214
[[nodiscard]] std::vector<BrepModel> 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<BrepModel> 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<double(const std::function<double(const Point3D&)>&)>

参见: 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 表面点(应满足
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<ParamRef> collect_params(SdfNodePtr& root)

参数 说明
root SDF 树根节点(可写引用,因为参数将被原地修改)

返回: 可变参数引用列表

参见: numerical_gradient 计算损失对参数的数值梯度

计算标量损失对收集到的参数的数值梯度
[[nodiscard]] std::vector<double> numerical_gradient(

参数 说明
params collect_params() 返回的参数引用列表
loss_fn 损失函数(无参数的可调用对象)
eps 差分步长(默认 1e-6

返回: 梯度向量 grad_lossgrad_loss[i] = ∂loss / ∂params[i].value

参见: collect_params 收集参数, GradientDescent 梯度下降优化器

固定学习率的简单梯度下降优化器

构造优化器
explicit GradientDescent(double lr) : lr_(lr) {}

参数 说明
lr 学习率(步长因子)

执行单步梯度下降
double step(std::vector<double>& 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 圆柱轴线方向(必须归一化,
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 三角形顶点 AXY 平面内)
b 三角形顶点 BXY 平面内)
c 三角形顶点 CXY 平面内)
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·nx,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 <typename Fn>

前序遍历(const 版本)
template <typename Fn>

参见: 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<int>& 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<SketchPoint>& 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 返回的缓冲区指针