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

139 lines
4.4 KiB
C++

#include "FITKOCCOperBool.h"
#include <TopoDS_Shape.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include "FITKOCCComandCommon.h"
#include <FITK_Interface/FITKInterfaceGeometry/FITKGeoEnum.h>
#include <FITK_Interface/FITKInterfaceGeometry/FITKVirtualTopoManager.h>
#include "FITKOCCVirtualTopoCreator.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelSurface.h"
namespace OCC
{
FITKOCCOperBool::FITKOCCOperBool() :OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCOperBool::update()
{
const TopoDS_Shape* s1{};
const TopoDS_Shape* s2{};
if (!m_Target.isNull() && !m_Tool.isNull()) {
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
auto targetCmd = geoCmdList->getDataByID(m_Target.CmdId);
if (targetCmd == nullptr) return false;
auto vTargetShape = targetCmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSSolid, m_Target.VirtualTopoId);
if (vTargetShape == nullptr) return false;
s1 = &(vTargetShape->getTopoShape());
auto toolCmd = geoCmdList->getDataByID(m_Tool.CmdId);
if (toolCmd == nullptr) return false;
auto vToolShape = toolCmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSSolid, m_Tool.VirtualTopoId);
if (vToolShape == nullptr) return false;
s2 = &(vToolShape->getTopoShape());
}
// 兼容旧接口
else if (_shape1 != nullptr && _shape2 != nullptr) {
FITKAbstractOCCModel* model1 = dynamic_cast<FITKAbstractOCCModel*>(_shape1);
FITKAbstractOCCModel* model2 = dynamic_cast<FITKAbstractOCCModel*>(_shape2);
if (model2 == nullptr || model1 == nullptr) return false;
s1 = model1->getShape();
s2 = model2->getShape();
}
else {
return false;
}
switch (_boolOperType)
{
case Interface::FITKAbsGeoOperBool::GBTCommon:
this->common(s1, s2);
break;
case Interface::FITKAbsGeoOperBool::GBTCut:
this->cut(s1, s2);
break;
case Interface::FITKAbsGeoOperBool::GBTAdd:
this->add(s1, s2);
break;
default:
return false;
}
return true;
}
void FITKOCCOperBool::cut(const TopoDS_Shape* shape1, const TopoDS_Shape* shape2)
{
try {
const TopoDS_Shape &aCuttedShape = BRepAlgoAPI_Cut(*shape1, *shape2);
_occShapeAgent->updateShape(aCuttedShape);
}
catch (...)
{
printLog(tr("Failed to perform a Boolean operation!"), 3);
return;
}
}
void FITKOCCOperBool::common(const TopoDS_Shape* shape1, const TopoDS_Shape* shape2)
{
try {
if (shape1 == nullptr || shape2 == nullptr) return;
const TopoDS_Shape &ashape = BRepAlgoAPI_Common(*shape1, *shape2);
if (!ashape.IsSame(TopoDS_Shape()))
{
_occShapeAgent->updateShape(ashape);
return;
}
BRepAlgoAPI_Section S(*shape1, *shape2, false);
S.Build();
if (S.IsDone())
{
_occShapeAgent->updateShape(S.Shape());
}
}
catch (...)
{
printLog(tr("Failed to perform a Boolean operation!"), 3);
return;
}
}
void FITKOCCOperBool::add(const TopoDS_Shape* shape1, const TopoDS_Shape* shape2)
{
try {
BRepAlgoAPI_Fuse fau(*shape1, *shape2);
if (!fau.IsDone()) return;
const TopoDS_Shape &aFusedShape = fau.Shape();
if (aFusedShape.IsNull()) return;
TopoDS_Shape shape = Command::GeoCommandCommon::removeSplitter(aFusedShape);
_occShapeAgent->updateShape(shape);
}
catch (...)
{
printLog(tr("Failed to perform a Boolean operation!"), 3);
return;
}
}
}