280 lines
9.0 KiB
Markdown
280 lines
9.0 KiB
Markdown
# B-Rep 工业建模教程
|
||
|
||
边界表示(Boundary Representation,B-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";
|
||
|
||
// ── 导出 ──────────────────────────────────────
|
||
// STEP(CAM 用)
|
||
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` 中预览。
|