Files
ViewDesignEngine/include/vde/brep/direct_modeling.h
T

191 lines
7.2 KiB
C++
Raw Normal View History

#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