|
|
#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);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|