#pragma once /** * @file advanced_blend.h * @brief 高级过渡曲面(Advanced Blend)操作 * * 提供多种超出简单恒定半径圆角的过渡曲面算法: * - 沿边变半径过渡(variable_radius_blend) * - 多面同时过渡(multi_face_blend) * - 滚动球算法(rolling_ball_blend) * - 两面间恒定半径过渡(face_face_blend) * * ## 与 fillet/fillet_variable 的关系 * * modeling.h 中的 fillet 和 fillet_variable 是面向最终用户的高层 API, * 本模块提供更底层的过渡曲面算法实现。两者可配合使用。 * * @ingroup brep */ #include "vde/brep/brep.h" #include namespace vde::brep { /** * @brief 沿边变半径过渡 * * 沿指定边的参数方向,在 r_start 和 r_end 之间线性插值半径, * 每段独立构建过渡曲面片段,最终拼接为完整过渡。 * * 算法: * 1. 定位目标边及其两个邻面 * 2. 计算两面法向量及角平分线方向 * 3. 沿边曲线采样 N 个截面,每个截面处计算半径和切点 * 4. 每相邻两截面间构建一张过渡曲面(NURBS quad patch) * 5. 重建两个邻面,切除过渡区域 * 6. 复制未受影响的面,组装壳和体 * * @param body 输入实体 * @param edge_id 目标边索引 * @param r_start 边起点处的过渡半径(≥ 0) * @param r_end 边终点处的过渡半径(≥ 0) * @param samples 沿边的截面采样数(默认 16) * @return 过渡后的新实体 * * @pre edge_id 有效,r_start ≥ 0, r_end ≥ 0 * @note samples 越大截面过渡越光滑,但面和边数增加 */ [[nodiscard]] BrepModel variable_radius_blend( const BrepModel& body, int edge_id, double r_start, double r_end, int samples = 16); /** * @brief 多面同时过渡 * * 对多个面同时施加恒定半径的过渡处理。每个目标面独立向内偏移, * 目标面之间的交角处构造球面填充,非目标面保持不变。 * * 算法: * 1. 对每个目标面,沿面法向量向内偏移半径距离 * 2. 检测目标面之间的共享边,在交线处构造圆柱过渡 * 3. 检测三面以上交角顶点,用球面贴片填充 * 4. 复制非目标面,组装壳和体 * * @param body 输入实体 * @param face_ids 目标面索引列表 * @param radius 过渡半径(> 0) * @return 过渡后的新实体 * * @pre face_ids 非空,所有索引有效,radius > 0 */ [[nodiscard]] BrepModel multi_face_blend( const BrepModel& body, const std::vector& face_ids, double radius); /** * @brief 滚动球算法过渡 * * 模拟一个半径为 radius 的球体沿目标边滚动,球体的扫掠包络面即为过渡曲面。 * 球体始终保持与边的两个邻面接触,其中心沿边的等距曲线移动。 * * 算法: * 1. 计算滚动球中心轨迹(沿边的 offset 曲线,offset = r / cos(half_angle)) * 2. 沿边采样球心位置 * 3. 每个球心位置计算球与两面的切点 * 4. 相邻截面间构建过渡曲面 patch(近似球体扫掠包络) * 5. 重建邻面、复制非影响面、组装壳和体 * * 对直边退化为圆柱过渡,对曲边产生自然的变曲率过渡。 * * @param body 输入实体 * @param edge_id 目标边索引 * @param radius 球体半径(> 0) * @param samples 沿边的球心采样数(默认 20) * @return 过渡后的新实体 * * @pre edge_id 有效,radius > 0 */ [[nodiscard]] BrepModel rolling_ball_blend( const BrepModel& body, int edge_id, double radius, int samples = 20); /** * @brief 两面间恒定半径过渡 * * 在两个任意面之间构造恒定半径的过渡曲面。与单边过渡不同, * 此函数处理两个面之间的整个共享或邻近区域。 * * 算法: * 1. 找到两面之间的共享边,或确定两面的邻近区域 * 2. 沿共享边界计算过渡曲面(恒定半径圆柱面) * 3. 切掉两面在过渡区域的部分 * 4. 插入过渡曲面,组装壳和体 * * @param body 输入实体 * @param face_a 第一个面索引 * @param face_b 第二个面索引 * @param radius 过渡半径(> 0) * @param samples 沿边界的截面采样数(默认 16) * @return 过渡后的新实体 * * @pre face_a 和 face_b 有效,radius > 0 */ [[nodiscard]] BrepModel face_face_blend( const BrepModel& body, int face_a, int face_b, double radius, int samples = 16); /** * @brief 形状过渡(Shape Fillet) * * 沿边采样变半径,逐段建模过渡曲面,自动检测三面交角并 * 以球面填充 + 过渡面处理。 * * 算法: * 1. 定位目标边及其两个邻面 * 2. 沿边曲线采样 N 个截面,每截面计算半径(r_start → r_end 线性插值) * 3. 计算每截面的角平分线方向和切点 * 4. 每相邻两截面间构建一张过渡曲面 * 5. 检测三面交角顶点(目标边端点处 ≥ 3 个面交汇) * - 若检测到三面交角:在交角顶点处构造球面填充面 * - 球面填充面与相邻过渡面之间插入过渡面 * 6. 重建两个邻面(切除过渡区域),复制其他面,组装壳和体 * * @param body 输入实体 * @param edge_id 目标边索引 * @param r_start 边起点处的过渡半径(≥ 0) * @param r_end 边终点处的过渡半径(≥ 0) * @param samples 沿边的截面采样数(默认 16) * @return 过渡后的新实体 * * @pre edge_id 有效,r_start ≥ 0, r_end ≥ 0 * @note 自动检测并处理三面交角,以球面填充 + 过渡面连接 */ [[nodiscard]] BrepModel shape_fillet( const BrepModel& body, int edge_id, double r_start, double r_end, int samples = 16); } // namespace vde::brep