11b606bd39
v6.0.1 — FFD Freeform Deformation: - ffd_deformation.h/.cpp: Bezier volume lattice, deform_brep/deform_mesh - Bernstein polynomial mapping, topology-preserving - Cage-based + lattice-based FFD, create_cage_lattice() v6.0.2 — Auto-Dimensioning + PMI/MBD + GD&T: - auto_dimensioning.h/.cpp: linear/angular/radial/diameter detection - ISO/ANSI/JIS drawing standards, smart label placement - gdt.h/.cpp: 14 GD&T symbols (ASME Y14.5), MMC/LMC/RFS material conditions - pmi_mbd.h/.cpp: PMIAnnotation, attach_pmi, PMIView, STEP AP242 export - 70/70 tests passing (23 auto-dim + 25 PMI + 22 GD&T regression) v6.0.3 — Web 3D Viewer Enhancement: - viewer/index.html + app.js: Three.js GLB/STL loading - OrbitControls, face coloring, dimension overlay, GD&T display - Measure tool (raycaster), clip plane slider, explode animation - Drag-and-drop file upload, responsive layout
201 lines
7.2 KiB
C++
201 lines
7.2 KiB
C++
#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
|