#include "FITKOCCModelOperFace.h" #include "FITK_Kernel/FITKAppFramework/FITKMessage.h" // Geometry #include "FITKOCCVirtualTopoCreator.h" #include "FITK_Interface/FITKInterfaceGeometry/FITKAbsVirtualTopoMapper.h" //OCC #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Global data #include "FITK_Kernel/FITKCore/FITKDataRepo.h" #include namespace OCC { FITKOCCModelOperFace::FITKOCCModelOperFace() : OCCShapeAgent(this) { _shapeAgent = _occShapeAgent; } bool FITKOCCModelOperFace::update() { if (m_tempVShapes.size() < 1) return false; QList shapes; for (int i = 0; i < m_tempVShapes.size(); ++i) { //数据获取 FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID(m_tempVShapes[i]->CmdId); if (comm == nullptr) return false; OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT(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 shapes) { TopoDS_Face face; QList 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 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 shapes) { if (shapes.size() != 2) return false; return false; } bool FITKOCCModelOperFace::updateImprintMapCircleToFace(QList shapes) { return false; } ///////////////FITKOCCModelOperFaceFillHoles/////////////////////////// FITKOCCModelOperFaceFillHoles::FITKOCCModelOperFaceFillHoles() : OCCShapeAgent(this) { _shapeAgent = _occShapeAgent; } bool FITKOCCModelOperFaceFillHoles::update() { if (m_tempVShapes.size() < 1) return false; QList shapes; for (int i = 0; i < m_tempVShapes.size(); ++i) { //数据获取 FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID(m_tempVShapes[i]->CmdId); if (comm == nullptr) return false; OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId); if (vOCCShapeEdge == nullptr) return false; shapes.append(vOCCShapeEdge->getTopoShape()); } return updateFillHoles(shapes); } bool FITKOCCModelOperFaceFillHoles::updateFillHoles(QList shapes) { TopoDS_Face face; QList 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 shapes; for (int i = 0; i < m_tempVShapes.size(); ++i) { //数据获取 FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID(m_tempVShapes[i]->CmdId); if (comm == nullptr) return false; OCC::FITKOCCTopoShape* vOCCShapeEdge = comm->getShapeT(Interface::FITKGeoEnum::VTopoShapeType::VSEdge, m_tempVShapes[i]->VirtualTopoId); if (vOCCShapeEdge == nullptr) return false; shapes.append(vOCCShapeEdge->getTopoShape()); } return updateFillGaps(shapes); } bool FITKOCCModelOperFaceFillGaps::updateFillGaps(QList 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(); 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 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 shapes; for (int i = 0; i < m_tempVShapes.size(); ++i) { if (m_tempVShapes[i] == nullptr) continue; //数据获取 FITKAbsGeoCommand* comm = FITKDATAREPO->getTDataByID(m_tempVShapes[i]->CmdId); if (comm == nullptr) { printLog(tr("data retrieval error."), 3); return false; } OCC::FITKOCCTopoShape* vOCCShapeFace = comm->getShapeT(Interface::FITKGeoEnum::VTopoShapeType::VSFace, m_tempVShapes[i]->VirtualTopoId); auto model = comm->getTShapeAgent(); 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(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 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; } }