Files
ViewDesignEngine/include/vde/brep/ffd_deformation.h
T

201 lines
7.2 KiB
C++
Raw Normal View History

#pragma once
/**
* @file ffd_deformation.h
* @brief Freeform Deformation (FFD) — 自由变形
*
* FFD 是一种基于控制格 (lattice) 的体积变形技术,可以将任意
* B-Rep 实体或网格进行拉伸、压缩、扭转等自由变形,保持拓扑不变。
*
* ## 核心概念
*
* - **FFD Lattice**: nx×ny×nz 的 Bézier 体积控制点网格。
* - **参数空间映射**: 将世界坐标点映射到 lattice 的 (s,t,u) 参数空间。
* - **Bernstein 多项式**: 用 Bernstein 基函数计算变形后的位置。
*
* ## FFD 类型
*
* | 类型 | 描述 |
* |--------------|----------------------------------------|
* | Lattice-based | 规则矩形网格,参数空间 [0,1]³ |
* | Cage-based | 任意包围多面体,自动生成 lattice 控制点 |
*
* ## 使用示例
*
* @code{.cpp}
* auto box = make_box(10, 5, 3);
* auto bbox = box.bounds();
* auto lattice = create_lattice(bbox, 3, 3, 3); // 3×3×3 控制点
*
* // 拉伸:移动顶面控制点
* std::vector<Vector3D> displacements(27);
* for (int i = 0; i < 3; ++i)
* for (int j = 0; j < 3; ++j)
* displacements[i*9 + j*3 + 2] = Vector3D(0, 0, 3.0); // z方向位移
*
* auto deformed = deform_brep(box, lattice, displacements);
* @endcode
*
* @ingroup brep
*/
#include "vde/core/point.h"
#include "vde/core/aabb.h"
#include "vde/brep/brep.h"
#include "vde/mesh/halfedge_mesh.h"
#include <vector>
namespace vde::brep {
using core::Point3D;
using core::Vector3D;
using core::AABB3D;
// ═══════════════════════════════════════════════
// FFD Lattice
// ═══════════════════════════════════════════════
/**
* @brief FFD 控制格结构
*
* 一个 nx×ny×nz 的 Bézier 体积控制点网格。
* 控制点存储在 control_points 中,按 k-major、j-major、i-minor 排列:
* index = (k * ny + j) * nx + i
*
* bbox 定义了 lattice 在世界空间中的边界,用于世界坐标 → 参数空间的映射。
*/
struct FFDLattice {
int nx = 0; ///< X 方向控制点数
int ny = 0; ///< Y 方向控制点数
int nz = 0; ///< Z 方向控制点数
std::vector<Point3D> control_points; ///< 控制点坐标 [nx*ny*nz]
AABB3D bbox; ///< 世界空间包围盒
/**
* @brief 总控制点数
*/
[[nodiscard]] size_t num_points() const { return control_points.size(); }
/**
* @brief 获取控制点
* @param i X 索引 (0..nx-1)
* @param j Y 索引 (0..ny-1)
* @param k Z 索引 (0..nz-1)
*/
[[nodiscard]] const Point3D& control_point(int i, int j, int k) const {
return control_points[(k * ny + j) * nx + i];
}
/** @brief 检查 lattice 是否有效 */
[[nodiscard]] bool is_valid() const {
return nx >= 2 && ny >= 2 && nz >= 2 &&
control_points.size() == static_cast<size_t>(nx * ny * nz);
}
};
/**
* @brief 创建规则格子 lattice
*
* 在给定包围盒内生成 nx×ny×nz 均匀分布的控制点网格。
*
* @param bbox 世界空间包围盒
* @param nx X 方向控制点数(≥ 2)
* @param ny Y 方向控制点数(≥ 2)
* @param nz Z 方向控制点数(≥ 2)
* @return FFDLattice 均匀控制格
*/
[[nodiscard]] FFDLattice create_lattice(const AABB3D& bbox, int nx, int ny, int nz);
/**
* @brief 从包围多面体生成 lattice (Cage-based FFD)
*
* 从一组顶点(包围多面体/cage 的顶点)计算包围盒,
* 生成 resolution 大小的均匀控制格。
*
* @param cage_vertices 包围多面体的顶点坐标
* @param nx X 方向分辨率(≥ 2
* @param ny Y 方向分辨率(≥ 2
* @param nz Z 方向分辨率(≥ 2
* @return FFDLattice 包围多面体的控制格
*/
[[nodiscard]] FFDLattice create_cage_lattice(const std::vector<Point3D>& cage_vertices,
int nx, int ny, int nz);
// ═══════════════════════════════════════════════
// Deformation API
// ═══════════════════════════════════════════════
/**
* @brief 对 B-Rep 实体进行 FFD 变形
*
* 将 B-Rep 的所有顶点映射到 lattice 参数空间,使用 Bernstein 多项式
* 计算变形后的位置。拓扑结构和面/边/壳关系保持不变。
*
* 算法:
* 1. 复制 BrepModel(保留拓扑结构)
* 2. 对每个顶点:
* a. 映射世界坐标到 lattice 参数空间 (s,t,u) ∈ [0,1]³
* b. 用 Bernstein 基函数求值,计算变形位移
* c. 应用位移到顶点位置
* 3. 返回变形后的 BrepModel
*
* @param body 输入 B-Rep 实体
* @param lattice FFD 控制格
* @param displacements 每个控制点的位移向量 [nx*ny*nz]
* @return 变形后的 B-Rep 实体(拓扑不变)
*
* @pre displacements.size() == lattice.num_points()
* @pre lattice.is_valid()
*/
[[nodiscard]] BrepModel deform_brep(const BrepModel& body,
const FFDLattice& lattice,
const std::vector<Vector3D>& displacements);
/**
* @brief 对三角网格进行 FFD 变形
*
* 将网格的所有顶点映射到 lattice 参数空间,用 Bernstein 多项式
* 计算变形后的新位置。
*
* @param mesh 输入三角网格
* @param lattice FFD 控制格
* @param displacements 每个控制点的位移向量 [nx*ny*nz]
* @return 变形后的网格(拓扑不变)
*
* @pre displacements.size() == lattice.num_points()
* @pre lattice.is_valid()
*/
[[nodiscard]] mesh::HalfedgeMesh deform_mesh(const mesh::HalfedgeMesh& mesh,
const FFDLattice& lattice,
const std::vector<Vector3D>& displacements);
// ═══════════════════════════════════════════════
// Internal: Bernstein evaluation
// ═══════════════════════════════════════════════
/**
* @brief Bernstein 基函数 B_{i,n}(t)
*
* B_{i,n}(t) = C(n,i) * t^i * (1-t)^{n-i}
*
* @param i 基函数索引 (0..n)
* @param n 多项式阶数
* @param t 参数值 ∈ [0,1]
* @return 基函数值
*/
[[nodiscard]] double bernstein(int i, int n, double t);
/**
* @brief 用 FFD lattice 对单个点进行变形计算
*
* 将世界坐标点映射到 lattice 参数空间,计算变形位移并应用。
*
* @param point 输入世界坐标点
* @param lattice FFD 控制格
* @param displacements 控制点位移向量
* @return 变形后的点坐标
*/
[[nodiscard]] Point3D deform_point(const Point3D& point,
const FFDLattice& lattice,
const std::vector<Vector3D>& displacements);
} // namespace vde::brep