]> OCCT Git - occt-copy.git/commitdiff
0029144: BOP PaveFiller hangs in some case CR29144
authornbv <nbv@opencascade.com>
Fri, 22 Sep 2017 08:24:35 +0000 (11:24 +0300)
committernbv <nbv@opencascade.com>
Tue, 10 Oct 2017 08:53:01 +0000 (11:53 +0300)
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.

13 files changed:
src/BOPAlgo/BOPAlgo_BuilderFace.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DS.hxx
src/BOPTools/BOPTools_AlgoTools.cxx
src/IntImpParGen/IntImpParGen_Intersector.gxx
src/IntTools/IntTools_BeanFaceIntersector.cxx
src/IntWalk/IntWalk_PWalking.cxx
tests/perf/modalg/bug29093_1 [new file with mode: 0644]
tests/perf/modalg/bug29093_2 [new file with mode: 0644]
tests/perf/modalg/bug29093_3 [new file with mode: 0644]

index f576009e91d9a48fe1ec0f6ca7cb982a45c9c7bb..243abbf2c0012aa6b5fc5c2381b6dd204d591594 100644 (file)
@@ -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));
     }
   }
   //
index bd4e512faec3dcb629e3cb1e6828e11e4348f58e..b7e80940d37a4837bab33a2afb1ba0370798b662 100644 (file)
@@ -30,6 +30,7 @@
 #include <BOPAlgo_Algo.hxx>
 #include <BOPCol_BaseAllocator.hxx>
 #include <TopAbs_ShapeEnum.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <Standard_Integer.hxx>
 #include <BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks.hxx>
 #include <Standard_Boolean.hxx>
@@ -493,7 +494,8 @@ protected:
   Standard_Boolean myIsPrimary;
   Standard_Boolean myAvoidBuildPCurve;
   BOPAlgo_GlueEnum myGlue;
-
+  TopTools_DataMapOfShapeListOfShape myMapOfErigins;
+  NCollection_DataMap<Standard_Integer, NCollection_List<Handle(BOPDS_PaveBlock)>> myMapICB;
 
 private:
 
index dfbfe61954da6bc5bbb7c0154a3bddc1f189fa50..bc8f430603336c6e77646be6804ae85608041686 100644 (file)
@@ -680,6 +680,42 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   // into all faces, not participated in creation of that edge, as IN edge
   PutSEInOtherFaces();
   //
+
+  {
+    NCollection_DataMap<TopoDS_Edge, Handle(BOPDS_CommonBlock)> aMapEC;
+    BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
+    Standard_Integer aNbPBP = aPBP.Extent();
+    //
+    for (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 (!myDS->IsCommonBlock(aPB))
+          continue;
+
+        const Standard_Integer anEIdx = aPB->Edge();
+        const TopoDS_Edge &anE = TopoDS::Edge(myDS->Shape(anEIdx));
+
+        Handle(BOPDS_CommonBlock) *aCB = aMapEC.ChangeSeek(anE);
+        if (!aCB)
+        {
+          aCB = aMapEC.Bound(anE, myDS->CommonBlock(aPB));
+          continue;
+        }
+
+        myDS->RemoveCommonBlock(aPB);
+        (*aCB)->AddPaveBlock(aPB);
+        myDS->SetCommonBlock(aPB, *aCB);
+      }
+    }
+  }
+
+
   //-----------------------------------------------------scope t
   aMVStick.Clear();
   aMPBOnIn.Clear();
@@ -1042,22 +1078,11 @@ void BOPAlgo_PaveFiller::PostTreatFF
               iE=myDS->Append(aSI);
             }
             //
-            // update real edge tolerance according to distances in common block if any
-            if (aPDS->IsCommonBlock(aPBRx)) {
-              const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
-              Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
-              if (!pTol) {
-                Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
-                pTol = aMCBTol.Bound(aCB, aTol);
-              }
-              //
-              if (aNC.Tolerance() < *pTol) {
-                aNC.SetTolerance(*pTol);
-              }
-            }
-            // append new PaveBlock to aLPBC
+
             Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
-            if (!pPBC) {
+            // append new PaveBlock to aLPBC
+            if (!pPBC)
+            {
               pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
               BOPDS_Pave aPaveR1, aPaveR2;
               aPaveR1 = aPBRx->Pave1();
@@ -1070,13 +1095,44 @@ void BOPAlgo_PaveFiller::PostTreatFF
               (*pPBC)->SetEdge(iE);
             }
             //
-            if (bOld) {
+            if (bOld)
+            {
               (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
               aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
             }
-            else {
+            else
+            {
               aLPBC.Append(*pPBC);
             }
+
+            // update real edge tolerance according to distances in common block if any
+            if (aPDS->IsCommonBlock(aPBRx))
+            {
+              const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
+              const Standard_Integer anIdxOriE = aPB1->OriginalEdge();
+
+              if (pPBC && (anIdxOriE > 0))
+              {
+                // If original edge exists                
+                NCollection_List<Handle(BOPDS_PaveBlock)> *aListOfPB = myMapICB.ChangeSeek(iE);
+                if (aListOfPB == 0)
+                {
+                  aListOfPB = myMapICB.Bound(iE, NCollection_List<Handle(BOPDS_PaveBlock)>());
+                }
+
+                aListOfPB->Append(*pPBC);
+              }
+
+              Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
+              if (!pTol) {
+                Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
+                pTol = aMCBTol.Bound(aCB, aTol);
+              }
+              //
+              if (aNC.Tolerance() < *pTol) {
+                aNC.SetTolerance(*pTol);
+              }
+            }
           }
         }
       }
@@ -2414,18 +2470,35 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
     anEF.SetContext(myContext);
     anEF.Perform();
     //
-    const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
-    if (aCPrts.Length() == 1) {
+    const IntTools_SequenceOfCommonPrts& aCPrts = anEF.CommonParts();
+    if (aCPrts.Length() == 1)
+    {
       Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
-      if (bCoinc) {
-        if (bCB) {
+      if (bCoinc)
+      {
+        if (bCB)
+        {
           aCB = myDS->CommonBlock(aPBChangeValue);
-        } else {
+          const NCollection_List<Handle(BOPDS_PaveBlock)> *aListOfPB = myMapICB.Seek(aPBChangeValue->Edge());
+          if (aListOfPB)
+          {
+            NCollection_List<Handle(BOPDS_PaveBlock)>::Iterator anItr(*aListOfPB);
+            for (; anItr.More(); anItr.Next())
+            {
+              Handle(BOPDS_PaveBlock) &aCurrPB = anItr.ChangeValue();
+              aCB->AddPaveBlock(aCurrPB);
+              myDS->SetCommonBlock(aCurrPB, aCB);
+            }
+          }
+          aCB->AddFace(nF);
+        }
+        else
+        {
           aCB = new BOPDS_CommonBlock;
           aCB->AddPaveBlock(aPBChangeValue);
+          aCB->AddFace(nF);
           myDS->SetCommonBlock(aPBChangeValue, aCB);
         }
-        aCB->AddFace(nF);
         //
         aMPBIn.Add(aPBChangeValue);
       }
index 1e91f5529ae7da1fc6d6f6b3b6b817bf554ec839..8598c7526cfe77158a76e1b881b1b22d658beefb 100644 (file)
@@ -691,12 +691,15 @@ void BOPAlgo_PaveFiller::MakePCurves()
   Standard_Integer aNb = aVMPC.Extent();
   for (i = 0; i < aNb; ++i)
   {
-    if (aVMPC(i).HasErrors())
+    const TopoDS_Face& aF = TopoDS::Face(aVMPC(i).Face());
+    const TopoDS_Edge& aE = TopoDS::Edge(aVMPC(i).Edge());
+    if (!BOPTools_AlgoTools2D::HasCurveOnSurface(aE, aF) ||
+        aVMPC(i).HasErrors())
     {
       TopoDS_Compound aWC;
       BRep_Builder().MakeCompound(aWC);
-      BRep_Builder().Add(aWC, aVMPC(i).Edge());
-      BRep_Builder().Add(aWC, aVMPC(i).Face());
+      BRep_Builder().Add(aWC, aE);
+      BRep_Builder().Add(aWC, aF);
       AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
     }
   }
index c89f7a31b95134fd9db3c39f7cb524bcaa931a18..e8d80a006c6a8e6135be131d799fc7f63ec10778 100644 (file)
@@ -1165,6 +1165,18 @@ void BOPDS_DS::SetCommonBlock(const Handle(BOPDS_PaveBlock)& thePB,
   }
 }
 
+//=======================================================================
+//function : RemoveCommonBlock
+//purpose  : 
+//=======================================================================
+void BOPDS_DS::RemoveCommonBlock(const Handle(BOPDS_PaveBlock)& thePB)
+{
+  //if (!IsCommonBlock(thePB))
+  //  return;
+
+  myMapPBCB.UnBind(thePB);
+}
+
 //
 // FaceInfo
 //
index 6b19debd0e7dca122b0bb7e26bfc3e9a5d693dc1..9d8f1b8364648260d566b670c8633562788fab75 100644 (file)
@@ -468,6 +468,10 @@ Standard_EXPORT virtual ~BOPDS_DS();
   //! of the existing vertices have been increased.
   Standard_EXPORT Standard_Boolean IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB);
 
+  //! Removes the Common-block from the myMapPBCB map.
+  Standard_EXPORT void RemoveCommonBlock(const Handle(BOPDS_PaveBlock)& thePB);
+
+
 protected:
 
   
index f853f19bf6bc9988f26afc93d57477e753b25817..09007492f1a58238c9bd2a5c8a7acbee43bb3544 100644 (file)
@@ -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);
     //
index cd02df9abb9bf0e84cb0064dc10f628c48cb34ab..f0cce694ecf579569acccee0c577029709d09ee6 100644 (file)
@@ -32,6 +32,8 @@
 #include <gp.hxx>
 #include <gp_Vec2d.hxx>
 
+#include <Precision.hxx>
+
 //======================================================================
 #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 (param1<TheImpCurveDomain.FirstParameter()
-          && param2>TheImpCurveDomain.LastParameter()) {
+        const Standard_Real aParF = TheImpCurveDomain.HasFirstPoint() ?
+                                      TheImpCurveDomain.FirstParameter() :
+                                      -Precision::Infinite();
+        const Standard_Real aParL = TheImpCurveDomain.HasLastPoint() ?
+                                      TheImpCurveDomain.LastParameter() :
+                                      Precision::Infinite();
+        
+        if (param1<aParF && param2>aParL)
+        {
           Standard_Real t;
           NbResultats++;
           t = TheImpCurveDomain.FirstParameter();
index 3839ac7b77a2a83013d170203f1a8781dd8bdd9d..877c7d5f932bf18c9bc26c9b7d6193b6beab92a9 100644 (file)
@@ -1337,14 +1337,16 @@ 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)) to avoid infinite loop
+    aDelta = (pointfound) ? (aDelta * 2.0) : (aDelta * 0.6667);
     aDelta = (aDelta < aDeltaRestrictor) ? aDelta : aDeltaRestrictor;
     
     aCurPar = (ToIncreaseParameter) ? (aPrevPar + aDelta) : (aPrevPar - aDelta);
index 92298b01c350a45cdf08f3b93ffb9ece3095fee5..79d5337b4396ae9ba4cb69253b065c6f75c23a48 100644 (file)
@@ -1653,6 +1653,20 @@ 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;
   Standard_Boolean bStop = !myIntersectionOn2S.IsTangent();
   Standard_Integer dIncKey = 1;
@@ -1664,6 +1678,42 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
   Standard_Integer uvit = 0;
   IntSurf_SequenceOfPntOn2S aSeqOfNewPoint;
 
+  previousPoint.Parameters(Param(1), Param(2), Param(3), Param(4));
+
+  if (Param(1) - UFirst1 < ResoU1)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(2) - VFirst1 < ResoV1)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(3) - UFirst2 < ResoU2)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(4) - VFirst2 < ResoV2)
+  {
+    return bOutOfTangentZone;
+  }
+
+  if (Param(1) - ULast1 > -ResoU1)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(2) - VLast1 > -ResoV1)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(3) - ULast2 > -ResoU2)
+  {
+    return bOutOfTangentZone;
+  }
+  else if (Param(4) - VLast2 > -ResoV2)
+  {
+    return bOutOfTangentZone;
+  }
+
   while (!bStop) {
     nbIterWithoutAppend++;
 
diff --git a/tests/perf/modalg/bug29093_1 b/tests/perf/modalg/bug29093_1
new file mode 100644 (file)
index 0000000..3e4af83
--- /dev/null
@@ -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 (file)
index 0000000..85296cc
--- /dev/null
@@ -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 (file)
index 0000000..f6fb653
--- /dev/null
@@ -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