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

455 lines
16 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "FITKOCCModelOperFace.h"
#include "FITK_Kernel/FITKAppFramework/FITKMessage.h"
// Geometry
#include "FITKOCCVirtualTopoCreator.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsVirtualTopoMapper.h"
//OCC
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <gp_Pnt.hxx>
#include <BRepLib.hxx>
#include <ShapeFix_Wire.hxx>
#include <ShapeBuild.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <BRepOffsetAPI_Sewing.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <TopExp_Explorer.hxx>
#include <BRep_Builder.hxx>
#include <ShapeFix_Shell.hxx>
#include <BRepFill_Filling.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"
#include <QDebug>
namespace OCC
{
FITKOCCModelOperFace::FITKOCCModelOperFace() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelOperFace::update()
{
if (m_tempVShapes.size() < 1) return false;
QList<TopoDS_Shape> shapes;
for (int i = 0; i < m_tempVShapes.size(); ++i)
{
//数据获取
FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID<FITKAbsGeoCommand>(m_tempVShapes[i]->CmdId);
if (comm == nullptr) return false;
OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT<OCC::FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId);
if (vOCCShapeEdge == nullptr) return false;
shapes.append(vOCCShapeEdge->getTopoShape());
}
//按类型处理
if (_faceOperType == Interface::FITKAbsGeoModelOperFace::GBTFillHoles)
{
return updateFillHoles(shapes);
}
else if (_faceOperType == Interface::FITKAbsGeoModelOperFace::GBTImprintMapPointToFace)
{
return updateImprintMapPointToFace(shapes);
}
else if (_faceOperType == Interface::FITKAbsGeoModelOperFace::GBTImprintMapLineToFace)
{
return updateImprintMapLineToFace(shapes);
}
else if (_faceOperType == Interface::FITKAbsGeoModelOperFace::GBTImprintMapCircleToFace)
{
return updateImprintMapCircleToFace(shapes);
}
return false;
}
bool FITKOCCModelOperFace::updateFillHoles(QList<TopoDS_Shape> shapes)
{
TopoDS_Face face;
QList<TopoDS_Edge> holes;
//数据筛选
for (int i = 0; i < shapes.size(); ++i)
{
if (shapes[i].ShapeType() == TopAbs_ShapeEnum::TopAbs_FACE && face.IsNull())
face = TopoDS::Face(shapes[i]);
else if (shapes[i].ShapeType() == TopAbs_ShapeEnum::TopAbs_EDGE)
holes.append(TopoDS::Edge(shapes[i]));
else
return false;
}
if (face.IsNull() || holes.size() < 1) return false;
BRepFill_Filling fill;
fill.LoadInitSurface(face);
for (int i = 0; i < holes.size(); ++i)
{
fill.Add(holes[i], GeomAbs_Shape::GeomAbs_C0);
}
fill.Build();
auto topoDsShape = fill.Face();
TopoDS_Compound aComp;
BRep_Builder BuildTool;
BuildTool.MakeCompound(aComp);
BuildTool.Add(aComp, face);
BuildTool.Add(aComp, topoDsShape);
//缝合
BRepOffsetAPI_Sewing sewing;
//缝合初始化
sewing.Init(_tolerance, Standard_True);
sewing.Load(aComp);
sewing.Perform();
//检查是否修改成功
if (!sewing.IsModified(sewing.SewedShape())) return false;
//消除缝合线
ShapeUpgrade_UnifySameDomain unif(sewing.SewedShape(), true, true, false);
unif.Build();
_occShapeAgent->updateShape(unif.Shape());
return true;
}
bool FITKOCCModelOperFace::updateImprintMapPointToFace(QList<TopoDS_Shape> shapes)
{
if (shapes.size() != 2) return false;
TopoDS_Face face;
TopoDS_Vertex point;
if (shapes[0].ShapeType() == TopAbs_ShapeEnum::TopAbs_FACE)
{
face = TopoDS::Face(shapes[0]);
point = TopoDS::Vertex(shapes[1]);
}
else
{
point = TopoDS::Vertex(shapes[0]);
face = TopoDS::Face(shapes[1]);
}
if (point.IsNull() || face.IsNull()) return false;
return false;
}
bool FITKOCCModelOperFace::updateImprintMapLineToFace(QList<TopoDS_Shape> shapes)
{
if (shapes.size() != 2) return false;
return false;
}
bool FITKOCCModelOperFace::updateImprintMapCircleToFace(QList<TopoDS_Shape> shapes)
{
return false;
}
///////////////FITKOCCModelOperFaceFillHoles///////////////////////////
FITKOCCModelOperFaceFillHoles::FITKOCCModelOperFaceFillHoles() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelOperFaceFillHoles::update()
{
if (m_tempVShapes.size() < 1) return false;
QList<TopoDS_Shape> shapes;
for (int i = 0; i < m_tempVShapes.size(); ++i)
{
//数据获取
FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID<FITKAbsGeoCommand>(m_tempVShapes[i]->CmdId);
if (comm == nullptr) return false;
OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT<OCC::FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId);
if (vOCCShapeEdge == nullptr) return false;
shapes.append(vOCCShapeEdge->getTopoShape());
}
return updateFillHoles(shapes);
}
bool FITKOCCModelOperFaceFillHoles::updateFillHoles(QList<TopoDS_Shape> shapes)
{
TopoDS_Face face;
QList<TopoDS_Edge> holes;
//数据筛选
for (int i = 0; i < shapes.size(); ++i)
{
if (shapes[i].ShapeType() == TopAbs_ShapeEnum::TopAbs_FACE && face.IsNull())
face = TopoDS::Face(shapes[i]);
else if (shapes[i].ShapeType() == TopAbs_ShapeEnum::TopAbs_EDGE)
holes.append(TopoDS::Edge(shapes[i]));
else
return false;
}
if (face.IsNull() || holes.size() < 1) return false;
BRepFill_Filling fill;
fill.LoadInitSurface(face);
for (int i = 0; i < holes.size(); ++i)
{
fill.Add(holes[i], GeomAbs_Shape::GeomAbs_C0);
}
fill.Build();
auto topoDsShape = fill.Face();
TopoDS_Compound aComp;
BRep_Builder BuildTool;
BuildTool.MakeCompound(aComp);
BuildTool.Add(aComp, face);
BuildTool.Add(aComp, topoDsShape);
//缝合
BRepOffsetAPI_Sewing sewing;
//缝合初始化
sewing.Init(_tolerance, Standard_True);
sewing.Load(aComp);
sewing.Perform();
//检查是否修改成功
if (!sewing.IsModified(sewing.SewedShape())) return false;
//消除缝合线
ShapeUpgrade_UnifySameDomain unif(sewing.SewedShape(), true, true, false);
unif.Build();
_occShapeAgent->updateShape(unif.Shape());
return true;
}
///////////////FITKOCCModelOperFaceFillGaps///////////////////////////
FITKOCCModelOperFaceFillGaps::FITKOCCModelOperFaceFillGaps() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelOperFaceFillGaps::update()
{
if (m_tempVShapes.size() < 1) return false;
QList<TopoDS_Shape> shapes;
for (int i = 0; i < m_tempVShapes.size(); ++i)
{
//数据获取
FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID<FITKAbsGeoCommand>(m_tempVShapes[i]->CmdId);
if (comm == nullptr) return false;
OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT<OCC::FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId);
if (vOCCShapeEdge == nullptr) return false;
shapes.append(vOCCShapeEdge->getTopoShape());
}
return updateFillGaps(shapes);
}
bool FITKOCCModelOperFaceFillGaps::updateFillGaps(QList<TopoDS_Shape> shapes)
{
if (shapes.size() < 1) return false;
//主面
TopoDS_Face mFace;
for (int i = 0; i < m_tempVShapes.size(); ++i)
{
// 向上查找所选边对应体数据。
Interface::FITKVirtualTopoMapper vMapper;
vMapper.mapTopo(m_tempVShapes[i]->VirtualTopoId, Interface::FITKGeoEnum::VTopoShapeType::VSFace);
// 获取查询结果。
int nRet = vMapper.length();
for (int i = 0; i < nRet; i++)
{
Interface::FITKAbsVirtualTopo* vFace = vMapper.virtualTopo(i);
auto occShape = vFace->getShapeT<OCC::FITKOCCTopoShape>();
if (occShape == nullptr) return false;
mFace = TopoDS::Face(occShape->getTopoShape());
}
}
//主面判断是否为空(填充面)
if (mFace.IsNull() || mFace.ShapeType() != TopAbs_ShapeEnum::TopAbs_FACE)
{
printLog(tr("data retrieval error."), 3);
return false;
}
bool isSuccessful = false;
auto tempWireShape = CheckAndForceCurveClosure(shapes, isSuccessful);
if (!isSuccessful || tempWireShape.IsNull()) return false;
TopoDS_Wire closedCurve = TopoDS::Wire(tempWireShape);
if (closedCurve.IsNull()) return false;
TopoDS_Face nFace = BRepBuilderAPI_MakeFace(closedCurve);
//TopoDS_Compound aComp;
//BRep_Builder BuildTool;
//BuildTool.MakeCompound(aComp);
//BuildTool.Add(aComp, mFace);
//BuildTool.Add(aComp, nFace);
////使用 BRepBuilderAPI_Sewing 缝合
BRepOffsetAPI_Sewing sewing;
//sewing.Init(1, Standard_True);
//sewing.Load(aComp);
sewing.Add(mFace);
sewing.Add(nFace);
sewing.Perform();
auto sewingFace = sewing.SewedShape();
//检查是否修改成功
if (sewing.IsModified(sewingFace)) return false;
//消除缝合线 统一拓扑
ShapeUpgrade_UnifySameDomain unif(sewingFace, false, true, false);
unif.Build();
_occShapeAgent->updateShape(unif.Shape());
return true;
//TopTools_ListOfShape aLSObjects; //进行连接的形状
//aLSObjects.Append(shape1);
//aLSObjects.Append(shape2);
//BOPAlgo_Builder aBuilder;
//aBuilder.SetArguments(aLSObjects);
////设置GF的选项
////设置并行处理模式默认为false
//Standard_Boolean bRunParallel = Standard_True;
//aBuilder.SetRunParallel(bRunParallel);
////设置模糊值默认为Precision :: Confusion
//Standard_Real aFuzzyValue = 1e-5;
//aBuilder.SetFuzzyValue(aFuzzyValue);
////设置安全处理模式默认为false
//Standard_Boolean bSafeMode = Standard_True;
//aBuilder.SetNonDestructive(bSafeMode);
////为重合的参数设置粘合模式(默认为关闭)
//BOPAlgo_GlueEnum aGlue = BOPAlgo_GlueShift;
//aBuilder.SetGlue(aGlue);
////禁用/启用对倒置固体的检查默认为true
//Standard_Boolean bCheckInverted = Standard_False;
//aBuilder.SetCheckInverted(bCheckInverted);
////设置OBB用法默认为false
//Standard_Boolean bUseOBB = Standard_True;
//aBuilder.SetUseOBB(bUseOBB);
////执行操作
//aBuilder.Perform();
////检查错误
//if (aBuilder.HasErrors()) return TopoDS_Shape();
//if (aBuilder.HasWarnings()) return TopoDS_Shape();
//// result of the operation
//return aBuilder.Shape();
}
TopoDS_Shape FITKOCCModelOperFaceFillGaps::CheckAndForceCurveClosure(QList<TopoDS_Shape> shapes, bool& isSuccessful)
{
isSuccessful = false;
BRepBuilderAPI_MakeWire mergeWires;
for (int i = 0; i < shapes.size(); i++)
{
//if (shapes[i].ShapeType() != TopAbs_ShapeEnum::TopAbs_EDGE) return TopoDS_Shape;
qDebug() << "shape Type : " << shapes[i].ShapeType();
TopoDS_Edge edge = TopoDS::Edge(shapes[i]);
if (edge.IsNull()) return TopoDS_Shape();
mergeWires.Add(BRepBuilderAPI_MakeWire(edge));
}
mergeWires.Build();
if (!mergeWires.IsDone())
{
printLog(tr("merge wires error."), 3);
return TopoDS_Shape();
}
isSuccessful = true;
return mergeWires.Shape();
}
///////////////FITKOCCModelOperFaceDeleteFloatingEdge///////////////////////////
FITKOCCModelOperFaceDeleteFloatingEdge::FITKOCCModelOperFaceDeleteFloatingEdge() : OCCShapeAgent(this)
{
_shapeAgent = _occShapeAgent;
}
bool FITKOCCModelOperFaceDeleteFloatingEdge::update()
{
if (m_tempVShapes.size() < 1) return false;
QList<TopoDS_Shape> shapes;
for (int i = 0; i < m_tempVShapes.size(); ++i)
{
if (m_tempVShapes[i] == nullptr) continue;
//数据获取
FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID<FITKAbsGeoCommand>(m_tempVShapes[i]->CmdId);
if (comm == nullptr)
{
printLog(tr("data retrieval error."), 3);
return false;
}
OCC::FITKOCCTopoShape* vOCCShapeFace = comm->getShapeT<OCC::FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSFace, m_tempVShapes[i]->VirtualTopoId);
auto model = comm->getTShapeAgent<FITKAbstractOCCModel>();
shapes.append(*model->getShape());
// 创建一个拓扑探索器
TopExp_Explorer explorer;
// 遍历形状下的所有面
for (explorer.Init(*model->getShape(), TopAbs_FACE); explorer.More(); explorer.Next()) {
// 获取当前面
TopoDS_Face face = TopoDS::Face(explorer.Current());
if(face.IsSame(vOCCShapeFace->getTopoShape()))
shapes.append(face);
}
//OCC::FITKOCCTopoShape* vOCCShapeLine = comm->getShapeT<OCC::FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId);
//
//if (vOCCShapeFace != nullptr)
//{
// shapes.append(vOCCShapeFace->getTopoShape());
//
//}
//else if (vOCCShapeLine != nullptr)
//{
// shapes.append(vOCCShapeLine->getTopoShape());
//}
}
return updateDeleteFloatingEdge(shapes);
}
bool FITKOCCModelOperFaceDeleteFloatingEdge::updateDeleteFloatingEdge(QList<TopoDS_Shape> shapes)
{
if (shapes.size() < 1 || shapes[0].IsNull())
{
printLog(tr("parameter error."), 3);
return false;
}
//if (shapes[0].ShapeType() != TopAbs_ShapeEnum::TopAbs_FACE)
//{
// printLog(tr("input error."), 3);
// return false;
//}
//消除缝合线 统一拓扑
ShapeUpgrade_UnifySameDomain unif(shapes[0], true, true, false);
TopTools_MapOfShape shapeList;
for (int i = 1; i < shapes.size(); i++)
{
shapeList.Add(shapes[i]);
}
//unif.KeepShapes(shapeList);
unif.Build();
auto h = unif.History();
bool a = h->IsRemoved(shapes[1]);
bool a34 = h->IsRemoved(shapes[2]);
bool a345 = h->IsRemoved(shapes[3]);
auto a1 = h->HasGenerated();
auto a2 = h->HasModified();
auto a3 = h->HasRemoved();
_occShapeAgent->updateShape(unif.Shape());
return true;
}
}