Files

150 lines
5.9 KiB
C++
Raw Permalink Normal View History

#pragma once
/**
* @file iga_prep.h
* @brief 等几何分析(IGA)准备 — NURBS→IGA 转换、节点插入、升阶、Bézier 提取
*
* IGAIsogeometric Analysis)使用与 CAD 相同的 NURBS 基函数进行仿真,
* 无需网格转换。本模块提供分析前处理工具。
*
* ## 功能
* - nurbs_to_iga: NURBS 曲面 → IGA 分析就绪数据(提取单元、连接矩阵)
* - knot_insertion: 节点细化(h-细化)
* - degree_elevation: 升阶(p-细化)
* - bezier_extraction: Bézier 提取算子(将 NURBS 基映射到 Bernstein 基)
*
* @ingroup curves
*/
#include "vde/curves/nurbs_surface.h"
#include "vde/core/point.h"
#include <vector>
#include <array>
#include <utility>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
// ═══════════════════════════════════════════════════════════
// IGA 数据结构
// ═══════════════════════════════════════════════════════════
/// IGA 分析单元(Bézier 单元)
struct IGAElement {
int id; ///< 单元 ID
std::array<int,2> span_u; ///< u 向节点区间 [i, i+1]
std::array<int,2> span_v; ///< v 向节点区间 [j, j+1]
int degree_u; ///< 单元 u 向阶次
int degree_v; ///< 单元 v 向阶次
std::vector<int> cp_indices; ///< 该单元的控制点索引(全局)
std::vector<std::vector<double>> extraction; ///< Bézier 提取算子 (ncp × nbernstein)
bool is_degenerate; ///< 是否为退化单元
};
/// IGA 分析网格(每片 NURBS 曲面的分析就绪数据)
struct IGAMesh {
NurbsSurface surface; ///< 源曲面(可能已细化/升阶)
std::vector<IGAElement> elements; ///< 单元列表
std::vector<int> knots_u; ///< 唯一点节点 u 向量
std::vector<int> knots_v; ///< 唯一点节点 v 向量
int degree_u; ///< u 向阶次
int degree_v; ///< v 向阶次
int num_cp_u; ///< u 向控制点数
int num_cp_v; ///< v 向控制点数
int num_elements; ///< 单元总数
};
/// 节点插入结果
struct KnotInsertionResult {
NurbsSurface surface; ///< 细化后的曲面
std::vector<double> new_knots_u; ///< 插入的 u 节点
std::vector<double> new_knots_v; ///< 插入的 v 节点
int old_cp_count; ///< 原控制点数
int new_cp_count; ///< 新控制点数
};
/// 升阶结果
struct DegreeElevationResult {
NurbsSurface surface; ///< 升阶后的曲面
int old_degree_u; ///< 原 u 阶次
int old_degree_v; ///< 原 v 阶次
int new_degree_u; ///< 新 u 阶次
int new_degree_v; ///< 新 v 阶次
int old_cp_count; ///< 原控制点数
int new_cp_count; ///< 新控制点数
};
/// Bézier 提取结果
struct BezierExtractionResult {
std::vector<std::vector<std::vector<double>>> operators; ///< 每个单元的 Bézier 提取算子
std::vector<Point3D> cp_coords; ///< 控制点坐标(原始顺序)
int degree_u; ///< u 向阶次
int degree_v; ///< v 向阶次
int num_elements; ///< 单元数
};
// ═══════════════════════════════════════════════════════════
// 核心函数
// ═══════════════════════════════════════════════════════════
/**
* @brief NURBS 曲面 → IGA 分析准备
*
* 从 NURBS 曲面提取 IGA 分析网格:分割为 Bézier 单元、生成连接信息。
*
* @param surface NURBS 曲面
* @return IGAMesh 包含单元分解和分析元数据
*
* @ingroup curves
*/
IGAMesh nurbs_to_iga(const NurbsSurface& surface);
/**
* @brief 节点插入(h-细化)
*
* 在 NURBS 曲面中插入新的节点,增加控制点数而不改变几何形状。
*
* @param surface NURBS 曲面
* @param knots_u u 方向要插入的新节点列表
* @param knots_v v 方向要插入的新节点列表
* @return KnotInsertionResult 包含细化后的曲面与统计信息
*
* @ingroup curves
*/
KnotInsertionResult knot_insertion(const NurbsSurface& surface,
const std::vector<double>& knots_u,
const std::vector<double>& knots_v);
/**
* @brief 升阶(p-细化)
*
* 提升 NURBS 曲面的阶次(u 和 v 分别提升 du, dv),
* 保持几何形状不变(近似)。
*
* @param surface NURBS 曲面
* @param du u 方向提升阶数(≥ 0)
* @param dv v 方向提升阶数(≥ 0)
* @return DegreeElevationResult 包含升阶后的曲面与统计信息
*
* @ingroup curves
*/
DegreeElevationResult degree_elevation(const NurbsSurface& surface,
int du = 1, int dv = 1);
/**
* @brief Bézier 提取算子
*
* 对每个非零节点区间计算 Bézier 提取矩阵 C,
* 将 NURBS 基函数表示为 Bernstein 多项式的线性组合:
* N(u) = C · B(u)
* 其中 B(u) 是 Bernstein 基,N(u) 是 NURBS 基。
*
* @param surface NURBS 曲面
* @return BezierExtractionResult
*
* @ingroup curves
*/
BezierExtractionResult bezier_extraction(const NurbsSurface& surface);
} // namespace vde::curves