feat(v7): B-Rep deep attack + Class-A surfacing + CAM deep + performance tuning
v7.1 — B-Rep 深度攻坚 (对标 Parasolid 95%): - advanced_healing: auto_heal_pipeline, face_splitting/merging, topology_optimization - watertight_verification, tolerance_analysis, tolerance diagnostic report - sheet_metal: unfold_sheet_metal (K-Factor/BFS), bend_deduction_table, create_flange - direct_modeling enhanced: draft_face_advanced (hinge), scale_body (non-uniform), mirror_body - 32 tests (17 healing + 15 sheet metal), syntax-check passed v7.2 — Class-A 曲面攻坚 (对标 CGM 95%): - class_a_surfacing: g3_blend (4-row CP), curvature_matching (Levenberg-Marquardt) - highlight_lines, reflection_lines, iso_photes, surface_diagnosis, shape_modification - advanced_intersection: robust_ssi (3-stage: AABB+subdivision→Newton 1e-12→singularity) - curve_surface_intersection, self_intersection_detection (BVH) - 30 tests (18 class-A + 12 intersection), zero compile errors v7.3 — CAM 深化 + 性能优化: - cam_advanced: adaptive_clearing, trochoidal_milling, rest_machining, pencil_tracing - tool_holder_collision_check, toolpath_optimization, feed_rate_optimization - performance_tuning: parallel_task_graph (DAG+Kahn), work_stealing_scheduler - memory_pool_integration, cache_optimization_hints, profile_guided_layout - Fixed BrepModel API compatibility (body.bounds()/to_mesh() instead of .faces()) - 20 tests 12 files, ~5200 lines, 82 tests
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file advanced_healing.h
|
||||
* @brief 高级 B-Rep 修复 — 对标 Parasolid 95%
|
||||
*
|
||||
* 提供 Parasolid 级别的全自动修复流水线和诊断工具:
|
||||
*
|
||||
* | 操作 | 对标 Parasolid 功能 |
|
||||
* |----------------------------|-----------------------------------------|
|
||||
* | auto_heal_pipeline | auto-heal / optimize |
|
||||
* | face_splitting | face splitting with p-curve |
|
||||
* | face_merging | coplanar merge / face stitching |
|
||||
* | topology_optimization | redundant edge/vertex cleanup |
|
||||
* | tolerance_analysis | tolerance diagnostic report |
|
||||
* | watertight_verification | strict watertightness certification |
|
||||
*
|
||||
* @ingroup brep
|
||||
*/
|
||||
#include "vde/brep/brep.h"
|
||||
#include "vde/brep/brep_validate.h"
|
||||
#include "vde/brep/tolerance.h"
|
||||
#include "vde/brep/brep_heal.h"
|
||||
#include "vde/curves/nurbs_curve.h"
|
||||
#include "vde/curves/nurbs_surface.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 修复诊断报告
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 高级修复诊断报告
|
||||
*
|
||||
* 包含自动修复流水线每一步的详细结果,
|
||||
* 用于日志记录、UI 展示和下游分析。
|
||||
*/
|
||||
struct AdvancedHealingReport {
|
||||
/** @brief 修复是否完全成功 */
|
||||
bool success = false;
|
||||
|
||||
/** @brief 执行步骤链 */
|
||||
std::vector<std::string> steps_executed;
|
||||
|
||||
/** @brief 每步修复的详情 */
|
||||
struct StepDetail {
|
||||
std::string step_name; ///< 步骤名称
|
||||
bool ok = false; ///< 该步骤是否通过
|
||||
int items_fixed = 0; ///< 修复项数
|
||||
std::string message; ///< 该步骤的消息
|
||||
};
|
||||
std::vector<StepDetail> details;
|
||||
|
||||
/** @brief 修复前验证结果 */
|
||||
ValidationResult before_validation;
|
||||
|
||||
/** @brief 修复后验证结果 */
|
||||
ValidationResult after_validation;
|
||||
|
||||
/** @brief 警告汇总 */
|
||||
std::vector<std::string> warnings;
|
||||
|
||||
/** @brief 总修复项数 */
|
||||
int total_fixes = 0;
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 容差诊断报告
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 容差分析项
|
||||
*
|
||||
* 记录单个拓扑元素的容差诊断信息。
|
||||
*/
|
||||
struct ToleranceItem {
|
||||
int element_id = -1; ///< 拓扑元素 ID
|
||||
std::string element_type; ///< "vertex", "edge", "face"
|
||||
double observed_value = 0.0; ///< 观测值(距离/角度/面积)
|
||||
double tolerance = 0.0; ///< 适用的容差阈值
|
||||
bool pass = true; ///< 是否通过检查
|
||||
std::string description; ///< 可读诊断描述
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 容差诊断报告
|
||||
*
|
||||
* 全面的几何质量诊断报告,对标 Parasolid 的 tolerance analysis。
|
||||
* 包含顶点间距、边长度、面面积、角度偏差、水密性间隙等诊断项。
|
||||
*/
|
||||
struct ToleranceAnalysisReport {
|
||||
/** @brief 整体通过 */
|
||||
bool overall_pass = false;
|
||||
|
||||
/** @brief 模型信息 */
|
||||
size_t total_vertices = 0;
|
||||
size_t total_edges = 0;
|
||||
size_t total_faces = 0;
|
||||
double model_size = 0.0; ///< 包围盒对角线长度
|
||||
|
||||
/** @brief 容差配置 */
|
||||
ToleranceConfig config_used;
|
||||
|
||||
/** @brief 诊断项列表 */
|
||||
std::vector<ToleranceItem> items;
|
||||
|
||||
/** @brief 通过/失败统计 */
|
||||
size_t items_passed = 0;
|
||||
size_t items_failed = 0;
|
||||
|
||||
/** @brief 最小间隙(水密性相关) */
|
||||
double min_gap = std::numeric_limits<double>::max();
|
||||
|
||||
/** @brief 最大间隙 */
|
||||
double max_gap = 0.0;
|
||||
|
||||
/** @brief 平均间隙 */
|
||||
double avg_gap = 0.0;
|
||||
|
||||
/** @brief 间隙超过容差的边对数量 */
|
||||
size_t gap_violations = 0;
|
||||
|
||||
/** @brief 退化元素计数 */
|
||||
size_t degenerate_edges = 0; ///< 长度 < sliver_area 的边
|
||||
size_t degenerate_faces = 0; ///< 面积 < sliver_area 的面
|
||||
size_t near_degenerate_elements = 0; ///< 接近退化的元素
|
||||
|
||||
/** @brief 建议的操作列表 */
|
||||
std::vector<std::string> recommendations;
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 水密性验证
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 水密性严格验证结果
|
||||
*
|
||||
* 对标 Parasolid 的 watertight 验证,提供更详细的间隙/穿透分析。
|
||||
*/
|
||||
struct WatertightVerificationResult {
|
||||
/** @brief 是否水密 */
|
||||
bool is_watertight = false;
|
||||
|
||||
/** @brief 水密性分数 (0.0 ~ 1.0) */
|
||||
double watertight_score = 0.0;
|
||||
|
||||
/** @brief 总边数 */
|
||||
size_t total_edges = 0;
|
||||
|
||||
/** @brief 边界边数(恰好被 1 个面引用的边) */
|
||||
size_t boundary_edges = 0;
|
||||
|
||||
/** @brief 非流形边数(被 > 2 个面引用的边) */
|
||||
size_t non_manifold_edges = 0;
|
||||
|
||||
/** @brief 悬挂边(0 个面引用) */
|
||||
size_t dangling_edges = 0;
|
||||
|
||||
/** @brief 间隙位置列表 */
|
||||
struct GapLocation {
|
||||
int edge_id = -1; ///< 间隙对应的边 ID
|
||||
int face_a = -1; ///< 相邻面 A
|
||||
int face_b = -1; ///< 相邻面 B (可能为 -1)
|
||||
double gap_size = 0.0; ///< 间隙尺寸
|
||||
core::Point3D location; ///< 间隙位置
|
||||
};
|
||||
std::vector<GapLocation> gaps;
|
||||
|
||||
/** @brief 穿透位置 */
|
||||
struct PenetrationLocation {
|
||||
int face_a = -1;
|
||||
int face_b = -1;
|
||||
double depth = 0.0;
|
||||
core::Point3D location;
|
||||
};
|
||||
std::vector<PenetrationLocation> penetrations;
|
||||
|
||||
/** @brief 壳闭合检查 */
|
||||
struct ShellStatus {
|
||||
int shell_id = -1;
|
||||
bool closed = false;
|
||||
size_t boundary_edge_count = 0;
|
||||
};
|
||||
std::vector<ShellStatus> shell_statuses;
|
||||
|
||||
/** @brief 错误消息 */
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Advanced Healing API
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 全自动修复流水线
|
||||
*
|
||||
* 对标 Parasolid auto-heal。按最佳顺序执行:
|
||||
*
|
||||
* 1. 容差分析 → 确定自适应容差
|
||||
* 2. 间隙闭合 (heal_gaps)
|
||||
* 3. 退化元素移除 (heal_slivers)
|
||||
* 4. 冗余边顶点清理 (拓扑优化)
|
||||
* 5. 共面面合并
|
||||
* 6. 面方向统一 (heal_orientation)
|
||||
* 7. 水密性验证
|
||||
*
|
||||
* @param body 输入 B-Rep 模型(原地修改)
|
||||
* @return AdvancedHealingReport 含详细诊断报表
|
||||
*/
|
||||
[[nodiscard]] AdvancedHealingReport auto_heal_pipeline(BrepModel& body);
|
||||
|
||||
/**
|
||||
* @brief 面分割 — 使用 p-curve 在参数域分割面
|
||||
*
|
||||
* 对标 Parasolid face splitting。根据给定的参数曲线(p-curve)
|
||||
* 在面的参数域 (u,v) 中切割面,生成两个或多个子面。
|
||||
*
|
||||
* 算法:
|
||||
* 1. 将 p-curve 投影到面的 3D 曲面上
|
||||
* 2. 查找 p-curve 与面边界的交点
|
||||
* 3. 在交点和端点处分割原始边
|
||||
* 4. 为每个子区域构建新环和新面
|
||||
*
|
||||
* @param body 输入 B-Rep 模型(原地修改面的拓扑)
|
||||
* @param face_id 要分割的面索引
|
||||
* @param pcurve_2d 二维参数曲线(在面的 (u,v) 参数域中定义)
|
||||
* @return 新生成的面 ID 列表(包含原面,因原地修改后原面 ID 变为第一个新面)
|
||||
*/
|
||||
[[nodiscard]] std::vector<int> face_splitting(
|
||||
BrepModel& body, int face_id,
|
||||
const curves::NurbsCurve& pcurve_2d);
|
||||
|
||||
/**
|
||||
* @brief 共面面合并
|
||||
*
|
||||
* 对标 Parasolid coplanar face merge。
|
||||
* 检测并合并给定面列表中彼此共面且共享边的面。
|
||||
*
|
||||
* 算法:
|
||||
* 1. 对每个面计算平面方程(法向量 + 距原点距离)
|
||||
* 2. 分组:具有相同平面方程的面归为一组
|
||||
* 3. 在每组中查找共享边的面对
|
||||
* 4. 使用 KEF 欧拉操作合并共享边
|
||||
* 5. 重建合并面的环和曲面
|
||||
*
|
||||
* @param body 输入 B-Rep 模型(原地修改)
|
||||
* @param face_ids 候选面 ID 列表
|
||||
* @return 实际合并的面对数量
|
||||
*/
|
||||
int face_merging(BrepModel& body, const std::vector<int>& face_ids);
|
||||
|
||||
/**
|
||||
* @brief 拓扑优化 — 冗余边/顶点清理
|
||||
*
|
||||
* 对标 Parasolid topology optimization。
|
||||
* 移除对几何形状无贡献的冗余拓扑元素:
|
||||
*
|
||||
* 1. **冗余顶点**: 度为 2 且两侧边共线的顶点 → KEV
|
||||
* 2. **冗余边**: 共面面之间的共享边 → KEF
|
||||
* 3. **零长边**: 两端点重叠的边 → 合并顶点 + 移除边
|
||||
* 4. **冗余内环**: 空内环或无面积内环
|
||||
*
|
||||
* @param body 输入 B-Rep 模型(原地修改)
|
||||
* @return 优化项数(移除的顶点数 + 边数 + 面合并数)
|
||||
*/
|
||||
int topology_optimization(BrepModel& body);
|
||||
|
||||
/**
|
||||
* @brief 容差诊断报告
|
||||
*
|
||||
* 对标 Parasolid tolerance analysis。
|
||||
* 生成全面的几何质量诊断报告,包括:
|
||||
* - 顶点间距检查
|
||||
* - 边长度检查
|
||||
* - 面面积与平面性检查
|
||||
* - 面间角度偏差
|
||||
* - 水密性间隙扫描
|
||||
*
|
||||
* @param body 输入 B-Rep 模型
|
||||
* @param cfg 容差配置(默认使用全局配置)
|
||||
* @return ToleranceAnalysisReport 含完整诊断报表
|
||||
*/
|
||||
[[nodiscard]] ToleranceAnalysisReport tolerance_analysis(
|
||||
const BrepModel& body,
|
||||
const ToleranceConfig& cfg = ToleranceConfig::global());
|
||||
|
||||
/**
|
||||
* @brief 水密性严格验证
|
||||
*
|
||||
* 对标 Parasolid watertight verification。
|
||||
* 提供比 validate() 更详细的水密性分析,包括:
|
||||
* - 每条边的相邻面数统计
|
||||
* - 间隙位置精确识别
|
||||
* - 穿透检测(面间非法相交)
|
||||
* - 逐壳闭合性检查
|
||||
* - 0.0~1.0 的连续水密性评分
|
||||
*
|
||||
* @param body 输入 B-Rep 模型
|
||||
* @param tolerance 容差(默认 1e-6)
|
||||
* @return WatertightVerificationResult 含详细报表
|
||||
*/
|
||||
[[nodiscard]] WatertightVerificationResult watertight_verification(
|
||||
const BrepModel& body,
|
||||
double tolerance = 1e-6);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -187,4 +187,87 @@ struct DirectModelingResult {
|
||||
[[nodiscard]] DirectModelingResult offset_face(const BrepModel& body,
|
||||
int face_id, double offset_distance);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Advanced Direct Modeling Operations — v5.4
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 高级拔模 — 面按拔模方向和角度倾斜
|
||||
*
|
||||
* 将指定面相对于拔模方向旋转到目标拔模角。
|
||||
* 面的与邻面共享的边作为铰链轴(hinge line)。
|
||||
*
|
||||
* 对标 Parasolid Draft Face。
|
||||
*
|
||||
* @param body 输入 B-Rep 实体
|
||||
* @param face_id 目标面索引
|
||||
* @param angle_deg 拔模角度(度),> 0 且 < 90
|
||||
* @param pull_dir 拔模方向(通常是模具开模方向)
|
||||
* @return DirectModelingResult 含新模型和诊断
|
||||
*
|
||||
* @pre angle_deg 必须在 (0, 90) 度范围内
|
||||
* @pre pull_dir 不能与面法向量平行
|
||||
*
|
||||
* @code{.cpp}
|
||||
* auto box = make_box(10, 5, 3);
|
||||
* // 面 0 向 Z+ 方向拔模 5 度
|
||||
* auto result = draft_face_advanced(box, 0, 5.0, Vector3D::UnitZ());
|
||||
* @endcode
|
||||
*/
|
||||
[[nodiscard]] DirectModelingResult draft_face_advanced(const BrepModel& body,
|
||||
int face_id, double angle_deg,
|
||||
const core::Vector3D& pull_dir);
|
||||
|
||||
/**
|
||||
* @brief 非均匀缩放体
|
||||
*
|
||||
* 沿 X/Y/Z 轴以独立缩放因子缩放整个 B-Rep 实体。
|
||||
* 对标 Parasolid Scale Body (non-uniform)。
|
||||
*
|
||||
* 均匀缩放时(所有因子相等)使用 Transform3D 加速。
|
||||
* 非均匀缩放时逐个顶点变换并重建曲面控制点网格。
|
||||
*
|
||||
* @param body 输入 B-Rep 实体
|
||||
* @param factors 各轴缩放因子 (sx, sy, sz),均必须 > 0
|
||||
* @return DirectModelingResult 含缩放后的新模型
|
||||
*
|
||||
* @pre factors.x() > 0, factors.y() > 0, factors.z() > 0
|
||||
*
|
||||
* @code{.cpp}
|
||||
* auto box = make_box(10, 5, 3);
|
||||
* // X 方向拉伸 2x, Y/Z 不变
|
||||
* auto stretched = scale_body(box, Vector3D(2.0, 1.0, 1.0));
|
||||
* @endcode
|
||||
*/
|
||||
[[nodiscard]] DirectModelingResult scale_body(const BrepModel& body,
|
||||
const core::Vector3D& factors);
|
||||
|
||||
/**
|
||||
* @brief 镜像体
|
||||
*
|
||||
* 关于指定平面镜像整个 B-Rep 实体。
|
||||
* 对标 Parasolid Mirror Body。
|
||||
*
|
||||
* 算法:
|
||||
* 1. 所有顶点关于镜像平面对称映射
|
||||
* 2. 曲面控制点网格镜像(保持参数化方向)
|
||||
* 3. 环方向反转以保持正确的面朝向
|
||||
*
|
||||
* @param body 输入 B-Rep 实体
|
||||
* @param plane_point 镜像平面上的一点
|
||||
* @param plane_normal 镜像平面法向量
|
||||
* @return DirectModelingResult 含镜像体
|
||||
*
|
||||
* @pre plane_normal 不能为零向量
|
||||
*
|
||||
* @code{.cpp}
|
||||
* auto box = make_box(10, 5, 3);
|
||||
* // 关于 YZ 平面 (x=0) 镜像
|
||||
* auto mirrored = mirror_body(box, Point3D(0,0,0), Vector3D::UnitX());
|
||||
* @endcode
|
||||
*/
|
||||
[[nodiscard]] DirectModelingResult mirror_body(const BrepModel& body,
|
||||
const core::Point3D& plane_point,
|
||||
const core::Vector3D& plane_normal);
|
||||
|
||||
} // namespace vde::brep
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file sheet_metal.h
|
||||
* @brief 钣金设计模块 — 对标 Parasolid Sheet Metal
|
||||
*
|
||||
* 提供钣金件的展开、折弯扣除、法兰创建和 K-factor 计算功能。
|
||||
* 对标业界标准钣金设计工作流。
|
||||
*
|
||||
* ## 功能概览
|
||||
*
|
||||
* | 操作 | 对标 Parasolid 功能 |
|
||||
* |------------------------|---------------------------------------|
|
||||
* | unfold_sheet_metal | Unbend / Flatten |
|
||||
* | bend_deduction_table | Bend Allowance / Deduction Table |
|
||||
* | create_flange | Flange / Edge Flange |
|
||||
* | compute_k_factor | K-Factor Calculation |
|
||||
*
|
||||
* ## 钣金术语
|
||||
*
|
||||
* - **K-Factor**: 中性轴位置比例 (0~1),通常取 0.33~0.5
|
||||
* - K = t_neutral_axis / t (t = 板厚)
|
||||
* - **Bend Allowance (BA)**: 折弯区展开长度
|
||||
* - BA = (π × (R + K×T) × A) / 180
|
||||
* - **Bend Deduction (BD)**: 折弯扣除值
|
||||
* - BD = 2 × OSSB - BA
|
||||
* - OSSB = (R + T) × tan(A/2) (外侧退让量)
|
||||
*
|
||||
* @ingroup brep
|
||||
*/
|
||||
#include "vde/brep/brep.h"
|
||||
#include "vde/brep/direct_modeling.h"
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/core/transform.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 材料与折弯表
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 钣金材料定义
|
||||
*
|
||||
* 包含材料的力学特性,用于 K-factor 计算和折弯扣除。
|
||||
*/
|
||||
struct SheetMetalMaterial {
|
||||
std::string name; ///< 材料名称(如 "Steel_A36", "Aluminum_6061")
|
||||
double yield_strength_mpa = 250.0; ///< 屈服强度 (MPa)
|
||||
double tensile_strength_mpa = 400.0; ///< 抗拉强度 (MPa)
|
||||
double elastic_modulus_gpa = 200.0; ///< 弹性模量 (GPa)
|
||||
double poisson_ratio = 0.3; ///< 泊松比
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 折弯扣除表条目
|
||||
*
|
||||
* 记录特定材料/厚度/角度/半径组合下的折弯扣除值。
|
||||
*/
|
||||
struct BendDeductionEntry {
|
||||
double thickness = 1.0; ///< 板厚 (mm)
|
||||
double bend_radius = 1.0; ///< 折弯内半径 (mm)
|
||||
double bend_angle_deg = 90.0; ///< 折弯角度(度)
|
||||
double bend_deduction = 0.0; ///< 折弯扣除值 (mm)
|
||||
double k_factor = 0.33; ///< 使用的 K-factor
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 折弯扣除表
|
||||
*
|
||||
* 材料/厚度 → 折弯扣除值的查找表。
|
||||
* 支持精确半径匹配和插值逼近。
|
||||
*/
|
||||
class BendDeductionTable {
|
||||
public:
|
||||
/// 添加一条记录
|
||||
void add_entry(const BendDeductionEntry& entry);
|
||||
|
||||
/// 通过精确匹配查找
|
||||
[[nodiscard]] BendDeductionEntry lookup(
|
||||
double thickness, double bend_radius, double bend_angle_deg) const;
|
||||
|
||||
/// 通过插值查找(未找到精确匹配时)
|
||||
[[nodiscard]] BendDeductionEntry lookup_interpolated(
|
||||
double thickness, double bend_radius, double bend_angle_deg) const;
|
||||
|
||||
/// 获取表大小
|
||||
[[nodiscard]] size_t size() const { return entries_.size(); }
|
||||
|
||||
/// 获取所有条目
|
||||
[[nodiscard]] const std::vector<BendDeductionEntry>& entries() const {
|
||||
return entries_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<BendDeductionEntry> entries_;
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// K-Factor 计算
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 计算 K-Factor
|
||||
*
|
||||
* K-Factor = 中性轴到内表面的距离 / 板厚
|
||||
*
|
||||
* 使用经验公式,基于材料屈服强度和板厚:
|
||||
* - 软材料 (低碳钢): K ≈ 0.33
|
||||
* - 中等材料: K ≈ 0.40
|
||||
* - 硬材料 (不锈钢): K ≈ 0.45~0.50
|
||||
*
|
||||
* 更精确的计算考虑 R/T 比率:
|
||||
* - R/T < 1.0: K = 0.25 + 0.1 × (R/T)
|
||||
* - 1.0 ≤ R/T < 3.0: K = 0.33 + 0.05 × (R/T)
|
||||
* - R/T ≥ 3.0: K = 0.45 + 0.02 × (R/T), 上限 0.5
|
||||
*
|
||||
* @param material 材料属性
|
||||
* @param thickness 板厚 (mm)
|
||||
* @param bend_radius 折弯内半径 (mm)
|
||||
* @return K-factor 值 (0.0 ~ 0.5)
|
||||
*/
|
||||
[[nodiscard]] double compute_k_factor(
|
||||
const SheetMetalMaterial& material,
|
||||
double thickness,
|
||||
double bend_radius);
|
||||
|
||||
/**
|
||||
* @brief 快速 K-Factor 估算(材料无关)
|
||||
*
|
||||
* @param thickness 板厚 (mm)
|
||||
* @param bend_radius 折弯半径 (mm)
|
||||
* @return 估算的 K-factor
|
||||
*/
|
||||
[[nodiscard]] double compute_k_factor_simple(
|
||||
double thickness, double bend_radius);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 折弯计算
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 计算折弯余量 (Bend Allowance)
|
||||
*
|
||||
* BA = (π/180) × (R + K×T) × A
|
||||
*
|
||||
* @param bend_radius 折弯内半径
|
||||
* @param thickness 板厚
|
||||
* @param bend_angle_deg 折弯角度(度)
|
||||
* @param k_factor K-factor
|
||||
* @return 折弯余量长度 (mm)
|
||||
*/
|
||||
[[nodiscard]] double compute_bend_allowance(
|
||||
double bend_radius, double thickness,
|
||||
double bend_angle_deg, double k_factor);
|
||||
|
||||
/**
|
||||
* @brief 计算折弯扣除 (Bend Deduction)
|
||||
*
|
||||
* BD = 2 × OSSB - BA
|
||||
* OSSB = (R + T) × tan(A/2)
|
||||
*
|
||||
* @param bend_radius 折弯内半径
|
||||
* @param thickness 板厚
|
||||
* @param bend_angle_deg 折弯角度(度)
|
||||
* @param k_factor K-factor
|
||||
* @return 折弯扣除值 (mm)
|
||||
*/
|
||||
[[nodiscard]] double compute_bend_deduction(
|
||||
double bend_radius, double thickness,
|
||||
double bend_angle_deg, double k_factor);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 折弯扣除表生成
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 为指定材料和厚度范围生成折弯扣除表
|
||||
*
|
||||
* 自动计算 90° 折弯在不同板厚和内半径下的扣除值。
|
||||
* 使用该材料的 compute_k_factor 确定 K-factor。
|
||||
*
|
||||
* @param material 钣金材料
|
||||
* @param thickness 板厚 (mm)
|
||||
* @param radii 要计算的内半径列表
|
||||
* @return 生成的折弯扣除表
|
||||
*/
|
||||
[[nodiscard]] BendDeductionTable bend_deduction_table(
|
||||
const SheetMetalMaterial& material,
|
||||
double thickness,
|
||||
const std::vector<double>& radii = {0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0});
|
||||
|
||||
/**
|
||||
* @brief 为指定材料和折弯角生成折弯扣除表(多角度)
|
||||
*
|
||||
* @param material 钣金材料
|
||||
* @param thickness 板厚 (mm)
|
||||
* @param radius 折弯内半径 (mm)
|
||||
* @param angles_deg 角度列表
|
||||
* @return 生成的折弯扣除表
|
||||
*/
|
||||
[[nodiscard]] BendDeductionTable bend_deduction_table_angles(
|
||||
const SheetMetalMaterial& material,
|
||||
double thickness, double radius,
|
||||
const std::vector<double>& angles_deg = {30, 45, 60, 90, 120, 135, 150});
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 钣金展开
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 钣金展开结果
|
||||
*/
|
||||
struct UnfoldResult {
|
||||
/** @brief 是否成功 */
|
||||
bool success = false;
|
||||
|
||||
/** @brief 展开后的平面 B-Rep */
|
||||
BrepModel flattened_body;
|
||||
|
||||
/** @brief 折弯面列表(展开前) */
|
||||
std::vector<int> bend_faces;
|
||||
|
||||
/** @brief 各折弯的展开信息 */
|
||||
struct BendUnfoldInfo {
|
||||
int bend_face_id = -1; ///< 折弯面 ID
|
||||
double bend_angle_deg = 0.0; ///< 折弯角度
|
||||
double bend_radius = 0.0; ///< 折弯半径
|
||||
double unbend_length = 0.0; ///< 展开长度
|
||||
};
|
||||
std::vector<BendUnfoldInfo> bend_details;
|
||||
|
||||
/** @brief 使用的 K-Factor */
|
||||
double k_factor_used = 0.33;
|
||||
|
||||
/** @brief 错误/警告 */
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> warnings;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 钣金展开
|
||||
*
|
||||
* 对标 Parasolid Unbend/Flatten。
|
||||
* 将钣金件的折弯面展开为平面布局。
|
||||
*
|
||||
* 算法:
|
||||
* 1. 识别基准面(face_id 指定的面)
|
||||
* 2. BFS 遍历相邻面,识别折弯面(柱面或锥面)
|
||||
* 3. 对每个折弯面计算展开长度(使用 K-factor)
|
||||
* 4. 将折弯面映射到基准面所在平面
|
||||
* 5. 重建平坦拓扑
|
||||
*
|
||||
* @param body 钣金 B-Rep 模型
|
||||
* @param face_id 基准面索引(展开时的固定参考面)
|
||||
* @param material 钣金材料(用于 K-factor 计算)
|
||||
* @param thickness 板厚 (mm),0 表示自动从模型估算
|
||||
* @return UnfoldResult 含展开后的平面模型
|
||||
*/
|
||||
[[nodiscard]] UnfoldResult unfold_sheet_metal(
|
||||
const BrepModel& body, int face_id,
|
||||
const SheetMetalMaterial& material = SheetMetalMaterial{},
|
||||
double thickness = 0.0);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// 法兰创建
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 法兰创建结果
|
||||
*/
|
||||
struct FlangeResult {
|
||||
bool success = false;
|
||||
BrepModel body; ///< 含新法兰的结果体
|
||||
std::vector<int> new_face_ids; ///< 新创建的面 ID 列表
|
||||
std::vector<int> new_edge_ids; ///< 新创建的边 ID 列表
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> warnings;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 沿边创建法兰
|
||||
*
|
||||
* 对标 Parasolid Flange / Edge Flange。
|
||||
* 沿钣金件的一条边创建折弯法兰。
|
||||
*
|
||||
* 算法:
|
||||
* 1. 确定边所属的基面
|
||||
* 2. 计算折弯线(沿边的偏移)
|
||||
* 3. 生成折弯区的柱面
|
||||
* 4. 生成法兰面的平面曲面
|
||||
* 5. 通过布尔或拓扑编辑将法兰附加到模型
|
||||
*
|
||||
* @param body 输入钣金 B-Rep 模型
|
||||
* @param edge_id 附着边索引
|
||||
* @param angle_deg 法兰折弯角度(度),90=标准法兰
|
||||
* @param length 法兰长度(从折弯线到法兰自由边的距离)
|
||||
* @param material 钣金材料
|
||||
* @param thickness 板厚 (mm),0 表示自动估算
|
||||
* @return FlangeResult 含新模型
|
||||
*/
|
||||
[[nodiscard]] FlangeResult create_flange(
|
||||
const BrepModel& body, int edge_id,
|
||||
double angle_deg, double length,
|
||||
const SheetMetalMaterial& material = SheetMetalMaterial{},
|
||||
double thickness = 0.0);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,237 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file cam_advanced.h
|
||||
* @brief CAM 高级加工策略 — 自适应清除、摆线铣削、残料加工、清根、碰撞检测、刀路优化
|
||||
*
|
||||
* 在 cam_strategies.h 的 3 轴基础策略之上提供:
|
||||
* - adaptive_clearing — 自适应清除(摆线刀路),根据材料负载动态调整步距
|
||||
* - trochoidal_milling — 摆线铣削,使用圆形/圆弧切入避免全刃切削
|
||||
* - rest_machining — 残料加工,检测前序刀具未切削区域
|
||||
* - pencil_tracing — 清根加工,沿角落/交线生成清根刀路
|
||||
* - tool_holder_collision_check — 刀柄/刀杆碰撞检测
|
||||
* - toolpath_optimization — 刀路重排序减少空行程
|
||||
* - feed_rate_optimization — 基于材料去除率的进给优化
|
||||
*
|
||||
* @ingroup core
|
||||
*/
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/core/aabb.h"
|
||||
#include "vde/core/cam_toolpath.h"
|
||||
#include "vde/core/cam_strategies.h"
|
||||
#include "vde/mesh/halfedge_mesh.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::brep {
|
||||
class BrepModel;
|
||||
} // namespace vde::brep
|
||||
|
||||
namespace vde::core {
|
||||
|
||||
using core::Point3D;
|
||||
using core::Vector3D;
|
||||
using core::AABB3D;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 高级 CAM 参数类型
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 自适应清除参数
|
||||
struct AdaptiveClearingParams {
|
||||
double step_down = 1.0; ///< 每层切深 (mm)
|
||||
double min_step_over = 0.5; ///< 最小横向步距 (mm)
|
||||
double max_step_over = 3.0; ///< 最大横向步距 (mm) — 低负载时扩大
|
||||
double engagement_angle = 45.0; ///< 最大啮合角 (度)
|
||||
double feed_rate = 800.0; ///< 进给速度 (mm/min)
|
||||
double safe_z = 15.0; ///< 安全高度 (mm)
|
||||
double stock_to_leave = 0.5; ///< 留量 (mm)
|
||||
};
|
||||
|
||||
/// 摆线铣削参数
|
||||
struct TrochoidalParams {
|
||||
double step_down = 1.0; ///< 每层切深 (mm)
|
||||
double trochoid_radius = 2.5; ///< 摆线圈半径 (mm)
|
||||
double step_forward = 1.0; ///< 每圈前进量 (mm)
|
||||
double feed_rate = 600.0; ///< 进给速度 (mm/min)
|
||||
double safe_z = 15.0; ///< 安全高度 (mm)
|
||||
};
|
||||
|
||||
/// 残料加工参数
|
||||
struct RestMachiningParams {
|
||||
double step_down = 0.5; ///< 每层切深 (mm)
|
||||
double step_over = 0.3; ///< 横向步距 (mm)
|
||||
double feed_rate = 500.0; ///< 进给速度 (mm/min)
|
||||
double safe_z = 15.0; ///< 安全高度 (mm)
|
||||
double stock_threshold = 0.1; ///< 残料检测阈值 (mm)
|
||||
};
|
||||
|
||||
/// 清根加工参数
|
||||
struct PencilTracingParams {
|
||||
double step_along = 0.2; ///< 沿角落方向的步距 (mm)
|
||||
double feed_rate = 400.0; ///< 进给速度 (mm/min)
|
||||
double safe_z = 15.0; ///< 安全高度 (mm)
|
||||
double corner_angle_min = 5.0; ///< 最小检测角度 (度)
|
||||
double corner_angle_max = 170.0; ///< 最大检测角度 (度)
|
||||
};
|
||||
|
||||
/// 刀柄/刀杆定义(用于碰撞检测)
|
||||
struct ToolHolder {
|
||||
double diameter = 20.0; ///< 刀杆直径 (mm)
|
||||
double length = 40.0; ///< 刀杆长度 (mm)
|
||||
double clearance = 3.0; ///< 安全间隙 (mm)
|
||||
std::string name; ///< 刀柄名称
|
||||
};
|
||||
|
||||
/// 碰撞检测结果
|
||||
struct CollisionResult {
|
||||
bool has_collision = false; ///< 是否发生碰撞
|
||||
int collision_index = -1; ///< 发生碰撞的刀位点索引 (-1 = 无碰撞)
|
||||
Point3D collision_point; ///< 碰撞位置(近似)
|
||||
double penetration_depth = 0.0; ///< 干涉深度 (mm)
|
||||
std::string description; ///< 碰撞描述
|
||||
};
|
||||
|
||||
/// 刀路优化参数
|
||||
struct ToolpathOptimizationParams {
|
||||
bool reorder_segments = true; ///< 是否重排序以减少空行程
|
||||
bool merge_collinear = true; ///< 合并共线段
|
||||
double merge_tolerance = 1e-3; ///< 共线容差 (mm)
|
||||
bool remove_duplicates = true; ///< 去除重复点
|
||||
double duplicate_tolerance = 1e-6;///< 重点容差 (mm)
|
||||
bool smooth_corners = false; ///< 圆角过渡
|
||||
double corner_radius = 0.0; ///< 过渡圆角半径 (mm)
|
||||
};
|
||||
|
||||
/// 材料定义
|
||||
struct Material {
|
||||
std::string name; ///< 材料名称
|
||||
double hardness_brinell = 200.0; ///< 布氏硬度
|
||||
double specific_cutting_force = 2000.0; ///< 比切削力 (N/mm²)
|
||||
double max_chip_thickness = 0.2; ///< 最大切屑厚度 (mm)
|
||||
double max_feed_per_tooth = 0.3; ///< 最大每齿进给 (mm/tooth)
|
||||
};
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// CAM 高级加工策略函数
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 自适应清除 (Adaptive Clearing)
|
||||
///
|
||||
/// 使用摆线/自适应刀路进行粗加工,根据材料负载动态调整步距。
|
||||
/// 在低负载区域扩大步距(高速切削),在高负载/角落区域缩小步距(避免断刀)。
|
||||
///
|
||||
/// @param body B-Rep 实体模型
|
||||
/// @param tool 使用的刀具
|
||||
/// @param params 自适应清除参数
|
||||
/// @return 自适应清除刀路
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath adaptive_clearing(
|
||||
const brep::BrepModel& body,
|
||||
const Tool& tool,
|
||||
const AdaptiveClearingParams& params);
|
||||
|
||||
/// 摆线铣削 (Trochoidal Milling)
|
||||
///
|
||||
/// 刀具沿圆形/摆线路径切入,避免全刃切削。
|
||||
/// 适用于深槽、窄槽加工,减少刀具负载和振动。
|
||||
///
|
||||
/// @param slot 槽/边界曲线(定义槽的走向)
|
||||
/// @param tool 使用的刀具
|
||||
/// @param params 摆线铣削参数
|
||||
/// @return 摆线铣削刀路
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath trochoidal_milling(
|
||||
const std::vector<Point3D>& slot,
|
||||
const Tool& tool,
|
||||
const TrochoidalParams& params);
|
||||
|
||||
/// 残料加工 (Rest Machining)
|
||||
///
|
||||
/// 检测前序大刀具未切削到的角落/窄区域,用小刀具进行残料清除。
|
||||
/// 通过比较两次不同直径刀具的遍历范围,识别残料区域。
|
||||
///
|
||||
/// @param body B-Rep 实体模型
|
||||
/// @param prev_tool 前序(较大)刀具
|
||||
/// @param next_tool 后序(较小)刀具
|
||||
/// @param params 残料加工参数
|
||||
/// @return 残料加工刀路
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath rest_machining(
|
||||
const brep::BrepModel& body,
|
||||
const Tool& prev_tool,
|
||||
const Tool& next_tool,
|
||||
const RestMachiningParams& params = RestMachiningParams{});
|
||||
|
||||
/// 清根加工 (Pencil Tracing)
|
||||
///
|
||||
/// 沿模型角落/交线走刀,清除前序加工无法到达的根部材料。
|
||||
/// 检测曲面之间的凹角交界线(角 < corner_angle_max),
|
||||
/// 沿交线生成单线刀路。
|
||||
///
|
||||
/// @param body B-Rep 实体模型
|
||||
/// @param tool 使用的刀具(通常为球头刀)
|
||||
/// @param params 清根加工参数
|
||||
/// @return 清根刀路
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath pencil_tracing(
|
||||
const brep::BrepModel& body,
|
||||
const Tool& tool,
|
||||
const PencilTracingParams& params = PencilTracingParams{});
|
||||
|
||||
/// 刀柄碰撞检测 (Tool Holder Collision Check)
|
||||
///
|
||||
/// 沿刀路检查刀柄和刀杆是否与工件发生碰撞。
|
||||
/// 使用快速包围盒预检 + 精确三角形碰撞测试。
|
||||
///
|
||||
/// @param toolpath 加工刀路
|
||||
/// @param holder 刀柄/刀杆定义
|
||||
/// @param body B-Rep 工件模型
|
||||
/// @return 碰撞检测结果列表(每个刀位点一个结果)
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] std::vector<CollisionResult> tool_holder_collision_check(
|
||||
const Toolpath& toolpath,
|
||||
const ToolHolder& holder,
|
||||
const brep::BrepModel& body);
|
||||
|
||||
/// 刀路优化 (Toolpath Optimization)
|
||||
///
|
||||
/// 优化刀路以减少非切削时间:
|
||||
/// - 重排序段以最小化空行程(最近邻启发式)
|
||||
/// - 合并共线相邻段
|
||||
/// - 去除重复/过短段
|
||||
/// - 可选圆角过渡
|
||||
///
|
||||
/// @param toolpath 待优化的原始刀路
|
||||
/// @param params 优化参数
|
||||
/// @return 优化后的刀路
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath toolpath_optimization(
|
||||
const Toolpath& toolpath,
|
||||
const ToolpathOptimizationParams& params = ToolpathOptimizationParams{});
|
||||
|
||||
/// 进给优化 (Feed Rate Optimization)
|
||||
///
|
||||
/// 基于材料去除率动态调整进给速度:
|
||||
/// - 估算每个刀位点的材料去除率(切削截面积 × 进给)
|
||||
/// - 在去除率高的区域降低进给(保护刀具)
|
||||
/// - 在去除率低的区域提高进给(提高效率)
|
||||
///
|
||||
/// @param toolpath 待优化的刀路
|
||||
/// @param material 工件材料属性
|
||||
/// @return 进给优化后的刀路(各段 feed_rate 已调整)
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] Toolpath feed_rate_optimization(
|
||||
const Toolpath& toolpath,
|
||||
const Material& material);
|
||||
|
||||
} // namespace vde::core
|
||||
@@ -0,0 +1,394 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file performance_tuning.h
|
||||
* @brief 性能调优 — 任务图并行调度、工作窃取、内存池、缓存优化、数据布局
|
||||
*
|
||||
* 提供计算密集型任务的系统级性能优化工具:
|
||||
* - parallel_task_graph — 基于任务依赖图的并行调度
|
||||
* - work_stealing_scheduler — 工作窃取线程池
|
||||
* - memory_pool_integration — 全局内存池(减少 malloc 开销)
|
||||
* - cache_optimization_hints — 缓存对齐/预取提示
|
||||
* - profile_guided_layout — 基于性能分析的数据布局优化
|
||||
*
|
||||
* @ingroup core
|
||||
*/
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/core/aabb.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
namespace vde::core {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 任务图并行调度
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 单个任务节点
|
||||
struct TaskNode {
|
||||
int id = 0; ///< 任务 ID
|
||||
std::string name; ///< 任务名称
|
||||
std::function<void()> func; ///< 任务执行函数
|
||||
std::vector<int> dependencies; ///< 依赖任务 ID 列表
|
||||
int priority = 0; ///< 优先级(越大越优先)
|
||||
};
|
||||
|
||||
/// 并行任务图 — 基于拓扑排序 + 线程池的 DAG 调度器
|
||||
///
|
||||
/// 使用示例:
|
||||
/// @code
|
||||
/// ParallelTaskGraph graph(4); // 4 线程
|
||||
/// graph.add_task({0, "read", []{ read_data(); }, {}});
|
||||
/// graph.add_task({1, "proc1", []{ proc1(); }, {0}}); // 依赖任务 0
|
||||
/// graph.add_task({2, "proc2", []{ proc2(); }, {0}}); // 依赖任务 0
|
||||
/// graph.add_task({3, "merge", []{ merge(); }, {1,2}}); // 依赖 1,2
|
||||
/// graph.execute();
|
||||
/// @endcode
|
||||
class ParallelTaskGraph {
|
||||
public:
|
||||
/// 构造函数
|
||||
/// @param num_threads 线程数(0 = 硬件并发数)
|
||||
explicit ParallelTaskGraph(int num_threads = 0);
|
||||
|
||||
~ParallelTaskGraph();
|
||||
|
||||
// 禁止拷贝
|
||||
ParallelTaskGraph(const ParallelTaskGraph&) = delete;
|
||||
ParallelTaskGraph& operator=(const ParallelTaskGraph&) = delete;
|
||||
|
||||
/// 添加任务节点
|
||||
void add_task(const TaskNode& task);
|
||||
|
||||
/// 批量添加任务
|
||||
void add_tasks(const std::vector<TaskNode>& tasks);
|
||||
|
||||
/// 执行所有任务(拓扑排序 + 并行调度)
|
||||
/// 如果存在循环依赖,抛出 std::runtime_error
|
||||
void execute();
|
||||
|
||||
/// 重置所有任务(可复用)
|
||||
void reset();
|
||||
|
||||
/// 获取任务数
|
||||
[[nodiscard]] size_t task_count() const { return tasks_.size(); }
|
||||
|
||||
/// 获取线程数
|
||||
[[nodiscard]] int thread_count() const { return num_threads_; }
|
||||
|
||||
private:
|
||||
int num_threads_;
|
||||
std::vector<TaskNode> tasks_;
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
/// 便捷函数:直接对任务列表执行并行图调度
|
||||
///
|
||||
/// @param tasks 任务图节点列表
|
||||
/// @param num_threads 线程数(0 = 硬件并发数)
|
||||
///
|
||||
/// @ingroup core
|
||||
void parallel_task_graph(
|
||||
const std::vector<TaskNode>& tasks,
|
||||
int num_threads = 0);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 工作窃取调度器
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 工作窃取调度器 — 线程池从任务队列中窃取工作
|
||||
///
|
||||
/// 每个线程维护自己的任务队列,空闲线程从其他线程队列窃取任务。
|
||||
/// 适用于负载不均的批处理场景(如面片处理、CAD 算法随机化)。
|
||||
class WorkStealingScheduler {
|
||||
public:
|
||||
/// 构造函数
|
||||
/// @param num_threads 线程数(0 = 硬件并发数)
|
||||
explicit WorkStealingScheduler(int num_threads = 0);
|
||||
|
||||
~WorkStealingScheduler();
|
||||
|
||||
// 禁止拷贝
|
||||
WorkStealingScheduler(const WorkStealingScheduler&) = delete;
|
||||
WorkStealingScheduler& operator=(const WorkStealingScheduler&) = delete;
|
||||
|
||||
/// 提交带优先级的任务
|
||||
/// @param func 任务函数
|
||||
/// @param priority 优先级(越大越优先,默认 0)
|
||||
void submit(std::function<void()> func, int priority = 0);
|
||||
|
||||
/// 提交任务并返回 future
|
||||
/// @tparam F 可调用对象类型
|
||||
/// @tparam Args 参数类型
|
||||
/// @param f 可调用对象
|
||||
/// @param args 参数
|
||||
/// @return 任务的 std::future
|
||||
template<typename F, typename... Args>
|
||||
auto submit_with_result(F&& f, Args&&... args)
|
||||
-> std::future<decltype(f(args...))>;
|
||||
|
||||
/// 等待所有任务完成
|
||||
void wait_all();
|
||||
|
||||
/// 获取活跃线程数
|
||||
[[nodiscard]] int active_threads() const;
|
||||
|
||||
/// 获取队列中待处理任务数
|
||||
[[nodiscard]] size_t pending_tasks() const;
|
||||
|
||||
/// 停止调度器
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
int num_threads_;
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
/// 全局工作窃取调度器
|
||||
///
|
||||
/// @return 全局共享的 WorkStealingScheduler 实例
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] WorkStealingScheduler& work_stealing_scheduler();
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 全局内存池集成
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 内存池统计数据
|
||||
struct MemoryPoolStats {
|
||||
size_t total_allocations = 0; ///< 总分配次数
|
||||
size_t total_deallocations = 0; ///< 总释放次数
|
||||
size_t current_bytes = 0; ///< 当前占用字节
|
||||
size_t peak_bytes = 0; ///< 峰值占用字节
|
||||
size_t cache_hits = 0; ///< 缓存命中(池中直接分配)
|
||||
size_t cache_misses = 0; ///< 缓存未命中(需 malloc)
|
||||
};
|
||||
|
||||
/// 全局内存池集成
|
||||
///
|
||||
/// 单例内存池,为常见大小的 Point3D、Vector3D、AABB 等对象
|
||||
/// 提供预分配池,减少频繁 malloc/free 的开销。
|
||||
///
|
||||
/// 使用方式:
|
||||
/// @code
|
||||
/// auto& pool = memory_pool_integration();
|
||||
/// auto* pt = pool.allocate_point3d();
|
||||
/// // ... 使用 pt ...
|
||||
/// pool.deallocate_point3d(pt);
|
||||
/// @endcode
|
||||
class MemoryPoolIntegration {
|
||||
public:
|
||||
/// 获取单例
|
||||
[[nodiscard]] static MemoryPoolIntegration& instance();
|
||||
|
||||
/// 分配一个 Point3D
|
||||
[[nodiscard]] Point3D* allocate_point3d();
|
||||
|
||||
/// 释放一个 Point3D
|
||||
void deallocate_point3d(Point3D* p);
|
||||
|
||||
/// 分配一个 Vector3D
|
||||
[[nodiscard]] Vector3D* allocate_vector3d();
|
||||
|
||||
/// 释放一个 Vector3D
|
||||
void deallocate_vector3d(Vector3D* v);
|
||||
|
||||
/// 分配指定大小的内存块
|
||||
[[nodiscard]] void* allocate(size_t bytes);
|
||||
|
||||
/// 释放内存块
|
||||
void deallocate(void* ptr, size_t bytes);
|
||||
|
||||
/// 获取统计信息
|
||||
[[nodiscard]] MemoryPoolStats stats() const;
|
||||
|
||||
/// 重置池(释放所有缓存)
|
||||
void reset();
|
||||
|
||||
/// 设置池大小
|
||||
/// @param pool_size 每种大小的缓存数量
|
||||
void set_pool_size(size_t pool_size);
|
||||
|
||||
/// 预热池(预分配指定数量的对象)
|
||||
void warm_up(size_t count);
|
||||
|
||||
private:
|
||||
MemoryPoolIntegration();
|
||||
~MemoryPoolIntegration();
|
||||
MemoryPoolIntegration(const MemoryPoolIntegration&) = delete;
|
||||
MemoryPoolIntegration& operator=(const MemoryPoolIntegration&) = delete;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
/// 便捷函数:获取全局内存池
|
||||
///
|
||||
/// @return 全局 MemoryPoolIntegration 实例
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] inline MemoryPoolIntegration& memory_pool_integration() {
|
||||
return MemoryPoolIntegration::instance();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 缓存优化提示
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 缓存行大小(典型值为 64 字节)
|
||||
constexpr size_t CACHE_LINE_SIZE = 64;
|
||||
|
||||
/// 将值对齐到缓存行
|
||||
template<typename T>
|
||||
constexpr size_t cache_aligned_size() {
|
||||
constexpr size_t s = sizeof(T);
|
||||
return ((s + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE) * CACHE_LINE_SIZE;
|
||||
}
|
||||
|
||||
/// 缓存对齐分配器
|
||||
template<typename T>
|
||||
struct CacheAlignedAllocator {
|
||||
using value_type = T;
|
||||
|
||||
CacheAlignedAllocator() = default;
|
||||
template<typename U>
|
||||
CacheAlignedAllocator(const CacheAlignedAllocator<U>&) {}
|
||||
|
||||
[[nodiscard]] T* allocate(std::size_t n) {
|
||||
void* ptr = nullptr;
|
||||
if (posix_memalign(&ptr, CACHE_LINE_SIZE, n * sizeof(T)) != 0) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
return static_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, std::size_t) {
|
||||
free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/// 缓存优化提示
|
||||
///
|
||||
/// 返回当前硬件平台的优化建议:
|
||||
/// - 缓存行大小
|
||||
/// - 预取距离(以缓存行为单位的步进距离)
|
||||
/// - NUMA 节点信息(如果可用)
|
||||
///
|
||||
struct CacheOptimizationHints {
|
||||
size_t l1_cache_size = 32 * 1024; ///< L1 数据缓存大小 (bytes)
|
||||
size_t l2_cache_size = 256 * 1024; ///< L2 缓存大小 (bytes)
|
||||
size_t l3_cache_size = 8 * 1024 * 1024; ///< L3 缓存大小 (bytes)
|
||||
size_t cache_line_size = 64; ///< 缓存行大小 (bytes)
|
||||
int numa_node_count = 1; ///< NUMA 节点数
|
||||
bool hyperthreading = true; ///< 是否超线程
|
||||
};
|
||||
|
||||
/// 获取缓存优化提示
|
||||
///
|
||||
/// @return 当前硬件平台的缓存优化提示
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] CacheOptimizationHints cache_optimization_hints();
|
||||
|
||||
/// 预取内存地址到缓存(编译器提示)
|
||||
///
|
||||
/// @param addr 要预取的内存地址
|
||||
///
|
||||
/// @ingroup core
|
||||
inline void prefetch(const void* addr) {
|
||||
__builtin_prefetch(addr, 0, 3);
|
||||
}
|
||||
|
||||
/// 预取写入(使缓存行进入修改状态)
|
||||
///
|
||||
/// @param addr 要预取的内存地址
|
||||
///
|
||||
/// @ingroup core
|
||||
inline void prefetch_write(const void* addr) {
|
||||
__builtin_prefetch(addr, 1, 3);
|
||||
}
|
||||
|
||||
/// 防止假共享的填充字段
|
||||
///
|
||||
/// 用法:将共享原子变量放在填充结构体中
|
||||
/// @code
|
||||
/// struct alignas(64) PaddedCounter {
|
||||
/// std::atomic<int> value{0};
|
||||
/// };
|
||||
/// @endcode
|
||||
template<size_t Alignment = CACHE_LINE_SIZE>
|
||||
struct PaddedAtomic {
|
||||
std::atomic<int> value{0};
|
||||
char padding[Alignment - sizeof(std::atomic<int>)]{};
|
||||
};
|
||||
static_assert(sizeof(PaddedAtomic<CACHE_LINE_SIZE>) == CACHE_LINE_SIZE,
|
||||
"PaddedAtomic must be exactly one cache line");
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// 数据布局优化 (Profile-Guided Layout)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// 访问频率记录
|
||||
struct AccessRecord {
|
||||
std::string field_name; ///< 字段名
|
||||
size_t access_count = 0; ///< 访问次数
|
||||
size_t cache_misses = 0; ///< 缓存未命中次数
|
||||
double hotness = 0.0; ///< 热度(访问/总访问)
|
||||
};
|
||||
|
||||
/// SoA (Structure of Arrays) 布局变换方案
|
||||
///
|
||||
/// 将 AoS 布局(结构体数组)转换为 SoA 布局(数组结构体)以改善缓存利用率。
|
||||
/// 适用场景:遍历大量 Point3D/Vector3D 进行坐标变换、碰撞检测等。
|
||||
struct SoALayoutPlan {
|
||||
std::vector<std::string> hot_fields; ///< 热字段列表(应放在前面)
|
||||
std::vector<std::string> cold_fields; ///< 冷字段列表(可放在后面)
|
||||
size_t stride_bytes = 0; ///< 行跨距 (bytes)
|
||||
double estimated_improvement = 0.0; ///< 预估性能提升比例
|
||||
};
|
||||
|
||||
/// 基于性能分析的数据布局优化
|
||||
///
|
||||
/// 分析给定类型的访问模式,生成 SoA 布局变换方案。
|
||||
/// 热字段(频繁访问)放在一起以提高缓存命中率,
|
||||
/// 冷字段(偶尔访问)分离以减少缓存污染。
|
||||
///
|
||||
/// @param access_records 各字段的访问记录
|
||||
/// @param type_name 类型名称
|
||||
/// @return SoA 布局变换方案
|
||||
///
|
||||
/// @ingroup core
|
||||
[[nodiscard]] SoALayoutPlan profile_guided_layout(
|
||||
const std::vector<AccessRecord>& access_records,
|
||||
const std::string& type_name = "");
|
||||
|
||||
/// Point3D 的 SoA 布局
|
||||
struct Point3DSoA {
|
||||
std::vector<double> x; ///< X 坐标数组
|
||||
std::vector<double> y; ///< Y 坐标数组
|
||||
std::vector<double> z; ///< Z 坐标数组
|
||||
|
||||
/// 从 AoS 转换为 SoA
|
||||
static Point3DSoA from_aos(const std::vector<Point3D>& points);
|
||||
|
||||
/// 从 SoA 转换为 AoS
|
||||
std::vector<Point3D> to_aos() const;
|
||||
|
||||
/// 点数
|
||||
[[nodiscard]] size_t size() const { return x.size(); }
|
||||
|
||||
/// 清空
|
||||
void clear() { x.clear(); y.clear(); z.clear(); }
|
||||
};
|
||||
|
||||
} // namespace vde::core
|
||||
@@ -0,0 +1,202 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file advanced_intersection.h
|
||||
* @brief 高级曲面求交 — 鲁棒 SSI(三阶段)、曲线-曲面求交、自交检测
|
||||
*
|
||||
* 对标 CGM 的工业级曲面求交算法,提供:
|
||||
* - 鲁棒曲面-曲面求交(三阶段:AABB细分→Newton精化→奇异点处理)
|
||||
* - 曲线-曲面求交
|
||||
* - 曲面自交检测
|
||||
*
|
||||
* @ingroup curves
|
||||
*/
|
||||
|
||||
#include "vde/curves/nurbs_curve.h"
|
||||
#include "vde/curves/nurbs_surface.h"
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/core/aabb.h"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
namespace vde::curves {
|
||||
|
||||
using core::Point3D;
|
||||
using core::Vector3D;
|
||||
using core::AABB3D;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Robust SSI — 鲁棒曲面-曲面求交
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// SSI 交线段(参数空间)
|
||||
struct SSISegment {
|
||||
/// 曲面 A 上的参数点 (u,v)
|
||||
std::vector<std::pair<double, double>> params_a;
|
||||
/// 曲面 B 上的参数点 (u,v)
|
||||
std::vector<std::pair<double, double>> params_b;
|
||||
/// 3D 空间点
|
||||
std::vector<Point3D> points;
|
||||
/// 是否为奇异交线(切线接触、重叠等)
|
||||
bool is_singular = false;
|
||||
/// 奇异类型描述
|
||||
std::string singularity_type;
|
||||
};
|
||||
|
||||
/// SSI 选项
|
||||
struct SSIOptions {
|
||||
/// 阶段1:AABB 细分参数
|
||||
int max_subdivision_depth = 8; ///< 最大细分深度
|
||||
double subdivision_tolerance = 1e-3; ///< 细分终止容差
|
||||
int min_patch_samples = 4; ///< 每子面片最少采样点
|
||||
|
||||
/// 阶段2:Newton 精化参数
|
||||
double newton_tolerance = 1e-12; ///< Newton 收敛容差
|
||||
int max_newton_iter = 30; ///< Newton 最大迭代次数
|
||||
double step_damping = 0.5; ///< 步长阻尼因子
|
||||
|
||||
/// 阶段3:奇异点检测参数
|
||||
double singular_condition_threshold = 1e-8; ///< 条件数阈值(小于此值判为奇异)
|
||||
double tangent_contact_angle_tol = 0.01; ///< 切线接触角度容差(弧度)
|
||||
bool detect_overlap = true; ///< 是否检测重叠面
|
||||
};
|
||||
|
||||
/// SSI 完整结果
|
||||
struct SSIResult {
|
||||
/// 交线段列表
|
||||
std::vector<SSISegment> segments;
|
||||
/// 阶段统计
|
||||
int phase1_subdivisions = 0; ///< 细分次数
|
||||
int phase1_candidates = 0; ///< 候选种子数
|
||||
int phase2_converged = 0; ///< Newton 收敛数
|
||||
int phase2_diverged = 0; ///< Newton 发散数
|
||||
int phase3_singularities = 0; ///< 检测到的奇异点数
|
||||
double total_time_ms = 0.0; ///< 总耗时(毫秒)
|
||||
bool success = false; ///< 是否成功完成
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 鲁棒曲面-曲面求交(三阶段)
|
||||
*
|
||||
* **阶段1:边界盒预筛选 + 自适应细分**
|
||||
* - 计算两曲面 AABB 盒,快速排除不相交区域
|
||||
* - 在参数域自适应四叉树细分,定位交线种子点
|
||||
* - 使用区间算术评估曲面片相交性
|
||||
*
|
||||
* **阶段2:Newton-Raphson 精化**
|
||||
* - 从种子点启动 Newton 迭代求解 F(u1,v1,u2,v2)=0
|
||||
* - 收敛到 1e-12 高精度
|
||||
* - 沿交线追踪(marching)生成连续交线段
|
||||
*
|
||||
* **阶段3:奇异点检测 + 特殊处理**
|
||||
* - Jacobian 条件数检测:识别切线接触、高阶接触
|
||||
* - 奇异点处使用 subdivision + 约束优化
|
||||
* - 重叠面使用采样投票 + 特征值分析
|
||||
*
|
||||
* @param surf_a 曲面 A
|
||||
* @param surf_b 曲面 B
|
||||
* @param options SSI 选项
|
||||
* @return 交线结果(含阶段统计)
|
||||
*
|
||||
* @note 对标 CGM Robust SSI / ACIS intersector
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] SSIResult robust_ssi(
|
||||
const NurbsSurface& surf_a,
|
||||
const NurbsSurface& surf_b,
|
||||
const SSIOptions& options = {});
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Curve-Surface Intersection — 曲线-曲面求交
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 曲线-曲面交点
|
||||
struct CSIntersectionPoint {
|
||||
double t; ///< 曲线上的参数
|
||||
double u, v; ///< 曲面上的参数 (u,v)
|
||||
Point3D position; ///< 3D 交点坐标
|
||||
double distance; ///< 交点处曲线到曲面的距离
|
||||
bool tangent_contact = false; ///< 是否为切线接触
|
||||
int multiplicity = 1; ///< 交点重数
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 曲线-曲面求交
|
||||
*
|
||||
* 计算 NURBS 曲线与 NURBS 曲面的所有交点。
|
||||
* 算法:
|
||||
* 1. 将曲线离散为线性段,建立曲线 AABB 加速结构
|
||||
* 2. 在曲面参数域使用细分 + Newton 精化
|
||||
* 3. 对切线接触情况使用更高阶方法
|
||||
*
|
||||
* @param curve NURBS 曲线
|
||||
* @param surf NURBS 曲面
|
||||
* @param tolerance 收敛容差(默认 1e-10)
|
||||
* @return 交点列表(按曲线参数 t 排序)
|
||||
*
|
||||
* @note 对标 CGM Curve-Surface Intersection
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] std::vector<CSIntersectionPoint> curve_surface_intersection(
|
||||
const NurbsCurve& curve,
|
||||
const NurbsSurface& surf,
|
||||
double tolerance = 1e-10);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Self-Intersection Detection — 自交检测
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 自交区域
|
||||
struct SelfIntersectionRegion {
|
||||
/// 参数空间中检测到自交的子区域范围
|
||||
double u_min, u_max, v_min, v_max;
|
||||
/// 自交类型
|
||||
enum Type {
|
||||
NONE = 0,
|
||||
EDGE_OVERLAP = 1, ///< 边界重叠
|
||||
INTERIOR_CROSS = 2, ///< 内部交叉
|
||||
TANGENT_CONTACT = 3, ///< 切线接触
|
||||
LOCAL_LOOP = 4 ///< 局部环
|
||||
};
|
||||
Type type = NONE;
|
||||
/// 3D 空间中最近交点
|
||||
Point3D closest_intersection;
|
||||
double min_distance = std::numeric_limits<double>::max();
|
||||
/// 曲面上最近自交处的法线夹角
|
||||
double normal_angle_deg = 0.0;
|
||||
};
|
||||
|
||||
/// 自交检测结果
|
||||
struct SelfIntersectionResult {
|
||||
bool has_self_intersection = false;
|
||||
std::vector<SelfIntersectionRegion> regions;
|
||||
double global_min_distance = std::numeric_limits<double>::max();
|
||||
int total_checks = 0;
|
||||
int intersecting_pairs = 0;
|
||||
double detection_time_ms = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 曲面自交检测
|
||||
*
|
||||
* 检测 NURBS 曲面是否自交(不同参数值映射到同一点/相近点)。
|
||||
* 算法:
|
||||
* 1. 对曲面参数域构建 BVH 加速结构
|
||||
* 2. 对每对不相邻的 BVH 节点,检测是否在 3D 空间相交
|
||||
* 3. 对疑似自交区域进行 Newton 精化确认
|
||||
* 4. 分类自交类型(交叉、重叠、切线接触、局部环)
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @param tolerance 自交检测容差(3D 空间距离,默认 1e-8)
|
||||
* @return 自交检测结果
|
||||
*
|
||||
* @note 对标 CGM Self-Intersection Check / ACIS self-intersect
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] SelfIntersectionResult self_intersection_detection(
|
||||
const NurbsSurface& surface,
|
||||
double tolerance = 1e-8);
|
||||
|
||||
} // namespace vde::curves
|
||||
@@ -0,0 +1,365 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file class_a_surfacing.h
|
||||
* @brief CGM Class-A 级曲面工具 — G3 过渡、曲率匹配、高光线、反射线、等照度、诊断、保形修改
|
||||
*
|
||||
* 对标 Dassault CGM 的 Class-A 曲面功能,提供汽车/航空工业级的曲面质量控制:
|
||||
* - G3 连续性过渡(位置+切平面+曲率+曲率变化率连续)
|
||||
* - 曲率匹配优化(最小二乘调整控制点使曲率场连续)
|
||||
* - 高光线/反射线/等照度分析(工业标准曲面光顺检测)
|
||||
* - 综合曲面诊断报告(多项指标评分)
|
||||
* - 保形修改(保持特征边界的曲面变形)
|
||||
*
|
||||
* @ingroup curves
|
||||
*/
|
||||
|
||||
#include "vde/curves/nurbs_curve.h"
|
||||
#include "vde/curves/nurbs_surface.h"
|
||||
#include "vde/core/point.h"
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::curves {
|
||||
|
||||
using core::Point3D;
|
||||
using core::Vector3D;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// G3 Blend — G3 连续性过渡曲面
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 边参数:定义过渡曲面的公共边方向与范围
|
||||
struct EdgeParams {
|
||||
int edge_a = 0; ///< surf_a 的边界索引 (0=umin, 1=umax, 2=vmin, 3=vmax)
|
||||
int edge_b = 0; ///< surf_b 的边界索引
|
||||
double blend_width = 0.1; ///< 过渡带宽度(参数域比例)
|
||||
bool align_orientation = true; ///< 是否自动对齐曲面朝向
|
||||
};
|
||||
|
||||
/// G3 连续性过渡结果
|
||||
struct G3BlendResult {
|
||||
NurbsSurface blend_surface; ///< 过渡曲面
|
||||
double max_position_error = 0.0; ///< 最大位置误差
|
||||
double max_tangent_error = 0.0; ///< 最大切平面角度误差(弧度)
|
||||
double max_curvature_error = 0.0; ///< 最大曲率偏差
|
||||
double max_curvature_derivative_error = 0.0; ///< 最大曲率变化率偏差
|
||||
bool g0_ok = false;
|
||||
bool g1_ok = false;
|
||||
bool g2_ok = false;
|
||||
bool g3_ok = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief G3 连续性过渡曲面
|
||||
*
|
||||
* 在两面公共边界处构造过渡曲面,使过渡面与两边曲面均达到 G3 连续。
|
||||
* 算法:
|
||||
* 1. 检测公共边界,提取边界曲线与跨边界导数(1阶、2阶、3阶)
|
||||
* 2. 构造 4 排过渡控制点,分别对应位置、切平面、曲率、曲率变化率约束
|
||||
* 3. 求解最小二乘系统保证 G3 连续
|
||||
*
|
||||
* @param surf_a 曲面 A
|
||||
* @param surf_b 曲面 B
|
||||
* @param params 边参数(边界索引、过渡宽度等)
|
||||
* @return G3 过渡结果(含过渡曲面与连续性验证数据)
|
||||
*
|
||||
* @note 对标 CGM G3 Filling 功能
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] G3BlendResult g3_blend(
|
||||
const NurbsSurface& surf_a,
|
||||
const NurbsSurface& surf_b,
|
||||
const EdgeParams& params);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Curvature Matching — 曲率匹配优化
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 曲率匹配选项
|
||||
struct CurvatureMatchOptions {
|
||||
double tolerance = 1e-8; ///< 收敛容差
|
||||
int max_iterations = 50; ///< 最大迭代次数
|
||||
int samples_per_edge = 20; ///< 边界采样点数
|
||||
double regularization = 0.01; ///< Tikhonov 正则化系数
|
||||
bool preserve_boundary = true; ///< 是否保持非匹配边界不变
|
||||
};
|
||||
|
||||
/// 曲率匹配结果
|
||||
struct CurvatureMatchResult {
|
||||
NurbsSurface matched_surface_b; ///< 匹配后的曲面 B
|
||||
double initial_rms_curvature_diff = 0.0; ///< 初始曲率 RMS 差
|
||||
double final_rms_curvature_diff = 0.0; ///< 最终曲率 RMS 差
|
||||
int iterations = 0; ///< 实际迭代次数
|
||||
bool converged = false; ///< 是否收敛
|
||||
std::vector<Point3D> displacement; ///< 控制点位移向量
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 曲率匹配优化
|
||||
*
|
||||
* 调整 surf_b 的控制点使两曲面沿公共边界的曲率场匹配,达到 G2+ 连续。
|
||||
* 使用 Levenberg-Marquardt 非线性最小二乘优化,约束边界控制点位移最小。
|
||||
*
|
||||
* @param surf_a 基准曲面 A(不变)
|
||||
* @param surf_b 待匹配曲面 B(将被修改)
|
||||
* @param options 优化选项
|
||||
* @return 匹配结果(含优化后的曲面 B)
|
||||
*
|
||||
* @note 对标 CGM Match Surface 功能
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] CurvatureMatchResult curvature_matching(
|
||||
const NurbsSurface& surf_a,
|
||||
const NurbsSurface& surf_b,
|
||||
const CurvatureMatchOptions& options = {});
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Highlight Lines — 高光线分析
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 高光线参数
|
||||
struct HighlightParams {
|
||||
std::vector<Vector3D> light_directions; ///< 多个光源方向(均自动归一化)
|
||||
int res_u = 50; ///< u 方向分辨率
|
||||
int res_v = 50; ///< v 方向分辨率
|
||||
int num_bands = 8; ///< 光带数量
|
||||
double band_width = 0.05; ///< 带宽(参数域比例)
|
||||
};
|
||||
|
||||
/// 高光线分析结果
|
||||
struct HighlightResult {
|
||||
int res_u, res_v; ///< 网格分辨率
|
||||
/// 高光线掩码网格 [dir_idx][u][v] ∈ {0,1}
|
||||
std::vector<std::vector<std::vector<int>>> band_mask;
|
||||
/// 各方向高光线连续性评分 [0,1]
|
||||
std::vector<double> continuity_scores;
|
||||
/// 综合评分
|
||||
double overall_score = 0.0;
|
||||
/// 不连续点列表 (u, v, dir_idx)
|
||||
std::vector<std::tuple<double, double, int>> discontinuities;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 高光线分析
|
||||
*
|
||||
* 模拟平行光源在曲面上的反射高光线,检测光线方向的几何不连续。
|
||||
* 高光线 ≤ C1 的断裂 = 曲面在此处仅有 C1 连续。
|
||||
* 高光线 C2 断裂 = 曲率不连续。
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @param light_dirs 光源方向列表
|
||||
* @param res_u u 方向分辨率
|
||||
* @param res_v v 方向分辨率
|
||||
* @param num_bands 光带数量
|
||||
* @return 高光线分析结果
|
||||
*
|
||||
* @note 对标 CGM Highlight Lines Analysis
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] HighlightResult highlight_lines(
|
||||
const NurbsSurface& surface,
|
||||
const std::vector<Vector3D>& light_dirs,
|
||||
int res_u, int res_v, int num_bands = 8);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Reflection Lines — 反射线分析
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 反射线分析结果
|
||||
struct ReflectionResult {
|
||||
int res_u, res_v; ///< 网格分辨率
|
||||
/// 反射线方向场 grid[u][v] = 反射光线方向
|
||||
std::vector<std::vector<Vector3D>> reflection_field;
|
||||
/// 反射线扭曲度 grid[u][v] ∈ [0,∞)
|
||||
std::vector<std::vector<double>> distortion;
|
||||
double max_distortion = 0.0;
|
||||
double mean_distortion = 0.0;
|
||||
bool is_fair = false; ///< 是否判定为光顺
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 反射线分析
|
||||
*
|
||||
* 计算虚拟环境(点光源或平行光)在曲面上的镜面反射线模式。
|
||||
* 通过计算反射方向场的扭曲度评估曲面光顺性。
|
||||
*
|
||||
* 算法:
|
||||
* law_of_reflection: r = 2(n·l)n - l (入射光方向 l,法线 n)
|
||||
* 扭曲度 = reflection_field 的方向导数幅值
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @param eye 观察点位置
|
||||
* @param light 光源位置(若为平行光则传入方向向量远端)
|
||||
* @param res_u u 方向分辨率
|
||||
* @param res_v v 方向分辨率
|
||||
* @return 反射线分析结果
|
||||
*
|
||||
* @note 对标 CGM Reflection Lines / Isophotes Analysis
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] ReflectionResult reflection_lines(
|
||||
const NurbsSurface& surface,
|
||||
const Point3D& eye,
|
||||
const Point3D& light,
|
||||
int res_u, int res_v);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Iso-Photes — 等照度分析
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 等照度线分析结果
|
||||
struct IsoPhoteResult {
|
||||
int res_u, res_v; ///< 网格分辨率
|
||||
/// 照度值网格 ∈ [-1, 1](光源方向·法线的点积)
|
||||
std::vector<std::vector<double>> illumination;
|
||||
/// 等照度线密度分布(直方图)
|
||||
std::vector<double> iso_histogram;
|
||||
/// 等照度线连续性 — 梯度突变点
|
||||
std::vector<std::pair<double,double>> gradient_discontinuities;
|
||||
double grad_max = 0.0;
|
||||
double grad_mean = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 等照度分析
|
||||
*
|
||||
* 计算光源照射下曲面上的等照度线(恒定 cosθ 线)。
|
||||
* 等照度线在 G1 连续处平滑,在仅有 C0 处出现转折。
|
||||
* 等照度线的质量直接反映曲面光顺度:
|
||||
* - 间距均匀 → 曲率均匀
|
||||
* - 无抖动 → 高阶连续性好
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @param res 分辨率(res × res 采样点)
|
||||
* @return 等照度分析结果
|
||||
*
|
||||
* @note 对标 CGM Iso-Photes Analysis
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] IsoPhoteResult iso_photes(
|
||||
const NurbsSurface& surface,
|
||||
int res);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Surface Diagnosis — 综合曲面诊断报告
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 诊断等级
|
||||
enum class DiagnosisGrade {
|
||||
A_CLASS = 0, ///< A 级曲面 — 通过所有检测
|
||||
B_CLASS = 1, ///< B 级曲面 — 可接受,有轻微缺陷
|
||||
C_CLASS = 2, ///< C 级曲面 — 需要修复
|
||||
FAIL = 3 ///< 不合格
|
||||
};
|
||||
|
||||
/// 子项诊断结果
|
||||
struct DiagnosisItem {
|
||||
std::string name; ///< 诊断项名称
|
||||
double value = 0.0; ///< 测量值
|
||||
double threshold = 0.0; ///< 阈值
|
||||
bool pass = false; ///< 是否通过
|
||||
std::string description; ///< 描述
|
||||
};
|
||||
|
||||
/// 综合曲面诊断报告
|
||||
struct SurfaceDiagnosisReport {
|
||||
DiagnosisGrade grade = DiagnosisGrade::FAIL;
|
||||
|
||||
/// 高斯曲率诊断
|
||||
DiagnosisItem gaussian_range; ///< 高斯曲率范围
|
||||
DiagnosisItem gaussian_continuity; ///< 高斯曲率连续性
|
||||
|
||||
/// 平均曲率诊断
|
||||
DiagnosisItem mean_range; ///< 平均曲率范围
|
||||
|
||||
/// 高光线诊断
|
||||
DiagnosisItem highlight_score; ///< 高光线评分
|
||||
|
||||
/// 反射线诊断
|
||||
DiagnosisItem reflection_distortion; ///< 反射扭曲度
|
||||
|
||||
/// 等照度诊断
|
||||
DiagnosisItem isophote_gradient; ///< 等照度梯度
|
||||
|
||||
/// 法线连续性
|
||||
DiagnosisItem normal_jump; ///< 最大法线跳跃(角度°)
|
||||
|
||||
/// 主曲率方向场
|
||||
DiagnosisItem principal_direction_flow; ///< 主方向场平滑度
|
||||
|
||||
/// 可展性
|
||||
DiagnosisItem developability; ///< 可展面检测
|
||||
|
||||
double overall_score = 0.0; ///< 综合评分 [0, 100]
|
||||
std::string recommendation; ///< 修复建议
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 综合曲面诊断报告
|
||||
*
|
||||
* 对单张 NURBS 曲面进行多项工业级质量检测,生成诊断报告:
|
||||
* 1. 高斯/平均曲率范围及连续性
|
||||
* 2. 高光线分析(4方向)
|
||||
* 3. 反射线扭曲度
|
||||
* 4. 等照度梯度
|
||||
* 5. 法线连续性(内部采样)
|
||||
* 6. 主曲率方向场流畅度
|
||||
* 7. 可展面检测
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @return 综合诊断报告
|
||||
*
|
||||
* @note 对标 CGM Surface Diagnosis / CATIA Generative Shape Design
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] SurfaceDiagnosisReport surface_diagnosis(
|
||||
const NurbsSurface& surface);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Shape Modification — 保形修改
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 约束点
|
||||
struct ShapeConstraint {
|
||||
Point3D target_point; ///< 目标位置
|
||||
double u = 0.0; ///< 曲面参数 u
|
||||
double v = 0.0; ///< 曲面参数 v
|
||||
double weight = 1.0; ///< 约束权重
|
||||
bool fix_position = true; ///< true=位置约束, false=仅法向约束
|
||||
Vector3D target_normal; ///< 目标法向(仅 fix_position=false 时使用)
|
||||
};
|
||||
|
||||
/// 保形修改结果
|
||||
struct ShapeModificationResult {
|
||||
NurbsSurface modified_surface; ///< 修改后的曲面
|
||||
std::vector<Point3D> control_displacements; ///< 控制点位移
|
||||
double max_displacement = 0.0; ///< 最大控制点位移
|
||||
double energy_preserved_ratio = 0.0; ///< 应变能保持率 (0~1)
|
||||
double boundary_deviation = 0.0; ///< 边界偏差
|
||||
int iterations = 0; ///< 迭代次数
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 保形修改
|
||||
*
|
||||
* 在约束条件下修改曲面控制点,同时最小化曲面变形能量,
|
||||
* 保持曲面的整体形状特征(边界、特征线等)。
|
||||
*
|
||||
* 算法:基于薄板样条能量最小化的约束优化
|
||||
* E = Σ (||S(u_i,v_i) - target_i||² · w_i) + λ · bending_energy(S)
|
||||
*
|
||||
* @param surface NURBS 曲面
|
||||
* @param constraints 约束点列表
|
||||
* @return 修改结果
|
||||
*
|
||||
* @note 对标 CGM Shape Modification / Control Point Morphing
|
||||
* @ingroup curves
|
||||
*/
|
||||
[[nodiscard]] ShapeModificationResult shape_modification(
|
||||
const NurbsSurface& surface,
|
||||
const std::vector<ShapeConstraint>& constraints);
|
||||
|
||||
} // namespace vde::curves
|
||||
Reference in New Issue
Block a user