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/FITKAbstractOCCModel.cpp

198 lines
5.8 KiB
C++

#include "FITKAbstractOCCModel.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractGeoModel.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKVirtualTopoManager.h"
#include "FITK_Kernel/FITKCore/FITKThreadPool.h"
#include "FITKOCCVirtualTopoCreator.h"
#include "FITKOCCShapeTriangulate.h"
#include <limits>
#include <TopoDS_Shape.hxx>
#include <BRepTools.hxx>
#include <STEPControl_Writer.hxx>
#include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TShort_Array1OfShortReal.hxx>
#include <StlAPI.hxx>
#include <QHash>
#include <QFile>
#include <QTextStream>
#include <QVector3D>
#include <QDebug>
//
// void printSubShape(Interface::FITKAbsVirtualTopo* topo)
// {
// if (topo == nullptr) return;
// qDebug() << topo->getShapeType() << " " << topo->getDataObjectID();
//
// const int n = topo->getSubTopoCount();
// QList<Interface::FITKAbsVirtualTopo*> subtopos;
// for (int i=0;i<n; ++i)
// {
// auto sub = topo->getSubTopo(i);
// subtopos.append(sub);
// qDebug() << sub->getShapeType() << " " << sub->getDataObjectID();
//
// }
// for (auto s : subtopos)
// {
// printSubShape(s);
// }
//
// qDebug() << "";
// }
//建立映射关系
static QHash<Interface::FITKModelEnum::FITKModelSetType, TopAbs_ShapeEnum> OCCShapeEnums = {
{Interface::FITKModelEnum::FITKModelSetType::FMSPoint, TopAbs_VERTEX},
{Interface::FITKModelEnum::FITKModelSetType::FMSEdge, TopAbs_EDGE},
{Interface::FITKModelEnum::FITKModelSetType::FMSSurface, TopAbs_FACE},
{Interface::FITKModelEnum::FITKModelSetType::FMSSolid, TopAbs_SOLID} };
namespace OCC
{
FITKAbstractOCCModel::FITKAbstractOCCModel(Interface::FITKAbsGeoCommand* c)
:Interface::FITKAbsGeoShapeAgent(c)
{
_shape = new TopoDS_Shape;
}
FITKAbstractOCCModel::~FITKAbstractOCCModel()
{
if(_shape) delete _shape;
}
bool FITKAbstractOCCModel::writeToFile(const QString & file)
{
QString lowerS = file.toLower();
QByteArray ba = lowerS.toLocal8Bit();
const char* c = ba.data();
bool ok = false;
//导出brep
if (lowerS.endsWith("brep"))
{
ok = BRepTools::Write(*_shape, c);
}
//导出stp
else if (lowerS.endsWith("stp") || lowerS.endsWith("step"))
{
STEPControl_Writer awriter;
awriter.Transfer(*_shape, STEPControl_AsIs);
ok = awriter.Write(c);
}
//写出 igs
else if (lowerS.endsWith("igs") || lowerS.endsWith("iges"))
{
IGESControl_Controller::Init();
IGESControl_Writer igesWriter;
igesWriter.AddShape(*_shape);
ok = igesWriter.Write(c);
}
return ok;
}
int FITKAbstractOCCModel::getShapeCount(Interface::FITKModelEnum::FITKModelSetType type)
{
if (!OCCShapeEnums.contains(type)) return -1;
TopAbs_ShapeEnum shapeType = OCCShapeEnums.value(type);
//建立映射
TopTools_IndexedMapOfShape maps;
TopExp::MapShapes(*_shape, shapeType, maps);
return maps.Extent();
}
const TopoDS_Shape FITKAbstractOCCModel::getShape(Interface::FITKModelEnum::FITKModelSetType type, const int id)
{
if (!OCCShapeEnums.contains(type)) return TopoDS_Shape();
TopAbs_ShapeEnum shapeType = OCCShapeEnums.value(type);
//建立映射
TopTools_IndexedMapOfShape maps;
TopExp::MapShapes(*_shape, shapeType, maps);
//key 从1开始
return maps.FindKey(id);
}
TopoDS_Shape* FITKAbstractOCCModel::getShape()
{
return _shape;
}
Interface::FITKGeoEnum::FITKGeoEngine FITKAbstractOCCModel::getGeoEngine()
{
return Interface::FITKGeoEnum::FGEOCC;
}
Interface::FITKModelEnum::AbsModelType FITKAbstractOCCModel::getAbsModelType()
{
return Interface::FITKModelEnum::AbsModelType::AMTGeometry;
}
void FITKAbstractOCCModel::getBoundaryBox(double* min, double* max)
{
if (min == nullptr || max == nullptr) return;
//计算包围盒
Bnd_Box box;
BRepBndLib::Add(*_shape, box, false);
gp_Pnt minpt = box.CornerMin();
gp_Pnt maxpt = box.CornerMax();
//复制值
min[0] = minpt.X();
min[1] = minpt.Y();
min[2] = minpt.Z();
max[0] = maxpt.X();
max[1] = maxpt.Y();
max[2] = maxpt.Z();
}
void FITKAbstractOCCModel::updateShape(const TopoDS_Shape& shape)
{
//正在执行构建拓扑
if (_buildingTopo) return;
*_shape = shape;
this->buildVirtualTopo();
}
void FITKAbstractOCCModel::buildVirtualTopo()
{
if (_buildingTopo) return;
_vtmanager->clear();
QString name;
if (_command)
name = _command->getDataObjectName();
FITKOCCVirtualTopoCreator* creator = new FITKOCCVirtualTopoCreator(*_shape, _vtmanager, name,_buildingTopo);
creator->createOCCTopos();
Core::FITKThreadPool::getInstance()->execTask(creator);
// v.creatOCCVirtualTopo(*_shape, _vtmanager);
// this->triangulation();
}
void FITKAbstractOCCModel::triangulation()
{
// this->triangulate(*_shape);
FITKOCCShapeTriangulate t(this);
t.triangulate();
}
int FITKAbstractOCCModel::shapeHashCode()
{
if (_shape == nullptr || _shape->IsNull()) return -1;
return _shape->HashCode(std::numeric_limits<int>::max());
}
OCCShapeAgent::OCCShapeAgent(Interface::FITKAbsGeoCommand* c)
{
_occShapeAgent = new FITKAbstractOCCModel(c);
}
}