2026-07-26 20:58:31 +08:00
|
|
|
|
#pragma once
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @file surface_analysis.h
|
|
|
|
|
|
* @brief 曲面分析工具集 — 曲率映射、斑马纹、曲率梳、偏差分析、拔模角
|
|
|
|
|
|
*
|
|
|
|
|
|
* 提供 CAD 级曲面质量分析功能:
|
|
|
|
|
|
* - 高斯/平均/主曲率网格
|
|
|
|
|
|
* - 斑马纹反射模拟
|
|
|
|
|
|
* - 曲率梳可视化数据
|
|
|
|
|
|
* - 曲面间偏差分析
|
|
|
|
|
|
* - 拔模角计算(增强现有实现)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @ingroup curves
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "vde/curves/nurbs_curve.h"
|
|
|
|
|
|
#include "vde/curves/nurbs_surface.h"
|
|
|
|
|
|
#include "vde/core/point.h"
|
|
|
|
|
|
#include "vde/brep/brep.h"
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <array>
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
|
|
|
|
namespace vde::curves {
|
|
|
|
|
|
|
|
|
|
|
|
using core::Point3D;
|
|
|
|
|
|
using core::Vector3D;
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Curvature Map Types
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 单点的曲率数据
|
|
|
|
|
|
struct CurvaturePoint {
|
|
|
|
|
|
double gaussian = 0.0; ///< 高斯曲率 K = κ₁·κ₂
|
|
|
|
|
|
double mean = 0.0; ///< 平均曲率 H = (κ₁+κ₂)/2
|
|
|
|
|
|
double k1 = 0.0; ///< 最大主曲率 κ₁
|
|
|
|
|
|
double k2 = 0.0; ///< 最小主曲率 κ₂
|
|
|
|
|
|
Vector3D d1; ///< 最大主方向
|
|
|
|
|
|
Vector3D d2; ///< 最小主方向
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲率网格(res_u+1 × res_v+1)
|
|
|
|
|
|
struct CurvatureMap {
|
|
|
|
|
|
int res_u, res_v; ///< 网格分辨率
|
|
|
|
|
|
std::vector<std::vector<CurvaturePoint>> grid; ///< grid[i][j] 对应 (u_i, v_j)
|
|
|
|
|
|
|
|
|
|
|
|
/// 高斯曲率极值
|
|
|
|
|
|
double min_gaussian = std::numeric_limits<double>::max();
|
|
|
|
|
|
double max_gaussian = -std::numeric_limits<double>::max();
|
|
|
|
|
|
|
|
|
|
|
|
/// 平均曲率极值
|
|
|
|
|
|
double min_mean = std::numeric_limits<double>::max();
|
|
|
|
|
|
double max_mean = -std::numeric_limits<double>::max();
|
|
|
|
|
|
|
|
|
|
|
|
/// 是否为可展曲面(高斯曲率 ≈ 0)
|
|
|
|
|
|
[[nodiscard]] bool is_developable(double tol = 1e-9) const;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算 NURBS 曲面的曲率映射
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在参数域均匀采样,计算每个采样点的高斯曲率、平均曲率、
|
|
|
|
|
|
* 主曲率及主方向。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param res_u u 方向分辨率(单元格数)
|
|
|
|
|
|
* @param res_v v 方向分辨率(单元格数)
|
|
|
|
|
|
* @return CurvatureMap
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] CurvatureMap curvature_map(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
int res_u, int res_v);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Zebra Stripe
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 斑马纹反射数据
|
|
|
|
|
|
struct ZebraStripeResult {
|
|
|
|
|
|
int res_u, res_v; ///< 网格分辨率
|
|
|
|
|
|
std::vector<std::vector<double>> intensity; ///< intensity[i][j] ∈ [0,1]
|
|
|
|
|
|
Vector3D light_direction; ///< 光照方向(归一化)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算斑马纹反射数据(等照度线模拟)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 模拟等间距平行光源在曲面上的反射效果,用于检测曲面光顺性。
|
|
|
|
|
|
* 斑马纹的密度和均匀度反映曲面的曲率变化。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param light_dir 光照方向(自动归一化)
|
|
|
|
|
|
* @param res_u u 方向分辨率
|
|
|
|
|
|
* @param res_v v 方向分辨率
|
|
|
|
|
|
* @return 反射强度网格
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] ZebraStripeResult zebra_stripe(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
const Vector3D& light_dir,
|
|
|
|
|
|
int res_u, int res_v);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Curvature Comb
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲率梳数据点
|
|
|
|
|
|
struct CurvatureCombPoint {
|
|
|
|
|
|
Point3D curve_point; ///< 曲线上的点
|
|
|
|
|
|
Vector3D curvature_vec; ///< 曲率向量(方向=主法线,长度∝曲率)
|
|
|
|
|
|
double curvature; ///< 曲率大小
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲率梳完整数据
|
|
|
|
|
|
struct CurvatureComb {
|
|
|
|
|
|
std::vector<CurvatureCombPoint> points;
|
|
|
|
|
|
double min_curvature = std::numeric_limits<double>::max();
|
|
|
|
|
|
double max_curvature = -std::numeric_limits<double>::max();
|
|
|
|
|
|
double scale = 1.0; ///< 缩放因子
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算曲线曲率梳数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在曲线上均匀采样,计算各点的曲率向量。
|
|
|
|
|
|
* 曲率梳将曲率大小可视化为从曲线向外延伸的线段长度。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param curve NURBS 曲线
|
|
|
|
|
|
* @param res 采样分辨率(点数)
|
|
|
|
|
|
* @param scale 曲率缩放因子(默认自动适配)
|
|
|
|
|
|
* @return 曲率梳数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] CurvatureComb curvature_comb(
|
|
|
|
|
|
const NurbsCurve& curve,
|
|
|
|
|
|
int res,
|
|
|
|
|
|
double scale = 0.0);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Deviation Analysis
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 偏差分析结果
|
|
|
|
|
|
struct DeviationResult {
|
|
|
|
|
|
double max_positive = 0.0; ///< 最大正偏差(surf_b 在 surf_a 外侧)
|
|
|
|
|
|
double max_negative = 0.0; ///< 最大负偏差(surf_b 在 surf_a 内侧)
|
|
|
|
|
|
double rms = 0.0; ///< 均方根偏差
|
|
|
|
|
|
double mean_absolute = 0.0; ///< 平均绝对偏差
|
|
|
|
|
|
size_t sample_count = 0; ///< 采样点数量
|
|
|
|
|
|
std::vector<double> deviations; ///< 各采样点的有符号偏差
|
|
|
|
|
|
std::vector<Point3D> sample_points_a; ///< surf_a 上的采样点
|
|
|
|
|
|
std::vector<Point3D> sample_points_b; ///< surf_b 上对应的最近点
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算两曲面的偏差分析
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在 surf_a 参数域均匀采样,对每个采样点寻找 surf_b 上的最近点,
|
|
|
|
|
|
* 沿 surf_a 法线方向计算有符号偏差。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf_a 基准曲面
|
|
|
|
|
|
* @param surf_b 对比曲面
|
|
|
|
|
|
* @param samples 采样点数量(总点数 = samples×samples)
|
|
|
|
|
|
* @return 偏差分析结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] DeviationResult deviation_analysis(
|
|
|
|
|
|
const NurbsSurface& surf_a,
|
|
|
|
|
|
const NurbsSurface& surf_b,
|
|
|
|
|
|
int samples);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Draft Face Angle (Enhanced)
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算 NURBS 曲面上指定参数点的拔模角
|
|
|
|
|
|
*
|
|
|
|
|
|
* 拔模角 = angle between surface normal and pull direction minus 90°
|
|
|
|
|
|
* 正值表示面沿拔模方向向外张开。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param u u 参数
|
|
|
|
|
|
* @param v v 参数
|
|
|
|
|
|
* @param pull_dir 拔模方向(自动归一化)
|
|
|
|
|
|
* @return 拔模角(弧度)
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] double draft_face_angle(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
double u, double v,
|
|
|
|
|
|
const Vector3D& pull_dir);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算 B-Rep 面的拔模角(增强版)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在面的参数域中采样多个点,返回面积加权平均拔模角。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param body B-Rep 模型
|
|
|
|
|
|
* @param face_id 面 ID
|
|
|
|
|
|
* @param pull_dir 拔模方向
|
|
|
|
|
|
* @param samples 每方向采样点数(默认 10)
|
|
|
|
|
|
* @return 面积加权平均拔模角(弧度),若面无效则返回 0
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] double draft_face_angle(
|
|
|
|
|
|
const brep::BrepModel& body,
|
|
|
|
|
|
int face_id,
|
|
|
|
|
|
const Vector3D& pull_dir,
|
|
|
|
|
|
int samples = 10);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算 B-Rep 面的拔模角分布
|
|
|
|
|
|
*
|
|
|
|
|
|
* 返回面上多个采样点的拔模角数据。
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct DraftAngleDistribution {
|
|
|
|
|
|
double min_angle, max_angle; ///< 拔模角范围
|
|
|
|
|
|
double mean_angle; ///< 平均拔模角
|
|
|
|
|
|
double area_weighted_angle; ///< 面积加权平均
|
|
|
|
|
|
std::vector<double> sample_angles; ///< 各采样点拔模角
|
|
|
|
|
|
std::vector<std::pair<double,double>> sample_params; ///< 对应参数 (u,v)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] DraftAngleDistribution draft_face_angle_distribution(
|
|
|
|
|
|
const brep::BrepModel& body,
|
|
|
|
|
|
int face_id,
|
|
|
|
|
|
const Vector3D& pull_dir,
|
|
|
|
|
|
int samples = 15);
|
|
|
|
|
|
|
2026-07-27 09:08:01 +08:00
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Inflection Lines
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲率过零点线段
|
|
|
|
|
|
struct InflectionSegment {
|
|
|
|
|
|
Point3D start; ///< 线段起点
|
|
|
|
|
|
Point3D end; ///< 线段终点
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲率过零分析结果
|
|
|
|
|
|
struct InflectionLinesResult {
|
|
|
|
|
|
std::vector<InflectionSegment> segments; ///< 高斯曲率过零点连线
|
|
|
|
|
|
int res_u, res_v; ///< 采样分辨率
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 提取曲面的曲率过零点连线(inflection lines)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在参数域密集采样高斯曲率,检测曲率符号变化点,连接相邻过零点
|
|
|
|
|
|
* 形成线段。用于检测曲面凹凸变化边界。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param res_u u 方向分辨率(默认 50)
|
|
|
|
|
|
* @param res_v v 方向分辨率(默认 50)
|
|
|
|
|
|
* @return 过零点线段集合
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] InflectionLinesResult inflection_lines(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
int res_u = 50, int res_v = 50);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Checker Mapping
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 棋盘格反射数据
|
|
|
|
|
|
struct CheckerMapResult {
|
|
|
|
|
|
int res_u, res_v; ///< 分辨率
|
|
|
|
|
|
std::vector<std::vector<double>> intensity; ///< intensity[i][j] ∈ [0,1](棋盘格亮度)
|
|
|
|
|
|
Vector3D view_dir; ///< 视线方向(归一化)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 计算棋盘格反射映射数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* 模拟棋盘格图案在曲面上的反射效果。将参数域 (u,v) 映射为棋盘格
|
|
|
|
|
|
* 纹理坐标,结合曲面法线计算反射强度。用于评估曲面光顺性——
|
|
|
|
|
|
* 反射棋盘格的均匀度和连续性反映曲率连续性。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param view_dir 视线方向(自动归一化)
|
|
|
|
|
|
* @param res_u u 方向分辨率(默认 60)
|
|
|
|
|
|
* @param res_v v 方向分辨率(默认 60)
|
|
|
|
|
|
* @return 棋盘格反射数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] CheckerMapResult checker_mapping(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
const Vector3D& view_dir,
|
|
|
|
|
|
int res_u = 60, int res_v = 60);
|
|
|
|
|
|
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
// Surface Checker Report
|
|
|
|
|
|
// ═══════════════════════════════════════════════════════════
|
|
|
|
|
|
|
|
|
|
|
|
/// 光顺性评估等级
|
|
|
|
|
|
enum class SmoothnessGrade {
|
|
|
|
|
|
A, ///< 优秀 — 反射条纹均匀、无突变、曲率连续
|
|
|
|
|
|
B, ///< 良好 — 轻微不均匀、局部小波动
|
|
|
|
|
|
C, ///< 一般 — 明显扭曲、局部不平滑
|
|
|
|
|
|
D ///< 差 — 严重扭曲、曲率突变
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// 曲面光顺性评估报告
|
|
|
|
|
|
struct SurfaceCheckerReport {
|
|
|
|
|
|
SmoothnessGrade grade; ///< 光顺性等级
|
|
|
|
|
|
double checker_uniformity; ///< 棋盘格均匀度 [0,1],1 最佳
|
|
|
|
|
|
double curvature_continuity; ///< 曲率连续性指数 [0,1]
|
|
|
|
|
|
double gaussian_range; ///< 高斯曲率范围
|
|
|
|
|
|
double mean_range; ///< 平均曲率范围
|
|
|
|
|
|
int inflection_count; ///< 曲率过零点数量
|
|
|
|
|
|
std::string description; ///< 文字描述
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 生成曲面光顺性评估报告
|
|
|
|
|
|
*
|
|
|
|
|
|
* 综合曲率分析、棋盘格反射和过零点检测,对曲面光顺性进行量化评估。
|
|
|
|
|
|
* 返回等级、均匀度、连续性等综合指标。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param surf NURBS 曲面
|
|
|
|
|
|
* @param res 综合分析分辨率(默认 60)
|
|
|
|
|
|
* @return 光顺性评估报告
|
|
|
|
|
|
*/
|
|
|
|
|
|
[[nodiscard]] SurfaceCheckerReport surface_checker_report(
|
|
|
|
|
|
const NurbsSurface& surf,
|
|
|
|
|
|
int res = 60);
|
|
|
|
|
|
|
2026-07-26 20:58:31 +08:00
|
|
|
|
} // namespace vde::curves
|