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

332 lines
13 KiB
C++

#include "FITKOCCSplitter.h"
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <Precision.hxx>
#include <BOPAlgo_Splitter.hxx>
#include <TopExp_Explorer.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <gp_Pln.hxx>
#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 {
// 构造函数
FITKOCCCurveSplitter::FITKOCCCurveSplitter() :OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
// 更新数据
bool FITKOCCCurveSplitter::update()
{
if (m_SourceShape.isNull() || m_ToolShape.isNull()) return false;
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
// 分割算法
BOPAlgo_Splitter splitter;
// 设置被分割的对象
auto sourceCmd = geoCmdList->getDataByID(m_SourceShape.CmdId);
if (sourceCmd == nullptr) return false;
auto sourceShape = sourceCmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_SourceShape.VirtualTopoId);
if (sourceShape == nullptr) return false;
TopoDS_Shape sourceTopoShape = sourceShape->getTopoShape();
if (sourceTopoShape.IsNull()) return false;
splitter.AddArgument(sourceTopoShape);
// 设置分割的工具对象
bool isDatumTool = m_ToolShape.isDatumObj();
if (isDatumTool) {
auto datum = geoCmdList->getDatumManager()->getDataByID(m_ToolShape.datumId());
if (datum == nullptr) return false;
int type = static_cast<int>(datum->getDatumType());
// 参考点
TopoDS_Shape toolShape;
if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTLine)) {
auto refPoint = dynamic_cast<Interface::FITKAbsGeoDatumPoint*>(datum);
if (refPoint == nullptr) return false;
double xyz[3]{};
refPoint->getPosition(xyz);
BRepBuilderAPI_MakeVertex vertex(gp_Pnt(xyz[0], xyz[1], xyz[2]));
toolShape = vertex.Shape();
}
else if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTPlane)) {
auto refLine = dynamic_cast<Interface::FITKAbsGeoDatumLine*>(datum);
if (refLine == nullptr) return false;
double start[3]{}, end[3]{};
refLine->getPosition(start);
refLine->getPosition2(end);
BRepBuilderAPI_MakeEdge edge(gp_Pnt(start[0], start[1], start[2]), gp_Pnt(end[0], end[1], end[2]));
toolShape = edge.Shape();
}
else {
auto refPlane = dynamic_cast<Interface::FITKAbsGeoDatumPlane*>(datum);
if (refPlane == nullptr) return false;
double loc[3]{}, normal[3]{}, up[3]{};
refPlane->getPlane(loc, normal, up);
gp_Pln plane(
gp_Pnt(loc[0], loc[1], loc[2]),
gp_Dir(normal[0], normal[1], normal[2])
);
BRepBuilderAPI_MakeFace face(plane);
toolShape = face.Shape();
}
if (toolShape.IsNull()) return false;
splitter.AddTool(toolShape);
}
else {
auto toolCmd = geoCmdList->getDataByID(m_ToolShape.cmdId());
if (toolCmd == nullptr) return false;
auto toolShape = toolCmd->getShapeT<FITKOCCTopoShape>(m_ToolShape.virtualTopoId());
if (toolShape == nullptr) return false;
TopoDS_Shape toolTopoShape = toolShape->getTopoShape();
if (toolTopoShape.IsNull()) return false;
splitter.AddTool(toolTopoShape);
}
// 更新分割
try {
splitter.Perform();
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopExp_Explorer exp;
int index = 0;
for (exp.Init(splitter.Shape(), TopAbs_EDGE); exp.More(); exp.Next())
{
aBuilder.Add(aCompound, exp.Current());
}
_occShapeAgent->updateShape(aCompound);
/*if (toolTopoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_VERTEX) {
gp_Pnt pnt = BRep_Tool::Pnt(TopoDS::Vertex(toolTopoShape));
m_Point = { pnt.X(), pnt.Y(), pnt.Z() };
}*/
}
catch (...)
{
printLog(tr("Failed to split!"), 3);
return false;
}
return true;
}
// 构造函数
FITKOCCSurfaceSplitter::FITKOCCSurfaceSplitter() :OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
// 更新数据
bool FITKOCCSurfaceSplitter::update()
{
if (m_SourceShape.isNull() || m_ToolShape.isNull()) return false;
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
// 分割算法
BOPAlgo_Splitter splitter;
// 设置被分割的对象
auto sourceCmd = geoCmdList->getDataByID(m_SourceShape.CmdId);
if (sourceCmd == nullptr) return false;
auto sourceShape = sourceCmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSFace, m_SourceShape.VirtualTopoId);
if (sourceShape == nullptr) return false;
TopoDS_Shape sourceTopoShape = sourceShape->getTopoShape();
if (sourceTopoShape.IsNull()) return false;
splitter.AddArgument(sourceTopoShape);
// 设置分割的工具对象
bool isDatumTool = m_ToolShape.isDatumObj();
if (isDatumTool) {
auto datum = geoCmdList->getDatumManager()->getDataByID(m_ToolShape.datumId());
if (datum == nullptr) return false;
int type = static_cast<int>(datum->getDatumType());
// 参考点
TopoDS_Shape toolShape;
if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTLine)) {
auto refPoint = dynamic_cast<Interface::FITKAbsGeoDatumPoint*>(datum);
if (refPoint == nullptr) return false;
double xyz[3]{};
refPoint->getPosition(xyz);
BRepBuilderAPI_MakeVertex vertex(gp_Pnt(xyz[0], xyz[1], xyz[2]));
toolShape = vertex.Shape();
}
else if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTPlane)) {
auto refLine = dynamic_cast<Interface::FITKAbsGeoDatumLine*>(datum);
if (refLine == nullptr) return false;
double start[3]{}, end[3]{};
refLine->getPosition(start);
refLine->getPosition2(end);
BRepBuilderAPI_MakeEdge edge(gp_Pnt(start[0], start[1], start[2]), gp_Pnt(end[0], end[1], end[2]));
toolShape = edge.Shape();
}
else {
auto refPlane = dynamic_cast<Interface::FITKAbsGeoDatumPlane*>(datum);
if (refPlane == nullptr) return false;
double loc[3]{}, normal[3]{}, up[3]{};
refPlane->getPlane(loc, normal, up);
gp_Pln plane(
gp_Pnt(loc[0], loc[1], loc[2]),
gp_Dir(normal[0], normal[1], normal[2])
);
BRepBuilderAPI_MakeFace face(plane);
toolShape = face.Shape();
}
if (toolShape.IsNull()) return false;
splitter.AddTool(toolShape);
}
else {
auto toolCmd = geoCmdList->getDataByID(m_ToolShape.cmdId());
if (toolCmd == nullptr) return false;
auto toolShape = toolCmd->getShapeT<FITKOCCTopoShape>(m_ToolShape.virtualTopoId());
if (toolShape == nullptr) return false;
TopoDS_Shape toolTopoShape = toolShape->getTopoShape();
if (toolTopoShape.IsNull()) return false;
splitter.AddTool(toolTopoShape);
}
// 更新分割
try {
splitter.Perform();
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopExp_Explorer exp;
int index = 0;
for (exp.Init(splitter.Shape(), TopAbs_FACE); exp.More(); exp.Next())
{
aBuilder.Add(aCompound, exp.Current());
}
_occShapeAgent->updateShape(aCompound);
}
catch (...)
{
printLog(tr("Failed to split!"), 3);
return false;
}
return true;
}
// 构造函数
FITKOCCSolidSplitter::FITKOCCSolidSplitter() :OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
// 更新数据
bool FITKOCCSolidSplitter::update()
{
if (m_SourceShape.isNull() || m_ToolShape.isNull()) return false;
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
// 分割算法
BOPAlgo_Splitter splitter;
// 设置被分割的对象
auto sourceCmd = geoCmdList->getDataByID(m_SourceShape.CmdId);
if (sourceCmd == nullptr) return false;
auto sourceShape = sourceCmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSSolid, m_SourceShape.VirtualTopoId);
if (sourceShape == nullptr) return false;
TopoDS_Shape sourceTopoShape = sourceShape->getTopoShape();
if (sourceTopoShape.IsNull()) return false;
splitter.AddArgument(sourceTopoShape);
// 设置分割的工具对象
bool isDatumTool = m_ToolShape.isDatumObj();
if (isDatumTool) {
auto datum = geoCmdList->getDatumManager()->getDataByID(m_ToolShape.datumId());
if (datum == nullptr) return false;
int type = static_cast<int>(datum->getDatumType());
// 参考点
TopoDS_Shape toolShape;
if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTLine)) {
auto refPoint = dynamic_cast<Interface::FITKAbsGeoDatumPoint*>(datum);
if (refPoint == nullptr) return false;
double xyz[3]{};
refPoint->getPosition(xyz);
BRepBuilderAPI_MakeVertex vertex(gp_Pnt(xyz[0], xyz[1], xyz[2]));
toolShape = vertex.Shape();
}
else if (type < static_cast<int>(Interface::FITKGeoEnum::FITKDatumType::FDTPlane)) {
auto refLine = dynamic_cast<Interface::FITKAbsGeoDatumLine*>(datum);
if (refLine == nullptr) return false;
double start[3]{}, end[3]{};
refLine->getPosition(start);
refLine->getPosition2(end);
BRepBuilderAPI_MakeEdge edge(gp_Pnt(start[0], start[1], start[2]), gp_Pnt(end[0], end[1], end[2]));
toolShape = edge.Shape();
}
else {
auto refPlane = dynamic_cast<Interface::FITKAbsGeoDatumPlane*>(datum);
if (refPlane == nullptr) return false;
double loc[3]{}, normal[3]{}, up[3]{};
refPlane->getPlane(loc, normal, up);
gp_Pln plane(
gp_Pnt(loc[0], loc[1], loc[2]),
gp_Dir(normal[0], normal[1], normal[2])
);
BRepBuilderAPI_MakeFace face(plane);
toolShape = face.Shape();
}
if (toolShape.IsNull()) return false;
splitter.AddTool(toolShape);
}
else {
auto toolCmd = geoCmdList->getDataByID(m_ToolShape.cmdId());
if (toolCmd == nullptr) return false;
auto toolShape = toolCmd->getShapeT<FITKOCCTopoShape>(m_ToolShape.virtualTopoId());
if (toolShape == nullptr) return false;
TopoDS_Shape toolTopoShape = toolShape->getTopoShape();
if (toolTopoShape.IsNull()) return false;
splitter.AddTool(toolTopoShape);
}
// 更新分割
try {
splitter.Perform();
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopExp_Explorer exp;
int index = 0;
for (exp.Init(splitter.Shape(), TopAbs_SOLID); exp.More(); exp.Next())
{
aBuilder.Add(aCompound, exp.Current());
}
_occShapeAgent->updateShape(aCompound);
}
catch (...)
{
printLog(tr("Failed to split!"), 3);
return false;
}
return true;
}
}