Files
ViewDesignEngine/include/vde/curves/nurbs_surface.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

163 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/core/point.h"
#include "vde/curves/bspline_curve.h"
#include "vde/curves/nurbs_curve.h"
#include <vector>
#include <array>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
/**
* @brief NURBS 张量积曲面
*
* 由 (nu+1)×(nv+1) 控制点网格、权重网格、u/v 节点向量及阶次定义。
* 求值公式:
* S(u,v) = Σ_i Σ_j N_{i,pu}(u)·N_{j,pv}(v)·w_{ij}·P_{ij}
* / Σ_i Σ_j N_{i,pu}(u)·N_{j,pv}(v)·w_{ij}
*
* 可精确表示球面、圆柱面、锥面等二次曲面。广泛应用于 CAD 数据交换。
*
* @ingroup curves
*/
class NurbsSurface {
public:
/**
* @brief 构造 NURBS 曲面
* @param control_grid 控制点网格
* @param knots_u u 向节点向量
* @param knots_v v 向节点向量
* @param weights 权重网格,维度与 control_grid 一致,所有值 > 0
* @param degree_u u 向阶次
* @param degree_v v 向阶次
* @code{.cpp}
* NurbsSurface sphere(grid, u_knots, v_knots, weights, 3, 3);
* @endcode
*/
NurbsSurface(std::vector<std::vector<Point3D>> control_grid,
std::vector<double> knots_u, std::vector<double> knots_v,
std::vector<std::vector<double>> weights,
int degree_u, int degree_v);
/**
* @brief 求曲面点 S(u,v)
* @param u u 参数
* @param v v 参数
* @return 曲面上对应 (u,v) 的 3D 点
*/
[[nodiscard]] Point3D evaluate(double u, double v) const;
/**
* @brief u 向偏导数
* @param u u 参数
* @param v v 参数
* @return ∂S/∂u
*/
[[nodiscard]] Vector3D derivative_u(double u, double v) const;
/**
* @brief v 向偏导数
* @param u u 参数
* @param v v 参数
* @return ∂S/∂v
*/
[[nodiscard]] Vector3D derivative_v(double u, double v) const;
/**
* @brief 单位法向量
* @param u u 参数
* @param v v 参数
* @return N(u,v) = normalize(∂S/∂u × ∂S/∂v)
*/
[[nodiscard]] Vector3D normal(double u, double v) const;
/**
* @brief u 向阶次
* @return pu
*/
[[nodiscard]] int degree_u() const { return degree_u_; }
/**
* @brief v 向阶次
* @return pv
*/
[[nodiscard]] int degree_v() const { return degree_v_; }
/**
* @brief 控制点数量
* @return {nu+1, nv+1},即网格的行数和列数
*/
[[nodiscard]] std::array<int, 2> num_control_points() const {
return {static_cast<int>(cp_.size()), static_cast<int>(cp_.empty()?0:cp_[0].size())};
}
/**
* @brief u 向节点向量
* @return 只读引用
*/
[[nodiscard]] const std::vector<double>& knots_u() const { return knots_u_; }
/**
* @brief v 向节点向量
* @return 只读引用
*/
[[nodiscard]] const std::vector<double>& knots_v() const { return knots_v_; }
/**
* @brief 控制点网格访问
* @return 只读引用
*/
[[nodiscard]] const std::vector<std::vector<Point3D>>& control_points() const { return cp_; }
/**
* @brief 权重网格访问
* @return 只读引用
*/
[[nodiscard]] const std::vector<std::vector<double>>& weights() const { return weights_; }
/**
* @brief 由两条 NURBS 曲线创建直纹面
* @param c1 起始曲线(v=0 边界)
* @param c2 终止曲线(v=1 边界)
* @return 直纹 NURBS 曲面
* @note 两条曲线需具有兼容的阶次和节点结构(内部做升阶和节点精化对齐)
* @see blend_surfaces ruled_surface
*/
static NurbsSurface ruled(const NurbsCurve& c1, const NurbsCurve& c2);
/**
* @brief 由截面曲线旋转生成旋转曲面
* @param profile 截面 NURBS 曲线
* @param axis_origin 旋转轴上一点
* @param axis_dir 旋转轴方向
* @param angle_rad 旋转角度(弧度),≤ 2π
* @return 旋转 NURBS 曲面
* @note 使用 NURBS 表示圆弧的权重方案;完整旋转生成闭曲面
* @code{.cpp}
* auto rev = NurbsSurface::revolve(profile, origin, {0,0,1}, M_PI);
* @endcode
*/
static NurbsSurface revolve(const NurbsCurve& profile, const Point3D& axis_origin,
const Vector3D& axis_dir, double angle_rad);
/**
* @brief 将 NURBS 曲面三角化
* @param res_u u 方向采样分辨率
* @param res_v v 方向采样分辨率
* @return {顶点数组, 三角形索引数组},每个三角形为 {i0,i1,i2}
* @note 生成 res_u×res_v 均匀网格,每个单元格拆为两个三角形
* @see tessellate
*/
[[nodiscard]] std::pair<std::vector<Point3D>, std::vector<std::array<int,3>>>
tessellate(int res_u, int res_v) const;
private:
std::vector<std::vector<Point3D>> cp_; ///< 控制点网格
std::vector<double> knots_u_, knots_v_; ///< u/v 向节点向量
std::vector<std::vector<double>> weights_; ///< 权重网格
int degree_u_, degree_v_; ///< u/v 向阶次
};
} // namespace vde::curves