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.
332 lines
13 KiB
C++
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;
|
|
}
|
|
}
|
|
|
|
|