You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AppFlow/FITK_Component/FITKGeoCompOCC/FITKOCCVirtualTopoCreator.cpp

284 lines
11 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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 <TopExp_Explorer.hxx>
#include <QHash>
#include <QList>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Iterator.hxx>
#include <QDateTime>
#include <QDebug>
namespace OCC
{
//几何类型映射
QHash<TopAbs_ShapeEnum, Interface::FITKGeoEnum::VTopoShapeType> 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<TopAbs_ShapeEnum> 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<TopoDS_Shape*>(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<int>::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<int, Interface::FITKAbsVirtualTopo*>& 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<int>::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<int>::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<Interface::FITKGeoEnum::VTopoShapeType, QHash<int, Interface::FITKAbsVirtualTopo*>> &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<Interface::FITKAbsVirtualTopo*> 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<int>::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<Core::FITKAbstractDataObject*> 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<int>::max());
// _virtualTopoHash.insert(hashInt, subtopo);
_topos[cvts][hashInt] = subtopo;
}
_topoMgr->appendVirtualTopoObjs(cvts, topoObjs);
}
}
}