#include "FITKOCCVirtualTopoCreator.h" #include "FITK_Interface/FITKInterfaceGeometry/FITKVirtualTopoManager.h" #include "FITK_Kernel/FITKAppFramework/FITKMessage.h" #include "FITK_Kernel/FITKCore/FITKThreadPool.h" #include "FITK_Kernel/FITKCore/FITKThreadTaskGroup.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace OCC { //几何类型映射 QHash OCCShapeEnumHash = { {TopAbs_COMPOUND, Interface::FITKGeoEnum::VSAssembly}, {TopAbs_SOLID, Interface::FITKGeoEnum::VSSolid}, {TopAbs_SHELL, Interface::FITKGeoEnum::VSShell}, {TopAbs_FACE, Interface::FITKGeoEnum::VSFace}, {TopAbs_WIRE, Interface::FITKGeoEnum::VSWire}, {TopAbs_EDGE, Interface::FITKGeoEnum::VSEdge}, {TopAbs_VERTEX, Interface::FITKGeoEnum::VSPoint}, }; //支持的OCC类型,需要注意层次顺序 QList OCCShapeEnumList = { TopAbs_COMPOUND,TopAbs_SOLID,TopAbs_SHELL ,TopAbs_FACE,TopAbs_WIRE, TopAbs_EDGE, TopAbs_VERTEX }; FITKOCCTopoShape::FITKOCCTopoShape(const TopoDS_Shape & shape) { _shape = new TopoDS_Shape; *_shape = shape; } bool FITKOCCTopoShape::isSameShape(void* s) { TopoDS_Shape* shape = static_cast(s); return shape->IsSame(*_shape); } const TopoDS_Shape& FITKOCCTopoShape::getTopoShape() const { return *_shape; } FITKOCCVirtualTopoCreator::FITKOCCVirtualTopoCreator(const TopoDS_Shape& shape, Interface::FITKVirtualTopoManager* topo, const QString& model, bool& r) :_shape(shape), _topoMgr(topo), _modelName(model), _runLabel(r) { _runLabel = true; } FITKOCCVirtualTopoCreator::~FITKOCCVirtualTopoCreator() { _runLabel = false; } void FITKOCCVirtualTopoCreator::run() { // Core::FITKThreadPool::getInstance()->wait(); if (_topoMgr == nullptr) return; if (_topoMgr->getAllShapeVirtualTopoCount() == 0) return; // AppFrame::FITKMessageNormal(QString("%1 building virtual topo...").arg(_modelName)); this->buildTopoTree(_shape, _topoMgr, _topoMgr->getRootObj()); // AppFrame::FITKMessageNormal(QString("%1 virtual topo built !").arg(_modelName)); // qDebug() << "topo build: " << QDateTime::currentDateTime().toString("hh:mm:ss:zzz"); } void FITKOCCVirtualTopoCreator::createOCCTopos() { // qDebug() << "build topo: " << QDateTime::currentDateTime().toString("hh:mm:ss:zzz"); if (_topoMgr == nullptr) return; //顶层形状类型 TopAbs_ShapeEnum shapeEnum = _shape.ShapeType(); int index = OCCShapeEnumList.indexOf(shapeEnum); if (index < 0) { shapeEnum = TopAbs_COMPOUND; index = 0; } //顶层节点 Interface::FITKGeoEnum::VTopoShapeType vts = OCCShapeEnumHash.value(shapeEnum); Interface::FITKAbsVirtualTopo* parent = new Interface::FITKAbsVirtualTopo; parent->setShapeType(vts); parent->setShape(new FITKOCCTopoShape(_shape)); _topoMgr->setRootObj(parent); _topoMgr->appendVirtualTopoObj(parent); parent->setIndexLabel(0); int hashInt = _shape.HashCode(std::numeric_limits::max()); // _virtualTopoHash.insert(hashInt, parent); _virtualTopoHash[vts][hashInt] = parent; Core::FITKThreadTaskGroup g; while (++index < OCCShapeEnumList.size()) { TopAbs_ShapeEnum cshapeEnum = OCCShapeEnumList[index]; if (!OCCShapeEnumHash.contains(cshapeEnum)) { //index++; continue; } Interface::FITKGeoEnum::VTopoShapeType cvts = OCCShapeEnumHash.value(cshapeEnum); // QHash& s = _virtualTopoHash[cvts]; FITKOCCVirtualTopoMapper* m = new FITKOCCVirtualTopoMapper(_shape, _topoMgr, _virtualTopoHash, index); g.appendThreadTask(m); //index++; } g.push2ThreadPool(); g.wait(); qDebug() << "create topo Obj: " << QDateTime::currentDateTime().toString("hh:mm:ss:zzz"); } void FITKOCCVirtualTopoCreator::buildTopoTree(const TopoDS_Shape& shape, Interface::FITKVirtualTopoManager* topomgr, Interface::FITKAbsVirtualTopo* parent) { //顶层形状类型 TopAbs_ShapeEnum shapeEnum = shape.ShapeType(); int index = OCCShapeEnumList.indexOf(shapeEnum); if (index < 0) { shapeEnum = TopAbs_COMPOUND; index = 0; } //遍历当前层级的字形状 while (++index < OCCShapeEnumList.size()) { TopAbs_ShapeEnum cshapeEnum = OCCShapeEnumList[index]; Interface::FITKGeoEnum::VTopoShapeType cvts = OCCShapeEnumHash.value(cshapeEnum); // 特殊处理复合对象。 Added by ChengHaotian 2024/09/19 //@{ if (shapeEnum == TopAbs_ShapeEnum::TopAbs_COMPOUND) { TopoDS_Iterator iter(shape); for (; iter.More(); iter.Next()) { const TopoDS_Shape & subShape = iter.Value(); const int sHash = subShape.HashCode(std::numeric_limits::max()); Interface::FITKGeoEnum::VTopoShapeType subCvts = OCCShapeEnumHash.value(subShape.ShapeType()); Interface::FITKAbsVirtualTopo* subtopo = _virtualTopoHash[subCvts][sHash]; if (subtopo == nullptr) continue; parent->addSubTopo(subtopo); if (subCvts == Interface::FITKGeoEnum::VSPoint) continue; this->buildTopoTree(subShape, topomgr, subtopo); break; } } //@} else { TopTools_IndexedMapOfShape map; TopExp::MapShapes(shape, cshapeEnum, map); const int subShapeCount = map.Extent(); if (subShapeCount < 1) continue; for (int i = 1; i <= subShapeCount; i++) { //当前形状 const TopoDS_Shape& subShape = map.FindKey(i); const int sHash = subShape.HashCode(std::numeric_limits::max()); Interface::FITKAbsVirtualTopo* subtopo = _virtualTopoHash[cvts][sHash]; //topomgr->getVirtualTopo(&subShape, cvts); if (subtopo == nullptr) continue; parent->addSubTopo(subtopo); if (cvts == Interface::FITKGeoEnum::VSPoint) continue; this->buildTopoTree(subShape, topomgr, subtopo); } } break; } } FITKOCCVirtualTopoMapper::FITKOCCVirtualTopoMapper(const TopoDS_Shape& shape, Interface::FITKVirtualTopoManager* topomgr, QHash> &topos, int shapeTypeIndex) :_shape(shape), _topos(topos), _topoMgr(topomgr), _shapeTypeIndex(shapeTypeIndex) { TopAbs_ShapeEnum cshapeEnum = OCCShapeEnumList[_shapeTypeIndex]; if (!OCCShapeEnumHash.contains(cshapeEnum)) return; Interface::FITKGeoEnum::VTopoShapeType cvts = OCCShapeEnumHash.value(cshapeEnum); // 特殊处理复合对象。 Added by ChengHaotian 2024/09/19 //@{ if (cshapeEnum == TopAbs_ShapeEnum::TopAbs_COMPOUND) { TopoDS_Iterator iter(_shape); for (; iter.More(); iter.Next()) { _topoList.append(new Interface::FITKAbsVirtualTopo); } } //@} else { TopTools_IndexedMapOfShape map; TopExp::MapShapes(_shape, cshapeEnum, map); const int subShapeCount = map.Extent(); if (subShapeCount < 1) return; for (int i = 1; i <= subShapeCount; ++i) { _topoList.append(new Interface::FITKAbsVirtualTopo); } } } void FITKOCCVirtualTopoMapper::run() { TopAbs_ShapeEnum cshapeEnum = OCCShapeEnumList[_shapeTypeIndex]; if (!OCCShapeEnumHash.contains(cshapeEnum)) return; Interface::FITKGeoEnum::VTopoShapeType cvts = OCCShapeEnumHash.value(cshapeEnum); // 特殊处理复合对象。 Added by ChengHaotian 2024/09/19 //@{ if (cshapeEnum == TopAbs_ShapeEnum::TopAbs_COMPOUND) { QList topoObjs; int iShape = 0; TopoDS_Iterator iter(_shape); for (; iter.More(); iter.Next()) { const TopoDS_Shape & subShape = iter.Value(); Interface::FITKGeoEnum::VTopoShapeType subCvts = OCCShapeEnumHash.value(subShape.ShapeType()); Interface::FITKAbsVirtualTopo* vTopo = _topoList[iShape]; vTopo->setShapeType(subCvts); vTopo->setShape(new FITKOCCTopoShape(subShape)); vTopo->setIndexLabel(iShape); topoObjs.append(vTopo); int hashInt = subShape.HashCode(std::numeric_limits::max()); _topos[subCvts][hashInt] = vTopo; iShape++; } _topoMgr->appendVirtualTopoObjs(topoObjs); } //@} else { TopTools_IndexedMapOfShape map; TopExp::MapShapes(_shape, cshapeEnum, map); const int subShapeCount = map.Extent(); if (subShapeCount < 1) return; QList topoObjs; for (int i = 1; i <= subShapeCount; i++) { //当前形状 const TopoDS_Shape & subShape = map.FindKey(i); Interface::FITKAbsVirtualTopo* subtopo = _topoList.at(i - 1);//new Interface::FITKAbsVirtualTopo; subtopo->setShapeType(cvts); subtopo->setShape(new FITKOCCTopoShape(subShape)); subtopo->setIndexLabel(i - 1); topoObjs.append(subtopo); int hashInt = subShape.HashCode(std::numeric_limits::max()); // _virtualTopoHash.insert(hashInt, subtopo); _topos[cvts][hashInt] = subtopo; } _topoMgr->appendVirtualTopoObjs(cvts, topoObjs); } } }