Files
ViewDesignEngine/docs/tutorial/03-brep-modeling.md
T
2026-07-24 12:42:49 +00:00

280 lines
9.0 KiB
Markdown
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.
# B-Rep 工业建模教程
边界表示(Boundary RepresentationB-Rep)是 CAD 系统中最常用的实体表示方法。ViewDesignEngine 提供高层建模 API 用于创建 B-Rep 实体,支持精确的几何计算和工业标准格式导出。
## 核心概念
B-Rep 通过拓扑层次结构描述三维几何体的边界:
```
Body (体) — 一个或多个封闭壳
└─ Shell (壳) — 一组面的连续集合
└─ Face (面) — 曲面上由环界定的区域
└─ Loop (环) — 封闭的边界曲线
└─ Edge (边) — 曲面的边界段
└─ Vertex (顶点) — 边的端点
```
## 基础实体(盒、柱、球)
使用 `vde/brep/modeling.h` 中的高层 API 创建基本体:
```cpp
#include <vde/brep/modeling.h>
#include <iostream>
using namespace vde::brep;
int main() {
// 轴对齐长方体:宽 × 高 × 深
auto box = make_box(100.0, 50.0, 30.0);
std::cout << "Box faces: " << box.num_faces()
<< ", edges: " << box.num_edges() << "\n";
// 圆柱体:半径 20,高度 80,64 段(精度)
auto cylinder = make_cylinder(20.0, 80.0, 64);
std::cout << "Cylinder faces: " << cylinder.num_faces() << "\n";
// 球体:半径 25,经度 32 段,纬度 32 段
auto sphere = make_sphere(25.0, 32, 32);
std::cout << "Sphere faces: " << sphere.num_faces() << "\n";
return 0;
}
```
## 扫掠特征(Extrude, Revolve, Sweep, Loft
扫掠操作将二维轮廓沿路径移动生成三维实体:
```cpp
#include <vde/brep/modeling.h>
#include <vde/curves/nurbs_curve.h>
#include <vde/core/point.h>
using namespace vde::brep;
using namespace vde::curves;
using namespace vde::core;
int main() {
// 创建一个矩形轮廓(作为 NURBS 曲线:封闭的 4 点控制多边形)
NurbsCurve profile;
profile.set_degree(1); // 线性
profile.set_knots({0, 0, 0.25, 0.5, 0.75, 1, 1});
profile.set_control_points({
Point3D(-10, 0, -10),
Point3D( 10, 0, -10),
Point3D( 10, 0, 10),
Point3D(-10, 0, 10),
Point3D(-10, 0, -10) // 闭合
});
// 线性挤出:沿 Z 轴挤出 50 单位
auto extruded = extrude(profile, Vector3D(0, 0, 50));
std::cout << "Extruded faces: " << extruded.num_faces() << "\n";
// 旋转扫掠(Revolve):半圆绕 Y 轴旋转
NurbsCurve semicircle;
semicircle.set_degree(2);
// ... 控制点定义上半圆 ...
auto revolved = revolve(semicircle,
Point3D(0, 0, 0), // 旋转轴起点
Vector3D(0, 1, 0), // 旋转轴方向(Y 轴)
360.0 // 角度(度)
);
std::cout << "Revolved faces: " << revolved.num_faces() << "\n";
// 沿路径扫掠(Sweep):圆形截面沿螺旋路径
NurbsCurve circle_profile; // 小圆
NurbsCurve helix_path; // 螺旋线
auto swept = sweep(circle_profile, helix_path);
// 放样(Loft):多个截面 → 实体
std::vector<NurbsCurve> profiles = {profile_a, profile_b, profile_c};
auto lofted = loft(profiles);
return 0;
}
```
## 特征操作(倒圆、倒角、抽壳)
编辑操作通过链式调用逐步细化模型:
```cpp
#include <vde/brep/modeling.h>
#include <vde/brep/step_export.h>
#include <vde/foundation/io_gltf.h>
using namespace vde::brep;
using namespace vde::foundation;
int main() {
// 基础块:100 × 60 × 40 mm
auto part = make_box(100.0, 60.0, 40.0);
// 对所有边倒圆角(face_id = 0 代表指定面,或对所有边操作)
part = fillet(part, 0, 5.0); // 半径 5mm 圆角
std::cout << "After fillet: " << part.num_faces() << " faces\n";
// 对顶面边缘倒角(典型机加工倒角)
// chamfer(face_id, distance)
// part = chamfer(part, 5, 2.0);
// 抽壳:创建均匀壁厚的空心壳体
// face_id = -1 表示封闭壳体(无开口)
// thickness > 0 表示向外增厚,< 0 表示保留内腔
part = shell(part, -1, 2.0);
std::cout << "After shell (2mm wall): "
<< part.num_faces() << " faces\n";
return 0;
}
```
## 布尔运算
B-Rep 层面支持精确布尔运算:
```cpp
#include <vde/brep/modeling.h>
#include <vde/brep/brep_boolean.h>
using namespace vde::brep;
int main() {
auto block = make_box(50, 50, 50);
auto cylinder = make_cylinder(15, 80, 64);
// 并集(Union):块 + 柱
auto union_result = brep_union(block, cylinder);
// 交集(Intersection):块 ∩ 柱
auto isect_result = brep_intersection(block, cylinder);
// 差集(Difference):块 - 柱(在块上打孔)
auto diff_result = brep_difference(block, cylinder);
std::cout << "Union: " << union_result.num_faces() << " faces\n";
std::cout << "Intersection: " << isect_result.num_faces() << " faces\n";
std::cout << "Difference: " << diff_result.num_faces() << " faces\n";
return 0;
}
```
## STEP 导出 → CAM
STEP(AP214)是工业制造的标准交换格式,可直接导入 CAM 软件生成刀具路径:
```cpp
#include <vde/brep/modeling.h>
#include <vde/brep/step_export.h>
using namespace vde::brep;
int main() {
auto part = make_box(80, 40, 20);
part = fillet(part, 0, 3.0);
part = shell(part, -1, 2.0);
// 导出为 STEP AP214 文件
export_step_file("flange.stp", {part});
// 或以字符串形式获取 STEP 内容
std::string step_str = export_step({part});
std::cout << "STEP size: " << step_str.size() << " chars\n";
std::cout << "STEP exported. Ready for:\n"
<< " - Fusion 360 / SolidWorks / FreeCAD\n"
<< " - CAM toolpath generation\n"
<< " - CMM inspection\n";
return 0;
}
```
## 完整示例:法兰零件
```cpp
/// 法兰零件:盒基 + 挤出环 → 倒角 → 钻孔阵列 → STEP/GLB 导出
#include <vde/brep/modeling.h>
#include <vde/brep/brep_boolean.h>
#include <vde/brep/step_export.h>
#include <vde/foundation/io_gltf.h>
#include <vde/core/point.h>
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace vde::brep;
using namespace vde::foundation;
using namespace vde::core;
int main() {
std::cout << std::fixed << std::setprecision(3);
// ── 法兰本体 ──────────────────────────────────
// 80×80×15 mm 的底座
double W = 80.0, D = 80.0, H = 15.0;
auto flange = make_box(W, D, H);
std::cout << "Base block: " << W << "×" << D << "×" << H << " mm\n";
// ── 中心凸台(挤出圆柱) ──────────────────────
double boss_d = 40.0, boss_h = 25.0;
auto boss = make_cylinder(boss_d / 2.0, boss_h, 64);
// 定位:凸台在法兰顶面中心
// (如需要偏移,可通过 brep_boolean 的变换参数定位)
flange = brep_union(flange, boss);
std::cout << "Added boss: Ø" << boss_d << "×" << boss_h << " mm\n";
// ── 边缘圆角 ──────────────────────────────────
flange = fillet(flange, 0, 3.0);
std::cout << "Edge fillet: R3.0 applied\n";
// ── 螺栓孔阵列(4 个 M8 通孔) ────────────────
double hole_d = 8.5; // M8 通孔直径
double bolt_circle_r = 30.0; // 螺栓孔分布圆半径
for (int i = 0; i < 4; i++) {
double angle = i * M_PI / 2.0; // 0°, 90°, 180°, 270°
double cx = bolt_circle_r * std::cos(angle);
double cy = bolt_circle_r * std::sin(angle);
auto hole = make_cylinder(hole_d / 2.0, H + 5.0, 32);
// 差集减孔(如需定位偏移,使用 brep_difference 的变换版本)
flange = brep_difference(flange, hole);
}
std::cout << "Bolt holes: 4ר" << hole_d << " on Ø" << bolt_circle_r * 2 << " BCD\n";
// ── 质量信息 ──────────────────────────────────
std::cout << "\nFinal part:\n"
<< " faces: " << flange.num_faces() << "\n"
<< " edges: " << flange.num_edges() << "\n";
// ── 导出 ──────────────────────────────────────
// STEPCAM 用)
export_step_file("flange.stp", {flange});
std::cout << " → flange.stp (STEP AP214)\n";
// GLB(预览用)
if (write_brep_gltf("flange.glb", flange, 32)) {
std::cout << " → flange.glb (GLB visualization)\n";
}
// ── 交互式预览 ────────────────────────────────
std::cout << "\nOpen viewer/index.html and drop flange.glb to inspect.\n";
return 0;
}
```
编译运行:
```bash
g++ -std=c++17 -I../include flange_demo.cpp -L. -lvde -o flange_demo
./flange_demo
```
生成的 `flange.stp` 可导入 FreeCAD / Fusion 360 进行 CAM 刀具路径生成,
`flange.glb` 可在项目自带的 `viewer/index.html` 中预览。