Files
ViewDesignEngine/include/vde/curves/generative_surfaces.h
T

136 lines
4.6 KiB
C++
Raw Normal View History

#pragma once
#include "vde/core/point.h"
#include "vde/curves/nurbs_surface.h"
#include "vde/curves/nurbs_curve.h"
#include <vector>
#include <optional>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
// ============================================================================
// Sweep — 扫描曲面
// ============================================================================
/**
* @brief 扫描类型枚举
*/
enum class SweepType : int {
Explicit = 0, ///< 显式扫描:profile 沿 path 平移+旋转(Frenet 标架),无扭转控制
Spine = 1, ///< 脊线扫描:用脊线控制扭转,修正 Frenet 标架
TwoGuides = 2 ///< 双引导线扫描:两条引导线控制 profile 沿路径的缩放
};
/**
* @brief 扫描选项
*
* 控制扫描行为:类型,以及引导线(用于 Spine / TwoGuides)。
* 对于 Explicitguide1/guide2/spine 均忽略;对于 Spine,需提供 spine;对于 TwoGuides,需提供 guide1 和 guide2。
*/
struct SweepOption {
SweepType type = SweepType::Explicit;
/// 脊线(用于 Spine 模式),控制扭转分布
std::optional<NurbsCurve> spine;
/// 第一引导线(用于 TwoGuides 模式)
std::optional<NurbsCurve> guide1;
/// 第二引导线(用于 TwoGuides 模式)
std::optional<NurbsCurve> guide2;
/// 沿路径的采样点数(默认 32)。越大越精确但曲面越重。
int samples = 32;
};
/**
* @brief 扫描曲面
*
* 将 profile 曲线沿 path 曲线扫描,生成 NURBS 曲面。
*
* @param profile 截面曲线(NURBS
* @param path 路径曲线(NURBS
* @param option 扫描选项(类型、引导线、采样数)
* @return 扫描 NURBS 曲面
*
* 三种模式:
* - ExplicitFrenet 标架沿路径对齐,profile 仅平移+旋转
* - Spine:使用独立脊线控制法向,消除 Frenet 标架在曲率零点处的翻转
* - TwoGuidesguide1 和 guide2 与 profile 两端对齐,线性缩放 profile 沿路径变化
*
* @ingroup curves
*/
[[nodiscard]] NurbsSurface sweep_surface(
const NurbsCurve& profile,
const NurbsCurve& path,
const SweepOption& option = {});
// ============================================================================
// Loft — 放样曲面
// ============================================================================
/**
* @brief 放样约束
*
* 控制首尾截面处的切线方向。
*/
struct LoftConstraint {
/// 起始截面切线方向(nullable)。曲面在 v=0 处的 ∂S/∂v 方向。
std::optional<Vector3D> start_tangent;
/// 终止截面切线方向(nullable)。曲面在 v=1 处的 ∂S/∂v 方向。
std::optional<Vector3D> end_tangent;
};
/**
* @brief 放样曲面
*
* 将 N 条截面曲线插值成一张光滑曲面(B 样条插值,v 向)。
*
* @param sections 截面曲线列表(至少 2 条)
* @param guides 引导线(可选)。每条引导线约束一个截面位置的分布;为空则截面均匀分布。
* @param constraints 切线约束(可选)。控制首尾截面处的曲面切线方向。
* @return 放样 NURBS 曲面
*
* 算法步骤:
* 1. 升阶+节点精化使所有截面控制点数一致
* 2. v 向 B 样条插值:每个 u 向控制点列沿 v 向插值
* 3. 若提供引导线,将截面沿引导线方向映射分布
* 4. 若提供切线约束,添加首尾导数条件
*
* @ingroup curves
*/
[[nodiscard]] NurbsSurface loft_surface(
const std::vector<NurbsCurve>& sections,
const std::vector<NurbsCurve>& guides = {},
const LoftConstraint& constraints = {});
// ============================================================================
// Net — 网格曲面
// ============================================================================
/**
* @brief 网格曲面(双向曲线网格 → 张量积 NURBS)
*
* 由 u 向和 v 向两组 NURBS 曲线构成网格曲面。
* 自动对齐交叉点、构建兼容的节点向量,生成张量积 NURBS 表示。
*
* @param u_curves u 向曲线组(≥ 2 条)
* @param v_curves v 向曲线组(≥ 2 条),允许与 u_curves 数量不等
* @return 网格 NURBS 曲面
*
* 算法步骤:
* 1. 计算所有 (u-curve, v-curve) 交叉点参数 (u_i, v_j)
* 2. 按平均参数对齐 u/v 向节点向量
* 3. 构建兼容控制点网格(每个交叉点为控制点)
* 4. 输出张量积 NURBS 曲面
*
* @ingroup curves
*/
[[nodiscard]] NurbsSurface net_surface(
const std::vector<NurbsCurve>& u_curves,
const std::vector<NurbsCurve>& v_curves);
} // namespace vde::curves