]> OCCT Git - occt-copy.git/commitdiff
0029144: BOP PaveFiller hangs in some case CR29144_3
authornbv <nbv@opencascade.com>
Fri, 22 Sep 2017 08:24:35 +0000 (11:24 +0300)
committeremv <emv@opencascade.com>
Fri, 19 Jan 2018 08:21:48 +0000 (11:21 +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 9d4007a0eb635a040857ae9fbe24bb992471a3ad..09d14ca62495889e6075f45b0fc2a28fee253512 100644 (file)
@@ -713,34 +713,30 @@ 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;
   TopTools_IndexedMapOfShape aME2;
   gp_Pnt2d aP2D;
   //
   bRet=Standard_False;
-  aState=TopAbs_UNKNOWN;
   const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
   //
   TopExp::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)) {
-      //
-      aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
-      BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV, theContext);
-      aP2D.SetCoord(aU, aV);
+    if (!BRep_Tool::Degenerated(aE))
+    {
       //
-      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 930e1a82d8095f9a2c08fd0f27b0026bce662b77..2fcf04c9081063c2fd196430b8a7bd2f1bc4b562 100644 (file)
@@ -711,7 +711,10 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   // Treat possible common zones by trying to put each section edge
   // into all faces, not participated in creation of that edge, as IN edge
   PutSEInOtherFaces();
-  //
+
+  // Filter the Common Blocks created on the Face/Face post treatment stage from duplicates
+  myDS->FilterCommonBlocks();
+
   //-----------------------------------------------------scope t
   aMVStick.Clear();
   aMPBOnIn.Clear();
index d7d3aa31b2ae5a5c6e2464969a927444f68837bd..23edc7d045257ef30095045e3a3d3c4170a0be31 100644 (file)
@@ -1144,13 +1144,7 @@ Handle(BOPDS_CommonBlock) BOPDS_DS::CommonBlock
 void BOPDS_DS::SetCommonBlock(const Handle(BOPDS_PaveBlock)& thePB,
                               const Handle(BOPDS_CommonBlock)& theCB)
 {
-  if (IsCommonBlock(thePB)) {
-    Handle(BOPDS_CommonBlock)& aCB = myMapPBCB.ChangeFind(thePB);
-    aCB=theCB;
-  }
-  else {
-    myMapPBCB.Bind(thePB, theCB);
-  }
+  myMapPBCB.Bind(thePB, theCB);
 }
 
 //
@@ -2106,4 +2100,50 @@ Standard_Boolean BOPDS_DS::IsValidShrunkData(const Handle(BOPDS_PaveBlock)& theP
     }
   }
   return Standard_True;
-}
\ No newline at end of file
+}
+
+//=======================================================================
+//function : FilterCommonBlocks
+//purpose  : 
+//=======================================================================
+void BOPDS_DS::FilterCommonBlocks()
+{
+  // Connection map from edge to common block
+  NCollection_DataMap<Standard_Integer, Handle(BOPDS_CommonBlock)> aMapEC;
+
+  // Iterate on all Pave Blocks in the Data Structure and make
+  // the Pave Blocks with the same edges be lined to the same Common Block
+  BOPDS_VectorOfListOfPaveBlock& aPBP = ChangePaveBlocksPool();
+  Standard_Integer aNbPBP = aPBP.Length();
+  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))
+        // not a Common block - skip
+        continue;
+
+      // Get index of the edge
+      const Standard_Integer anEIdx = aPB->Edge();
+
+      Handle(BOPDS_CommonBlock) *aCB = aMapEC.ChangeSeek(anEIdx);
+      if (!aCB)
+      {
+        // Firstly met edge. Make all other Pave Blocks with the same edge
+        // be linked to the same Common Block.
+        aCB = aMapEC.Bound(anEIdx, CommonBlock(aPB));
+      }
+      else
+      {
+        // Update the information about Common Block
+        (*aCB)->AddPaveBlock(aPB);
+        SetCommonBlock(aPB, *aCB);
+      }
+    }
+  }
+}
index 2201d5f499962aa77298986df59103510a279bbf..39aa33bc68dd5de8148fa433ecd27d0f3cefc2df 100644 (file)
@@ -478,6 +478,10 @@ Standard_EXPORT virtual ~BOPDS_DS();
                                          Bnd_Box& theBox,
                                          const Standard_Boolean theCheckInverted = Standard_True);
 
+  //! Filter the Common Blocks on edges so that all Pave Blocks with the same Edge
+  //! have the same Common Block linked to it.
+  Standard_EXPORT void FilterCommonBlocks();
+
 protected:
 
   
index b971decf90a1d114b0ca7e9a2c7a740b0eb08ed4..2d7ba533873eac228bb89c202cf313fe239cc1ae 100644 (file)
@@ -1757,6 +1757,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 141e90586580ee605ca9c9796fa7584ca5228890..5707b91c1b5cbaa1f0bfe067a973111306d3014d 100644 (file)
@@ -1654,10 +1654,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;
@@ -1665,7 +1724,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