921c29cb22
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
274 lines
10 KiB
C++
274 lines
10 KiB
C++
#pragma once
|
||
/**
|
||
* @file direct_modeling.h
|
||
* @brief 直接建模操作 — 面级推拉/偏移/移动/替换
|
||
*
|
||
* 直接建模(Direct Modeling / Synchronous Technology)允许用户
|
||
* 直接操纵几何面而不依赖特征历史树。该模块提供:
|
||
*
|
||
* | 操作 | 含义 |
|
||
* |--------------|-----------------------------------------|
|
||
* | tweak_face | 面沿法向微调偏移,邻面自动延伸保持水密 |
|
||
* | move_face | 面刚体移动(平移+旋转),检测不穿透邻面 |
|
||
* | replace_face | 面替换(交换曲面),边界兼容性检查 |
|
||
* | push_pull | 推拉:正值=挤出加材料,负值=切除减材料 |
|
||
* | offset_face | 面等距偏移 |
|
||
*
|
||
* 所有操作返回 DirectModelingResult,含成功/失败诊断及生成的新模型。
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
|
||
#include "vde/brep/brep.h"
|
||
#include "vde/curves/nurbs_surface.h"
|
||
#include "vde/core/transform.h"
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
namespace vde::brep {
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// DirectModelingResult — 操作结果
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief 直接建模操作结果
|
||
*
|
||
* 包含成功/失败标志、错误/警告诊断信息及生成的新模型。
|
||
* 即使操作部分成功(如某些邻面未能延伸)也会在 warnings 中记录。
|
||
*/
|
||
struct DirectModelingResult {
|
||
/** @brief 操作是否成功(至少基本几何有效) */
|
||
bool success = false;
|
||
|
||
/** @brief 结果模型(success=true 时有效,否则为输入副本) */
|
||
BrepModel body;
|
||
|
||
/** @brief 错误消息列表(导致 success=false) */
|
||
std::vector<std::string> errors;
|
||
|
||
/** @brief 警告消息列表(不影响 success) */
|
||
std::vector<std::string> warnings;
|
||
|
||
/** @brief 受影响的面数 */
|
||
int affected_faces = 0;
|
||
|
||
/** @brief 新建的面数(推拉产生的侧面等) */
|
||
int new_faces = 0;
|
||
|
||
/** @brief 操作类型名称(供日志/UI 显示) */
|
||
std::string operation;
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// Direct Modeling Operations
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief 面微调:沿法向偏移指定距离
|
||
*
|
||
* 将面沿其法向量方向偏移 delta。邻面自动延伸/裁剪
|
||
* 以保持水密封闭体。适合小范围的面调整。
|
||
*
|
||
* @param body 输入 B-Rep 实体
|
||
* @param face_id 目标面索引(0..num_faces-1)
|
||
* @param delta 偏移距离(正=沿法向向外,负=向内)
|
||
* @return DirectModelingResult 含新模型和诊断信息
|
||
*
|
||
* @pre face_id 在 [0, body.num_faces()) 范围内
|
||
* @pre 实体应为封闭水密体
|
||
*
|
||
* @code{.cpp}
|
||
* auto box = make_box(2, 2, 2);
|
||
* auto result = tweak_face(box, 0, 0.5); // 顶面上移 0.5
|
||
* // 四个侧面自动延伸保持水密
|
||
* @endcode
|
||
*/
|
||
[[nodiscard]] DirectModelingResult tweak_face(const BrepModel& body,
|
||
int face_id, double delta);
|
||
|
||
/**
|
||
* @brief 面移动:对指定面施加刚体变换
|
||
*
|
||
* 通过 4x4 仿射变换矩阵移动面。检测移动后面是否
|
||
* 与邻面相交(产生自交),相交时返回错误。
|
||
*
|
||
* @param body 输入 B-Rep 实体
|
||
* @param face_id 目标面索引
|
||
* @param transform 刚体变换矩阵(仅平移+旋转,不含缩放)
|
||
* @return DirectModelingResult 含新模型和诊断
|
||
*
|
||
* @note 非均匀缩放会导致法线失真;使用 Transform3D 时建议只用平移+旋转
|
||
* @note 移动后检测面是否穿透邻面(通过法线方向变化判断)
|
||
*
|
||
* @code{.cpp}
|
||
* auto box = make_box(2, 2, 2);
|
||
* auto T = translate(Vector3D(0.5, 0, 0)) * rotate_z(M_PI / 4);
|
||
* auto result = move_face(box, 0, T);
|
||
* @endcode
|
||
*/
|
||
[[nodiscard]] DirectModelingResult move_face(const BrepModel& body,
|
||
int face_id,
|
||
const core::Transform3D& transform);
|
||
|
||
/**
|
||
* @brief 面替换:用新曲面替换面的现有曲面
|
||
*
|
||
* 新曲面与原面必须有兼容的边界:新曲面的四条边界
|
||
* 应近似匹配面的四条边界边。不兼容时操作失败。
|
||
*
|
||
* @param body 输入 B-Rep 实体
|
||
* @param face_id 目标面索引
|
||
* @param new_surface 替换用的新 NURBS 曲面
|
||
* @return DirectModelingResult 含新模型和诊断
|
||
*
|
||
* @note 仅替换曲面的几何定义,拓扑结构不变
|
||
* @note 新曲面参数域应与原曲面兼容(边界对应对齐)
|
||
*
|
||
* @code{.cpp}
|
||
* auto box = make_box(2, 2, 2);
|
||
* NurbsSurface curved_surf = ...; // 曲面边界与 box 顶面匹配
|
||
* auto result = replace_face(box, 0, curved_surf);
|
||
* @endcode
|
||
*/
|
||
[[nodiscard]] DirectModelingResult replace_face(const BrepModel& body,
|
||
int face_id,
|
||
const curves::NurbsSurface& new_surface);
|
||
|
||
/**
|
||
* @brief 推拉操作:沿法线挤出(正值)或切除(负值)
|
||
*
|
||
* 正值 distance:面沿法向向外挤出,自动创建四侧面
|
||
* 闭合新体积。等同于"挤出添加材料"。
|
||
*
|
||
* 负值 distance:面沿法向向内凹陷,邻面自动延伸
|
||
* 封闭。等同于"切除材料"。
|
||
*
|
||
* @param body 输入 B-Rep 实体
|
||
* @param face_id 目标面索引
|
||
* @param distance 推拉距离(正=挤出加材料,负=切除减材料)
|
||
* @return DirectModelingResult 含新模型和诊断
|
||
*
|
||
* @pre distance 的绝对值不超过实体在法线方向的最小厚度
|
||
*
|
||
* @code{.cpp}
|
||
* auto box = make_box(2, 2, 2);
|
||
* // 顶面挤出 1.0 → 凸台
|
||
* auto pad = push_pull(box, 0, 1.0);
|
||
* // 顶面切除 0.5 → 凹陷
|
||
* auto pocket = push_pull(box, 0, -0.5);
|
||
* @endcode
|
||
*/
|
||
[[nodiscard]] DirectModelingResult push_pull(const BrepModel& body,
|
||
int face_id, double distance);
|
||
|
||
/**
|
||
* @brief 面等距偏移:将面均匀偏移指定距离
|
||
*
|
||
* 面等距偏移与 tweak_face 的区别:
|
||
* - offset_face 保证偏移后曲面与原曲面处处等距(等距曲面)
|
||
* - tweak_face 是近似偏移(沿平均法向移动顶点)
|
||
*
|
||
* 对于平面,两者等价。对于曲面,offset_face 生成
|
||
* 真正的等距曲面。
|
||
*
|
||
* @param body 输入 B-Rep 实体
|
||
* @param face_id 目标面索引
|
||
* @param offset_distance 等距偏移距离(正=向外,负=向内)
|
||
* @return DirectModelingResult 含新模型和诊断
|
||
*
|
||
* @warning 自由曲面等距偏移可能产生自交,需检查结果有效性
|
||
*
|
||
* @code{.cpp}
|
||
* auto sphere = make_sphere(3.0);
|
||
* auto result = offset_face(sphere, 0, 0.2); // 面均匀外扩 0.2
|
||
* @endcode
|
||
*/
|
||
[[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
|