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

759 lines
30 KiB
C++

#include "FITKOCCModelSolid.h"
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <TopoDS.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepOffset_MakeOffset.hxx>
#include <BRepOffsetAPI_MakePipe.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <Precision.hxx>
#include <BRepBndLib.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.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"
#include <FITKOCCModelCurve.h>
namespace {
struct CWire {
Bnd_Box Bound;
BRepBuilderAPI_MakeWire MakeWire{};
gp_Pnt Start{};
gp_Pnt End{};
bool isNull() { return MakeWire.Edge().IsNull(); }
bool isClosed() { return MakeWire.Shape().Closed(); }
};
}
namespace OCC
{
FITKOCCModelClosedSurfaceSolid::FITKOCCModelClosedSurfaceSolid() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelClosedSurfaceSolid::update()
{
if (m_Faces.isEmpty()) return false;
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
BRepBuilderAPI_Sewing sewing;
for (int i = 0; i < m_Faces.size(); ++i) {
auto face = m_Faces.at(i);
if (face.isNull()) continue;
auto cmd = geoCmdList->getDataByID(face.CmdId);
if (cmd == nullptr)
{
printLog(tr("Failed to get geometry command."), 3);
return false;
}
auto vshape = cmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSFace, face.VirtualTopoId);
if (vshape == nullptr)
{
printLog(tr("Failed to get face from virtual topo."), 3);
return false;
}
auto topoShape = vshape->getTopoShape();
if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_FACE) {
TopoDS_Face f = TopoDS::Face(topoShape);
if (f.IsNull()) continue;
if (f.Orientation() == TopAbs_Orientation::TopAbs_REVERSED) {
f.Reverse();
}
sewing.Add(f);
}
else {
printLog(tr("Error topo shape type for make wire."), 3);
return false;
}
}
sewing.Perform();
auto type = sewing.SewedShape().ShapeType();
/*if (type == TopAbs_COMPOUND)
{
TopoDS_Builder aShellBuilder;
TopoDS_Shell aShell;
aShellBuilder.MakeShell(aShell);
int faceCount = 0;
int edgeCount = 0;
for (TopoDS_Iterator anExp(sewing.SewedShape()); anExp.More(); anExp.Next())
{
const TopoDS_Shape &curShape1 = anExp.Value();
TopAbs_ShapeEnum type1 = curShape1.ShapeType();
if (type1 == TopAbs_SHELL)
{
for (TopExp_Explorer anExp(curShape1, TopAbs_FACE); anExp.More(); anExp.Next())
{
const TopoDS_Shape &curShape2 = anExp.Current();
aShellBuilder.Add(aShell, curShape2);
faceCount++;
}
}
}
}*/
if (type != TopAbs_SHELL)
{
printLog(tr("Error topo shape type for make wire."), 3);
return false;
}
try {
TopoDS_Shell shell = TopoDS::Shell(sewing.SewedShape());
if (shell.IsNull() || !shell.Closed()) {
printLog(tr("Must be closed shell."), 3);
return false;
}
BRepBuilderAPI_MakeSolid solid(shell);
if (!solid.IsDone()) {
printLog(tr("Error topo shape type for make wire."), 3);
return false;
}
_occShapeAgent->updateShape(solid.Shape());
}
catch (...)
{
printLog(tr("Failed to make solid!"), 3);
return false;
}
return true;
}
FITKOCCModelExtrudeSolid::FITKOCCModelExtrudeSolid() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelExtrudeSolid::update()
{
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
auto cmd = geoCmdList->getDataByID(m_SourceSurface.CmdId);
if (cmd == nullptr) return false;
Interface::FITKGeoEnum::VTopoShapeType type = cmd->getGeometryCommandType() == Interface::FITKGeoEnum::FITKGeometryComType::FGTSketch2D ? Interface::FITKGeoEnum::VTopoShapeType::VSAssembly : Interface::FITKGeoEnum::VTopoShapeType::VSFace;
auto shape = cmd->getShapeT<FITKOCCTopoShape>(type, m_SourceSurface.VirtualTopoId);
if (shape == nullptr) return false;
auto topoShape = shape->getTopoShape();
gp_Vec dir(m_Direction[0], m_Direction[1], m_Direction[2]);
auto mag = dir.Magnitude();
if (mag <= Precision::Confusion()) {
printLog(tr("The direction cannot be a zero vector!"), 3);
return false;
}
dir = dir * m_Length / mag;
try {
// 如果是草绘则返回的是线的组合体,需要合并面
if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPOUND)
{
TopoDS_Compound compound = TopoDS::Compound(topoShape);
TopExp_Explorer exp;
QList<CWire> wiresList{};
// 按封闭曲线分组
for (exp.Init(compound, TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
if (edge.IsNull()) continue;
Standard_Real first;
Standard_Real last;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, first, last);
gp_Pnt start = curve->Value(first);
gp_Pnt end = curve->Value(last);
/* 自成封闭的曲线 */
/* @{ */
if (start.Distance(end) < Precision::Confusion()) {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
/* @} */
/* 是否能拼接到已有曲线 */
/* @{ */
bool isSep{ true };
for (auto& wire : wiresList) {
// 已经闭合的曲线不参与比较
if (wire.isClosed()) continue;
if (wire.Start.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = end;
isSep = false;
break;
}
else if (wire.Start.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = start;
isSep = false;
break;
}
else if (wire.End.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = end;
isSep = false;
break;
}
else if (wire.End.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = start;
isSep = false;
break;
}
else {
printLog(QString("wire.Start: [%1, %2, %3]; wire.End: [%4, %5, %6]").arg(wire.Start.X()).arg(wire.Start.Y()).arg(wire.Start.Z()).arg(wire.End.X()).arg(wire.End.Y()).arg(wire.End.Z()), 2);
printLog(QString("Start: [%1, %2, %3]; End: [%4, %5, %6]").arg(start.X()).arg(start.Y()).arg(start.Z()).arg(end.X()).arg(end.Y()).arg(end.Z()), 2);
}
}
/* @} */
// 如果能连接到已有曲线,则分析下一条边
if (!isSep) continue;
// 如果不能连接到已有曲线,则自成一条新的曲线
else {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
}
// 检测封闭性,计算包围盒
for (auto wire : wiresList) {
if (!wire.isClosed()) {
printLog(tr("The selected sketch contains several open profile."), 3);
return false;
}
else {
BRepBndLib::Add(wire.MakeWire.Shape(), wire.Bound);
}
}
/* 按包围盒大小排序 */
/* @{ */
for (int i = 0; i < wiresList.size() - 1; ++i) {
int n = i;
while (n >= 0 && wiresList.at(n).Bound.IsOut(wiresList.at(n + 1).Bound)) {
auto temp = wiresList.at(n);
wiresList[n] = wiresList[n + 1];
wiresList[n + 1] = temp;
n--;
}
}
/* @} */
// 初始化组合对象。
BRep_Builder builder;
TopoDS_Compound compoundSolid;
builder.MakeCompound(compoundSolid);
auto count = wiresList.size();
for (int i = 0; i < count; ++i) {
auto wire = wiresList.at(i);
BRepBuilderAPI_MakeFace face(wire.MakeWire, true);
if (count > i + 1) {
CWire cwire = wiresList.at(i + 1);
TopoDS_Shape innerShape = cwire.MakeWire.Shape();
if (innerShape.ShapeType() != TopAbs_WIRE) return false;
TopoDS_Wire innerWire = TopoDS::Wire(innerShape);
if (innerWire.IsNull()) return false;
innerWire.Reverse();
face.Add(innerWire);
++i;
}
face.Build();
if (!face.IsDone()) return false;
builder.Add(compoundSolid, BRepPrimAPI_MakePrism(face, dir).Shape());
}
_occShapeAgent->updateShape(compoundSolid);
}
else {
_occShapeAgent->updateShape(BRepPrimAPI_MakePrism(topoShape, dir).Shape());
}
}
catch (...)
{
printLog(tr("Failed to make solid!"), 3);
return false;
}
return true;
}
FITKOCCModelRevolSolid::FITKOCCModelRevolSolid() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelRevolSolid::update()
{
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
auto cmd = geoCmdList->getDataByID(m_SourceSurface.CmdId);
if (cmd == nullptr) return false;
Interface::FITKGeoEnum::VTopoShapeType type = cmd->getGeometryCommandType() == Interface::FITKGeoEnum::FITKGeometryComType::FGTSketch2D ? Interface::FITKGeoEnum::VTopoShapeType::VSAssembly : Interface::FITKGeoEnum::VTopoShapeType::VSFace;
auto vshape = cmd->getShapeT<FITKOCCTopoShape>(type, m_SourceSurface.VirtualTopoId);
if (vshape == nullptr) return false;
auto topoShape = vshape->getTopoShape();
//m_OriginId;
gp_Ax1 ax1(
gp_Pnt(m_RotateAxisPoint1[0], m_RotateAxisPoint1[1], m_RotateAxisPoint1[2]),
gp_Dir(m_RotateAxisPoint2[0] - m_RotateAxisPoint1[0], m_RotateAxisPoint2[1] - m_RotateAxisPoint1[1], m_RotateAxisPoint2[2] - m_RotateAxisPoint1[2]));
try {
// 如果是草绘则返回的是线的组合体,需要合并面
if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPOUND)
{
TopoDS_Compound compound = TopoDS::Compound(topoShape);
TopExp_Explorer exp;
QList<CWire> wiresList{};
// 按封闭曲线分组
for (exp.Init(compound, TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
if (edge.IsNull()) continue;
Standard_Real first;
Standard_Real last;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, first, last);
gp_Pnt start = curve->Value(first);
gp_Pnt end = curve->Value(last);
/* 自成封闭的曲线 */
/* @{ */
if (start.Distance(end) < Precision::Confusion()) {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
/* @} */
/* 是否能拼接到已有曲线 */
/* @{ */
bool isSep{ true };
for (auto& wire : wiresList) {
// 已经闭合的曲线不参与比较
if (wire.isClosed()) continue;
if (wire.Start.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = end;
isSep = false;
break;
}
else if (wire.Start.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = start;
isSep = false;
break;
}
else if (wire.End.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = end;
isSep = false;
break;
}
else if (wire.End.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = start;
isSep = false;
break;
}
else {
printLog(QString("wire.Start: [%1, %2, %3]; wire.End: [%4, %5, %6]").arg(wire.Start.X()).arg(wire.Start.Y()).arg(wire.Start.Z()).arg(wire.End.X()).arg(wire.End.Y()).arg(wire.End.Z()), 2);
printLog(QString("Start: [%1, %2, %3]; End: [%4, %5, %6]").arg(start.X()).arg(start.Y()).arg(start.Z()).arg(end.X()).arg(end.Y()).arg(end.Z()), 2);
}
}
/* @} */
// 如果能连接到已有曲线,则分析下一条边
if (!isSep) continue;
// 如果不能连接到已有曲线,则自成一条新的曲线
else {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
}
// 检测封闭性,计算包围盒
for (auto wire : wiresList) {
if (!wire.isClosed()) {
printLog(tr("The selected sketch contains several open profile."), 3);
return false;
}
else {
BRepBndLib::Add(wire.MakeWire.Shape(), wire.Bound);
}
}
/* 按包围盒大小排序 */
/* @{ */
for (int i = 0; i < wiresList.size() - 1; ++i) {
int n = i;
while (n >= 0 && wiresList.at(n).Bound.IsOut(wiresList.at(n + 1).Bound)) {
auto temp = wiresList.at(n);
wiresList[n] = wiresList[n + 1];
wiresList[n + 1] = temp;
n--;
}
}
/* @} */
// 初始化组合对象。
BRep_Builder builder;
TopoDS_Compound compoundSolid;
builder.MakeCompound(compoundSolid);
auto count = wiresList.size();
for (int i = 0; i < count; ++i) {
auto wire = wiresList.at(i);
BRepBuilderAPI_MakeFace face(wire.MakeWire, true);
if (count > i + 1) {
CWire cwire = wiresList.at(i + 1);
TopoDS_Shape innerShape = cwire.MakeWire.Shape();
if (innerShape.ShapeType() != TopAbs_WIRE) return false;
TopoDS_Wire innerWire = TopoDS::Wire(innerShape);
if (innerWire.IsNull()) return false;
innerWire.Reverse();
face.Add(innerWire);
++i;
}
face.Build();
if (!face.IsDone()) return false;
builder.Add(compoundSolid, BRepPrimAPI_MakeRevol(face, ax1, m_Angle * M_PI / 180).Shape());
}
_occShapeAgent->updateShape(compoundSolid);
}
else {
_occShapeAgent->updateShape(BRepPrimAPI_MakeRevol(topoShape, ax1, m_Angle * M_PI / 180).Shape());
}
}
catch (...)
{
printLog(tr("Failed to make solid!"), 3);
return false;
}
return true;
}
FITKOCCModelSweepSolid::FITKOCCModelSweepSolid() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelSweepSolid::update()
{
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
auto profileCmd = geoCmdList->getDataByID(m_Profile.CmdId);
auto curveCmd = geoCmdList->getDataByID(m_Curve.CmdId);
if (profileCmd == nullptr || curveCmd == nullptr) return false;
Interface::FITKGeoEnum::VTopoShapeType profileType = profileCmd->getGeometryCommandType() == Interface::FITKGeoEnum::FITKGeometryComType::FGTSketch2D ? Interface::FITKGeoEnum::VTopoShapeType::VSAssembly : Interface::FITKGeoEnum::VTopoShapeType::VSFace;
auto profileShape = profileCmd->getShapeT<FITKOCCTopoShape>(profileType, m_Profile.VirtualTopoId);
Interface::FITKGeoEnum::VTopoShapeType curveType = curveCmd->getGeometryCommandType() == Interface::FITKGeoEnum::FITKGeometryComType::FGTSketch2D ? Interface::FITKGeoEnum::VTopoShapeType::VSAssembly : Interface::FITKGeoEnum::VTopoShapeType::VSEdge;
auto curveShape = curveCmd->getShapeT<FITKOCCTopoShape>(curveType, m_Curve.VirtualTopoId);
if (profileShape == nullptr || curveShape == nullptr) return false;
auto profileTopoShape = profileShape->getTopoShape();
auto curveTopoShape = curveShape->getTopoShape();
try {
/* 分析扫略线 */
/*@{*/
TopoDS_Wire sweepWire;
auto type = curveTopoShape.ShapeType();
if (type == TopAbs_ShapeEnum::TopAbs_WIRE)
{
sweepWire = TopoDS::Wire(curveTopoShape);
}
else if (type == TopAbs_ShapeEnum::TopAbs_EDGE) {
sweepWire = BRepBuilderAPI_MakeWire(TopoDS::Edge(curveTopoShape));
}
else if (type == TopAbs_ShapeEnum::TopAbs_COMPOUND) {
TopoDS_Compound compound = TopoDS::Compound(curveTopoShape);
TopExp_Explorer exp;
BRepBuilderAPI_MakeWire makeWire;
for (exp.Init(compound, TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
if (edge.IsNull()) continue;
makeWire.Add(edge);
}
makeWire.Build();
if (!makeWire.IsDone()) return false;
sweepWire = TopoDS::Wire(makeWire.Shape());
}
else return false;
/*@}*/
// 如果是草绘则返回的是线的组合体,需要合并面
if (profileTopoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPOUND)
{
TopoDS_Compound compound = TopoDS::Compound(profileTopoShape);
TopExp_Explorer exp;
QList<CWire> wiresList{};
// 按封闭曲线分组
for (exp.Init(compound, TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
if (edge.IsNull()) continue;
Standard_Real first;
Standard_Real last;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, first, last);
gp_Pnt start = curve->Value(first);
gp_Pnt end = curve->Value(last);
/* 自成封闭的曲线 */
/* @{ */
if (start.Distance(end) < Precision::Confusion()) {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
/* @} */
/* 是否能拼接到已有曲线 */
/* @{ */
bool isSep{ true };
for (auto& wire : wiresList) {
// 已经闭合的曲线不参与比较
if (wire.isClosed()) continue;
if (wire.Start.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = end;
isSep = false;
break;
}
else if (wire.Start.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.Start = start;
isSep = false;
break;
}
else if (wire.End.Distance(start) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = end;
isSep = false;
break;
}
else if (wire.End.Distance(end) < Precision::Confusion())
{
wire.MakeWire.Add(edge);
wire.End = start;
isSep = false;
break;
}
else {
printLog(QString("wire.Start: [%1, %2, %3]; wire.End: [%4, %5, %6]").arg(wire.Start.X()).arg(wire.Start.Y()).arg(wire.Start.Z()).arg(wire.End.X()).arg(wire.End.Y()).arg(wire.End.Z()), 2);
printLog(QString("Start: [%1, %2, %3]; End: [%4, %5, %6]").arg(start.X()).arg(start.Y()).arg(start.Z()).arg(end.X()).arg(end.Y()).arg(end.Z()), 2);
}
}
/* @} */
// 如果能连接到已有曲线,则分析下一条边
if (!isSep) continue;
// 如果不能连接到已有曲线,则自成一条新的曲线
else {
CWire w;
w.MakeWire.Add(edge);
w.Start = start;
w.End = end;
wiresList.push_back(w);
continue;
}
}
// 检测封闭性,计算包围盒
for (auto wire : wiresList) {
if (!wire.isClosed()) {
printLog(tr("The selected sketch contains several open profile."), 3);
return false;
}
else {
BRepBndLib::Add(wire.MakeWire.Shape(), wire.Bound);
}
}
/* 按包围盒大小排序 */
/* @{ */
for (int i = 0; i < wiresList.size() - 1; ++i) {
int n = i;
while (n >= 0 && wiresList.at(n).Bound.IsOut(wiresList.at(n + 1).Bound)) {
auto temp = wiresList.at(n);
wiresList[n] = wiresList[n + 1];
wiresList[n + 1] = temp;
n--;
}
}
/* @} */
// 初始化组合对象。
BRep_Builder builder;
TopoDS_Compound compoundSolid;
builder.MakeCompound(compoundSolid);
auto count = wiresList.size();
for (int i = 0; i < count; ++i) {
auto wire = wiresList.at(i);
BRepBuilderAPI_MakeFace face(wire.MakeWire, true);
if (count > i + 1) {
CWire cwire = wiresList.at(i + 1);
TopoDS_Shape innerShape = cwire.MakeWire.Shape();
if (innerShape.ShapeType() != TopAbs_WIRE) return false;
TopoDS_Wire innerWire = TopoDS::Wire(innerShape);
if (innerWire.IsNull()) return false;
innerWire.Reverse();
face.Add(innerWire);
++i;
}
face.Build();
if (!face.IsDone()) return false;
builder.Add(compoundSolid, BRepOffsetAPI_MakePipe(sweepWire, face).Shape());
}
_occShapeAgent->updateShape(compoundSolid);
}
else {
BRepOffsetAPI_MakePipe pipe(sweepWire, profileTopoShape);
pipe.Build();
if (!pipe.IsDone()) return false;
_occShapeAgent->updateShape(pipe.Shape());
}
return true;
}
catch (...)
{
printLog(tr("Failed to make solid!"), 3);
return false;
}
}
FITKOCCModelMultiSectionSolid::FITKOCCModelMultiSectionSolid() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelMultiSectionSolid::update()
{
if (m_Sections.size() < 2) return false;
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
BRepOffsetAPI_ThruSections thruSection(true);
for (auto section : m_Sections) {
auto cmd = geoCmdList->getDataByID(section.CmdId);
if (cmd == nullptr) return false;
Interface::FITKGeoEnum::VTopoShapeType type = cmd->getGeometryCommandType() == Interface::FITKGeoEnum::FITKGeometryComType::FGTSketch2D ? Interface::FITKGeoEnum::VTopoShapeType::VSAssembly : Interface::FITKGeoEnum::VTopoShapeType::VSEdge;
auto vshape = cmd->getShapeT<FITKOCCTopoShape>(type, section.VirtualTopoId);
if (vshape == nullptr) return false;
auto topoShape = vshape->getTopoShape();
if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_EDGE) {
BRepLib_MakeWire wire(TopoDS::Edge(topoShape));
thruSection.AddWire(wire.Wire());
}
else if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_WIRE) {
thruSection.AddWire(TopoDS::Wire(topoShape));
}
else if (topoShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPOUND) {
TopExp_Explorer exp;
BRepLib_MakeWire wire;
// 按封闭曲线分组
for (exp.Init(topoShape, TopAbs_EDGE); exp.More(); exp.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
if (edge.IsNull()) continue;
wire.Add(edge);
}
try
{
wire.Build();
if (!wire.IsDone()) return false;
thruSection.AddWire(wire.Wire());
}
catch (...)
{
printLog(tr("Failed to make wire!"), 3);
return false;
}
}
}
try {
thruSection.Build();
if (!thruSection.IsDone()) return false;
_occShapeAgent->updateShape(thruSection.Shape());
}
catch (...)
{
printLog(tr("Failed to make solid!"), 3);
return false;
}
return true;
}
}