【Qt + OpenCASCADE】实现 SolidWorks 风格的装配树(附完整代码)
一、目的实现像 SolidWorks 那样左边是结构树右边是 3D 视图选中树节点 → 对应 3D 实体变为亮色高亮勾选/取消勾选树节点 → 对应 3D 实体在视图中显示/消失二、效果三、实现QTreeViewQAbstractItemMode树形结构展示、选中/勾选交互OpenCASCADE (OCCT)STEP 文件读取STEP 装配结构解析、BRep/装配模型管理、3D 渲染四、重点代码讲解a、step文件导入boolStepPartTreeView::loadStepFile(constQStringfilePath,constocc::handleTDocStd_Documentdoc){clearTree();if(doc.IsNull()){QMessageBox::warning(this,QStringLiteral(错误),QStringLiteral(XCAF 文档未初始化));returnfalse;}STEPCAFControl_Reader reader;reader.SetColorMode(true);reader.SetNameMode(true);reader.SetLayerMode(true);IFSelect_ReturnStatus statusreader.ReadFile(filePath.toUtf8().constData());if(status!IFSelect_RetDone){QMessageBox::warning(this,QStringLiteral(错误),QStringLiteral(无法读取 STEP 文件));returnfalse;}if(!reader.Transfer(doc)){QMessageBox::warning(this,QStringLiteral(错误),QStringLiteral(STEP 数据转换失败));returnfalse;}occ::handleXCAFDoc_ShapeToolshapeToolXCAFDoc_DocumentTool::ShapeTool(doc-Main());if(!shapeTool.IsNull()){shapeTool-UpdateAssemblies();}m_model-loadDocument(doc);expandToDepth(1);if(!m_context.IsNull()!m_model-graph().IsNull()){constQListintvisibleIdsm_model-visibleGraphNodeIds();for(intid:visibleIds){occ::handleAIS_InteractiveObjectaisensureAIS(id);if(!ais.IsNull()){m_context-Display(ais,AIS_Shaded,-1,false);}}if(!m_view.IsNull()){m_view-FitAll();if(m_occtViewer)m_occtViewer-fill();}m_context-UpdateCurrentViewer();}returntrue;}voidStepPartTreeModel::loadDocument(constocc::handleTDocStd_Documentdoc){beginResetModel();m_nodes.clear();m_graphIdToNodeIndex.clear();m_rootNodeIndex-1;m_docdoc;if(!m_doc.IsNull()){m_graphnewXCAFDoc_AssemblyGraph(m_doc);constTColStd_PackedMapOfIntegerrootsm_graph-GetRoots();QString rootNameQStringLiteral(装配体);for(TColStd_PackedMapOfInteger::Iteratorit(roots);it.More();it.Next()){QString ngetShapeName(m_graph-GetNode(it.Key()));if(!n.isEmpty()){rootNamen;break;}}m_rootNodeIndexappendNode(rootName,FeatNodeKind::RootDoc,-1,-1);for(TColStd_PackedMapOfInteger::Iteratorit(roots);it.More();it.Next()){buildAssemblyBranch(it.Key(),m_rootNodeIndex);}}else{m_graph.Nullify();}endResetModel();}b、选中高亮voidStepPartTreeView::onSelectionChanged(constQItemSelection,constQItemSelection){clearHighlight();constQModelIndexList selselectionModel()-selectedRows();QListintids;for(constQModelIndexidx:sel){intnodeIdxstatic_castint(idx.internalId());QListintsubIds;m_model-collectShapeGraphIds(nodeIdx,subIds);constQListintsubIdsConstsubIds;for(intid:subIdsConst){if(!ids.contains(id))ids.append(id);}if(subIds.isEmpty()){inteffIdm_model-effectiveGraphNodeId(nodeIdx);if(effId0!ids.contains(effId))ids.append(effId);}}if(ids.isEmpty()){if(!m_context.IsNull())m_context-UpdateCurrentViewer();return;}constQListintidsConstids;for(intid:idsConst){highlightNode(id);}intfirstIdids.first();TDF_Label labelm_model-labelFromGraphId(firstId);if(!m_context.IsNull())m_context-UpdateCurrentViewer();emitnodeSelected(firstId,label);}c、勾选显隐voidStepPartTreeModel::setNodeVisibleRecursive(intnodeIndex,boolvisible){if(nodeIndex0||nodeIndexm_nodes.size())return;NodeInfoinfom_nodes[nodeIndex];if(info.visible!visible){info.visiblevisible;QModelIndex idxcreateIndex(info.rowInParent,0,quintptr(nodeIndex));emitdataChanged(idx,idx,{Qt::CheckStateRole,IsVisibleRole});}constQVectorintchildreninfo.childrenIndex;for(intchild:children)setNodeVisibleRecursive(child,visible);}voidStepPartTreeView::onModelDataChanged(constQModelIndextopLeft,constQModelIndex,constQListintroles){if(!roles.contains(Qt::CheckStateRole))return;if(!topLeft.isValid())return;QListintids;intnodeIdxstatic_castint(topLeft.internalId());m_model-collectShapeGraphIds(nodeIdx,ids);if(ids.isEmpty()){inteffIdm_model-effectiveGraphNodeId(nodeIdx);if(effId0)ids.append(effId);}boolvisibletopLeft.data(IsVisibleRole).toBool();if(m_context.IsNull())return;boolchangedfalse;constQListintidsConstids;for(intid:idsConst){if(m_highlightedNodeIds.contains(id)){if(!visible){autoitm_aisObjects.find(id);if(it!m_aisObjects.end()!it.value().IsNull()){restoreOriginalColor(it.value());if(m_context-IsDisplayed(it.value())){m_context-Erase(it.value(),false);changedtrue;}}m_highlightedNodeIds.remove(id);}continue;}occ::handleAIS_InteractiveObjectais;autoitm_aisObjects.find(id);if(it!m_aisObjects.end()){aisit.value();}else{aisensureAIS(id);}if(ais.IsNull())continue;if(visible){if(!m_context-IsDisplayed(ais)){m_context-Display(ais,AIS_Shaded,-1,false);changedtrue;}}else{if(m_context-IsDisplayed(ais)){m_context-Erase(ais,false);changedtrue;}}}if(changed)m_context-UpdateCurrentViewer();emitupdateViewRequired();}d、AIS 对象的懒惰初始化 缓存occ::handleAIS_InteractiveObjectStepPartTreeView::ensureAIS(intgraphNodeId){autoitm_aisObjects.find(graphNodeId);if(it!m_aisObjects.end())returnit.value();if(m_model-graph().IsNull()||m_context.IsNull())returnocc::handleAIS_InteractiveObject();TDF_Label labelm_model-graph()-GetNode(graphNodeId);if(label.IsNull())returnocc::handleAIS_InteractiveObject();occ::handleAIS_InteractiveObjectais;TopoDS_Shape shape;try{if(XCAFDoc_ShapeTool::GetShape(label,shape)!shape.IsNull()){}else{shapegetShapeRecursive(label);}}catch(...){shapegetShapeRecursive(label);}if(!shape.IsNull()){try{occ::handleAIS_ShapeaisShapenewAIS_Shape(shape);aisShape-SetDisplayMode(AIS_Shaded);m_context-Display(aisShape,AIS_Shaded,-1,false);if(m_context-IsDisplayed(aisShape)){aisaisShape;m_context-Erase(ais,false);}else{m_context-Remove(aisShape,false);}}catch(...){}}if(ais.IsNull()){try{occ::handleXCAFPrs_AISObjectxcafAisnewXCAFPrs_AISObject(label);xcafAis-SetDisplayMode(AIS_Shaded);m_context-Display(xcafAis,AIS_Shaded,-1,false);if(m_context-IsDisplayed(xcafAis)){aisxcafAis;m_context-Erase(ais,false);}else{m_context-Remove(xcafAis,false);}}catch(...){}}if(!ais.IsNull()){m_aisObjects[graphNodeId]ais;}returnais;}e、视图初始化voidOcctViewerWidget::showEvent(QShowEvent*event){// 延迟初始化if(!m_isCreated){initOcctViewer();}}voidOcctViewerWidget::initOcctEnv(){occ::handleOpenGl_GraphicDriverFactoryfactorynewOpenGl_GraphicDriverFactory();Graphic3d_GraphicDriverFactory::RegisterFactory(factory,true);occ::handleGraphic3d_GraphicDriverFactorydriverFactoryGraphic3d_GraphicDriverFactory::DefaultDriverFactory();if(driverFactory.IsNull())return;m_displayConnectionnewAspect_DisplayConnection();m_driverdriverFactory-CreateDriver(m_displayConnection);if(m_driver.IsNull())return;// 创建视图管理器m_viewernewV3d_Viewer(m_driver);m_viewer-SetDefaultViewSize(1000.0);m_viewer-SetDefaultViewProj(V3d_XposYnegZpos);m_viewer-SetComputedMode(true);m_viewer-SetDefaultComputedMode(true);m_viewer-SetDefaultLights();m_viewer-SetLightOn();// 创建交互上下文m_contextnewAIS_InteractiveContext(m_viewer);m_context-SetPixelTolerance(10);// 设置选择像素差// 创建内部视图m_viewm_context-CurrentViewer()-CreateView();}voidOcctViewerWidget::initOcctViewer(){// m_occtWindow new OcctWindow(this);WId window_handle(WId)winId();m_occtWindownewWNT_Window((Aspect_Handle)window_handle);m_view-SetWindow(m_occtWindow);if(!m_occtWindow-IsMapped()){m_occtWindow-Map();}m_view-SetBackgroundColor(Quantity_NOC_BLACK);m_view-MustBeResized();m_view-Camera()-SetProjectionType(Graphic3d_Camera::Projection_Orthographic);showViewCube();m_isCreatedtrue;isometric();fill();}项目源码Windows 环境 OCCT 8.0 编译构建及与 Qt6 项目集成对你有用就点个赞以后需要用到就收藏⭐

相关新闻

C++内联函数:原理、应用与性能优化实战指南

C++内联函数:原理、应用与性能优化实战指南

1. 从“函数调用”说起:为什么我们需要内联函数?写C代码,尤其是性能敏感的程序时,你肯定遇到过这样的纠结:某个函数逻辑很简单,比如就是比较两个数的大小,或者做一次简单的位运算。把它单独封装…

2026/7/26 7:14:38阅读更多 →
Python RPA自动化安全扫描:集成SonoQuest实现漏洞管理全流程

Python RPA自动化安全扫描:集成SonoQuest实现漏洞管理全流程

1. 项目概述:当RPA遇见安全工具如果你是一名安全工程师、运维人员,或者任何需要与安全扫描工具打交道的开发者,那么你肯定对重复、繁琐的手动操作深恶痛绝。每天登录SonoQuest(一款知名的开源安全扫描与漏洞管理平台)的…

2026/7/26 7:14:38阅读更多 →
小波神经网络在金融时间序列预测中的实战应用

小波神经网络在金融时间序列预测中的实战应用

1. 项目概述:小波神经网络在时间序列预测中的应用在金融数据分析领域,股票价格预测一直是个极具挑战性的课题。传统的时间序列分析方法(如ARIMA)往往难以捕捉市场中的非线性特征和突变信号。我在实际项目中尝试将小波变换与神经网…

2026/7/26 7:12:38阅读更多 →
Mac系统自带OpenSSL生成RSA密钥:从原理到实战排错指南

Mac系统自带OpenSSL生成RSA密钥:从原理到实战排错指南

1. 项目概述:为什么Mac用户应该拥抱自带的OpenSSL如果你是一名Mac开发者,或者需要处理任何与加密、证书、API密钥相关的工作,那么“生成RSA密钥”这个需求对你来说一定不陌生。无论是配置SSH免密登录服务器、为你的应用生成签名密钥、还是对接…

2026/7/26 8:22:49阅读更多 →
AI浏览器技术解析:从架构变革到开发实践

AI浏览器技术解析:从架构变革到开发实践

如果你还在把浏览器当成简单的网页查看器,那可能已经错过了AI时代最重要的生产力变革。最近各大浏览器厂商的动作表明,AI正在彻底重塑浏览器的核心价值——从被动的信息展示工具,变成主动的智能工作伙伴。传统浏览器解决的是"如何看到信…

2026/7/26 8:22:49阅读更多 →
AIGC检测与人工降重:学术论文修改实战指南

AIGC检测与人工降重:学术论文修改实战指南

1. 论文AIGC检测与修改的必要性最近帮学弟学妹改论文时发现,很多人的初稿在AIGC检测工具中都会出现高疑似度提示。这其实很正常——现在大家都会用AI辅助写作,但直接提交AI生成的内容确实存在学术风险。我去年投稿时也遇到过类似情况,后来摸索…

2026/7/26 8:22:49阅读更多 →
游戏修改器开发:跨进程内存读写原理与实践

游戏修改器开发:跨进程内存读写原理与实践

1. 项目概述:揭开修改器的神秘面纱第一次接触游戏修改器时,我也曾被那些"一键秒杀""无限金币"的功能震撼到。直到后来逆向分析了几款主流修改器,才发现它们的核心原理出奇地简单——本质上就是通过跨进程内存读写实现的自…

2026/7/26 8:22:49阅读更多 →
3分钟快速汉化Figma界面:FigmaCN中文插件完整使用指南

3分钟快速汉化Figma界面:FigmaCN中文插件完整使用指南

3分钟快速汉化Figma界面:FigmaCN中文插件完整使用指南 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面而烦恼吗?作为中文设计师&#xff0…

2026/7/26 8:22:49阅读更多 →
TI硬件加密处理器实战:AES/SHA-256寄存器编程与性能优化指南

TI硬件加密处理器实战:AES/SHA-256寄存器编程与性能优化指南

1. 项目概述:硬件加密处理器的核心价值 在嵌入式系统和物联网设备里,数据安全不再是“锦上添花”,而是“生死攸关”的底线。无论是智能门锁的通信、车载网络的指令,还是工业传感器的数据,一旦在传输或存储过程中被窃取…

2026/7/26 8:20:49阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/26 0:01:28阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/26 0:01:28阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/26 0:01:28阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/26 0:01:28阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/26 0:01:28阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/26 0:01:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/25 23:03:25阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/25 19:03:04阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/25 19:03:04阅读更多 →