Files
ViewDesignEngine/include/vde/brep/direct_modeling.h
T
茂之钳 6bc9db663e
CI / Build & Test (push) Failing after 33s
CI / Release Build (push) Failing after 39s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v5-M3): large assembly LOD + constraint solver + CAM strategies + direct modeling
M3.1 — 大装配 LOD + 约束求解器 (Agent #0):
- assembly_lod.h/.cpp: 3-level LOD (Full/Simplified/BBox), view-distance auto-switch
- constraint_solver.h/.cpp: ConstraintGraph, DOF analysis, Newton-Raphson solver
- 7 constraint types, over-constraint detection, incremental solve
- 59 tests (22 LOD + 37 constraint)

M3.2 — 完整 CAM 策略 (Agent #1):
- cam_strategies.h/.cpp: roughing(Z-layer), finishing(parallel/spiral), drilling(G81/G83/G84)
- Tool/ToolLibrary, PostProcessor (Fanuc/Siemens/Heidenhain)
- material_removal_simulation with volume stats
- 27 tests, 26/27 passing

M3.3 — 直接建模 (Agent #2):
- direct_modeling.h/.cpp: tweak_face, move_face, replace_face, push_pull, offset_face
- Auto neighbor-face extension for watertightness
- DirectModelingResult with diagnostics
- 23 tests with validate() verification

12 files, ~5400 lines, 109 tests
2026-07-26 21:19:38 +08:00

191 lines
7.2 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
/**
* @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);
} // namespace vde::brep