ViewDesignEngine  3.1.0
高性能 CAD 计算几何引擎
vde::sdf 命名空间参考

struct  GradResult
 前向模梯度结果: SDF 值 + 梯度 更多...
 
struct  ParamGrad
 参数梯度结构体 更多...
 
struct  OptimizeResult
 优化结果 更多...
 
struct  SymmetryResult
 对称检测结果 更多...
 
struct  ParamRef
 SDF 树中可变参数的引用 更多...
 
class  GradientDescent
 固定学习率的简单梯度下降优化器 更多...
 
struct  SdfParams
 SDF 节点参数联合体 更多...
 
class  SdfNode
 SDF 表达式树节点 更多...
 
struct  SdfBBox
 SDF 树的包围盒(AABB) 更多...
 

类型定义

using LossFn = std::function< double(const std::function< double(const Point3D &)> &)>
 损失函数类型 更多...
 
using SdfNodePtr = std::shared_ptr< SdfNode >
 

枚举

enum class  SdfOp : uint8_t {
  Sphere , Box , RoundBox , Torus ,
  Capsule , Cylinder , Cone , Plane ,
  Ellipsoid , TriangularPrism , HexPrism , Link ,
  Wedge , Union , Intersection , Difference ,
  SmoothUnion , SmoothIntersection , SmoothDifference , Round ,
  Onion , Repeat , MirrorX , MirrorY ,
  MirrorZ , Translate , Rotate , Scale ,
  Twist , Bend , Elongate , CheapBend ,
  Displace
}
 CSG 树的所有节点类型 更多...
 

函数

Vector3D gradient (const std::function< double(const Point3D &)> &f, const Point3D &p, double h=1e-6)
 SDF 的空间梯度(中心差分近似) 更多...
 
GradResult evaluate_with_gradient (const std::function< double(const Point3D &)> &f, const Point3D &p, double h=1e-6)
 同时计算 SDF 值和梯度的便捷函数 更多...
 
double sphere_radius_gradient (const Point3D &p, double radius, double h=1e-6)
 球体 SDF 对半径的参数梯度 ∂f/∂r 更多...
 
double box_extent_gradient (const Point3D &p, const Point3D &extents, int axis, double h=1e-6)
 长方体 SDF 对各轴半尺寸的参数梯度 ∂f/∂extent[i] 更多...
 
double torus_major_gradient (const Point3D &p, double major_r, double minor_r, double h=1e-6)
 圆环 SDF 对主半径的参数梯度 ∂f/∂major_r 更多...
 
double torus_minor_gradient (const Point3D &p, double major_r, double minor_r, double h=1e-6)
 圆环 SDF 对副半径的参数梯度 ∂f/∂minor_r 更多...
 
double cylinder_height_gradient (const Point3D &p, double radius, double height, double h=1e-6)
 圆柱 SDF 对高度的参数梯度 ∂f/∂height 更多...
 
double cylinder_radius_gradient (const Point3D &p, double radius, double height, double h=1e-6)
 圆柱 SDF 对半径的参数梯度 ∂f/∂radius 更多...
 
Vector3D sphere_gradient_analytic (const Point3D &p, double)
 球体 SDF 的解析梯度 更多...
 
Vector3D box_gradient_analytic (const Point3D &p, const Point3D &half_extents)
 长方体 SDF 的解析梯度 更多...
 
Vector3D torus_gradient_analytic (const Point3D &p, double major_r, double minor_r)
 圆环 SDF 的解析梯度 更多...
 
Vector3D cylinder_gradient_analytic (const Point3D &p, double)
 无限圆柱(沿 Y 轴)的解析梯度 更多...
 
Vector3D plane_gradient_analytic (const Vector3D &normal)
 平面的解析梯度 更多...
 
Vector3D capsule_gradient_analytic (const Point3D &p, const Point3D &a, const Point3D &b, double radius)
 胶囊体 SDF 的解析梯度 更多...
 
Vector3D chain_union (const Vector3D &grad_a, const Vector3D &grad_b, double d1, double d2)
 并集操作后的梯度传递 更多...
 
Vector3D chain_intersection (const Vector3D &grad_a, const Vector3D &grad_b, double d1, double d2)
 交集操作后的梯度传递 更多...
 
Vector3D chain_difference (const Vector3D &grad_a, const Vector3D &grad_b, double d1, double d2)
 差集操作后的梯度传递 更多...
 
Vector3D chain_smooth_union (const Vector3D &grad_a, const Vector3D &grad_b, double d1, double d2, double k)
 平滑并集操作的梯度传递(含完整链式法则) 更多...
 
GradResult chain_translate (const GradResult &child_result, const Point3D &)
 平移变换后的梯度传递(梯度不变) 更多...
 
GradResult chain_rotate (const GradResult &child_result, double angle_rad)
 绕 Y 轴旋转后的梯度传递 更多...
 
GradResult chain_scale (const GradResult &child_result, const Point3D &factors)
 非均匀缩放后的梯度传递 更多...
 
GradResult chain_twist (const GradResult &child_result, double amount, const Point3D &p)
 扭曲变换后的梯度传递(含完整雅可比) 更多...
 
GradResult chain_repeat (const GradResult &child_result, const Point3D &, const Point3D &)
 周期重复后的梯度传递(梯度不变) 更多...
 
ParamGrad sphere_param_grad (const Point3D &p, double radius, double h=1e-6)
 球体所有参数的梯度(当前仅 radius 有意义) 更多...
 
ParamGrad box_param_grad (const Point3D &p, const Point3D &half_extents, double h=1e-6)
 长方体所有参数的梯度 更多...
 
ParamGrad cylinder_param_grad (const Point3D &p, double radius, double height, double h=1e-6)
 圆柱所有参数的梯度 更多...
 
double op_union (double d1, double d2)
 布尔并集: A ∪ B 更多...
 
double op_intersection (double d1, double d2)
 布尔交集: A ∩ B 更多...
 
double op_difference (double d1, double d2)
 布尔差集: A \ B 更多...
 
double op_smooth_union (double d1, double d2, double k)
 平滑并集(带混合过渡) 更多...
 
double op_smooth_intersection (double d1, double d2, double k)
 平滑交集(带混合过渡) 更多...
 
double op_smooth_difference (double d1, double d2, double k)
 平滑差集(带混合过渡) 更多...
 
double op_round (double d, double r)
 圆角偏移: 将等值面向外扩展 r 单位 更多...
 
double op_onion (double d, double thickness)
 洋葱皮/壳层修饰: 取绝对值后减去厚度 更多...
 
Point3D op_repeat (const Point3D &p, const Point3D &cell)
 无限重复(周期复制) 更多...
 
Point3D op_mirror_x (const Point3D &p, double offset=0.0)
 镜像对称(X=0 平面),可选偏移 更多...
 
Point3D op_mirror_y (const Point3D &p)
 镜像对称(Y=0 平面) 更多...
 
Point3D op_mirror_z (const Point3D &p)
 镜像对称(Z=0 平面) 更多...
 
Point3D op_translate (const Point3D &p, const Point3D &offset)
 空间平移(逆变换) 更多...
 
Point3D op_rotate (const Point3D &p, double angle_rad)
 绕 Y 轴旋转(逆变换) 更多...
 
Point3D op_scale (const Point3D &p, const Point3D &s)
 非均匀缩放(逆变换) 更多...
 
Point3D op_twist (const Point3D &p, double amount)
 绕 Y 轴的扭曲变换 更多...
 
Point3D op_bend (const Point3D &p, double k)
 弯曲变换(绕 Z 轴弯曲 XZ 平面) 更多...
 
Point3D op_elongate (const Point3D &p, const Point3D &h)
 拉伸/压扁域变形(消除拉伸方向上的内部体积) 更多...
 
Point3D op_cheap_bend (const Point3D &p, double k)
 简化弯曲变换(绕 X 轴弯曲 YZ 平面) 更多...
 
double op_displace (double d, const Point3D &p, double amplitude, double frequency)
 正弦波位移扰动 更多...
 
OptimizeResult fit_to_point_cloud (const SdfNodePtr &initial, const std::vector< Point3D > &target_points, double learning_rate=0.01, int max_iterations=100)
 将参数化形状拟合到目标点云 更多...
 
OptimizeResult fit_surface_to_points (const SdfNodePtr &initial, const std::vector< Point3D > &surface_points, double learning_rate=0.01, int max_iterations=100)
 将形状表面移动到目标采样点 更多...
 
OptimizeResult fit_to_sdf (const SdfNodePtr &source, const std::function< double(const Point3D &)> &target_sdf, const Point3D &bmin, const Point3D &bmax, int grid_resolution=16, double learning_rate=0.01, int max_iterations=100)
 拟合一个 SDF 形状以匹配另一个目标 SDF 更多...
 
bool resolve_collision (SdfNodePtr &shape_a, SdfNodePtr &shape_b, double step_size=0.1, int max_iterations=50)
 通过平移解决两个形状之间的穿透 更多...
 
double penetration_depth (const SdfNodePtr &shape_a, const SdfNodePtr &shape_b, const Point3D &bmin, const Point3D &bmax, int samples=1000)
 估算两个形状之间的最小穿透距离 更多...
 
double accessibility (const SdfNodePtr &shape, const Point3D &p, const Vector3D &direction, int hemisphere_samples=64)
 计算形状表面上点的可及性分数 更多...
 
Point3D find_accessible_point (const SdfNodePtr &shape, const Vector3D &approach_dir, const Point3D &bmin, const Point3D &bmax, int grid_res=32)
 找到给定接近方向下具有最大可及性的表面点 更多...
 
double symmetry_score (const SdfNodePtr &shape, const Point3D &bmin, const Point3D &bmax, const Vector3D &plane_normal, double plane_offset=0.0, int samples=1000)
 检测形状在给定方向上的反射对称性 更多...
 
SymmetryResult find_symmetry_plane (const SdfNodePtr &shape, const Point3D &bmin, const Point3D &bmax, int samples=1000)
 自动找到形状的最佳反射对称平面 更多...
 
double estimate_volume (const SdfNodePtr &shape, const Point3D &bmin, const Point3D &bmax, int samples=10000)
 通过蒙地卡罗法估算隐式形状的体积 更多...
 
Point3D center_of_mass (const SdfNodePtr &shape, const Point3D &bmin, const Point3D &bmax, int samples=10000)
 通过蒙地卡罗法估算形状的质心 更多...
 
std::vector< ParamRefcollect_params (SdfNodePtr &root)
 从叶节点收集所有可变数值参数 更多...
 
std::vector< double > numerical_gradient (const std::vector< ParamRef > &params, const std::function< double()> &loss_fn, double eps=1e-6)
 计算标量损失对收集到的参数的数值梯度 更多...
 
double sphere (const Point3D &p, double radius)
 球体的 SDF 更多...
 
double box (const Point3D &p, const Point3D &half_extents)
 轴对齐立方体的 SDF 更多...
 
double round_box (const Point3D &p, const Point3D &half_extents, double r)
 圆角立方体的 SDF 更多...
 
double torus (const Point3D &p, double major_radius, double minor_radius)
 圆环面的 SDF 更多...
 
double capsule (const Point3D &p, const Point3D &a, const Point3D &b, double radius)
 胶囊体的 SDF 更多...
 
double cylinder (const Point3D &p, double radius, double height)
 带平端盖的圆柱体 SDF 更多...
 
double plane (const Point3D &p, const Vector3D &normal, double offset)
 平面的 SDF 更多...
 
double ellipsoid (const Point3D &p, const Point3D &radii)
 椭球体的 SDF(有界梯度近似) 更多...
 
double hex_prism (const Point3D &p, double radius, double height)
 正六棱柱的 SDF 更多...
 
double infinite_cylinder (const Point3D &p, const Vector3D &axis, double radius)
 无限长圆柱的 SDF 更多...
 
double wedge (const Point3D &p, double w, double h, double d)
 楔形体的 SDF 更多...
 
double extrusion (const Point3D &, double sdf_2d)
 二维 SDF 沿 Z 轴的无限挤出 更多...
 
double extrusion_bounded (const Point3D &p, double sdf_2d, double half_height)
 二维 SDF 的有限长度挤出 更多...
 
double revolution (const Point3D &, double sdf_2d, double)
 二维轮廓绕 Y 轴的旋转体 SDF 更多...
 
double cone (const Point3D &p, double angle_rad, double height)
 圆锥台的 SDF(非内联实现) 更多...
 
double triangular_prism (const Point3D &p, const Point3D &a, const Point3D &b, const Point3D &c, double height)
 三角棱柱的 SDF(非内联实现) 更多...
 
double link (const Point3D &p, double length, double major_r, double minor_r)
 双环链接体的 SDF(非内联实现) 更多...
 
double infinite_cone (const Point3D &p, const Point3D &apex, const Vector3D &axis, double angle_rad)
 无限圆锥的 SDF(非内联实现) 更多...
 
mesh::MCMesh sdf_to_mesh (const SdfNodePtr &root, int resolution=64, double iso_level=0.0)
 将 SDF 表达式树转换为三角网格 更多...
 
mesh::MCMesh sdf_to_mesh_lambda (const std::function< double(double, double, double)> &f, const Point3D &bmin, const Point3D &bmax, int resolution=64, double iso_level=0.0)
 将 Lambda SDF 函数转换为三角网格 更多...
 
void evaluate_batch (const SdfNodePtr &root, const double *points, int n, double *distances)
 在批处理模式下求值 SDF 更多...
 
void gradient_batch (const SdfNodePtr &root, const double *points, int n, double *gradients)
 在批处理模式下求值 SDF 的空间梯度 更多...
 
void evaluate_with_gradient_batch (const SdfNodePtr &root, const double *points, int n, double *distances, double *gradients)
 一次遍历同时求值 SDF 值和梯度 更多...
 
double evaluate (const SdfNodePtr &root, const Point3D &p)
 在空间点 p 处求值 SDF 树 更多...
 
Point3D estimate_bounds (const SdfNodePtr &root, double margin=1.0)
 估算 SDF 树的包围半尺寸 更多...
 
SdfBBox estimate_bbox (const SdfNodePtr &root, double margin=1.0)
 估算 SDF 树的完整轴对齐包围盒 更多...
 

类型定义说明

◆ LossFn

using vde::sdf::LossFn = typedef std::function<double(const std::function<double(const Point3D&)>&)>

损失函数类型

接受一个 SDF 求值函数(封装了参数化的形状),返回标量损失。

参见
fit_to_point_cloud 使用该类型的内置实现

在文件 sdf_optimize.h65 行定义.

◆ SdfNodePtr

using vde::sdf::SdfNodePtr = typedef std::shared_ptr<SdfNode>

在文件 sdf_tree.h48 行定义.

枚举类型说明

◆ SdfOp

enum vde::sdf::SdfOp : uint8_t
strong

CSG 树的所有节点类型

枚举涵盖三类操作:

  • **图元**(Sphere, Box, ...) — 叶子节点,产生基本几何体
  • **CSG 布尔**(Union, Intersection, Difference) — 二叉树组合
  • **修饰/变形**(Round, Translate, Twist, ...) — 单子节点变换
参见
SdfParams 对应的参数结构
枚举值
Sphere 
Box 
RoundBox 
Torus 
Capsule 
Cylinder 
Cone 
Plane 
Ellipsoid 
TriangularPrism 
HexPrism 
Link 
Wedge 
Union 
Intersection 
Difference 
SmoothUnion 
SmoothIntersection 
SmoothDifference 
Round 
Onion 
Repeat 
MirrorX 
MirrorY 
MirrorZ 
Translate 
Rotate 
Scale 
Twist 
Bend 
Elongate 
CheapBend 
Displace 

在文件 sdf_tree.h60 行定义.

函数说明

◆ accessibility()

double vde::sdf::accessibility ( const SdfNodePtr shape,
const Point3D &  p,
const Vector3D &  direction,
int  hemisphere_samples = 64 
)

计算形状表面上点的可及性分数

从表面点 p 发射半球光线,统计未被形状遮挡的比例。 返回 0(完全不可及)到 1(完全可及)之间的分数。

参数
shapeSDF 形状
p表面点(应满足 |sdf(p)| < ε)
direction接近方向
hemisphere_samples半球采样光线数量(默认 64)
返回
可及性分数 [0, 1]
注解
采样数越多越精确,但线性增加计算量。
参见
find_accessible_point 找到最大可及性的表面点

◆ box()

double vde::sdf::box ( const Point3D &  p,
const Point3D &  half_extents 
)
inline

轴对齐立方体的 SDF

计算点到以原点为中心的轴对齐长方体表面的有符号距离。

算法概要:

  1. 将点的各分量取绝对值,得到第一卦限对称映射
  2. 减去半边长得到相对于面的距离 qᵢ = |pᵢ| - halfExtentᵢ
  3. 外部距离 = ||max(q,0)||,内部惩罚 = min(max(qₓ,q_y,q_z), 0)

结果在面外为真实欧氏距离,边/角区域使用 L2 距离组合保证连续性。

参数
p采样点
half_extents半边长 (hx, hy, hz),均必须 ≥ 0
返回
有符号距离
// 2×3×4 的盒子
double d = box(Point3D(0.0, 0.0, 0.0), Point3D(1.0, 1.5, 2.0));
foundation::Point3D Point3D
双精度三维点(重新导出)
Definition: point.h:31
double box(const Point3D &p, const Point3D &half_extents)
轴对齐立方体的 SDF
参见
round_box 带圆角的盒子
wedge 对角切割的半盒子

在文件 sdf_primitives.h96 行定义.

被这些函数引用 box_extent_gradient().

◆ box_extent_gradient()

double vde::sdf::box_extent_gradient ( const Point3D &  p,
const Point3D &  extents,
int  axis,
double  h = 1e-6 
)
inline

长方体 SDF 对各轴半尺寸的参数梯度 ∂f/∂extent[i]

参数
p采样点
extents半边长
axis轴索引: 0=x, 1=y, 2=z
h差分步长
返回
∂f/∂extent[axis]
参见
box_param_grad 封装版本

在文件 sdf_gradient.h143 行定义.

引用了 box().

被这些函数引用 box_param_grad().

◆ box_gradient_analytic()

Vector3D vde::sdf::box_gradient_analytic ( const Point3D &  p,
const Point3D &  half_extents 
)
inline

长方体 SDF 的解析梯度

算法:

  • 外部: 梯度分量非零当且仅当对应坐标超出 semi-extent,方向向外
  • 内部: 梯度指向最近的表面(单分量)

注意:长方体 SDF 使用平滑近似,边缘处的梯度在内部/外部是分段常数。

参数
p采样点
half_extents半边长
返回
解析梯度

在文件 sdf_gradient.h243 行定义.

◆ box_param_grad()

ParamGrad vde::sdf::box_param_grad ( const Point3D &  p,
const Point3D &  half_extents,
double  h = 1e-6 
)
inline

长方体所有参数的梯度

分别计算三个轴的半尺寸对 SDF 值的影响。

参数
p采样点
half_extents半边长
h差分步长
返回
参数梯度(d_extents 分量填充)
参见
box_extent_gradient 底层数值差分

在文件 sdf_gradient.h661 行定义.

引用了 box_extent_gradient() , 以及 vde::sdf::ParamGrad::d_extents.

◆ capsule()

double vde::sdf::capsule ( const Point3D &  p,
const Point3D &  a,
const Point3D &  b,
double  radius 
)
inline

胶囊体的 SDF

以线段 ab 为骨架、半径为 radius 的扫掠球体。 等价于线段上最近的点到 p 的距离减去 radius。

算法概要:

  1. 将 p 投影到线段 ab 上,投影参数 h = clamp(pa·ba / ba·ba, 0, 1)
  2. 计算 p 到投影点的距离减去 radius

退化情况: 当 |ba| ≈ 0(a ≈ b),退化为以 a 为球心的球体。

参数
p采样点
a线段起点
b线段终点
radius扫掠球半径,必须 > 0
返回
有符号距离
// 从 (0,-2,0) 到 (0,2,0) 的胶囊、半径 0.5
double d = capsule(p, Point3D(0,-2,0), Point3D(0,2,0), 0.5);
double capsule(const Point3D &p, const Point3D &a, const Point3D &b, double radius)
胶囊体的 SDF
参见
cylinder 两端平头的圆柱(非球形端盖)

在文件 sdf_primitives.h189 行定义.

◆ capsule_gradient_analytic()

Vector3D vde::sdf::capsule_gradient_analytic ( const Point3D &  p,
const Point3D &  a,
const Point3D &  b,
double  radius 
)
inline

胶囊体 SDF 的解析梯度

梯度指向点 p 到最近线段上的投影方向。

算法:

  1. 找到 p 在线段 ab 上的投影点 closest
  2. 若 |p-closest| ≈ 0(点在轴上),返回零向量
  3. 否则梯度 = (p - closest) / |p - closest|

退化情况: 当 a ≈ b(线段退化为点)时,退化为球体的径向梯度。

参数
p采样点
a线段起点
b线段终点
radius扫掠球半径
返回
解析梯度

在文件 sdf_gradient.h354 行定义.

◆ center_of_mass()

Point3D vde::sdf::center_of_mass ( const SdfNodePtr shape,
const Point3D &  bmin,
const Point3D &  bmax,
int  samples = 10000 
)

通过蒙地卡罗法估算形状的质心

对形状内部的采样点取算术平均。

公式: COM ≈ Σ p_i / N_inside,其中 sdf(p_i) < 0

参数
shapeSDF 形状
bmin采样包围盒最小角点
bmax采样包围盒最大角点
samples蒙地卡罗采样数(默认 10000)
返回
近似质心坐标
参见
estimate_volume 体积估算

◆ chain_difference()

Vector3D vde::sdf::chain_difference ( const Vector3D &  grad_a,
const Vector3D &  grad_b,
double  d1,
double  d2 
)
inline

差集操作后的梯度传递

若 A 决定结果 (d1 > -d2),使用 ∇A;否则使用 -∇B(B 的内部变成外部)。

参数
grad_a子对象 A 的梯度
grad_b子对象 B 的梯度
d1f_A
d2f_B
返回
合并后的梯度

在文件 sdf_gradient.h424 行定义.

◆ chain_intersection()

Vector3D vde::sdf::chain_intersection ( const Vector3D &  grad_a,
const Vector3D &  grad_b,
double  d1,
double  d2 
)
inline

交集操作后的梯度传递

取两个子对象中较远者的梯度(因为距离值来自较远者)。

返回
合并后的梯度

在文件 sdf_gradient.h407 行定义.

◆ chain_repeat()

GradResult vde::sdf::chain_repeat ( const GradResult child_result,
const Point3D &  ,
const Point3D &   
)
inline

周期重复后的梯度传递(梯度不变)

重复映射是平移变换的叠加,每个晶格内梯度相同(周期域)。 在晶格边界处存在不连续性。

参数
child_result中心晶格内的子对象求值
cell晶格尺寸(仅接口保留)
p原始采样点(仅接口保留)
返回
相同梯度
警告
在晶格边界处梯度不连续,可能影响基于梯度的优化。

在文件 sdf_gradient.h597 行定义.

◆ chain_rotate()

GradResult vde::sdf::chain_rotate ( const GradResult child_result,
double  angle_rad 
)
inline

绕 Y 轴旋转后的梯度传递

由于 op_rotate 对采样点施加 R(-θ),链式法则要求对梯度施加 R(θ)。 即:∇f_world = R(θ) · ∇f_local

参数
child_result旋转后坐标系中的子对象求值
angle_rad旋转角度
返回
世界坐标系的梯度
参见
op_rotate 对应的域变形操作

在文件 sdf_gradient.h498 行定义.

引用了 vde::sdf::GradResult::grad.

◆ chain_scale()

GradResult vde::sdf::chain_scale ( const GradResult child_result,
const Point3D &  factors 
)
inline

非均匀缩放后的梯度传递

公式: ∇f_world = (∇f_child.x / sx, ∇f_child.y / sy, ∇f_child.z / sz)

因为 f_world(p) = f_child(p / s),由链式法则得 ∂f_world/∂p = ∇f_child · diag(1/s)。

注解
缩放后梯度不再是单位长度,除非是均匀缩放。
参数
child_result缩放后坐标系中的子对象求值
factors缩放因子
返回
世界坐标系的梯度

在文件 sdf_gradient.h525 行定义.

引用了 vde::sdf::GradResult::grad.

◆ chain_smooth_union()

Vector3D vde::sdf::chain_smooth_union ( const Vector3D &  grad_a,
const Vector3D &  grad_b,
double  d1,
double  d2,
double  k 
)
inline

平滑并集操作的梯度传递(含完整链式法则)

与普通并集的硬切换不同,本函数使用多项式混合函数的导数来平滑插值两个子对象的梯度。

推导: f = d₁(1-h) + d₂h - k·h(1-h),h = clamp(0.5+0.5(d₂-d₁)/k, 0, 1) ∂f/∂d₁ = 2 - 3h ∂f/∂d₂ = 3h - 1

在混合区域 (0 < h < 1) 内,权重平滑地从 A 过渡到 B。

参数
grad_a子对象 A 的梯度
grad_b子对象 B 的梯度
d1f_A
d2f_B
k混合参数
返回
平滑合并后的梯度
参见
op_smooth_union 对应的平滑并集 SDF 操作
chain_union 硬切换版本

在文件 sdf_gradient.h452 行定义.

引用了 chain_union().

◆ chain_translate()

GradResult vde::sdf::chain_translate ( const GradResult child_result,
const Point3D &   
)
inline

平移变换后的梯度传递(梯度不变)

平移是等距变换(isometry),函数值不变, 因此子对象的梯度直接穿透。

参数
child_result变换空间中的子对象求值结果
offset平移量(仅接口保留)
返回
相同梯度

在文件 sdf_gradient.h481 行定义.

◆ chain_twist()

GradResult vde::sdf::chain_twist ( const GradResult child_result,
double  amount,
const Point3D &  p 
)
inline

扭曲变换后的梯度传递(含完整雅可比)

扭曲 T(p) 绕 Y 轴旋转角度 amount·p_y。 梯度传递需要对雅可比矩阵的转置做链式法则:

雅可比 J:

∂T_x/∂p_x = c, ∂T_x/∂p_y = -a·(p_x·s + p_z·c), ∂T_x/∂p_z = -s
∂T_y/∂p_x = 0, ∂T_y/∂p_y = 1, ∂T_y/∂p_z = 0
∂T_z/∂p_x = s, ∂T_z/∂p_y = a·(p_x·c - p_z·s), ∂T_z/∂p_z = c

其中 c = cos(a·p_y), s = sin(a·p_y), a = amount。

参数
child_result扭曲空间中的子对象求值
amount单位高度的旋转量
p原始采样点
返回
世界坐标系的梯度
参见
op_twist 对应的域变形操作
chain_rotate 不含 Y 依赖的简化旋转梯度传递

在文件 sdf_gradient.h558 行定义.

引用了 vde::sdf::GradResult::grad.

◆ chain_union()

Vector3D vde::sdf::chain_union ( const Vector3D &  grad_a,
const Vector3D &  grad_b,
double  d1,
double  d2 
)
inline

并集操作后的梯度传递

取两个子对象中较近者的梯度(因为距离值来自较近者)。

参数
grad_a子对象 A 的梯度
grad_b子对象 B 的梯度
d1A 的 SDF 值
d2B 的 SDF 值
返回
合并后的梯度
警告
当 d1 ≈ d2 时,梯度可能在两个子对象间不连续跳变。
参见
chain_smooth_union 避免不连续的平滑版本

在文件 sdf_gradient.h394 行定义.

被这些函数引用 chain_smooth_union().

◆ collect_params()

std::vector<ParamRef> vde::sdf::collect_params ( SdfNodePtr root)

从叶节点收集所有可变数值参数

遍历 SDF 树,收集所有图元节点中可优化的参数引用。 返回的 ParamRef 列表可传递给 numerical_gradient() 进行优化。

参数
rootSDF 树根节点(可写引用,因为参数将被原地修改)
返回
可变参数引用列表
auto root = SdfNode::op_union(
SdfNode::box(Point3D(0.5, 0.5, 0.5))
);
auto params = collect_params(root);
// params[0].value 指向球体半径
// params[1..4] 指向盒子的 extents 分量
static SdfNodePtr box(const Point3D &half_extents)
创建轴对齐长方体节点
static SdfNodePtr sphere(double r)
创建球体节点
static SdfNodePtr op_union(SdfNodePtr a, SdfNodePtr b)
创建并集节点: A ∪ B
std::vector< ParamRef > collect_params(SdfNodePtr &root)
从叶节点收集所有可变数值参数
参见
numerical_gradient 计算损失对参数的数值梯度

◆ cone()

double vde::sdf::cone ( const Point3D &  p,
double  angle_rad,
double  height 
)

圆锥台的 SDF(非内联实现)

沿 Y 轴、以原点为中心的有限长圆锥台。 顶点在 y = +height/2(半径 0),底面在 y = -height/2(半径 height·tan(angle_rad))。

算法概要: 将三维问题分解为二维 (r, y) 平面内点到三角形区域的距离计算, 其中 r = √(pₓ² + p𝓏²),三角形由底边和高决定。

参数
p采样点
angle_rad半锥角(弧度),决定底面半径
height锥体总高度,必须 > 0
返回
有符号距离
警告
当 angle_rad 接近 π/2 时底面半径极大,可能导致数值不稳定。
参见
cylinder 半锥角为 0 时的退化情况
infinite_cone 无限圆锥

◆ cylinder()

double vde::sdf::cylinder ( const Point3D &  p,
double  radius,
double  height 
)
inline

带平端盖的圆柱体 SDF

沿 Y 轴、以原点为中心的有限长圆柱体。两端为平切面(非球形端盖)。

算法概要:

  1. 水平距离: d_xz = √(pₓ² + p𝓏²) - radius
  2. 垂直距离: d_y = |p_y| - height/2
  3. 用二维 min/max L2 组合计算矩形区域到圆角的 SDF

结果在柱面上为真实距离,在端盖边缘有连续过渡。

参数
p采样点
radius圆柱截面半径,必须 > 0
height圆柱总高度(从 -h/2 到 +h/2),必须 > 0
返回
有符号距离
// 半径 1.0、高度 3.0 的圆柱
double d = cylinder(Point3D(1.0, 0.0, 0.0), 1.0, 3.0);
double cylinder(const Point3D &p, double radius, double height)
带平端盖的圆柱体 SDF
参见
capsule 两端球形端盖的圆柱
infinite_cylinder 无限长圆柱
cone 圆锥台

在文件 sdf_primitives.h227 行定义.

被这些函数引用 cylinder_height_gradient() , 以及 cylinder_radius_gradient().

◆ cylinder_gradient_analytic()

Vector3D vde::sdf::cylinder_gradient_analytic ( const Point3D &  p,
double   
)
inline

无限圆柱(沿 Y 轴)的解析梯度

公式: ∇f = (pₓ, 0, p𝓏) / √(pₓ² + p𝓏²)

梯度仅含水平分量,方向为从轴线径向向外。 在轴线上退化返回 (0,1,0)。

参数
p采样点
radius圆柱半径(未使用,保留接口一致)
返回
解析梯度

在文件 sdf_gradient.h312 行定义.

◆ cylinder_height_gradient()

double vde::sdf::cylinder_height_gradient ( const Point3D &  p,
double  radius,
double  height,
double  h = 1e-6 
)
inline

圆柱 SDF 对高度的参数梯度 ∂f/∂height

参数
p采样点
radius圆柱半径
height圆柱高度
h差分步长
返回
参数梯度

在文件 sdf_gradient.h188 行定义.

引用了 cylinder().

被这些函数引用 cylinder_param_grad().

◆ cylinder_param_grad()

ParamGrad vde::sdf::cylinder_param_grad ( const Point3D &  p,
double  radius,
double  height,
double  h = 1e-6 
)
inline

圆柱所有参数的梯度

分别计算半径和高度对 SDF 值的影响。

参数
p采样点
radius圆柱半径
height圆柱高度
h差分步长
返回
参数梯度(d_radius, d_height 填充)

在文件 sdf_gradient.h682 行定义.

引用了 cylinder_height_gradient(), cylinder_radius_gradient(), vde::sdf::ParamGrad::d_height , 以及 vde::sdf::ParamGrad::d_radius.

◆ cylinder_radius_gradient()

double vde::sdf::cylinder_radius_gradient ( const Point3D &  p,
double  radius,
double  height,
double  h = 1e-6 
)
inline

圆柱 SDF 对半径的参数梯度 ∂f/∂radius

返回
参数梯度

在文件 sdf_gradient.h199 行定义.

引用了 cylinder().

被这些函数引用 cylinder_param_grad().

◆ ellipsoid()

double vde::sdf::ellipsoid ( const Point3D &  p,
const Point3D &  radii 
)
inline

椭球体的 SDF(有界梯度近似)

以原点为中心的椭球,半轴长为 radii = (rx, ry, rz)。

算法概要:

使用 bound-normalized 近似方法:

  1. 缩放坐标: pr = p / radii
  2. k0 = |pr|,k1 = |p / radii²|
  3. f = k0 * (k0 - 1) / k1

该方法保证在表面上 f = 0,但内部/远处的距离为近似值。 相比精确椭球距离,避开了六次方程的昂贵求根。

参数
p采样点
radii半轴长 (rx, ry, rz),均必须 > 0
返回
有符号距离(近似)
注解
当三个半径相等时退化为球体,此时使用 sphere() 更精确高效。
当点到原点距离远大于最大半径时,近似精度下降。
// 扁椭球: rx=2, ry=1, rz=1
double d = ellipsoid(Point3D(2.0, 0.0, 0.0), Point3D(2, 1, 1));
double ellipsoid(const Point3D &p, const Point3D &radii)
椭球体的 SDF(有界梯度近似)
参见
sphere 精确球体(rx=ry=rz 时的特例)

在文件 sdf_primitives.h294 行定义.

◆ estimate_bbox()

SdfBBox vde::sdf::estimate_bbox ( const SdfNodePtr root,
double  margin = 1.0 
)

估算 SDF 树的完整轴对齐包围盒

在 estimate_bounds 基础上计算对称 AABB。

参数
rootSDF 树的根节点
margin额外安全边距
返回
AABB 包围盒
auto bbox = estimate_bbox(root, 0.5);
// bbox.min = (-hx-0.5, -hy-0.5, -hz-0.5)
// bbox.max = ( hx+0.5, hy+0.5, hz+0.5)
SdfBBox estimate_bbox(const SdfNodePtr &root, double margin=1.0)
估算 SDF 树的完整轴对齐包围盒

◆ estimate_bounds()

Point3D vde::sdf::estimate_bounds ( const SdfNodePtr root,
double  margin = 1.0 
)

估算 SDF 树的包围半尺寸

通过对叶节点包围盒的递归合并,估算从树根到最远角落的半径。 结果是包围盒的半边长(从中心到面的距离)。

参数
rootSDF 树的根节点
margin额外安全边距(默认 1.0)
返回
包围半边长 (hx, hy, hz)
注解
变形节点(旋转/弯曲/扭曲等)会使包围盒放大,以保守估计覆盖变形后区域。
参见
estimate_bbox 完整 AABB 结果

◆ estimate_volume()

double vde::sdf::estimate_volume ( const SdfNodePtr shape,
const Point3D &  bmin,
const Point3D &  bmax,
int  samples = 10000 
)

通过蒙地卡罗法估算隐式形状的体积

在包围盒内均匀随机采样,统计落在形状内部的点比例, 乘以包围盒体积得到近似体积。

公式: V ≈ V_box · N_inside / N_total,其中 N_inside = count(sdf(p_i) < 0)

参数
shapeSDF 形状
bmin采样包围盒最小角点
bmax采样包围盒最大角点
samples蒙地卡罗采样数(默认 10000)
返回
近似体积
注解
精度与 √samples 成正比。10000 采样 ≈ 1% 相对误差。
包围盒应尽可能紧致以减小方差。
参见
center_of_mass 蒙地卡罗质心估算

◆ evaluate()

double vde::sdf::evaluate ( const SdfNodePtr root,
const Point3D &  p 
)

在空间点 p 处求值 SDF 树

递归遍历表达式树,在叶节点调用对应图元的 SDF 函数, 在内部节点执行 CSG 操作或域变形。

算法概要:

  1. 域变形节点先对 p 做变换,将变换后的点传入子节点
  2. CSG 布尔节点分别求值两个子节点后组合
  3. 图元节点直接调用内联 SDF 函数
参数
rootSDF 表达式树的根节点
p世界空间中的采样点
返回
有符号距离(负 = 内部,零 = 表面,正 = 外部)
auto root = SdfNode::sphere(1.0);
double d = evaluate(root, Point3D(0.5, 0.0, 0.0)); // ≈ -0.5
double evaluate(const SdfNodePtr &root, const Point3D &p)
在空间点 p 处求值 SDF 树
参见
estimate_bounds 估计树的包围盒

◆ evaluate_batch()

void vde::sdf::evaluate_batch ( const SdfNodePtr root,
const double *  points,
int  n,
double *  distances 
)

在批处理模式下求值 SDF

对 n 个三维点逐一求值 SDF 树,将距离值写入预分配的输出数组。

性能特征:

  • O(n) 时间复杂度,每个点独立求值
  • 内存访问模式: 顺序读取 3n 个 double,顺序写入 n 个 double
  • 无 SIMD 优化(当前 CPU 后端)
参数
rootSDF 表达式树根节点
points点数组,length = 3·n,x,y,z 交替存储
n点数
distances输出数组,length = n,写入有符号距离值
前置条件
points 和 distances 必须非空,且各自有足够长度
std::vector<double> pts = {0,0,0, 1,0,0, 2,0,0}; // 3 points
std::vector<double> dists(3);
evaluate_batch(root, pts.data(), 3, dists.data());
void evaluate_batch(const SdfNodePtr &root, const double *points, int n, double *distances)
在批处理模式下求值 SDF
参见
evaluate 单点求值
gradient_batch 批量梯度计算

◆ evaluate_with_gradient()

GradResult vde::sdf::evaluate_with_gradient ( const std::function< double(const Point3D &)> &  f,
const Point3D &  p,
double  h = 1e-6 
)
inline

同时计算 SDF 值和梯度的便捷函数

参数
fSDF 函数
p求值点
h差分步长
返回
value + grad 结构
参见
gradient 仅计算梯度

在文件 sdf_gradient.h102 行定义.

引用了 gradient().

◆ evaluate_with_gradient_batch()

void vde::sdf::evaluate_with_gradient_batch ( const SdfNodePtr root,
const double *  points,
int  n,
double *  distances,
double *  gradients 
)

一次遍历同时求值 SDF 值和梯度

相比于分别调用 evaluate_batch + gradient_batch, 本函数在一次遍历中完成两者,避免重复遍历树。

参数
rootSDF 表达式树根节点
points点数组,length = 3·n
n点数
distances输出距离数组,length = n
gradients输出梯度数组,length = 3·n
注解
对于大量点的场景(n > 1000),推荐使用本函数以获得 ~2× 速度提升。
int n = 10000;
std::vector<double> pts(3*n), dists(n), grads(3*n);
// ... fill pts ...
evaluate_with_gradient_batch(root, pts.data(), n, dists.data(), grads.data());
void evaluate_with_gradient_batch(const SdfNodePtr &root, const double *points, int n, double *distances, double *gradients)
一次遍历同时求值 SDF 值和梯度
参见
evaluate_batch 仅求距离
gradient_batch 仅求梯度

◆ extrusion()

double vde::sdf::extrusion ( const Point3D &  ,
double  sdf_2d 
)
inline

二维 SDF 沿 Z 轴的无限挤出

将二维 SDF 沿 Z 轴无限延伸。三维点的 SDF 值等于其 (x,y) 投影处的二维 SDF 值。

使用模式: 先计算二维 SDF 值,再传入此函数:

double sdf_2d = circle_sdf(p.x(), p.y()); // 用户自定义二维 SDF
double sdf_3d = extrusion(p, sdf_2d);
double extrusion(const Point3D &, double sdf_2d)
二维 SDF 沿 Z 轴的无限挤出
参数
p三维采样点(仅 x,y 分量被隐式使用——通过 sdf_2d 参数间接)
sdf_2d预计算的二维 SDF 值(在 (p.x, p.y) 处求值)
返回
三维有符号距离(等于 sdf_2d)
注解
p 参数仅保持接口一致,实际不影响结果。
对于有限长度的挤出,使用 extrusion_bounded()
参见
extrusion_bounded 有限长度的挤出
revolution 二维轮廓绕 Y 轴旋转

在文件 sdf_primitives.h428 行定义.

◆ extrusion_bounded()

double vde::sdf::extrusion_bounded ( const Point3D &  p,
double  sdf_2d,
double  half_height 
)
inline

二维 SDF 的有限长度挤出

将二维 SDF 沿 Z 轴挤出并通过 |pz| ≤ half_height 做 bounded 限制。 相当于对二维 SDF 与 Z 轴平板做交集。

参数
p三维采样点
sdf_2d预计算的二维 SDF 值(在 (p.x, p.y) 处求值)
half_height挤出半高度(Z 方向),必须 ≥ 0
返回
有符号距离
// 圆形截面、总高 4.0 的短柱
double d2d = std::sqrt(p.x()*p.x() + p.y()*p.y()) - 1.0;
double d3d = extrusion_bounded(p, d2d, 2.0);
double extrusion_bounded(const Point3D &p, double sdf_2d, double half_height)
二维 SDF 的有限长度挤出
参见
extrusion 无限挤出
hex_prism 六棱柱(特例化 bounded extrusion 实现)

在文件 sdf_primitives.h452 行定义.

◆ find_accessible_point()

Point3D vde::sdf::find_accessible_point ( const SdfNodePtr shape,
const Vector3D &  approach_dir,
const Point3D &  bmin,
const Point3D &  bmax,
int  grid_res = 32 
)

找到给定接近方向下具有最大可及性的表面点

在包围盒内的规则网格上搜索,计算每个网格点处的可及性分数。

参数
shapeSDF 形状
approach_dir接近方向(如工具接近方向)
bmin搜索包围盒最小角点
bmax搜索包围盒最大角点
grid_res搜索网格分辨率(默认 32)
返回
最大可及性的表面点
参见
accessibility 单点可及性计算

◆ find_symmetry_plane()

SymmetryResult vde::sdf::find_symmetry_plane ( const SdfNodePtr shape,
const Point3D &  bmin,
const Point3D &  bmax,
int  samples = 1000 
)

自动找到形状的最佳反射对称平面

尝试多个候选平面方向(沿主轴和若干采样方向), 返回对称性分数最高的平面。

参数
shapeSDF 形状
bmin包围盒最小角点
bmax包围盒最大角点
samples每个候选方向的采样数(默认 1000)
返回
最佳对称平面及其分数
参见
symmetry_score 给定方向的对称性检测

◆ fit_surface_to_points()

OptimizeResult vde::sdf::fit_surface_to_points ( const SdfNodePtr initial,
const std::vector< Point3D > &  surface_points,
double  learning_rate = 0.01,
int  max_iterations = 100 
)

将形状表面移动到目标采样点

与 fit_to_point_cloud 类似,但损失函数使用 L = mean(|sdf(p_i)|)。 这强制采样点位于表面上(而非仅靠近表面)。

参数
initial初始形状
surface_points目标表面点
learning_rate学习率
max_iterations最大迭代次数
返回
优化结果
参见
fit_to_point_cloud 更通用的点云拟合(可包含内部/外部点)

◆ fit_to_point_cloud()

OptimizeResult vde::sdf::fit_to_point_cloud ( const SdfNodePtr initial,
const std::vector< Point3D > &  target_points,
double  learning_rate = 0.01,
int  max_iterations = 100 
)

将参数化形状拟合到目标点云

最小化目标表面点到拟合形状表面的有符号距离。

算法概要:

  1. 遍历 target_points 计算每个点到初始形状的 SDF 值
  2. 用有限差分计算形状参数对损失的梯度
  3. 梯度下降更新参数
  4. 重复直至收敛或达到最大迭代次数
参数
initial初始形状(sphere, box, cylinder 等),其参数将被优化
target_points目标点云(表面采样点)
learning_rate梯度下降步长(默认 0.01)
max_iterations最大迭代次数(默认 100)
返回
优化结果(含优化后的形状和收敛信息)
注解
损失函数为 L = mean(|sdf(p_i)|),即点到表面的平均绝对距离。
initial 的共享子节点不会被复制——返回的 optimize_shape 共享未修改的子树。
std::vector<Point3D> points = { point cloud data };
auto sphere = SdfNode::sphere(1.0);
auto result = fit_to_point_cloud(sphere, points, 0.01, 200);
// result.optimized_shape 的 params.radius 已被优化
OptimizeResult fit_to_point_cloud(const SdfNodePtr &initial, const std::vector< Point3D > &target_points, double learning_rate=0.01, int max_iterations=100)
将参数化形状拟合到目标点云
double sphere(const Point3D &p, double radius)
球体的 SDF
参见
fit_surface_to_points 类似但仅最小化 |sdf| 而非有符号距离
fit_to_sdf 拟合到另一个 SDF

◆ fit_to_sdf()

OptimizeResult vde::sdf::fit_to_sdf ( const SdfNodePtr source,
const std::function< double(const Point3D &)> &  target_sdf,
const Point3D &  bmin,
const Point3D &  bmax,
int  grid_resolution = 16,
double  learning_rate = 0.01,
int  max_iterations = 100 
)

拟合一个 SDF 形状以匹配另一个目标 SDF

在规则网格上采样两个 SDF,最小化它们之间的均方差。

损失函数: L = mean((sdf_source(p_i) - sdf_target(p_i))²)

适合将一个参数化形状"画像"成一个更复杂的隐式形状。

参数
source被优化的参数化形状
target_sdf目标 SDF 函数
bmin采样网格最小角点
bmax采样网格最大角点
grid_resolution采样网格分辨率(默认 16)
learning_rate学习率
max_iterations最大迭代次数
返回
优化结果
警告
网格分辨率每增加一倍,计算量增加 8 倍。使用 8~32 可获得合理速度。
参见
fit_to_point_cloud 拟合到点云

◆ gradient()

Vector3D vde::sdf::gradient ( const std::function< double(const Point3D &)> &  f,
const Point3D &  p,
double  h = 1e-6 
)
inline

SDF 的空间梯度(中心差分近似)

使用三轴中心有限差分: ∂f/∂x ≈ (f(x+h, y, z) - f(x-h, y, z)) / (2h)

二阶精度,适用于任意黑盒 SDF 函数。

参数
fSDF 函数(接受 Point3D 参数)
p求值点
h差分步长(默认 1e-6)
返回
梯度向量 ∇f(p)
注解
步长太小会导致舍入误差主导,太大导致截断误差主导。 默认值 1e-6 在单精度场景下是较好的平衡。
对于含不连续性的 SDF(如 sharp CSG),有限差分可能在边界产生错误梯度。
auto f = [](const Point3D& p) { return sphere(p, 1.0); };
Vector3D n = gradient(f, Point3D(1, 0, 0)); // ≈ (1, 0, 0)
foundation::Vector3D Vector3D
双精度三维向量(重新导出)
Definition: point.h:49
Vector3D gradient(const std::function< double(const Point3D &)> &f, const Point3D &p, double h=1e-6)
SDF 的空间梯度(中心差分近似)
Definition: sdf_gradient.h:65
参见
evaluate_with_gradient 一次性获取值和梯度

在文件 sdf_gradient.h65 行定义.

被这些函数引用 evaluate_with_gradient().

◆ gradient_batch()

void vde::sdf::gradient_batch ( const SdfNodePtr root,
const double *  points,
int  n,
double *  gradients 
)

在批处理模式下求值 SDF 的空间梯度

对 n 个点逐一计算空间梯度 ∇f = (df/dx, df/dy, df/dz), 结果写入预分配的梯度数组。

参数
rootSDF 表达式树根节点
points点数组,length = 3·n
n点数
gradients输出数组,length = 3·n,x,y,z 梯度分量交替存储
前置条件
points 和 gradients 必须非空,且有足够长度
参见
evaluate_batch 批量距离求值
evaluate_with_gradient_batch 同时获取距离和梯度(减少重复采样)

◆ hex_prism()

double vde::sdf::hex_prism ( const Point3D &  p,
double  radius,
double  height 
)
inline

正六棱柱的 SDF

六边形位于 XZ 平面,尖顶沿 X 轴方向,沿 Y 轴挤出的正六棱柱。

算法概要:

  1. 将点对称映射到第一象限后,计算二维六边形的 SDF
  2. 六边形 SDF 通过两组约束平面表示: max(px + 0.577*pz, 1.155*pz) - radius
  3. 沿 Y 轴做 bounded extrusion
参数
p采样点
radius六边形外接圆半径(中心到顶点),必须 > 0
height挤出总高度(±h/2 沿 Y 轴),必须 > 0
返回
有符号距离
// 外接圆半径 1.0、高度 2.0 的六棱柱
double d = hex_prism(Point3D(0.0, 0.0, 0.0), 1.0, 2.0);
double hex_prism(const Point3D &p, double radius, double height)
正六棱柱的 SDF
参见
extrusion_bounded 通用 bounded extrusion 算子

在文件 sdf_primitives.h333 行定义.

◆ infinite_cone()

double vde::sdf::infinite_cone ( const Point3D &  p,
const Point3D &  apex,
const Vector3D &  axis,
double  angle_rad 
)

无限圆锥的 SDF(非内联实现)

从顶点出发沿轴方向无限延伸的圆锥,半锥角为 angle_rad。 与 cone() 不同,本函数无高度限制,锥体向轴的正方向无限扩展。

参数
p采样点
apex锥顶位置
axis锥轴方向(必须归一化),锥体沿此方向扩展
angle_rad半锥角(弧度)
返回
有符号距离
前置条件
axis.norm() ≈ 1.0
// 顶点在原点、沿 Y 轴、半锥角 30° 的无限锥
double d = infinite_cone(p, Point3D(0,0,0), Vector3D(0,1,0), M_PI/6);
double infinite_cone(const Point3D &p, const Point3D &apex, const Vector3D &axis, double angle_rad)
无限圆锥的 SDF(非内联实现)
参见
cone 有限高圆锥台

◆ infinite_cylinder()

double vde::sdf::infinite_cylinder ( const Point3D &  p,
const Vector3D &  axis,
double  radius 
)
inline

无限长圆柱的 SDF

沿任意方向的无限长圆柱(无端盖),轴线过原点。

数学公式: f(p) = |p × axis| - radius

叉积给出点到轴线的垂直距离。

参数
p采样点
axis圆柱轴线方向(必须归一化,|axis| = 1)
radius截面半径,必须 > 0
返回
有符号距离
前置条件
axis.norm() ≈ 1.0
// 沿 Z 轴的无限圆柱
double d = infinite_cylinder(p, Vector3D(0,0,1), 0.5);
double infinite_cylinder(const Point3D &p, const Vector3D &axis, double radius)
无限长圆柱的 SDF
参见
cylinder 有限长圆柱(带平端盖)

在文件 sdf_primitives.h365 行定义.

◆ link()

double vde::sdf::link ( const Point3D &  p,
double  length,
double  major_r,
double  minor_r 
)

双环链接体的 SDF(非内联实现)

两个并列的圆环面沿 X 轴排列,等效于经典链环结构。 常用于链条、连杆等机械连接件的快速建模。

参数
p采样点
length两个环心沿 X 轴的距离
major_r每个环的主半径(环的半径)
minor_r每个环的管半径(截面的粗细)
返回
有符号距离
// 环间距 2.0、主半径 1.0、管半径 0.2 的双环
double d = link(Point3D(1.0, 0.0, 0.0), 2.0, 1.0, 0.2);
double link(const Point3D &p, double length, double major_r, double minor_r)
双环链接体的 SDF(非内联实现)
参见
torus 单个圆环

◆ numerical_gradient()

std::vector<double> vde::sdf::numerical_gradient ( const std::vector< ParamRef > &  params,
const std::function< double()> &  loss_fn,
double  eps = 1e-6 
)

计算标量损失对收集到的参数的数值梯度

对每个参数逐个做中心差分,返回梯度向量。

参数
paramscollect_params() 返回的参数引用列表
loss_fn损失函数(无参数的可调用对象)
eps差分步长(默认 1e-6)
返回
梯度向量 grad_loss,grad_loss[i] = ∂loss / ∂params[i].value
auto params = collect_params(root);
auto loss = [&]() {
double s = 0;
for (auto& pt : target_points) s += std::abs(evaluate(root, pt));
return s / target_points.size();
};
auto grad = numerical_gradient(params, loss, 1e-6);
std::vector< double > numerical_gradient(const std::vector< ParamRef > &params, const std::function< double()> &loss_fn, double eps=1e-6)
计算标量损失对收集到的参数的数值梯度
参见
collect_params 收集参数
GradientDescent 梯度下降优化器

◆ op_bend()

Point3D vde::sdf::op_bend ( const Point3D &  p,
double  k 
)
inline

弯曲变换(绕 Z 轴弯曲 XZ 平面)

将空间沿 X 轴弯曲,弯曲量由参数 k 控制。

变换:

p'_x = cos(k·p_x)·p_x - sin(k·p_x)·p_y
p'_y = sin(k·p_x)·p_x + cos(k·p_x)·p_y
p'_z = p_z
参数
p原始采样点
k弯曲曲率参数(k 越大弯曲越剧烈)
返回
弯曲后的采样点
// 轻度弯曲的长方体
Point3D q = op_bend(p, 0.2);
double d = box(q, Point3D(3, 0.3, 0.3));
Point3D op_bend(const Point3D &p, double k)
弯曲变换(绕 Z 轴弯曲 XZ 平面)
参见
op_cheap_bend 简化版弯曲(仅绕 X 轴)
op_twist 扭曲变换

在文件 sdf_operations.h457 行定义.

◆ op_cheap_bend()

Point3D vde::sdf::op_cheap_bend ( const Point3D &  p,
double  k 
)
inline

简化弯曲变换(绕 X 轴弯曲 YZ 平面)

比 op_bend 更快但精度较低的弯曲,仅在 YZ 方向产生偏移。

变换:

p'_x = p_x
p'_y = p_y·cos(k·p_x) - p_z·sin(k·p_x)
p'_z = p_y·sin(k·p_x) + p_z·cos(k·p_x)
参数
p原始采样点
k弯曲曲率参数
返回
弯曲后的采样点
注解
使用场景:不需要精确物理弯曲,仅需视觉效果时优先用此函数以节省计算。
参见
op_bend 完整弯曲变换

在文件 sdf_operations.h515 行定义.

◆ op_difference()

double vde::sdf::op_difference ( double  d1,
double  d2 
)
inline

布尔差集: A \ B

从对象 A 中减去对象 B 所占区域。

数学公式: f = max(d1, -d2)

将第二个距离值取反后取最大值:B 的外部变成内部,内部变成外部。

参数
d1被减对象 A 的 SDF 值
d2减去对象 B 的 SDF 值
返回
差集的 SDF 值
// 从球体中减去盒子
double d = op_difference(sphere(p, 1.0), box(p, Point3D(0.3, 0.3, 0.3)));
double op_difference(double d1, double d2)
布尔差集: A \ B
参见
op_smooth_difference 带平滑过渡的差集

在文件 sdf_operations.h94 行定义.

◆ op_displace()

double vde::sdf::op_displace ( double  d,
const Point3D &  p,
double  amplitude,
double  frequency 
)
inline

正弦波位移扰动

在距离场上叠加一个三维正弦波的微小扰动。

数学公式: f = d + amplitude · ∏_i sin(p_i · frequency)

三个方向的 sin 函数乘积产生体纹理效果。

参数
d原始 SDF 值
p采样点(用于扰动计算)
amplitude扰动幅值
frequency空间频率
返回
扰动后的 SDF 值
警告
扰动能轻易破坏距离场的 Lipschitz 性质(|∇f| ≤ 1), 导致 ray-marching 效率下降。需控制 amplitude/frequency 在合理范围内。
// 给球体添加微小波纹
double d = op_displace(sphere(p, 1.0), p, 0.05, 4.0);
double op_displace(double d, const Point3D &p, double amplitude, double frequency)
正弦波位移扰动

在文件 sdf_operations.h545 行定义.

◆ op_elongate()

Point3D vde::sdf::op_elongate ( const Point3D &  p,
const Point3D &  h 
)
inline

拉伸/压扁域变形(消除拉伸方向上的内部体积)

将点沿各主轴方向向原点压缩,消除 |p_i| ≤ h_i 区域的内部信息。 这在组合建模中用于从对象中挖去沿坐标轴的孔道。

变换: 对每个分量 i:

  • 若 |p_i| > h_i: p'_i = p_i - sign(p_i)·h_i
  • 否则: p'_i = 0
参数
p原始采样点
h各轴的拉伸阈值 (hx, hy, hz),均 ≥ 0
返回
变形后的采样点
// 将球体沿 X 轴拉伸,挖去|x|≤1 的区域
Point3D q = op_elongate(p, Point3D(1, 0, 0));
double d = sphere(q, 1.5);
Point3D op_elongate(const Point3D &p, const Point3D &h)
拉伸/压扁域变形(消除拉伸方向上的内部体积)
参见
op_repeat 周期重复

在文件 sdf_operations.h486 行定义.

◆ op_intersection()

double vde::sdf::op_intersection ( double  d1,
double  d2 
)
inline

布尔交集: A ∩ B

取两个距离值的最大值。保留同时属于两个对象的区域。

数学公式: f = max(d1, d2)

参数
d1第一个对象的 SDF 值
d2第二个对象的 SDF 值
返回
交集的 SDF 值
// 球体与盒子的交集(取共同区域)
double d = op_intersection(sphere(p, 1.0), box(p, Point3D(0.5, 0.5, 0.5)));
double op_intersection(double d1, double d2)
布尔交集: A ∩ B
参见
op_smooth_intersection 带平滑过渡的交集

在文件 sdf_operations.h70 行定义.

◆ op_mirror_x()

Point3D vde::sdf::op_mirror_x ( const Point3D &  p,
double  offset = 0.0 
)
inline

镜像对称(X=0 平面),可选偏移

将空间关于 x = offset 平面取镜像对称。

变换: p'_x = offset + |p_x - offset|

参数
p原始采样点
offset镜像平面沿 X 轴的偏移量(默认 0 = X=0 平面)
返回
映射到镜像半空间的点
// 关于 X=1 平面对称
Point3D q = op_mirror_x(p, 1.0);
Point3D op_mirror_x(const Point3D &p, double offset=0.0)
镜像对称(X=0 平面),可选偏移
参见
op_mirror_y YZ 平面镜像
op_mirror_z XY 平面镜像

在文件 sdf_operations.h279 行定义.

◆ op_mirror_y()

Point3D vde::sdf::op_mirror_y ( const Point3D &  p)
inline

镜像对称(Y=0 平面)

将空间关于 XZ 平面取镜像对称。

变换: p'_y = |p_y|

参数
p原始采样点
返回
映射到上半空间的点
// 关于 Y=0 对称(上下对称)
double d = sphere(q - Point3D(0, 1.0, 0), 0.5); // 上下各一个球
Point3D op_mirror_y(const Point3D &p)
镜像对称(Y=0 平面)

在文件 sdf_operations.h299 行定义.

◆ op_mirror_z()

Point3D vde::sdf::op_mirror_z ( const Point3D &  p)
inline

镜像对称(Z=0 平面)

将空间关于 XY 平面取镜像对称。

变换: p'_z = |p_z|

参数
p原始采样点
返回
映射到前半空间的点

在文件 sdf_operations.h313 行定义.

◆ op_onion()

double vde::sdf::op_onion ( double  d,
double  thickness 
)
inline

洋葱皮/壳层修饰: 取绝对值后减去厚度

数学公式: f = |d| - thickness

将 SDF 的等值面变为一个厚度为 2·thickness 的壳层。 原始表面变成壳层的内外边界。

参数
dSDF 值
thickness壳层半厚度,必须 > 0
返回
壳层的 SDF 值
// 0.05 厚的球壳
double shell = op_onion(sphere(p, 1.0), 0.05);
BrepModel shell(const BrepModel &body, int face_id, double thickness)
抽壳(挖空实体)
double op_onion(double d, double thickness)
洋葱皮/壳层修饰: 取绝对值后减去厚度
参见
op_round 圆角偏移

在文件 sdf_operations.h223 行定义.

◆ op_repeat()

Point3D vde::sdf::op_repeat ( const Point3D &  p,
const Point3D &  cell 
)
inline

无限重复(周期复制)

将空间映射到以 cell 为周期的单位晶格中。 每个晶格是边长为 cell 的轴对齐长方体。

变换: p' = p - cell·round(p / cell)

配合任何 SDF 使用,可生成无限周期阵列。

参数
p原始采样点
cell晶格尺寸 (cx, cy, cz),各分量必须 > 0 才生效
返回
映射到中心晶格内的点
// 在空间中无限重复的球体阵列(间距 2)
Point3D q = op_repeat(p, Point3D(2, 2, 2));
double d = sphere(q, 0.5);
Point3D op_repeat(const Point3D &p, const Point3D &cell)
无限重复(周期复制)
注解
边界处 SDF 可能不连续,需要确保各晶格间映射是连续的。

在文件 sdf_operations.h251 行定义.

◆ op_rotate()

Point3D vde::sdf::op_rotate ( const Point3D &  p,
double  angle_rad 
)
inline

绕 Y 轴旋转(逆变换)

将采样点绕 Y 轴旋转 -angle_rad,使后续 SDF 表现出正向旋转效果。

变换矩阵:

p'_x = p_x·cos(θ) + p_z·sin(θ)
p'_y = p_y
p'_z = -p_x·sin(θ) + p_z·cos(θ)
参数
p原始采样点
angle_rad旋转角度(弧度),正值 = 逆时针(从上往下看)
返回
逆旋转后的采样点
// 将盒子绕 Y 轴旋转 45°
Point3D q = op_rotate(p, M_PI / 4);
double d = box(q, Point3D(1, 1, 1));
Point3D op_rotate(const Point3D &p, double angle_rad)
绕 Y 轴旋转(逆变换)
参见
op_twist 绕 Y 轴的扭曲变换
op_bend 弯曲变换

在文件 sdf_operations.h368 行定义.

◆ op_round()

double vde::sdf::op_round ( double  d,
double  r 
)
inline

圆角偏移: 将等值面向外扩展 r 单位

数学公式: f = d - r

相当于对隐式曲面做正向膨胀。配合其他运算可实现倒圆角效果。 例如 box SDF + op_round 即等价于 round_box。

参数
dSDF 值
r偏移距离(正值 = 膨胀,负值 = 收缩)
返回
偏移后的 SDF 值
// 给任意形状加 0.1 的圆角
double rounded = op_round(my_sdf(p), 0.1);
double op_round(double d, double r)
圆角偏移: 将等值面向外扩展 r 单位
参见
op_onion 壳层修饰
round_box 特例化的圆角立方体

在文件 sdf_operations.h200 行定义.

◆ op_scale()

Point3D vde::sdf::op_scale ( const Point3D &  p,
const Point3D &  s 
)
inline

非均匀缩放(逆变换)

将采样点各分量分别除以缩放因子。

变换: p'_i = p_i / s_i

参数
p原始采样点
s各轴缩放因子 (sx, sy, sz),均必须 ≠ 0
返回
缩放后的采样点
警告
非均匀缩放会破坏 SDF 的距离性质(梯度不再是单位长度)。 只有均匀缩放(sx=sy=sz)才能保持距离场精确性。
// 均匀缩小为一半
Point3D q = op_scale(p, Point3D(2, 2, 2));
double d = sphere(q, 1.0); // 实际半径变为 0.5
Point3D op_scale(const Point3D &p, const Point3D &s)
非均匀缩放(逆变换)
参见
op_translate 平移(等距变换)
op_rotate 旋转(等距变换)

在文件 sdf_operations.h397 行定义.

◆ op_smooth_difference()

double vde::sdf::op_smooth_difference ( double  d1,
double  d2,
double  k 
)
inline

平滑差集(带混合过渡)

与平滑并集类似,但应用于差集操作。

数学公式: h = clamp(0.5 - 0.5·(d2+d1)/k, 0, 1) f = d1·(1-h) + (-d2)·h + k·h·(1-h)

参数
d1被减对象 A 的 SDF 值
d2减去对象 B 的 SDF 值
k混合强度参数
返回
平滑混合后的 SDF 值
参见
op_difference 无平滑的标准差集
op_smooth_union 平滑并集

在文件 sdf_operations.h172 行定义.

◆ op_smooth_intersection()

double vde::sdf::op_smooth_intersection ( double  d1,
double  d2,
double  k 
)
inline

平滑交集(带混合过渡)

与平滑并集类似,但应用于交集操作。

数学公式: h = clamp(0.5 - 0.5·(d1-d2)/k, 0, 1) f = d1·(1-h) + d2·h + k·h·(1-h)

参数
d1第一个对象的 SDF 值
d2第二个对象的 SDF 值
k混合强度参数
返回
平滑混合后的 SDF 值
参见
op_intersection 无平滑的标准交集
op_smooth_union 平滑并集

在文件 sdf_operations.h149 行定义.

◆ op_smooth_union()

double vde::sdf::op_smooth_union ( double  d1,
double  d2,
double  k 
)
inline

平滑并集(带混合过渡)

通过多项式混合函数在两个对象接合处产生平滑圆角过渡。

数学公式: h = clamp(0.5 + 0.5·(d1-d2)/k, 0, 1) f = d1·(1-h) + d2·h - k·h·(1-h)

混合参数 k 控制过渡区域的宽度。k 越大,过渡越平滑但越偏离原始几何。

参数
d1第一个对象的 SDF 值
d2第二个对象的 SDF 值
k混合强度参数(> 0 时平滑过渡;≤ 0 时退化为普通并集)
返回
平滑混合后的 SDF 值
注解
多项式混合是函数 f(x)=x 在 [0,k] 区间的平滑近似。在 d1=d2 处,f 向下偏移 k/4。
警告
k 值过大(超过对象尺寸的 10)会严重改变几何形态。
// 两个球体平滑融合,过渡区宽度 0.3
double d = op_smooth_union(sphere(p, 1.0), sphere(p - Point3D(1.2,0,0), 1.0), 0.3);
double op_smooth_union(double d1, double d2, double k)
平滑并集(带混合过渡)
参见
op_union 无平滑的标准并集
op_smooth_intersection 平滑交集
op_smooth_difference 平滑差集

在文件 sdf_operations.h126 行定义.

◆ op_translate()

Point3D vde::sdf::op_translate ( const Point3D &  p,
const Point3D &  offset 
)
inline

空间平移(逆变换)

将采样点向反方向平移,使后续 SDF 求值表现出正向移动效果。

变换: p' = p - offset

例如 offset = (2, 0, 0) 会使 SDF 在空间中表现为向右移动 2 个单位。

参数
p原始采样点
offset平移量(对象正向移动的方向)
返回
逆平移后的采样点
// 球体向右平移 2 个单位
Point3D q = op_translate(p, Point3D(2, 0, 0));
double d = sphere(q, 1.0);
Point3D op_translate(const Point3D &p, const Point3D &offset)
空间平移(逆变换)
参见
op_rotate 旋转变换
op_scale 缩放变换

在文件 sdf_operations.h339 行定义.

◆ op_twist()

Point3D vde::sdf::op_twist ( const Point3D &  p,
double  amount 
)
inline

绕 Y 轴的扭曲变换

旋转角度随 Y 坐标线性变化: angle = amount · p_y。

变换:

p'_x = p_x·cos(amount·p_y) - p_z·sin(amount·p_y)
p'_y = p_y
p'_z = p_x·sin(amount·p_y) + p_z·cos(amount·p_y)
参数
p原始采样点
amount单位高度上的旋转量(弧度/单位长度)
返回
扭曲后的采样点
// 在上方 2 个单位处旋转 90 度的扭曲
Point3D q = op_twist(p, M_PI / 4);
double d = box(q, Point3D(0.5, 2, 0.5));
Point3D op_twist(const Point3D &p, double amount)
绕 Y 轴的扭曲变换
参见
op_rotate 恒定角度旋转
op_bend 弯曲变换

在文件 sdf_operations.h426 行定义.

◆ op_union()

double vde::sdf::op_union ( double  d1,
double  d2 
)
inline

布尔并集: A ∪ B

取两个距离值的最小值。在两个子对象的距离场中选择较近者。

数学公式: f = min(d1, d2)

最常见的 CSG 组合操作,用于合并两个几何体。

参数
d1第一个对象的 SDF 值
d2第二个对象的 SDF 值
返回
并集的 SDF 值
double d = op_union(sphere(p, 1.0), box(p, Point3D(0.5, 0.5, 0.5)));
double op_union(double d1, double d2)
布尔并集: A ∪ B
参见
op_smooth_union 带平滑过渡的并集
op_intersection 交集

在文件 sdf_operations.h48 行定义.

◆ penetration_depth()

double vde::sdf::penetration_depth ( const SdfNodePtr shape_a,
const SdfNodePtr shape_b,
const Point3D &  bmin,
const Point3D &  bmax,
int  samples = 1000 
)

估算两个形状之间的最小穿透距离

在包围盒内随机采样,找到两个 SDF 均 ≤ 0 的区域(重叠区), 计算重叠点到表面的最大距离。

参数
shape_a形状 A
shape_b形状 B
bmin公共包围盒最小角点
bmax公共包围盒最大角点
samples蒙地卡罗采样数(默认 1000)
返回
最大穿透深度(负值表示不重叠时的最小间距)
参见
resolve_collision 解决穿透

◆ plane()

double vde::sdf::plane ( const Point3D &  p,
const Vector3D &  normal,
double  offset 
)
inline

平面的 SDF

通过原点的平面,法向量为 normal,偏移量为 offset。

数学公式: f(p) = p·n - offset

其中 n 为单位法向量。f > 0 表示点在法向量指向的一侧。 偏移量沿法向量正方向移动平面。

参数
p采样点
normal单位法向量(必须已归一化)
offset沿法向量正方向的偏移量
返回
有符号距离
前置条件
normal.norm() ≈ 1.0(调用方负责归一化)
// 通过原点、法向量朝上的平面
double d = plane(p, Vector3D(0,1,0), 0.0);
// 向上偏移 2 个单位的平面
double d2 = plane(p, Vector3D(0,1,0), 2.0);
double plane(const Point3D &p, const Vector3D &normal, double offset)
平面的 SDF
参见
wedge 两个平面+盒子的组合(对角切割)

在文件 sdf_primitives.h261 行定义.

◆ plane_gradient_analytic()

Vector3D vde::sdf::plane_gradient_analytic ( const Vector3D &  normal)
inline

平面的解析梯度

公式: ∇f = normal

平面的梯度为常向量(法向量),与位置无关。

参数
normal单位法向量
返回
梯度(等于 normal)
注解
这是最简单的解析梯度,因为平面 SDF 是线性的。

在文件 sdf_gradient.h331 行定义.

◆ resolve_collision()

bool vde::sdf::resolve_collision ( SdfNodePtr shape_a,
SdfNodePtr shape_b,
double  step_size = 0.1,
int  max_iterations = 50 
)

通过平移解决两个形状之间的穿透

在穿透区域采样点,沿梯度方向平移形状以分离它们。 修改传入的形状(原地修改 translate_offset 参数)。

参数
shape_a形状 A(原地修改)
shape_b形状 B(原地修改)
step_size每次迭代的平移步长(默认 0.1)
max_iterations最大迭代次数(默认 50)
返回
true 如果碰撞被成功解决;false 如果在迭代次数内未能解决
auto sphere_a = SdfNode::sphere(1.0);
auto sphere_b = SdfNode::translate(SdfNode::sphere(1.0), Point3D(1.5, 0, 0));
bool resolved = resolve_collision(sphere_a, sphere_b, 0.1, 100);
static SdfNodePtr translate(SdfNodePtr child, const Point3D &offset)
创建平移节点
bool resolve_collision(SdfNodePtr &shape_a, SdfNodePtr &shape_b, double step_size=0.1, int max_iterations=50)
通过平移解决两个形状之间的穿透
参见
penetration_depth 估算穿透深度

◆ revolution()

double vde::sdf::revolution ( const Point3D &  ,
double  sdf_2d,
double   
)
inline

二维轮廓绕 Y 轴的旋转体 SDF

将二维 SDF 绕 Y 轴旋转,生成旋转体的三维 SDF。

使用模式: 二维 SDF 定义在 (r, y) 坐标中,其中 r 为水平距离 = √(pₓ² + p𝓏²) - offset。 用户需要在调用前将 (r, y) 转换为二维采样并计算 SDF 值。

参数
p三维采样点(接口保留,不直接使用)
sdf_2d预计算的二维 SDF(在 (√(pₓ²+p𝓏²)-offset, p.y) 处求值)
offset径向偏移量(从 Y 轴的起点距离)
返回
有符号距离
// 在距 Y 轴 2.0 处、截面半径 0.5 的圆环
double r = std::sqrt(p.x()*p.x() + p.z()*p.z()) - 2.0;
double sdf_2d = std::sqrt(r*r + p.y()*p.y()) - 0.5;
double d3d = revolution(p, sdf_2d, 2.0);
double revolution(const Point3D &, double sdf_2d, double)
二维轮廓绕 Y 轴的旋转体 SDF
参见
torus 圆环(revolution 的特例:截面为圆)

在文件 sdf_primitives.h479 行定义.

◆ round_box()

double vde::sdf::round_box ( const Point3D &  p,
const Point3D &  half_extents,
double  r 
)
inline

圆角立方体的 SDF

box() 使用相同的核心算法,但在最后减去圆角半径 r。 相当于先对 box SDF 做膨胀(offset),再缩回,等价于对边角做半径为 r 的倒圆处理。

数学公式: f(p) = box(p, half_extents) - r

参数
p采样点
half_extents半边长 (hx, hy, hz)
r圆角半径,必须 < min(half_extents) 否则整体形态改变
返回
有符号距离
警告
当 r 超过某轴半边长时,该维度的边会被完全圆化,表面不再平坦。 实际应用中限制 r ≤ 0.5 * min(hx, hy, hz) 可保证形态可控。
// 带 0.2 圆角的 2×2×2 立方体
double d = round_box(p, Point3D(1, 1, 1), 0.2);
double round_box(const Point3D &p, const Point3D &half_extents, double r)
圆角立方体的 SDF
参见
box 无圆角的长方体
op_round 对任意 SDF 做圆角偏移

在文件 sdf_primitives.h126 行定义.

◆ sdf_to_mesh()

mesh::MCMesh vde::sdf::sdf_to_mesh ( const SdfNodePtr root,
int  resolution = 64,
double  iso_level = 0.0 
)

将 SDF 表达式树转换为三角网格

使用 Marching Cubes 算法在 SDF 树的包围盒内采样并生成网格。 包围盒由 estimate_bbox() 自动确定。

算法步骤:

  1. 调用 estimate_bbox(root) 确定采样范围
  2. 构建分辨率 resolution³ 体素网格
  3. 在每个体素角点求值 SDF
  4. 用 Marching Cubes 提取 iso_level 等值面
参数
rootSDF 表达式树的根节点
resolution每轴的网格分辨率(例如 64 表示 64³ 体素网格)
iso_level等值面水平(0.0 = 隐式表面)
返回
包含顶点和三角形索引的 MCMesh
注解
分辨率推荐为 2 的幂(32, 64, 128, 256)以获得最佳缓存性能。
对于大尺寸但细节少的几何体,使用较低的 resolution 即可获得光滑结果。
auto root = SdfNode::sphere(2.0);
auto mesh = sdf_to_mesh(root, 128); // 128³ 体素网格
// mesh.vertices 和 mesh.indices 可直接用于渲染或导出
mesh::MCMesh sdf_to_mesh(const SdfNodePtr &root, int resolution=64, double iso_level=0.0)
将 SDF 表达式树转换为三角网格
参见
sdf_to_mesh_lambda Lambda 版本的 SDF 转网格(Python 友好)
estimate_bbox 包围盒估算

◆ sdf_to_mesh_lambda()

mesh::MCMesh vde::sdf::sdf_to_mesh_lambda ( const std::function< double(double, double, double)> &  f,
const Point3D &  bmin,
const Point3D &  bmax,
int  resolution = 64,
double  iso_level = 0.0 
)

将 Lambda SDF 函数转换为三角网格

接受 C++ lambda 或 std::function 作为 SDF 定义,适合 Python 绑定场景。 与 sdf_to_mesh() 不同,本函数需要调用方显式提供包围盒。

参数
fSDF 函数,签名为 double(double x, double y, double z) → 有符号距离
bmin采样包围盒最小角点
bmax采样包围盒最大角点
resolution每轴分辨率
iso_level等值面水平(默认 0.0)
返回
MCMesh 三角网格
// 球体 lambda
auto sphere_lambda = [](double x, double y, double z) {
return std::sqrt(x*x + y*y + z*z) - 1.0;
};
auto mesh = sdf_to_mesh_lambda(sphere_lambda,
Point3D(-1.5, -1.5, -1.5), Point3D(1.5, 1.5, 1.5), 64);
mesh::MCMesh sdf_to_mesh_lambda(const std::function< double(double, double, double)> &f, const Point3D &bmin, const Point3D &bmax, int resolution=64, double iso_level=0.0)
将 Lambda SDF 函数转换为三角网格
参见
sdf_to_mesh 基于 SDF 树的网格转换

◆ sphere()

double vde::sdf::sphere ( const Point3D &  p,
double  radius 
)
inline

球体的 SDF

计算三维空间中一点到球面的有符号距离。

数学公式: f(p) = |p| - r

f < 0: 点在球内
f = 0: 点在球面上
f > 0: 点在球外

|∇f| = 1 在球外和球面上严格成立,球内在原点处退化(梯度为零)。

参数
p采样点(三维坐标)
radius球半径,必须 > 0
返回
有符号距离
注解
球位于原点。如需其他位置,使用 op_translate 对采样点做反向平移。
double d = sphere(Point3D(1.0, 0.0, 0.0), 0.5); // d = 0.5 (外部)
double inside = sphere(Point3D(0.0, 0.0, 0.0), 1.0); // d = -1.0 (球心)
参见
ellipsoid 各轴半径不同的椭球
cylinder 沿 Y 轴的圆柱

在文件 sdf_primitives.h68 行定义.

被这些函数引用 sphere_radius_gradient().

◆ sphere_gradient_analytic()

Vector3D vde::sdf::sphere_gradient_analytic ( const Point3D &  p,
double   
)
inline

球体 SDF 的解析梯度

公式: ∇f = p / |p|

即从球心指向采样点的单位径向向量。 注意:球心处 p = (0,0,0),梯度退化,返回零向量。

参数
p采样点
radius球半径(当前未使用,保留以保持接口一致)
返回
解析梯度(单位向量)
注解
在表面上 (|p| = radius),梯度即为外法向量。

在文件 sdf_gradient.h223 行定义.

◆ sphere_param_grad()

ParamGrad vde::sdf::sphere_param_grad ( const Point3D &  p,
double  radius,
double  h = 1e-6 
)
inline

球体所有参数的梯度(当前仅 radius 有意义)

参数
p采样点
radius球体半径
h差分步长
返回
参数梯度(仅 d_radius 非零)
参见
sphere_radius_gradient 底层数值差分

在文件 sdf_gradient.h642 行定义.

引用了 vde::sdf::ParamGrad::d_radius , 以及 sphere_radius_gradient().

◆ sphere_radius_gradient()

double vde::sdf::sphere_radius_gradient ( const Point3D &  p,
double  radius,
double  h = 1e-6 
)
inline

球体 SDF 对半径的参数梯度 ∂f/∂r

用中心差分计算: (sphere(p, r+h) - sphere(p, r-h)) / (2h)

参数
p采样点
radius球体半径
h差分步长(默认 1e-6)
返回
∂f/∂radius
注解
对于球体,解析梯度为 -1(球面上),但此函数提供与实现无关的数值验证。
参见
sphere_param_grad 封装版本

在文件 sdf_gradient.h127 行定义.

引用了 sphere().

被这些函数引用 sphere_param_grad().

◆ symmetry_score()

double vde::sdf::symmetry_score ( const SdfNodePtr shape,
const Point3D &  bmin,
const Point3D &  bmax,
const Vector3D &  plane_normal,
double  plane_offset = 0.0,
int  samples = 1000 
)

检测形状在给定方向上的反射对称性

在形状的包围盒内随机采样点对 (p, p') 其中 p' 是关于给定平面的反射。 比较两点的 SDF 值以评估对称程度。

参数
shapeSDF 形状
bmin包围盒最小角点
bmax包围盒最大角点
plane_normal反射平面的法向量
plane_offset反射平面的偏移量(沿法向量方向,默认 0)
samples采样点对数(默认 1000)
返回
对称性分数 [0, 1](0 = 完全不对称,1 = 完美对称)
参见
find_symmetry_plane 自动寻找最佳对称平面

◆ torus()

double vde::sdf::torus ( const Point3D &  p,
double  major_radius,
double  minor_radius 
)
inline

圆环面的 SDF

圆环位于 XZ 平面内,绕 Y 轴对称。

数学公式:

  1. 计算环向半径: q = √(pₓ² + p𝓏²) - R_major
  2. 管向距离: f = √(q² + p_y²) - R_minor

R_major = 环心到管心的距离(主半径) R_minor = 管的截面半径(副半径)

参数
p采样点
major_radius主半径(环的半径),必须 > 0
minor_radius副半径(管的粗细),必须 > 0
返回
有符号距离
警告
当 major_radius ≤ minor_radius 时,环孔消失形成苹果状(self-intersecting torus)。
// 主半径 2.0、管半径 0.5 的圆环
double d = torus(Point3D(2.0, 0.0, 0.0), 2.0, 0.5); // d ≈ 0.0(表面上)
double torus(const Point3D &p, double major_radius, double minor_radius)
圆环面的 SDF
参见
link 双环连接体(两个并行圆环的组合)

在文件 sdf_primitives.h159 行定义.

被这些函数引用 torus_major_gradient() , 以及 torus_minor_gradient().

◆ torus_gradient_analytic()

Vector3D vde::sdf::torus_gradient_analytic ( const Point3D &  p,
double  major_r,
double  minor_r 
)
inline

圆环 SDF 的解析梯度

SDF: f = √((√(pₓ²+p𝓏²) - R_major)² + p_y²) - R_minor

梯度通过链式法则推导,将环向距离和 Y 方向分别求导。

特殊情况: 在 Y 轴上 (pₓ=p𝓏=0),x 和 z 梯度分量退化为 0。

参数
p采样点
major_r主半径
minor_r副半径
返回
解析梯度

在文件 sdf_gradient.h280 行定义.

◆ torus_major_gradient()

double vde::sdf::torus_major_gradient ( const Point3D &  p,
double  major_r,
double  minor_r,
double  h = 1e-6 
)
inline

圆环 SDF 对主半径的参数梯度 ∂f/∂major_r

参数
p采样点
major_r主半径
minor_r副半径
h差分步长
返回
参数梯度

在文件 sdf_gradient.h162 行定义.

引用了 torus().

◆ torus_minor_gradient()

double vde::sdf::torus_minor_gradient ( const Point3D &  p,
double  major_r,
double  minor_r,
double  h = 1e-6 
)
inline

圆环 SDF 对副半径的参数梯度 ∂f/∂minor_r

返回
参数梯度

在文件 sdf_gradient.h173 行定义.

引用了 torus().

◆ triangular_prism()

double vde::sdf::triangular_prism ( const Point3D &  p,
const Point3D &  a,
const Point3D &  b,
const Point3D &  c,
double  height 
)

三角棱柱的 SDF(非内联实现)

以 XY 平面中任意三角形为截面、沿 Z 轴 ±height/2 挤出的棱柱。

参数
p采样点
a三角形顶点 A(XY 平面内)
b三角形顶点 B(XY 平面内)
c三角形顶点 C(XY 平面内)
height挤出总高度(沿 Z 轴),必须 > 0
返回
有符号距离
前置条件
a, b, c 三点不共线(构成有效三角形)
// 顶点为 (0,0), (2,0), (0,2)、高度 1.0 的三棱柱
double d = triangular_prism(p, Point3D(0,0,0), Point3D(2,0,0), Point3D(0,2,0), 1.0);
double triangular_prism(const Point3D &p, const Point3D &a, const Point3D &b, const Point3D &c, double height)
三角棱柱的 SDF(非内联实现)
参见
wedge 直角三角形楔形体

◆ wedge()

double vde::sdf::wedge ( const Point3D &  p,
double  w,
double  h,
double  d 
)
inline

楔形体的 SDF

立方体沿 XZ 平面对角线切割的一半。切割面为 z = x。 楔形体占据盒子内 z ≥ x 的区域。

几何形状:

  • 盒子: [-w/2, w/2] × [-h/2, h/2] × [-d/2, d/2]
  • 保留区域: 盒子内 z ≥ x 的半空间
参数
p采样点
w宽度(X 方向)
h高度(Y 方向)
d深度(Z 方向)
返回
有符号距离
// 2×2×2 的楔形体(保留 z ≥ x 的一半)
double d = wedge(Point3D(-0.5, 0.0, 0.5), 2.0, 2.0, 2.0);
double wedge(const Point3D &p, double w, double h, double d)
楔形体的 SDF
参见
box 完整立方体
plane 独立平面 SDF

在文件 sdf_primitives.h393 行定义.