Files
ViewDesignEngine/include/vde/brep/modeling.h
T
茂之钳 e573cf958f
CI / Build & Test (push) Failing after 36s
CI / Release Build (push) Failing after 34s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
docs: v3.8 engineering drawing + G2 continuity plan
2026-07-24 15:15:53 +00:00

295 lines
9.3 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 modeling.h
* @brief 高层 B-Rep 建模 API
*
* 提供 B-Rep 实体的创建和编辑操作,类比于 CAD 系统的特征建模功能。
*
* ## 功能概览
*
* | 类别 | 操作 |
* |----------------|---------------------------------------------|
* | 基本体 | make_box, make_cylinder, make_sphere |
* | 扫掠特征 | extrude, revolve, sweep, loft |
* | 编辑操作 | fillet, chamfer, shell |
*
* ## 使用模式
*
* 每个函数返回一个新的 BrepModel(值语义),适合链式构建:
*
* @code{.cpp}
* auto body = make_box(10, 5, 3);
* // 或者更复杂的构建:
* auto profile = NURBS 曲线;
* auto swept = extrude(profile, Vector3D(0, 0, 10));
* auto rounded = fillet(swept, 0, 2.0);
* @endcode
*
* @ingroup brep
*/
#include "vde/core/point.h"
#include "vde/brep/brep.h"
namespace vde::brep {
using core::Point3D;
using core::Vector3D;
using core::AABB3D;
// ═══════════════════════════════════════════════
// 扫掠特征
// ═══════════════════════════════════════════════
/**
* @brief 沿方向挤出平面轮廓
*
* 将平面曲线沿给定方向扫掠,生成柱状实体。
*
* **算法:** 曲线的每个点沿方向向量平移,两端加盖平面形成封闭实体。
*
* @param profile 轮廓曲线(必须位于一个平面内)
* @param dir 挤出方向向量(其长度决定挤出距离)
* @return 挤出后的 B-Rep 实体
*
* @pre profile 必须是平面曲线(存在于某个平面内)且闭合
*
* @code{.cpp}
* // 沿 Z 轴挤出 5 个单位
* auto circle = NurbsCurve::create_circle(Point3D(0,0,0), 2.0);
* auto cylinder = extrude(circle, Vector3D(0, 0, 5));
* @endcode
*
* @see revolve 旋转扫掠
* @see sweep 沿任意路径扫掠
*/
[[nodiscard]] BrepModel extrude(const curves::NurbsCurve& profile, const Vector3D& dir);
/**
* @brief 绕轴旋转平面轮廓
*
* 将轮廓绕给定轴旋转,生成旋转体(如轮子、瓶子等)。
*
* @param profile 轮廓曲线(通常位于轴的半平面中)
* @param axis_origin 旋转轴上的一个点
* @param axis_dir 旋转轴方向(单位向量)
* @param angle_rad 旋转角度(弧度,默认 2π = 完整的旋转体)
* @return 旋转后的 B-Rep 实体
*
* @pre profile 必须在轴的同一侧(不应跨越轴线)
*
* @code{.cpp}
* // 绕 Y 轴旋转半圆,生成球体的一半
* NurbsCurve semicircle = 在 XZ 平面中的半圆弧;
* auto half_sphere = revolve(semicircle, Point3D(0,0,0),
* Vector3D(0,1,0), M_PI);
* @endcode
*
* @see extrude 线性挤出
* @see make_sphere 直接创建球体
*/
[[nodiscard]] BrepModel revolve(const curves::NurbsCurve& profile,
const Point3D& axis_origin,
const Vector3D& axis_dir,
double angle_rad = 2.0 * M_PI);
/**
* @brief 沿任意路径扫掠轮廓
*
* 轮廓沿一条空间路径曲线运动,生成管道或异形截面杆。
*
* @param profile 截面轮廓(需位于路径起点的垂直平面内)
* @param path 扫掠路径曲线
* @return 扫掠后的 B-Rep 实体
*
* @note 路径曲率过大处可能出现自交,需要控制路径的光滑性。
*
* @code{.cpp"}
* auto circle = NurbsCurve::create_circle(Point3D(0,0,0), 0.5);
* auto helix = NurbsCurve::create_helix(// ...);
* auto pipe = sweep(circle, helix);
* @endcode
*
* @see extrude 直线挤出
* @see revolve 旋转扫掠
*/
[[nodiscard]] BrepModel sweep(const curves::NurbsCurve& profile,
const curves::NurbsCurve& path);
/**
* @brief 在两个或多个轮廓曲线之间放样
*
* 通过线性或平滑插值连接多个平行或非平行轮廓,
* 生成过渡实体。
*
* @param profiles 轮廓曲线列表(至少 2 条)
* @return 放样后的 B-Rep 实体
*
* @pre profiles.size() ≥ 2
* @pre 所有轮廓应是平面曲线(逐一)
*
* @code{.cpp}
* auto profile_a = NurbsCurve::create_circle(Point3D(0,0,0), 5.0);
* auto profile_b = NurbsCurve::create_circle(Point3D(0,0,10), 2.0);
* auto cone = loft({profile_a, profile_b});
* @endcode
*
* @see extrude 单轮廓挤出
*/
[[nodiscard]] BrepModel loft(const std::vector<curves::NurbsCurve>& profiles);
// ═══════════════════════════════════════════════
// 基本体
// ═══════════════════════════════════════════════
/**
* @brief 创建立方体
*
* 以原点为中心、轴对齐的立方体。
*
* @param w 宽度(X 方向),必须 > 0
* @param h 高度(Y 方向),必须 > 0
* @param d 深度(Z 方向),必须 > 0
* @return 实心立方体 B-Rep
*
* @code{.cpp}
* auto box = make_box(10, 5, 3); // 10×5×3 的盒子
* @endcode
*
* @see make_cylinder 圆柱体
* @see make_sphere 球体
*/
[[nodiscard]] BrepModel make_box(double w, double h, double d);
/**
* @brief 创建圆柱体
*
* 沿 Y 轴、以原点为中心的圆柱体。
*
* @param radius 截面半径,必须 > 0
* @param height 总高度,沿 Y 轴从 -h/2 到 +h/2
* @param segments 截面分段数(边数,默认 32)
* @return 实心圆柱体 B-Rep
*
* @note segments 越大圆柱越光滑,但面和边数增加。
*
* @code{.cpp}
* auto cyl = make_cylinder(2.0, 10.0, 64); // 高精度圆柱
* @endcode
*
* @see make_box 立方体
* @see make_sphere 球体
*/
[[nodiscard]] BrepModel make_cylinder(double radius, double height, int segments = 32);
/**
* @brief 创建球体
*
* 以原点为中心的球体。
*
* @param radius 球半径,必须 > 0
* @param segments_u 经度方向分段数(默认 32)
* @param segments_v 纬度方向分段数(默认 16)
* @return 实心球体 B-Rep
*
* @code{.cpp}
* auto sphere = make_sphere(5.0, 32, 32);
* @endcode
*
* @see make_cylinder 圆柱体
*/
[[nodiscard]] BrepModel make_sphere(double radius, int segments_u = 32, int segments_v = 16);
// ═══════════════════════════════════════════════
// 编辑操作
// ═══════════════════════════════════════════════
/**
* @brief 对边做圆角处理
*
* 在指定的边上施加恒定半径的圆角(倒圆)。
* 适用于凹边和凸边。
*
* @param body 输入实体
* @param edge_id 要倒圆的边 ID
* @param radius 圆角半径,必须 > 0
* @return 圆角后的新实体
*
* @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 对边做倒角
*
* 将尖锐边替换为 45° 斜面。
*
* @param body 输入实体
* @param edge_id 要倒角的边 ID
* @param distance 倒角距离(从原边沿两个面各偏移的距离)
* @return 倒角后的新实体
*
* @pre distance > 0
*
* @see fillet 圆角
*/
[[nodiscard]] BrepModel chamfer(const BrepModel& body, int edge_id, double distance);
/**
* @brief 抽壳(挖空实体)
*
* 将实体变为等厚度的壳,去除指定面形成开口。
*
* @param body 输入实心实体
* @param face_id 要移除的面 ID(形成开口),-1 表示封闭壳(不开口)
* @param thickness 壁厚(正值 = 向外偏移,负值 = 向内偏移)
* @return 抽壳后的新实体
*
* @note 壁厚不应超过实体最小尺寸的一半。
* @note 当 face_id = -1 时,结果是一个封闭的壳(中空但没有开口)。
*
* @code{.cpp"}
* auto box = make_box(10, 5, 3);
* auto shelled = shell(box, 0, 0.5); // 移除面 0,壁厚 0.5
* @endcode
*
* @see fillet 圆角
*/
[[nodiscard]] BrepModel shell(const BrepModel& body, int face_id, double thickness);
} // namespace vde::brep