From 6ce74431d87330f0d6e8447ee54db40d93164546 Mon Sep 17 00:00:00 2001 From: nbv Date: Fri, 22 Sep 2017 11:24:35 +0300 Subject: [PATCH] 0029144: BOP PaveFiller hangs in some case 1. Method IntWalk_PWalking::ExtendLineInCommonZone(...) now is not called if the already found intersection point is on surface boundary. As result, the intersection line going along any boundary will never be extended. It is appropriate for high-level OCCT-algorithm because they will take the boundary (not computed line) as intersection result. 2. Method IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(...) has been corrected in order to avoid infinite loop described in the issue. The algorithm of obtaining the neighborhood of the intersection point has been improved. 3. Now, IsInside(...) static function (see BOPAlgo_BuilderFace.cxx file) does not need a 2D-curve for classified edge on the face. It allows avoiding exceptions in cases when the curve creation is impossible. 4. Post-processing has been added to join several common blocks to one. Method BOPDS_DS::RemoveCommonBlock(...) has been added in order to avoid duplication after joining. --- src/BOPAlgo/BOPAlgo_BuilderFace.cxx | 22 +++---- src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx | 3 + src/BOPDS/BOPDS_DS.cxx | 41 +++++++++++- src/BOPDS/BOPDS_DS.hxx | 3 + src/BOPTools/BOPTools_AlgoTools.cxx | 4 ++ src/IntImpParGen/IntImpParGen_Intersector.gxx | 13 +++- src/IntTools/IntTools_BeanFaceIntersector.cxx | 9 ++- src/IntWalk/IntWalk_PWalking.cxx | 64 ++++++++++++++++++- tests/perf/modalg/bug29093_1 | 42 ++++++++++++ tests/perf/modalg/bug29093_2 | 32 ++++++++++ tests/perf/modalg/bug29093_3 | 32 ++++++++++ 11 files changed, 246 insertions(+), 19 deletions(-) create mode 100644 tests/perf/modalg/bug29093_1 create mode 100644 tests/perf/modalg/bug29093_2 create mode 100644 tests/perf/modalg/bug29093_3 diff --git a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx index f576009e91..243abbf2c0 100644 --- a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx +++ b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx @@ -810,7 +810,6 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole, Handle(IntTools_Context)& theContext) { Standard_Boolean bRet; - Standard_Real aT, aU, aV; TopAbs_State aState; TopExp_Explorer aExp; @@ -824,20 +823,19 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole, BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA // aExp.Init(theHole, TopAbs_EDGE); - if (aExp.More()) { - const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current())); - if (aME2.Contains(aE)) { + if (aExp.More()) + { + const TopoDS_Edge& aE = (*(TopoDS_Edge *) (&aExp.Current())); + if (aME2.Contains(aE)) + { return bRet; } - if (!BRep_Tool::Degenerated(aE)) { + if (!BRep_Tool::Degenerated(aE)) + { // - aT=BOPTools_AlgoTools2D::IntermediatePoint(aE); - BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV, theContext); - aP2D.SetCoord(aU, aV); - // - IntTools_FClass2d& aClsf=theContext->FClass2d(aF2); - aState=aClsf.Perform(aP2D); - bRet=(aState==TopAbs_IN); + gp_Pnt aP3D; + BOPTools_AlgoTools::PointOnEdge(aE, BOPTools_AlgoTools2D::IntermediatePoint(aE), aP3D); + bRet = theContext->IsPointInFace(aP3D, aF2, BRep_Tool::Tolerance(aE)); } } // diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index dfbfe61954..37a16e2254 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -680,6 +680,9 @@ void BOPAlgo_PaveFiller::MakeBlocks() // into all faces, not participated in creation of that edge, as IN edge PutSEInOtherFaces(); // + + myDS->FilterOfCommonBlocks(); + //-----------------------------------------------------scope t aMVStick.Clear(); aMPBOnIn.Clear(); diff --git a/src/BOPDS/BOPDS_DS.cxx b/src/BOPDS/BOPDS_DS.cxx index c89f7a31b9..9ed03f53d1 100644 --- a/src/BOPDS/BOPDS_DS.cxx +++ b/src/BOPDS/BOPDS_DS.cxx @@ -2106,4 +2106,43 @@ Standard_Boolean BOPDS_DS::IsValidShrunkData(const Handle(BOPDS_PaveBlock)& theP } } return Standard_True; -} \ No newline at end of file +} + +//======================================================================= +//function : FilterOfCommonBlocks +//purpose : +//======================================================================= +void BOPDS_DS::FilterOfCommonBlocks() +{ + NCollection_DataMap aMapEC; + BOPDS_VectorOfListOfPaveBlock& aPBP = ChangePaveBlocksPool(); + Standard_Integer aNbPBP = aPBP.Extent(); + // + for (Standard_Integer i = 0; i < aNbPBP; ++i) + { + BOPDS_ListOfPaveBlock& aLPB = aPBP(i); + BOPDS_ListIteratorOfListOfPaveBlock aItPB; + aItPB.Initialize(aLPB); + for (; aItPB.More(); aItPB.Next()) + { + const Handle(BOPDS_PaveBlock) &aPB = aItPB.Value(); + + if (!IsCommonBlock(aPB)) + continue; + + const Standard_Integer anEIdx = aPB->Edge(); + const TopoDS_Edge &anE = TopoDS::Edge(Shape(anEIdx)); + + Handle(BOPDS_CommonBlock) *aCB = aMapEC.ChangeSeek(anE); + if (!aCB) + { + aCB = aMapEC.Bound(anE, CommonBlock(aPB)); + continue; + } + + myMapPBCB.UnBind(aPB); + (*aCB)->AddPaveBlock(aPB); + SetCommonBlock(aPB, *aCB); + } + } +} diff --git a/src/BOPDS/BOPDS_DS.hxx b/src/BOPDS/BOPDS_DS.hxx index 6b19debd0e..3e3e7690f2 100644 --- a/src/BOPDS/BOPDS_DS.hxx +++ b/src/BOPDS/BOPDS_DS.hxx @@ -468,6 +468,9 @@ Standard_EXPORT virtual ~BOPDS_DS(); //! of the existing vertices have been increased. Standard_EXPORT Standard_Boolean IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB); + //! Combines the common-blocks and removes excess common-blocks + Standard_EXPORT void FilterOfCommonBlocks(); + protected: diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index f853f19bf6..09007492f1 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -1657,6 +1657,10 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE, } } // + + if(aLCEFx.IsEmpty()) + return Standard_False; + // F2 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext); // diff --git a/src/IntImpParGen/IntImpParGen_Intersector.gxx b/src/IntImpParGen/IntImpParGen_Intersector.gxx index cd02df9abb..f0cce694ec 100644 --- a/src/IntImpParGen/IntImpParGen_Intersector.gxx +++ b/src/IntImpParGen/IntImpParGen_Intersector.gxx @@ -32,6 +32,8 @@ #include #include +#include + //====================================================================== #define EPSDIST Tol #define EPSNUL TolConf @@ -164,8 +166,15 @@ void IntImpParGen_Intersector::And_Domaine_Objet1_Intersections(const ImpTool& T Resultat2.SetValue(NbResultats, Inter2_And_Domain2.Value(indice_2)); } else { //====== la borne2 et la borne1 sont hors domaine ===== - if (param1TheImpCurveDomain.LastParameter()) { + const Standard_Real aParF = TheImpCurveDomain.HasFirstPoint() ? + TheImpCurveDomain.FirstParameter() : + -Precision::Infinite(); + const Standard_Real aParL = TheImpCurveDomain.HasLastPoint() ? + TheImpCurveDomain.LastParameter() : + Precision::Infinite(); + + if (param1aParL) + { Standard_Real t; NbResultats++; t = TheImpCurveDomain.FirstParameter(); diff --git a/src/IntTools/IntTools_BeanFaceIntersector.cxx b/src/IntTools/IntTools_BeanFaceIntersector.cxx index 3839ac7b77..6f202cc76d 100644 --- a/src/IntTools/IntTools_BeanFaceIntersector.cxx +++ b/src/IntTools/IntTools_BeanFaceIntersector.cxx @@ -1337,14 +1337,19 @@ void IntTools_BeanFaceIntersector::ComputeRangeFromStartPoint(const Standard_Boo if(BoundaryCondition && (isboundaryindex || !isvalidindex)) break; } - else { + else + { aDeltaRestrictor = aDelta; } // if point found decide to increase aDelta using derivative of distance function // - aDelta = (pointfound) ? (aDelta * 2.) : (aDelta * 0.5); + // (aDelta*2) and (aDelta/(3/2)). + // Use of constants 2 and 0.5 leads to infinite loop + // connected with the sequence: pointfound == TRUE ==> + // aDelta *= 2.0 ==> pointfound == FALSE ==> aDelta *= 0.5 ... + aDelta *= (pointfound) ? 2.0 : 0.6667; aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor; aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta); diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index 92298b01c3..e2e623f474 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -1653,10 +1653,69 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso, const Standard_Boolean theDirectionFlag) { + // Caro1 and Caro2 + const Handle(Adaptor3d_HSurface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1(); + const Handle(Adaptor3d_HSurface)& Caro2 = myIntersectionOn2S.Function().AuxillarSurface2(); + // + const Standard_Real UFirst1 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro1); + const Standard_Real VFirst1 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro1); + const Standard_Real ULast1 = Adaptor3d_HSurfaceTool::LastUParameter(Caro1); + const Standard_Real VLast1 = Adaptor3d_HSurfaceTool::LastVParameter(Caro1); + + const Standard_Real UFirst2 = Adaptor3d_HSurfaceTool::FirstUParameter(Caro2); + const Standard_Real VFirst2 = Adaptor3d_HSurfaceTool::FirstVParameter(Caro2); + const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter(Caro2); + const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter(Caro2); + Standard_Boolean bOutOfTangentZone = Standard_False; + TColStd_Array1OfReal Param(1,4); + + previousPoint.Parameters(Param(1), Param(2), Param(3), Param(4)); + + // If the point is already in the boundary + // we avoid extension (see bug #29093). + if (Param(1) - UFirst1 < ResoU1) + { + return bOutOfTangentZone; + } + + if (Param(2) - VFirst1 < ResoV1) + { + return bOutOfTangentZone; + } + + if (Param(3) - UFirst2 < ResoU2) + { + return bOutOfTangentZone; + } + + if (Param(4) - VFirst2 < ResoV2) + { + return bOutOfTangentZone; + } + + if (Param(1) - ULast1 > -ResoU1) + { + return bOutOfTangentZone; + } + + if (Param(2) - VLast1 > -ResoV1) + { + return bOutOfTangentZone; + } + + if (Param(3) - ULast2 > -ResoU2) + { + return bOutOfTangentZone; + } + + if (Param(4) - VLast2 > -ResoV2) + { + return bOutOfTangentZone; + } + Standard_Boolean bStop = !myIntersectionOn2S.IsTangent(); Standard_Integer dIncKey = 1; - TColStd_Array1OfReal Param(1,4); IntWalk_StatusDeflection aStatus = IntWalk_OK; Standard_Integer nbIterWithoutAppend = 0; Standard_Integer nbEqualPoints = 0; @@ -1664,7 +1723,8 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop Standard_Integer uvit = 0; IntSurf_SequenceOfPntOn2S aSeqOfNewPoint; - while (!bStop) { + while (!bStop) + { nbIterWithoutAppend++; if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) { diff --git a/tests/perf/modalg/bug29093_1 b/tests/perf/modalg/bug29093_1 new file mode 100644 index 0000000000..3e4af838e5 --- /dev/null +++ b/tests/perf/modalg/bug29093_1 @@ -0,0 +1,42 @@ +puts "========" +puts "OCC29093" +puts "========" +puts "" +################################# +# BOP PaveFiller hungs and constantly consumes memory +################################# + +puts "TODO OCC28989 ALL : Error! Big tolerance value!" +puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_" + +bclearobjects; +bcleartools; + +restore [locate_data_file bug29093_hung.brep] a +explode a So +baddobjects a_1 +baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14 + +dchrono cr restart + +bfillds +bbuild result + +dchrono cr stop counter bbuild + +regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance result] full MaxTol + +# Maximal tolerance value must be updated after the fix. +# Current tolerance value is 803.89403359886296. + +if {${MaxTol} > 1.0e-4} { + puts "Error! Big tolerance value!" +} + +checkshape result + +smallview +donly result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file diff --git a/tests/perf/modalg/bug29093_2 b/tests/perf/modalg/bug29093_2 new file mode 100644 index 0000000000..85296cc26b --- /dev/null +++ b/tests/perf/modalg/bug29093_2 @@ -0,0 +1,32 @@ +puts "========" +puts "OCC29093" +puts "========" +puts "" +################################# +# BOP PaveFiller hungs and constantly consumes memory +################################# + +puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_" + +bclearobjects; +bcleartools; + +restore [locate_data_file bug29093_hung2.brep] a +explode a So +baddobjects a_1 +baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14 + +dchrono cr restart + +bfillds +bbuild result + +dchrono cr stop counter bbuild + +checkshape result + +smallview +donly result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file diff --git a/tests/perf/modalg/bug29093_3 b/tests/perf/modalg/bug29093_3 new file mode 100644 index 0000000000..f6fb6532d2 --- /dev/null +++ b/tests/perf/modalg/bug29093_3 @@ -0,0 +1,32 @@ +puts "========" +puts "OCC29093" +puts "========" +puts "" +################################# +# BOP PaveFiller hungs and constantly consumes memory +################################# + +puts "TODO OCC29145 ALL : Faulty shapes in variables faulty_1 to faulty_" + +bclearobjects; +bcleartools; + +restore [locate_data_file bug29093_hung3.brep] a +explode a So +baddobjects a_1 +baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14 + +dchrono cr restart + +bfillds +bbuild result + +dchrono cr stop counter bbuild + +checkshape result + +smallview +donly result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file -- 2.39.5