From: Dmitrii Kulikov <164657232+AtheneNoctuaPt@users.noreply.github.com> Date: Sat, 29 Nov 2025 16:25:18 +0000 (+0000) Subject: Modelling - Boolean fuse segfaults on loft (#860) X-Git-Tag: V7_9_3~10 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=b26323673dae098140d4aff5128f1a49db91a9ee;p=occt.git Modelling - Boolean fuse segfaults on loft (#860) - Added null checks for 2D curve handles to prevent dereferencing null geometry - Refactored `ProcessDE()` to use modern C++ idioms (auto, structured bindings, range-based iteration patterns) - Simplified `FindPaveBlocks()` using a lambda function to reduce code duplication --- diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx index 1d8584e4e3..051ec3e7ff 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx @@ -53,133 +53,102 @@ static Standard_Boolean AddSplitPoint(const Handle(BOPDS_PaveBlock)& thePBD, void BOPAlgo_PaveFiller::ProcessDE(const Message_ProgressRange& theRange) { Message_ProgressScope aPSOuter(theRange, NULL, 1); - - Standard_Integer nF, aNb, nE, nV, nVSD, aNbPB; - Handle(NCollection_BaseAllocator) aAllocator; - Handle(BOPDS_PaveBlock) aPBD; - TColStd_ListIteratorOfListOfInteger aItLI; // // 1. Find degenerated edges //-----------------------------------------------------scope f // - aAllocator = NCollection_BaseAllocator::CommonBaseAllocator(); - BOPDS_ListOfPaveBlock aLPBOut(aAllocator); - // - aNb = myDS->NbSourceShapes(); - for (nE = 0; nE < aNb; ++nE) + + for (int anEdgeIndex = 0; anEdgeIndex < myDS->NbSourceShapes(); ++anEdgeIndex) { - const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE); - if (aSIE.ShapeType() == TopAbs_EDGE) + const BOPDS_ShapeInfo& anEdgeInfo = myDS->ShapeInfo(anEdgeIndex); + if (anEdgeInfo.ShapeType() != TopAbs_EDGE) + { + continue; + } + + if (int nF = 0; anEdgeInfo.HasFlag(nF)) { - if (aSIE.HasFlag(nF)) + const BOPDS_ShapeInfo& aSIF = myDS->ShapeInfo(nF); + int nV = anEdgeInfo.SubShapes().First(); + if (int nVSD = 0; myDS->HasShapeSD(nV, nVSD)) { - const BOPDS_ShapeInfo& aSIF = myDS->ShapeInfo(nF); - nV = aSIE.SubShapes().First(); - if (myDS->HasShapeSD(nV, nVSD)) - { - nV = nVSD; - } - // nV,nE,nF - // - if (aSIF.ShapeType() == TopAbs_FACE) + nV = nVSD; + } + + if (aSIF.ShapeType() == TopAbs_FACE) + { + // 1. Find PaveBlocks that go through nV for nF + BOPDS_ListOfPaveBlock aLPBOut(NCollection_BaseAllocator::CommonBaseAllocator()); + FindPaveBlocks(nV, nF, aLPBOut); + if (!aLPBOut.IsEmpty()) { - // 1. Find PaveBlocks that go through nV for nF - FindPaveBlocks(nV, nF, aLPBOut); - aNbPB = aLPBOut.Extent(); - if (aNbPB) - { - // - // 2. - BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE); - Standard_ASSERT_VOID(!aLPBD.IsEmpty(), "ListOfPaveBlock is unexpectedly empty"); - if (aLPBD.IsEmpty()) - continue; - aPBD = aLPBD.First(); - // - FillPaves(nV, nE, nF, aLPBOut, aPBD); - // - myDS->UpdatePaveBlock(aPBD); - } // - MakeSplitEdge(nE, nF); + // 2. + BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(anEdgeIndex); + Standard_ASSERT_VOID(!aLPBD.IsEmpty(), "ListOfPaveBlock is unexpectedly empty"); + if (aLPBD.IsEmpty()) + continue; + Handle(BOPDS_PaveBlock) aPBD = aLPBD.First(); // - aLPBOut.Clear(); - } - if (aSIF.ShapeType() == TopAbs_EDGE) - { - Standard_Real aTol = 1.e-7; - Standard_Integer nEn; - BRep_Builder BB; - const TopoDS_Edge& aDE = (*(TopoDS_Edge*)(&myDS->Shape(nE))); - const TopoDS_Vertex& aVn = (*(TopoDS_Vertex*)(&myDS->Shape(nV))); + FillPaves(nV, anEdgeIndex, nF, aLPBOut, aPBD); // - TopoDS_Edge aE = aDE; - aE.EmptyCopy(); - BB.Add(aE, aVn); - BB.Degenerated(aE, Standard_True); - BB.UpdateEdge(aE, aTol); - BOPDS_ShapeInfo aSI; - aSI.SetShapeType(TopAbs_EDGE); - aSI.SetShape(aE); - nEn = myDS->Append(aSI); - BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE); - aPBD = aLPBD.First(); - aPBD->SetEdge(nEn); + myDS->UpdatePaveBlock(aPBD); } + // + MakeSplitEdge(anEdgeIndex, nF); } - if (UserBreak(aPSOuter)) + if (aSIF.ShapeType() == TopAbs_EDGE) { - return; + const TopoDS_Edge& aDE = (*(TopoDS_Edge*)(&myDS->Shape(anEdgeIndex))); + const TopoDS_Vertex& aVn = (*(TopoDS_Vertex*)(&myDS->Shape(nV))); + // + TopoDS_Edge aE = aDE; + aE.EmptyCopy(); + BRep_Builder BB; + BB.Add(aE, aVn); + BB.Degenerated(aE, Standard_True); + BB.UpdateEdge(aE, Precision::Confusion()); + BOPDS_ShapeInfo aSI; + aSI.SetShapeType(TopAbs_EDGE); + aSI.SetShape(aE); + const int nEn = myDS->Append(aSI); + BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(anEdgeIndex); + Handle(BOPDS_PaveBlock) aPBD = aLPBD.First(); + aPBD->SetEdge(nEn); } } + + if (UserBreak(aPSOuter)) + { + return; + } } } //================================================================================================= -void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer nV, - const Standard_Integer nF, - BOPDS_ListOfPaveBlock& aLPBOut) +void BOPAlgo_PaveFiller::FindPaveBlocks(const Standard_Integer thePaveIndex, + const Standard_Integer theFaceInfoIndex, + BOPDS_ListOfPaveBlock& theFoundBlocks) { - Standard_Integer i, aNbPBOn, aNbPBIn, aNbPBSc, nV1, nV2; - // - const BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF); - // In - const BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.PaveBlocksIn(); - aNbPBIn = aMPBIn.Extent(); - for (i = 1; i <= aNbPBIn; ++i) - { - const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(i); - aPB->Indices(nV1, nV2); - if (nV == nV1 || nV == nV2) - { - aLPBOut.Append(aPB); - } - } - // On - const BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.PaveBlocksOn(); - aNbPBOn = aMPBOn.Extent(); - for (i = 1; i <= aNbPBOn; ++i) - { - const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(i); - aPB->Indices(nV1, nV2); - if (nV == nV1 || nV == nV2) - { - aLPBOut.Append(aPB); - } - } - // Sections - const BOPDS_IndexedMapOfPaveBlock& aMPBSc = aFI.PaveBlocksSc(); - aNbPBSc = aMPBSc.Extent(); - for (i = 1; i <= aNbPBSc; ++i) - { - const Handle(BOPDS_PaveBlock)& aPB = aMPBSc(i); - aPB->Indices(nV1, nV2); - if (nV == nV1 || nV == nV2) + auto processPaveBlocks = [thePaveIndex, + &theFoundBlocks](const BOPDS_IndexedMapOfPaveBlock& thePaveBlocksMap) { + for (int aBlockIndex = 1; aBlockIndex <= thePaveBlocksMap.Size(); ++aBlockIndex) { - aLPBOut.Append(aPB); + const Handle(BOPDS_PaveBlock)& aPaveBlock = thePaveBlocksMap(aBlockIndex); + int nV1, nV2; + aPaveBlock->Indices(nV1, nV2); + if (thePaveIndex == nV1 || thePaveIndex == nV2) + { + theFoundBlocks.Append(aPaveBlock); + } } - } + }; + + const BOPDS_FaceInfo& aFaceInfo = myDS->ChangeFaceInfo(theFaceInfoIndex); + processPaveBlocks(aFaceInfo.PaveBlocksIn()); + processPaveBlocks(aFaceInfo.PaveBlocksOn()); + processPaveBlocks(aFaceInfo.PaveBlocksSc()); } //================================================================================================= @@ -279,6 +248,11 @@ void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD, // Get 2D curve Standard_Real aTD1, aTD2; Handle(Geom2d_Curve) aC2DDE = BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2); + if (aC2DDE.IsNull()) + { + return; + } + // Get direction of the curve Standard_Boolean bUDir = Abs(aC2DDE->Value(aTD1).Y() - aC2DDE->Value(aTD2).Y()) < Precision::PConfusion(); diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx index b773937a1d..8d4a3092a8 100644 --- a/src/BOPTools/BOPTools_AlgoTools_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx @@ -678,10 +678,15 @@ void CorrectWires(const TopoDS_Face& aFx, const TopTools_IndexedMapOfShape& aMap aIt.Initialize(aLE); for (; aIt.More(); aIt.Next()) { - const TopoDS_Edge& aE = *(TopoDS_Edge*)(&aIt.Value()); - const Handle(Geom2d_Curve)& aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); - Standard_Real aT = BRep_Tool::Parameter(aV, aE); - Standard_Boolean isClosed = Standard_False; + const TopoDS_Edge& aE = *(TopoDS_Edge*)(&aIt.Value()); + const Handle(Geom2d_Curve)& aC2D = BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); + if (aC2D.IsNull()) + { + continue; + } + + Standard_Real aT = BRep_Tool::Parameter(aV, aE); + Standard_Boolean isClosed = Standard_False; { TopoDS_Vertex aV1, aV2; TopExp::Vertices(aE, aV1, aV2);