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

src/BOPAlgo/BOPAlgo_BuilderFace.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.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 dfbfe61954da6bc5bbb7c0154a3bddc1f189fa50..37a16e22544d1b6baec8b85871c6490920813e67 100644 (file)
@@ -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();
index c89f7a31b95134fd9db3c39f7cb524bcaa931a18..9ed03f53d1e5d9a0dd4b96220426b25d6bf5ddfb 100644 (file)
@@ -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<TopoDS_Edge, Handle(BOPDS_CommonBlock)> 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);
+    }
+  }
+}
index 6b19debd0e7dca122b0bb7e26bfc3e9a5d693dc1..3e3e7690f2e54d6b1337810b2c3aa8a9daa245ff 100644 (file)
@@ -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:
 
   
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..6f202cc76d77b2e5b8763d63267b20ac08a18b3d 100644 (file)
@@ -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);
index 92298b01c350a45cdf08f3b93ffb9ece3095fee5..e2e623f4742f2ffcd48fadcfb00b2ad1900c9cde 100644 (file)
@@ -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 (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