尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

采用 OpenCASCADE 提取布尔运算后平面图形的外轮廓

采用 OpenCASCADE 提取布尔运算后平面图形的外轮廓
📅 发布时间:2026/6/21 23:04:13

采用 OpenCASCADE 提取布尔运算后平面图形的外轮廓

在 CAD 建模和几何处理中,经常需要从复杂形状中提取外轮廓。本文将深入探讨如何使用 OpenCASCADE 库在 C++ 中高效提取布尔运算后平面图形的外轮廓,并提供完整可运行的代码示例。

理论基础

平面图形的数学表示

在计算几何中,一个平面图形可以表示为:

S={(x,y)∈R2∣f(x,y)≥0}S = \{ (x,y) \in \mathbb{R}^2 | f(x,y) \geq 0 \}S={(x,y)∈R2∣f(x,y)≥0}

其中 f(x,y)f(x,y)f(x,y) 是定义图形边界的隐式函数。对于通过布尔运算获得的图形,其边界由多个分段曲线组成:

∂S=⋃i=1nCi(t),t∈[ai,bi]\partial S = \bigcup_{i=1}^{n} C_i(t), \quad t \in [a_i, b_i]∂S=i=1⋃n​Ci​(t),t∈[ai​,bi​]

其中 Ci(t)C_i(t)Ci​(t) 是参数化的曲线段。

OpenCASCADE 拓扑结构

OpenCASCADE 使用 BREP(边界表示)模型表示几何形状,其拓扑结构包括:

  • 顶点 (Vertex):0维几何元素
  • 边 (Edge):1维几何元素,由曲线定义
  • 线框 (Wire):边的有序连接
  • 面 (Face):由线框界定的2维曲面
  • 壳 (Shell):面的集合
  • 实体 (Solid):封闭壳

对于平面图形,我们关注的是其外线框 (Outer Wire),即定义图形最外边界的线框。

完整代码实现

示例 1:基本外轮廓提取

#include <BRepTools.hxx>#include <TopExp_Explorer.hxx>#include <TopoDS.hxx>#include <TopoDS_Face.hxx>#include <TopoDS_Wire.hxx>#include <gp_Circ.hxx>#include <gp_Pln.hxx>#include <gp_Ax2.hxx>#include <gp_Dir.hxx>#include <gp_Pnt.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <BRepAlgoAPI_Cut.hxx>#include <iostream>// 创建圆形平面TopoDS_Shape CreateCircleFace(double radius) {gp_Pln plane(gp::XOY());gp_Circ circle(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), radius);TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle);TopoDS_Wire wire = BRepBuilderAPI_MakeWire(edge);return BRepBuilderAPI_MakeFace(wire);}// 创建矩形平面TopoDS_Shape CreateRectangleFace(double width, double height) {gp_Pnt p1(-width/2, -height/2, 0);gp_Pnt p2(width/2, -height/2, 0);gp_Pnt p3(width/2, height/2, 0);gp_Pnt p4(-width/2, height/2, 0);TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(p1, p2);TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(p2, p3);TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge(p3, p4);TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge(p4, p1);TopoDS_Wire wire = BRepBuilderAPI_MakeWire(e1, e2, e3, e4);return BRepBuilderAPI_MakeFace(wire);}// 获取形状的外轮廓TopoDS_Wire GetOuterWire(const TopoDS_Shape& shape) {if (shape.IsNull()) {throw std::runtime_error("输入形状为空");}TopExp_Explorer faceExplorer(shape, TopAbs_FACE);if (!faceExplorer.More()) {throw std::runtime_error("形状中未找到面");}const TopoDS_Face& face = TopoDS::Face(faceExplorer.Current());TopoDS_Wire outerWire = BRepTools::OuterWire(face);if (outerWire.IsNull()) {throw std::runtime_error("提取外轮廓失败");}return outerWire;}int main() {try {// 创建几何图形TopoDS_Shape circle = CreateCircleFace(50.0);TopoDS_Shape rectangle = CreateRectangleFace(40.0, 40.0);// 执行布尔运算BRepAlgoAPI_Cut cutter(circle, rectangle);cutter.Build();if (!cutter.IsDone()) {throw std::runtime_error("布尔运算失败");}// 获取结果形状TopoDS_Shape resultShape = cutter.Shape();// 提取外轮廓TopoDS_Wire outerWire = GetOuterWire(resultShape);// 输出结果std::cout << "成功提取外轮廓" << std::endl;std::cout << "轮廓包含 " << outerWire.NbChildren() << " 条边" << std::endl;} catch (const std::exception& e) {std::cerr << "错误: " << e.what() << std::endl;return 1;}return 0;}

示例 2:高级外轮廓处理

在这里插入图片描述

#include <BRepTools.hxx>#include <TopExp_Explorer.hxx>#include <TopoDS.hxx>#include <TopoDS_Face.hxx>#include <TopoDS_Wire.hxx>#include <TopTools_ListOfShape.hxx>#include <gp_Circ.hxx>#include <gp_Pln.hxx>#include <gp_Ax2.hxx>#include <gp_Dir.hxx>#include <gp_Pnt.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <BRepAlgoAPI_Cut.hxx>#include <BRepAlgoAPI_Fuse.hxx>#include <BRepCheck_Analyzer.hxx>#include <iostream>#include <vector>// 创建圆形平面TopoDS_Shape CreateCircleFace(double radius) {gp_Pln plane(gp::XOY());gp_Circ circle(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), radius);TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle);TopoDS_Wire wire = BRepBuilderAPI_MakeWire(edge);return BRepBuilderAPI_MakeFace(wire);}// 创建多边形平面TopoDS_Shape CreatePolygonFace(const std::vector<gp_Pnt>& points) {if (points.size() < 3) {throw std::runtime_error("多边形至少需要3个点");}BRepBuilderAPI_MakeWire wireMaker;for (size_t i = 0; i < points.size(); i++) {size_t next = (i + 1) % points.size();TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(points[i], points[next]);wireMaker.Add(edge);}if (!wireMaker.IsDone()) {throw std::runtime_error("创建线框失败");}return BRepBuilderAPI_MakeFace(wireMaker.Wire());}// 获取所有外轮廓TopTools_ListOfShape GetAllOuterWires(const TopoDS_Shape& shape) {TopTools_ListOfShape resultWires;// 验证形状有效性BRepCheck_Analyzer analyzer(shape);if (!analyzer.IsValid()) {throw std::runtime_error("形状拓扑结构无效");}// 遍历所有面for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {TopoDS_Face face = TopoDS::Face(exp.Current());// 获取面的外轮廓TopoDS_Wire outerWire = BRepTools::OuterWire(face);if (!outerWire.IsNull()) {resultWires.Append(outerWire);}// 可选:获取内轮廓(孔洞)/*TopExp_Explorer wireExp(face, TopAbs_WIRE);for (; wireExp.More(); wireExp.Next()) {TopoDS_Wire wire = TopoDS::Wire(wireExp.Current());if (!wire.IsSame(outerWire)) {// 处理内轮廓}}*/}return resultWires;}int main() {try {// 创建复杂几何图形std::vector<gp_Pnt> hexPoints = {gp_Pnt(0, 0, 0),gp_Pnt(30, 0, 0),gp_Pnt(45, 25, 0),gp_Pnt(30, 50, 0),gp_Pnt(0, 50, 0),gp_Pnt(-15, 25, 0)};TopoDS_Shape hexagon = CreatePolygonFace(hexPoints);TopoDS_Shape circle = CreateCircleFace(25.0);// 执行布尔并集运算BRepAlgoAPI_Fuse fuser(hexagon, circle);fuser.Build();if (!fuser.IsDone()) {throw std::runtime_error("布尔并集运算失败");}// 获取结果形状TopoDS_Shape fusedShape = fuser.Shape();// 提取所有外轮廓TopTools_ListOfShape outerWires = GetAllOuterWires(fusedShape);// 输出结果std::cout << "找到 " << outerWires.Extent() << " 个外轮廓" << std::endl;// 遍历所有外轮廓int wireCount = 1;for (TopTools_ListIteratorOfListOfShape it(outerWires); it.More(); it.Next()) {TopoDS_Wire wire = TopoDS::Wire(it.Value());std::cout << "轮廓 " << wireCount++ << " 包含 "<< wire.NbChildren() << " 条边" << std::endl;}} catch (const std::exception& e) {std::cerr << "错误: " << e.what() << std::endl;return 1;}return 0;}

相关新闻

  • 题解:AtCoder ARC209D A_A_i
  • Kotlin Coroutines
  • 我的标题

最新新闻

  • 2026年国内铜屑压饼机厂家实力及核心参数对比 - 起跑123
  • 3分钟搞定B站缓存视频转换:m4s转mp4的完整免费方案
  • SCMP报名需要工作证明吗?需要什么材料? - 众智商学院课程中心
  • 2026年国内铜屑压块机厂家:性能、服务及降本效果对比 - 起跑123
  • 【共创季稿事节】鸿蒙原生 ArkTS 布局实战:使用 Stack 实现商品 Tag 标签叠加
  • 武汉市汉阳区管道疏通|维小达|马桶、蹲便器、地漏、洗菜盆、洗手盆、浴缸一站式疏通养护服务 - 维小达科技

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号