docs: v3.8 engineering drawing + G2 continuity plan
This commit is contained in:
@@ -347,6 +347,12 @@ public:
|
||||
*/
|
||||
[[nodiscard]] std::vector<int> vertex_edges(int vertex_id) const;
|
||||
|
||||
// ── 友元:拓扑修复需要直接访问内部数据 ──
|
||||
friend int heal_merge_vertices(BrepModel&, double);
|
||||
friend int heal_merge_edges(BrepModel&, double);
|
||||
friend int heal_close_gaps(BrepModel&, double);
|
||||
friend int heal_orientation(BrepModel&);
|
||||
|
||||
private:
|
||||
std::vector<TopoVertex> vertices_;
|
||||
std::vector<TopoEdge> edges_;
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file brep_heal.h
|
||||
* @brief B-Rep 拓扑修复
|
||||
*
|
||||
* 对 BrepModel 执行拓扑修复操作,处理导入 STEP/IGES 文件时常见的
|
||||
* 几何缺陷:重复顶点、冗余边、间隙和方向不一致。
|
||||
*
|
||||
* ## 修复流水线
|
||||
*
|
||||
* 1. heal_merge_vertices — 合并重合顶点
|
||||
* 2. heal_merge_edges — 合并重合边
|
||||
* 3. heal_close_gaps — 闭合小间隙
|
||||
* 4. heal_orientation — 统一面方向
|
||||
*
|
||||
* 建议通过 heal_topology() 一次性执行完整流水线。
|
||||
*
|
||||
* @ingroup brep
|
||||
*/
|
||||
#include "vde/brep/brep.h"
|
||||
#include "vde/brep/brep_validate.h"
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/**
|
||||
* @brief 合并重合顶点
|
||||
*
|
||||
* 扫描所有顶点对,将距离小于 tolerance 的顶点合并为一个。
|
||||
* 更新所有引用被合并顶点的边,使其指向保留的顶点。
|
||||
*
|
||||
* @param body 待修复的 B-Rep 模型(原地修改)
|
||||
* @param tolerance 距离容差,默认 1e-6
|
||||
* @return 合并的顶点对数
|
||||
*
|
||||
* @note 合并后 body.vertices_ 的大小会减小。
|
||||
* @note 顶点 ID 引用的重定向使用 Edges → Loops 层次。
|
||||
*/
|
||||
int heal_merge_vertices(BrepModel& body, double tolerance = 1e-6);
|
||||
|
||||
/**
|
||||
* @brief 合并重合边
|
||||
*
|
||||
* 查找共享端点且曲线几何几乎相同的边对,将其中一条边合并到另一条。
|
||||
* 更新所有引用被合并边的环,使其指向保留的边。
|
||||
*
|
||||
* @param body 待修复的 B-Rep 模型(原地修改)
|
||||
* @param tolerance 曲线几何比较容差,默认 1e-6
|
||||
* @return 合并的边对数
|
||||
*/
|
||||
int heal_merge_edges(BrepModel& body, double tolerance = 1e-6);
|
||||
|
||||
/**
|
||||
* @brief 闭合面之间的微小间隙
|
||||
*
|
||||
* 检查每条边的端点是否在 max_gap 范围内接近另一条边的端点。
|
||||
* 将接近的顶点吸附到一起,消除拓扑间隙。
|
||||
*
|
||||
* @param body 待修复的 B-Rep 模型(原地修改)
|
||||
* @param max_gap 最大间隙尺寸,默认 1e-4
|
||||
* @return 闭合的间隙数
|
||||
*/
|
||||
int heal_close_gaps(BrepModel& body, double max_gap = 1e-4);
|
||||
|
||||
/**
|
||||
* @brief 统一面方向(全部向外)
|
||||
*
|
||||
* 通过符号体积计算确保所有面法向量朝外。
|
||||
* 对于方向朝内的面,翻转其 reversed 标志。
|
||||
*
|
||||
* @param body 待修复的 B-Rep 模型(原地修改)
|
||||
* @return 翻转的面数
|
||||
*/
|
||||
int heal_orientation(BrepModel& body);
|
||||
|
||||
/**
|
||||
* @brief 执行完整拓扑修复流水线
|
||||
*
|
||||
* 按推荐顺序执行所有修复步骤:
|
||||
* 顶点合并 → 边合并 → 间隙闭合 → 方向统一
|
||||
* 最后调用 validate() 检查修复结果。
|
||||
*
|
||||
* @param body 待修复的 B-Rep 模型(原地修改)
|
||||
* @param tolerance 用于顶点/边合并的距离容差,默认 1e-6
|
||||
* @return true 如果修复后模型通过验证
|
||||
*
|
||||
* @code{.cpp}
|
||||
* BrepModel body = import_step("part.step");
|
||||
* if (heal_topology(body)) {
|
||||
* // 模型已修复,可以安全执行布尔运算等操作
|
||||
* auto result = validate(body);
|
||||
* assert(result.valid);
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
bool heal_topology(BrepModel& body, double tolerance = 1e-6);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -214,18 +214,45 @@ using core::AABB3D;
|
||||
* @return 圆角后的新实体
|
||||
*
|
||||
* @note 圆角半径不能超过相邻面的最小宽度,否则会产生自交。
|
||||
* @note 只支持恒定半径圆角。变半径圆角尚未实现。
|
||||
*
|
||||
* @code{.cpp}
|
||||
* auto box = make_box(10, 5, 3);
|
||||
* auto rounded = fillet(box, 0, 2.0); // 对边 0 做半径 2 的圆角
|
||||
* @endcode
|
||||
*
|
||||
* @see fillet_variable 变半径圆角
|
||||
* @see chamfer 倒角
|
||||
* @see shell 抽壳
|
||||
*/
|
||||
[[nodiscard]] BrepModel fillet(const BrepModel& body, int edge_id, double radius);
|
||||
|
||||
/**
|
||||
* @brief 变半径圆角
|
||||
*
|
||||
* 沿边的参数方向在 r_start 和 r_end 之间线性插值半径,
|
||||
* 生成平滑过渡的圆角曲面。
|
||||
*
|
||||
* @param body 输入实体
|
||||
* @param edge_id 要倒圆的边 ID
|
||||
* @param r_start 边起点处的圆角半径
|
||||
* @param r_end 边终点处的圆角半径
|
||||
* @param samples 沿边的横截面采样数(默认 8)
|
||||
* @return 变半径圆角后的新实体
|
||||
*
|
||||
* @pre r_start ≥ 0, r_end ≥ 0,且至少一个 > 0
|
||||
* @note samples 越大截面过渡越光滑,但面和边数增加。
|
||||
*
|
||||
* @code{.cpp}
|
||||
* auto box = make_box(10, 5, 3);
|
||||
* auto result = fillet_variable(box, 0, 0.5, 2.0, 12);
|
||||
* // 边 0 从 0.5 到 2.0 逐渐变化的圆角
|
||||
* @endcode
|
||||
*
|
||||
* @see fillet 恒定半径圆角
|
||||
*/
|
||||
[[nodiscard]] BrepModel fillet_variable(const BrepModel& body, int edge_id,
|
||||
double r_start, double r_end, int samples = 8);
|
||||
|
||||
/**
|
||||
* @brief 对边做倒角
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user