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++

#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;
}
}