0026132: Invalid result of boolean operation
authornbv <nbv@opencascade.com>
Tue, 19 Jan 2016 11:05:25 +0000 (14:05 +0300)
committerabv <abv@opencascade.com>
Thu, 21 Jan 2016 12:50:29 +0000 (15:50 +0300)
1. The procedures for check of coincidence between Edge-Edge and Edge-Face have been added. These methods are used instead of searching interferences between corresponding sub-shapes. In most cases (including case for this issue), new methods are more reliable and faster than intersections. However, its use should be avoided in case when the edge is not coincide with edge/face of another argument evidently (e.g. if edge vertices are not in another edge/face).

2. Interface of both IntTools_EdgeFace and IntTools_EdgeEdge has been changed (adding/deleted some field and methods).

Some test cases have been corrected in accordance with their new behavior.
Test case for issue CR26132.

12 files changed:
src/ApproxInt/ApproxInt_KnotTools.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/IntTools/IntTools_EdgeEdge.cxx
src/IntTools/IntTools_EdgeEdge.hxx
src/IntTools/IntTools_EdgeEdge.lxx
src/IntTools/IntTools_EdgeFace.cxx
src/IntTools/IntTools_EdgeFace.hxx
src/IntTools/IntTools_FaceFace.cxx
tests/bugs/modalg_1/buc60462_1
tests/bugs/modalg_1/buc60462_2
tests/bugs/modalg_6/bug26132 [new file with mode: 0755]

index f155c87..0fa2043 100644 (file)
@@ -201,7 +201,7 @@ void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_
     theInds.Append(aCurv.Upper());
   }
 
-#if defined(APPROXINT_KNOTTOOLS_DEBUG) || defined(OCCT_DEBUG)
+#if defined(APPROXINT_KNOTTOOLS_DEBUG)
   {
     cout << "Feature indices new: " << endl;
     i;
@@ -597,7 +597,7 @@ void ApproxInt_KnotTools::BuildKnots(const TColgp_Array1OfPnt& thePntsXYZ,
   // II: Build draft knot sequence.
   ComputeKnotInds(aCoords, aDim, thePars, aKnots);
 
-#if defined(APPROXINT_KNOTTOOLS_DEBUG) || defined(OCCT_DEBUG)
+#if defined(APPROXINT_KNOTTOOLS_DEBUG)
     cout << "Draft knot sequence: " << endl;
     for(i = aKnots.Lower(); i <= aKnots.Upper();  ++i)
     {
@@ -608,7 +608,7 @@ void ApproxInt_KnotTools::BuildKnots(const TColgp_Array1OfPnt& thePntsXYZ,
   // III: Build output knot sequence.
   FilterKnots(aKnots, theMinNbPnts, theKnots);
 
-#if defined(APPROXINT_KNOTTOOLS_DEBUG) || defined(OCCT_DEBUG)
+#if defined(APPROXINT_KNOTTOOLS_DEBUG)
     cout << "Result knot sequence: " << endl;
     for(i = theKnots.Lower(); i <= theKnots.Upper();  ++i)
     {
index 12ea5ff..6f36c6f 100644 (file)
@@ -281,8 +281,9 @@ void BOPAlgo_PaveFiller::PerformEE()
     return; 
   }
   //
-  Standard_Boolean bJustAdd;
+  Standard_Boolean bJustAdd, bExpressCompute;
   Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbFdgeEdge;
+  Standard_Integer nV11, nV12, nV21, nV22;
   Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
   TopAbs_ShapeEnum aType;
   BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
@@ -330,6 +331,8 @@ void BOPAlgo_PaveFiller::PerformEE()
       }
       aPB1->ShrunkData(aTS11, aTS12, aBB1);
       //
+      aPB1->Indices(nV11, nV12);
+      //
       aIt2.Initialize(aLPB2);
       for (; aIt2.More(); aIt2.Next()) {
         Bnd_Box aBB2;
@@ -347,8 +350,15 @@ void BOPAlgo_PaveFiller::PerformEE()
         aPB1->Range(aT11, aT12);
         aPB2->Range(aT21, aT22);
         //
+        aPB2->Indices(nV21, nV22);
+        //
+        bExpressCompute=((nV11==nV21 && nV12==nV22) ||
+                         (nV12==nV21 && nV11==nV22));
+        //
         BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1();
-        // 
+        //
+        anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute);
+        //
         anEdgeEdge.SetPaveBlock1(aPB1);
         anEdgeEdge.SetPaveBlock2(aPB2);
         //
index f142aa2..f7643cb 100644 (file)
@@ -147,6 +147,8 @@ void BOPAlgo_PaveFiller::PerformEF()
   }
   //
   Standard_Boolean bJustAdd, bV[2];
+  Standard_Boolean bV1, bV2, bExpressCompute;
+  Standard_Integer nV1, nV2;
   Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
   Standard_Integer aNbEdgeFace, k;
   Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
@@ -186,6 +188,9 @@ void BOPAlgo_PaveFiller::PerformEF()
     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
     //
+    const BOPCol_MapOfInteger& aMVIn=aFI.VerticesIn();
+    const BOPCol_MapOfInteger& aMVOn=aFI.VerticesOn();
+    //
     aTolE=BRep_Tool::Tolerance(aE);
     aTolF=BRep_Tool::Tolerance(aF);
     //
@@ -210,6 +215,11 @@ void BOPAlgo_PaveFiller::PerformEF()
         continue;
       }
       //
+      aPBR->Indices(nV1, nV2);
+      bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
+      bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
+      bExpressCompute=bV1 && bV2;
+      //
       BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Append1();
       //
       aEdgeFace.SetIndices(nE, nF);
@@ -221,6 +231,7 @@ void BOPAlgo_PaveFiller::PerformEF()
       aEdgeFace.SetTolF (aTolF);
       aEdgeFace.SetDiscretize (aDiscretize);
       aEdgeFace.SetDeflection (aDeflection);
+      aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
       //
       IntTools_Range aSR(aTS1, aTS2);
       IntTools_Range anewSR=aSR;
index b27f96c..6d212df 100644 (file)
@@ -211,6 +211,17 @@ void IntTools_EdgeEdge::Perform()
     return;
   }
   //
+  if (myQuickCoincidenceCheck) {
+    if (IsCoincident()) {
+      Standard_Real aT11, aT12, aT21, aT22;
+      //
+      myRange1.Range(aT11, aT12);
+      myRange2.Range(aT21, aT22);
+      AddSolution(aT11, aT12, aT21, aT22, TopAbs_EDGE);
+      return;
+    }
+  }
+  //
   IntTools_SequenceOfRanges aRanges1, aRanges2;
   //
   //3.2. Find ranges containig solutions
@@ -222,6 +233,47 @@ void IntTools_EdgeEdge::Perform()
 }
 
 //=======================================================================
+//function :  IsCoincident
+//purpose  : 
+//=======================================================================
+Standard_Boolean IntTools_EdgeEdge::IsCoincident() 
+{
+  Standard_Integer i, iCnt, aNbSeg, aNbP2;
+  Standard_Real dT, aT1, aCoeff, aTresh, aD;
+  Standard_Real aT11, aT12, aT21, aT22;
+  GeomAPI_ProjectPointOnCurve aProjPC;
+  gp_Pnt aP1;
+  //
+  aTresh=0.5;
+  aNbSeg=23;
+  myRange1.Range(aT11, aT12);
+  myRange2.Range(aT21, aT22);
+  //
+  aProjPC.Init(myGeom2, aT21, aT22);
+  //
+  dT=(aT12-aT11)/aNbSeg;
+  //
+  iCnt=0;
+  for(i=0; i <= aNbSeg; ++i) {
+    aT1 = aT11+i*dT;
+    myGeom1->D0(aT1, aP1);
+    //
+    aProjPC.Perform(aP1);
+    aNbP2=aProjPC.NbPoints();
+    if (!aNbP2) {
+      continue;
+    }
+    //
+    aD=aProjPC.LowerDistance();
+    if(aD < myTol) {
+      ++iCnt; 
+    }
+  }
+  //
+  aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
+  return aCoeff > aTresh;
+}
+//=======================================================================
 //function : FindSolutions
 //purpose  : 
 //=======================================================================
index bc8c852..a9a432a 100644 (file)
@@ -106,7 +106,15 @@ public:
   const IntTools_SequenceOfCommonPrts& CommonParts() const;
 
 
+  //! Sets the flag myQuickCoincidenceCheck
+  void UseQuickCoincidenceCheck (const Standard_Boolean bFlag) {
+    myQuickCoincidenceCheck=bFlag;
+  }
 
+  //! Returns the flag myQuickCoincidenceCheck
+  Standard_Boolean IsCoincidenceCheckedQuickly () {
+    return myQuickCoincidenceCheck;
+  }
 
 protected:
 
@@ -170,6 +178,8 @@ protected:
   Standard_EXPORT Standard_Boolean IsIntersection (const Standard_Real aT11,
     const Standard_Real aT12, const Standard_Real aT21, const Standard_Real aT22);
 
+  //! Checks if the edges are coincident really.
+  Standard_EXPORT Standard_Boolean IsCoincident();
 
   TopoDS_Edge myEdge1;
   TopoDS_Edge myEdge2;
@@ -192,6 +202,14 @@ protected:
   Standard_Integer myErrorStatus;
   IntTools_SequenceOfCommonPrts myCommonParts;
 
+  //! Allows avoiding use Edge-Edge intersection
+  //! algorithm (i.e. speeding up the Boolean algorithm)
+  //! if the edges are coincided really.
+  //! If it is not evidently set of this flag should
+  //! be avoided (otherwise, the performance of
+  //! Boolean algorithm will be slower).
+  Standard_Boolean myQuickCoincidenceCheck;
+
 private:
 
 };
index 2508d53..398afc7 100644 (file)
@@ -33,7 +33,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge()
   myRange1(0., 0.),
   myRange2(0., 0.),
   mySwap(Standard_False),
-  myErrorStatus(0)
+  myErrorStatus(0),
+  myQuickCoincidenceCheck(Standard_False)
 {
 }
 //=======================================================================
@@ -57,7 +58,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge&  theEdge1,
   myRange1(0., 0.),
   myRange2(0., 0.),
   mySwap(Standard_False),
-  myErrorStatus(0)
+  myErrorStatus(0),
+  myQuickCoincidenceCheck(Standard_False)
 {
 }
 //=======================================================================
@@ -85,7 +87,8 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge&  theEdge1,
   myRange1(aT11, aT12),
   myRange2(aT21, aT22),
   mySwap(Standard_False),
-  myErrorStatus(0)
+  myErrorStatus(0),
+  myQuickCoincidenceCheck(Standard_False)
 {
 }
 //=======================================================================
index 90a397c..3d6749d 100644 (file)
@@ -76,12 +76,10 @@ static
   myTolF=1.e-7;
   myDiscret=30;
   myEpsT   =1e-12;
-  myEpsNull=1e-12;
   myDeflection=0.01;
   myIsDone=Standard_False;
   myErrorStatus=1;
-  myParallel=Standard_False;
-  myPar1=0.;
+  myQuickCoincidenceCheck=Standard_False;
 }
 //=======================================================================
 //function : SetContext
@@ -189,15 +187,6 @@ void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
   myEpsT=anEpsT;
 } 
 //=======================================================================
-//function : SetEpsilonNull
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::SetEpsilonNull(const Standard_Real anEpsNull) 
-{
-  myEpsNull=anEpsNull;
-} 
-
-//=======================================================================
 //function : SetRange
 //purpose  : 
 //=======================================================================
@@ -214,8 +203,7 @@ void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
 //=======================================================================
 void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange) 
 {
-  myRange.SetFirst (aRange.First());
-  myRange.SetLast  (aRange.Last());
+  SetRange(aRange.First(), aRange.Last());
 } 
 //=======================================================================
 //function : IsDone
@@ -249,7 +237,84 @@ const IntTools_Range&  IntTools_EdgeFace::Range() const
 {
   return myRange;
 } 
+//=======================================================================
+//function :  IsCoincident
+//purpose  : 
+//=======================================================================
+Standard_Boolean IntTools_EdgeFace::IsCoincident() 
+{
+  Standard_Integer i, iCnt;
+  Standard_Real dT, aT, aD, aT1, aT2, aU, aV;
+
+  gp_Pnt aP;
+  TopAbs_State aState;
+  gp_Pnt2d aP2d;
+  //
+  GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
+
+  const Standard_Integer aNbSeg=23;
+  const Standard_Real aTresh=0.5;
+  const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
+                         aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
+  const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);
+
+  aT1=myRange.First();
+  aT2=myRange.Last();
+  dT=(aT2-aT1)/aNbSeg;
+  //
+  Standard_Boolean isClassified = Standard_False;
+  iCnt=0;
+  for(i=0; i <= aNbSeg; ++i) {
+    aT = aT1+i*dT;
+    aP=myC.Value(aT);
+    //
+    aProjector.Perform(aP);
+    if (!aProjector.IsDone()) {
+      continue;
+    }
+    //
+    
+    aD=aProjector.LowerDistance();
+    if (aD>myCriteria) {
+      continue;
+    }
+    //
+
+    ++iCnt; 
+
+    //We classify only three points: in the begin, in the 
+    //end and in the middle of the edge.
+    //However, exact middle point (when i == (aNbSeg + 1)/2)
+    //can be unprojectable. Therefore, it will not be able to
+    //be classified. Therefore, points with indexes in 
+    //[aTreshIdxF, aTreshIdxL] range are made available 
+    //for classification.
+    //isClassified == TRUE if MIDDLE point has been choosen and
+    //classified correctly.
+
+    if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
+      continue;
+
+    if(isClassified && (i != aNbSeg))
+      continue;
+
+    aProjector.LowerDistanceParameters(aU, aV);
+    aP2d.SetX(aU);
+    aP2d.SetY(aV);
+
+    IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
+    aState = aClass2d.Perform(aP2d);
+    
+    if(aState == TopAbs_OUT)
+      return Standard_False;
 
+    if(i != 0)
+      isClassified = Standard_True;
+  }
+  //
+  const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
+  return (aCoeff > aTresh);
+}
 //=======================================================================
 //function : CheckData
 //purpose  : 
@@ -270,6 +335,7 @@ void IntTools_EdgeFace::CheckData()
 void IntTools_EdgeFace::Prepare() 
 {
   Standard_Integer pri;
+  Standard_Real aTmin, aTmax;
   IntTools_CArray1OfReal aPars;
  
   //
@@ -280,15 +346,15 @@ void IntTools_EdgeFace::Prepare()
   //
   // 2.Prepare myCriteria
   if (aCurveType==GeomAbs_BSplineCurve||
- aCurveType==GeomAbs_BezierCurve) {
+    aCurveType==GeomAbs_BezierCurve) {
     myCriteria=1.5*myTolE+myTolF;
   }
   else {
     myCriteria = myTolE + myTolF + Precision::Confusion();
   }
   // 2.a myTmin, myTmax
-  myTmin=myRange.First();
-  myTmax=myRange.Last();
+  aTmin=myRange.First();
+  aTmax=myRange.Last();
   // 2.b myFClass2d
   myS.Initialize (myFace,Standard_True);
   myFClass2d.Init(myFace, 1.e-6);
@@ -298,7 +364,7 @@ void IntTools_EdgeFace::Prepare()
   //
   //
   // 3.Prepare myPars 
-  pri = IntTools::PrepareArgs(myC, myTmax, myTmin, 
+  pri = IntTools::PrepareArgs(myC, aTmax, aTmin, 
                               myDiscret, myDeflection, aPars);
   if (pri) {
     myErrorStatus=6;
@@ -544,300 +610,6 @@ Standard_Boolean IntTools_EdgeFace::IsEqDistance
 }
 //
 //=======================================================================
-//function : PrepareArgsFuncArrays
-//purpose  : Obtain 
-//           myFuncArray and myArgsArray for the interval [ta, tb]
-//=======================================================================  
-void IntTools_EdgeFace::PrepareArgsFuncArrays(const Standard_Real ta,
-                                              const Standard_Real tb)
-{
-  IntTools_CArray1OfReal anArgs, aFunc;
-  Standard_Integer i, aNb, pri;
-  Standard_Real t, f, f1;
-  //
-  // Prepare values of arguments for the interval [ta, tb]
-  pri=IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
-  
-  if (pri) {
-    myErrorStatus=8;
-    return;
-  }
-  //...
-  aNb=anArgs.Length();
-
-  if (!aNb){
-    myErrorStatus=9;
-    return;
-  }
-  //
-  // Prepare values of functions for the interval [ta, tb]
-  aFunc.Resize(aNb);
-  for (i=0; i<aNb; i++) {
-    t=anArgs(i);
-    f1=DistanceFunction(t);
-    f=f1+myCriteria; 
-
-    if (myErrorStatus==11)
-      return;
-    
-    if (f1 < myEpsNull) { 
-      f=0.;
-    }
-    aFunc(i)=f;
-  }
-  //
-  // Add points where the derivative = 0  
-  AddDerivativePoints(anArgs, aFunc);
-
-}
-
-//=======================================================================
-
-namespace {
-  // Auxiliary: comparator function for sorting ranges
-  bool IntTools_RangeComparator (const IntTools_Range& theLeft, const IntTools_Range& theRight)
-  {
-    return theLeft.First() < theRight.First();
-  }
-}
-
-//=======================================================================
-//function : AddDerivativePoints
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::AddDerivativePoints
-  (const IntTools_CArray1OfReal& t,
-   const IntTools_CArray1OfReal& f)  
-{
-  Standard_Integer i, j, n, k, nn=100;
-  Standard_Real fr, tr, tr1, dEpsNull=10.*myEpsNull;
-  IntTools_CArray1OfReal fd;
-  TColStd_SequenceOfReal aTSeq, aFSeq;  
-
-  n=t.Length();
-  fd.Resize(n+1);
-  //
-  // Table of derivatives
-  Standard_Real dfx, tx, tx1, fx, fx1, dt=1.e-6;
-  // Left limit
-  tx=t(0);
-  tx1=tx+dt;
-  fx=f(0);
-  fx1=DistanceFunction(tx1);
-  fx1=fx1+myCriteria;
-  if (fx1 < myEpsNull) { 
-    fx1=0.;
-  }
-  dfx=(fx1-fx)/dt;
-  fd(0)=dfx;
-  
-  if (fabs(fd(0)) < dEpsNull){
-    fd(0)=0.;
-  }
-  
-
-  k=n-1;
-  for (i=1; i<k; i++) {
-    fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
-    if (fabs(fd(i)) < dEpsNull){
-      fd(i)=0.;
-    }
-  }
-  // Right limit
-  tx=t(n-1);
-  tx1=tx-dt;
-  fx=f(n-1);
-  fx1=DistanceFunction(tx1);
-  fx1=fx1+myCriteria;
-  if (fx1 < myEpsNull) { 
-    fx1=0.;
-  }
-  dfx=(fx-fx1)/dt;
-  fd(n-1)=dfx;
-  
-  if (fabs(fd(n-1)) < dEpsNull){
-    fd(n-1)=0.;
-  }
-  //
-  // Finding the range where the derivatives have different signs
-  // for neighbouring points
-  for (i=1; i<n; i++) {
-    Standard_Real fd1, fd2, t1, t2;
-    t1 =t(i-1);
-    t2 =t(i);
-    fd1=fd(i-1);
-    fd2=fd(i);
-
-    if (fd1*fd2 < 0.) {
-      if (fabs(fd1) < myEpsNull) {
- tr=t1;
- fr=DistanceFunction(tr);//fd1;
-      }
-      else if (fabs(fd2) < myEpsNull) {
- tr=t2;
- fr=DistanceFunction(tr);
-      }
-      else {
- tr=FindSimpleRoot(2, t1, t2, fd1);
- fr=DistanceFunction(tr);
-      }
-      
-      aTSeq.Append(tr);
-      aFSeq.Append(fr);
-    }
-  } // end of for (i=1; i<n; i++)
-  //
-  // remove identical t, f
-  nn=aTSeq.Length();
-  if (nn) {
-    for (i=1; i<=aTSeq.Length(); i++) {
-      tr=aTSeq(i);
-      for (j=0; j<n; j++) {
- tr1=t(j);
- if (fabs (tr1-tr) < myEpsT) {
-   aTSeq.Remove(i);
-   aFSeq.Remove(i);
- }
-      }
-    }
-    nn=aTSeq.Length();
-  }
-  //
-  // sorting args and funcs in increasing order
-  if (nn) {
-    k=nn+n;
-    IntTools_Array1OfRange anArray1OfRange(1, k);
-    for (i=1; i<=n; i++) {
-      anArray1OfRange(i).SetFirst(t(i-1));
-      anArray1OfRange(i).SetLast (f(i-1));
-    }
-    for (i=1; i<=nn; i++) {
-      anArray1OfRange(n+i).SetFirst(aTSeq(i));
-      anArray1OfRange(n+i).SetLast (aFSeq(i));
-    }
-    
-    std::sort (anArray1OfRange.begin(), anArray1OfRange.end(), IntTools_RangeComparator);
-    
-    // filling the  output arrays
-    myArgsArray.Resize(k);
-    myFuncArray.Resize(k);
-    for (i=1; i<=k; i++) {
-      myArgsArray(i-1)=anArray1OfRange(i).First();
-      myFuncArray(i-1)=anArray1OfRange(i).Last ();
-    }
-  }
-  
-  else { // nn=0
-    myArgsArray.Resize(n);
-    myFuncArray.Resize(n);
-    for (i=0; i<n; i++) {
-      myArgsArray(i)=t(i); 
-      myFuncArray(i)=f(i); 
-    }
-  }
-}
-
-//=======================================================================
-//function : DerivativeFunction
-//purpose  : 
-//=======================================================================
-Standard_Real IntTools_EdgeFace::DerivativeFunction
-  (const Standard_Real t2)
-{
-  Standard_Real t1, t3, aD1, aD2, aD3;
-  Standard_Real dt=1.e-9;
-  t1=t2-dt;
-  aD1=DistanceFunction(t1);
-  t3=t2+dt;
-  aD3=DistanceFunction(t3);
-  
-  aD2=.5*(aD3-aD1)/dt;
-  return aD2; 
-}
-
-//=======================================================================
-//function : FindSimpleRoot
-//purpose  : [private]
-//=======================================================================
-Standard_Real IntTools_EdgeFace::FindSimpleRoot 
-  (const Standard_Integer IP,
-   const Standard_Real tA,
-   const Standard_Real tB,
-   const Standard_Real fA)
-{
-  Standard_Real r, a, b, y, x0, s;
-  
-  a=tA; b=tB; r=fA;
-  
-  for(;;) {
-    x0=.5*(a+b);
-
-    if (IP==1)
-      y=DistanceFunction(x0);
-    else 
-      y=DerivativeFunction(x0);
-    
-    if (fabs(b-a) < myEpsT || y==0.) {
-      return x0;
-    }
-    
-        
-    s=y*r;
-
-    if (s<0.) {
-      b=x0;
-      continue;
-    }
-
-    if (s>0.) {
-      a=x0; r=y;
-    }
-  }
-}
-//=======================================================================
-//function : FindGoldRoot
-//purpose  : [private]
-//=======================================================================
-Standard_Real IntTools_EdgeFace::FindGoldRoot
-  (const Standard_Real tA,
-   const Standard_Real tB,
-   const Standard_Real coeff)
-{
-  Standard_Real gs=0.61803399;
-  Standard_Real a, b, xp, xl, yp, yl;
-
-  a=tA;  b=tB;
-  
-  xp=a+(b-a)*gs;
-  xl=b-(b-a)*gs;
-  yp=coeff*DistanceFunction(xp);
-  yl=coeff*DistanceFunction(xl);
-  
-  for(;;) {
-    
-    if (fabs(b-a) < myEpsT) {
-      return .5*(b+a);
-    }
-    
-    if (yp < yl) {
-      a=xl;
-      xl=xp;
-      xp=a+(b-a)*gs;
-      yp=coeff*DistanceFunction(xp);
-    }
-    
-    else {
-      b=xp;
-      xp=xl;
-      yp=yl;
-      xl=b-(b-a)*gs;
-      yl=coeff*DistanceFunction(xl);
-    }
-  }
-}  
-
-//=======================================================================
 //function : MakeType
 //purpose  : 
 //=======================================================================
@@ -894,183 +666,6 @@ Standard_Integer IntTools_EdgeFace::MakeType
 
 
 //=======================================================================
-//function : IsIntersection
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::IsIntersection (const Standard_Real ta, 
-                                        const Standard_Real tb) 
-{
-  IntTools_CArray1OfReal anArgs, aFunc;
-  Standard_Integer i, aNb, aCnt=0;
-  //
-  Standard_Integer aCntIncreasing=1, aCntDecreasing=1;
-  Standard_Real t, f, f1;
-  //
-  // Prepare values of arguments for the interval [ta, tb]
-  IntTools::PrepareArgs (myC, tb, ta, myDiscret, myDeflection, anArgs);
-  aNb=anArgs.Length();
-  
-  aFunc.Resize(aNb);
-  for (i=0; i<aNb; i++) {
-    t=anArgs(i);
-    
-    f1=DistanceFunction(t);
-    f=f1+myCriteria; 
-
-    if (fabs(f1) < myEpsNull) { 
-      aCnt++;
-      f=0.;
-    }
-    aFunc(i)=f;
-    //
-    if (i) {
-      if (aFunc(i)>aFunc(i-1)) {
- aCntIncreasing++;
-      }
-      if (aFunc(i)<aFunc(i-1)) {
- aCntDecreasing++;
-      }
-    }
-    //
-  }
-
-  if (aCnt==aNb) {
-    myParallel=Standard_True;
-    return;
-  }
-  
-  FindDerivativeRoot(anArgs, aFunc);
-
-  //
-  if (myParallel) {
-    if (!(myC.GetType()==GeomAbs_Line 
-   && 
-   myS.GetType()==GeomAbs_Cylinder)) {
-      if (aCntDecreasing==aNb) {
- myPar1=anArgs(aNb-1);
- myParallel=Standard_False;
-      }
-      if (aCntIncreasing==aNb) {
- myPar1=anArgs(0);
- myParallel=Standard_False;
-      }
-    }
-  }
-  //
-  return ;
-}
-
-//=======================================================================
-//function : FindDerivativeRoot
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::FindDerivativeRoot
-  (const IntTools_CArray1OfReal& t,
-   const IntTools_CArray1OfReal& f)  
-{
-  Standard_Integer i, n, k;
-  Standard_Real tr;
-  IntTools_CArray1OfReal fd;
-  TColStd_SequenceOfReal aTSeq, aFSeq;  
-  
-  myPar1=0.;
-  myParallel=Standard_True;
-  
-  n=t.Length();
-  fd.Resize(n+1);
-  //
-  // Table of derivatives
-  fd(0)=(f(1)-f(0))/(t(1)-t(0));
-  if (fabs(fd(0)) < myEpsNull) {
-    fd(0)=0.;
-  }
-
-  k=n-1;
-  for (i=1; i<k; i++) {
-    fd(i)=.5*(f(i+1)-f(i-1))/(t(i)-t(i-1));
-    if (fabs(fd(i)) < myEpsNull) {
-      fd(i)=0.;
-    }
-  }
-
-  fd(n-1)=(f(n-1)-f(n-2))/(t(n-1)-t(n-2));
-  if (fabs(fd(n-1)) < myEpsNull) {
-    fd(n-1)=0.;
-  }
-  //
-  // Finding the range where the derivatives have different signs
-  // for neighbouring points
-  for (i=1; i<n; i++) {
-    Standard_Real fd1, fd2, t1, t2, fabsfd1, fabsfd2;
-    Standard_Boolean bF1, bF2;
-    t1 =t(i-1);
-    t2 =t(i);
-    fd1=fd(i-1);
-    fd2=fd(i);
-
-    fabsfd1=fabs(fd1);
-    bF1=fabsfd1 < myEpsNull;
-    
-    fabsfd2=fabs(fd2);
-    bF2=fabsfd2 < myEpsNull;
-    //
-    if (fd1*fd2 < 0.) {
-      tr=FindSimpleRoot(2, t1, t2, fd1);
-      DistanceFunction(tr);
-      myPar1=tr;
-      myParallel=Standard_False;
-      break;
-    }
-    
-    if (!bF1 && bF2) {
-      tr=t2;
-      myPar1=tr;
-      myParallel=Standard_False;
-      break;
-    }
-    
-    if (bF1 && !bF2) {
-      tr=t1;
-      myPar1=tr;
-      myParallel=Standard_False;
-      break;
-    }
-
-  }
-}
-//=======================================================================
-//function : RemoveIdenticalRoots 
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::RemoveIdenticalRoots()
-{
-  Standard_Integer aNbRoots, j, k;
-
-  aNbRoots=mySequenceOfRoots.Length();
-  for (j=1; j<=aNbRoots; j++) { 
-    const IntTools_Root& aRj=mySequenceOfRoots(j);
-    for (k=j+1; k<=aNbRoots; k++) {
-      const IntTools_Root& aRk=mySequenceOfRoots(k);
-      
-      Standard_Real aTj, aTk, aDistance;
-      gp_Pnt aPj, aPk;
-
-      aTj=aRj.Root();
-      aTk=aRk.Root();
-
-      myC.D0(aTj, aPj);
-      myC.D0(aTk, aPk);
-
-      aDistance=aPj.Distance(aPk);
-      if (aDistance < myCriteria) {
- mySequenceOfRoots.Remove(k);
- aNbRoots=mySequenceOfRoots.Length();
-      }
-    }
-  }
-}
-
-//=======================================================================
 //function : CheckTouch 
 //purpose  : 
 //=======================================================================
@@ -1197,6 +792,7 @@ Standard_Boolean IntTools_EdgeFace::CheckTouch
 
   return theflag;
 }
+
 //=======================================================================
 //function : Perform
 //purpose  : 
@@ -1239,15 +835,23 @@ void IntTools_EdgeFace::Perform()
     myCriteria = myTolE + myTolF + Precision::Confusion();
   }
   
-  myTmin=myRange.First();
-  myTmax=myRange.Last();
-  
   myS.Initialize (myFace,Standard_True);
   
   if(myContext.IsNull()) {
     myFClass2d.Init(myFace, 1.e-6);
   }
-  
+  //
+  if (myQuickCoincidenceCheck) {
+    if (IsCoincident()) {
+      aCommonPrt.SetType(TopAbs_EDGE);
+      aCommonPrt.SetRange1(myRange.First(), myRange.Last());
+      MakeType (aCommonPrt); 
+      mySeqOfCommonPrts.Append(aCommonPrt);
+      myIsDone=Standard_True;
+      return;
+    }
+  }
+  //
   IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
   //
@@ -1544,7 +1148,6 @@ Standard_Integer AdaptiveDiscret (const Standard_Integer iDiscret,
   return iDiscretNew;
 }
 
-
 #ifdef _MSC_VER
 #pragma warning ( default : 4101 )
 #endif
index 360c180..08458ff 100644 (file)
@@ -30,7 +30,6 @@
 #include <IntTools_SequenceOfRanges.hxx>
 #include <IntTools_FClass2d.hxx>
 #include <IntTools_CArray1OfReal.hxx>
-#include <IntTools_SequenceOfRoots.hxx>
 #include <IntTools_SequenceOfCommonPrts.hxx>
 #include <IntTools_Range.hxx>
 class IntTools_Context;
@@ -101,11 +100,6 @@ public:
   //! Initializes algorithm by parameter tolerance
   Standard_EXPORT void SetEpsilonT (const Standard_Real anEpsT);
   
-
-  //! Initializes algorithm by distance tolerance
-  Standard_EXPORT void SetEpsilonNull (const Standard_Real anEpsNull);
-  
-
   //! Sets boundaries for edge.
   //! The algorithm processes edge inside these boundaries.
   Standard_EXPORT void SetRange (const IntTools_Range& aRange);
@@ -149,15 +143,20 @@ public:
 
   //! Returns boundaries for edge
   Standard_EXPORT const IntTools_Range& Range() const;
-  
-  Standard_EXPORT static Standard_Boolean IsEqDistance (const gp_Pnt& aP, const BRepAdaptor_Surface& aS, const Standard_Real aT, Standard_Real& aD);
 
+  //! Sets the flag myQuickCoincidenceCheck
+  void UseQuickCoincidenceCheck(const Standard_Boolean bFlag) {
+    myQuickCoincidenceCheck=bFlag;
+  }
 
+  //! Returns the flag myQuickCoincidenceCheck
+  Standard_Boolean IsCoincidenceCheckedQuickly () {
+    return myQuickCoincidenceCheck;
+  }
 
 
 protected:
-
-  
+  Standard_EXPORT static Standard_Boolean IsEqDistance (const gp_Pnt& aP, const BRepAdaptor_Surface& aS, const Standard_Real aT, Standard_Real& aD);
   Standard_EXPORT void CheckData();
   
   Standard_EXPORT void Prepare();
@@ -168,28 +167,14 @@ protected:
   
   Standard_EXPORT Standard_Real DistanceFunction (const Standard_Real t);
   
-  Standard_EXPORT Standard_Real DerivativeFunction (const Standard_Real t);
-  
-  Standard_EXPORT void PrepareArgsFuncArrays (const Standard_Real t1, const Standard_Real t2);
-  
-  Standard_EXPORT void AddDerivativePoints (const IntTools_CArray1OfReal& t, const IntTools_CArray1OfReal& f);
-  
-  Standard_EXPORT Standard_Real FindSimpleRoot (const Standard_Integer IP, const Standard_Real ta, const Standard_Real tb, const Standard_Real fA);
-  
-  Standard_EXPORT Standard_Real FindGoldRoot (const Standard_Real ta, const Standard_Real tb, const Standard_Real coeff);
-  
   Standard_EXPORT Standard_Integer MakeType (IntTools_CommonPrt& aCP);
-  
-  Standard_EXPORT void IsIntersection (const Standard_Real ta, const Standard_Real tb);
-  
-  Standard_EXPORT void FindDerivativeRoot (const IntTools_CArray1OfReal& t, const IntTools_CArray1OfReal& f);
-  
-  Standard_EXPORT void RemoveIdenticalRoots();
-  
+   
   Standard_EXPORT Standard_Boolean CheckTouch (const IntTools_CommonPrt& aCP, Standard_Real& aTX);
   
   Standard_EXPORT Standard_Boolean CheckTouchVertex (const IntTools_CommonPrt& aCP, Standard_Real& aTX);
 
+  //! Checks if the edge is in the face really.
+  Standard_EXPORT Standard_Boolean IsCoincident();
 
 
 
@@ -203,11 +188,8 @@ private:
   Standard_Real myTolF;
   Standard_Integer myDiscret;
   Standard_Real myEpsT;
-  Standard_Real myEpsNull;
   Standard_Real myDeflection;
   BRepAdaptor_Curve myC;
-  Standard_Real myTmin;
-  Standard_Real myTmax;
   BRepAdaptor_Surface myS;
   Standard_Real myCriteria;
   Standard_Boolean myIsDone;
@@ -215,15 +197,16 @@ private:
   Handle(IntTools_Context) myContext;
   IntTools_SequenceOfRanges myProjectableRanges;
   IntTools_FClass2d myFClass2d;
-  IntTools_CArray1OfReal myFuncArray;
-  IntTools_CArray1OfReal myArgsArray;
-  IntTools_SequenceOfRoots mySequenceOfRoots;
   IntTools_SequenceOfCommonPrts mySeqOfCommonPrts;
-  Standard_Real myPar1;
-  Standard_Boolean myParallel;
   IntTools_Range myRange;
 
-
+  //! Allows avoiding use Edge-Face intersection
+  //! algorithm (i.e. speeding up the Boolean algorithm)
+  //! if the edges are coincided really.
+  //! If it is not evidently set of this flag should
+  //! be avoided (otherwise, the performance of
+  //! Boolean algorithm will be slower).
+  Standard_Boolean myQuickCoincidenceCheck;
 };
 
 
index bbd6879..e6ead52 100644 (file)
@@ -888,10 +888,27 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     }
     L = aWLine;
 
-    //
-    //if(!myListOfPnts.IsEmpty()) {
-    //  bAvoidLineConstructor = Standard_True;
-    //}
+#ifdef INTTOOLS_FACEFACE_DEBUG
+    if(!myListOfPnts.IsEmpty()) {
+      char aBuff[10000];
+      const IntSurf_PntOn2S& aPt = myListOfPnts.First();
+      Standard_Real u1, v1, u2, v2;
+      aPt.Parameters(u1, v1, u2, v2);
+
+      Sprintf(aBuff,"bopcurves <face1 face2> -2d");
+      IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);
+      for(;IterLOP1.More(); IterLOP1.Next())
+      {
+        const IntSurf_PntOn2S& aPt = IterLOP1.Value();
+        Standard_Real u1, v1, u2, v2;
+        aPt.Parameters(u1, v1, u2, v2);
+
+        Sprintf(aBuff, "%s -p %+10.20f %+10.20f %+10.20f %+10.20f", aBuff, u1, v1, u2, v2);
+      }
+
+      cout << aBuff << endl;
+    }
+#endif
 
     Standard_Integer nbp = aWLine->NbPnts();
     const IntSurf_PntOn2S& p1 = aWLine->Point(1);
index 039cd8e..1938c3f 100755 (executable)
@@ -1,4 +1,4 @@
-#puts "TODO OCC12345 ALL: Error : The length of result shape is"
+#puts "TODO OCC27024 ALL: Error : The length of result shape is"
 
 puts "============="
 puts "BUC60462"
index badc77a..3465d65 100755 (executable)
@@ -1,5 +1,6 @@
-puts "TODO ?OCC26717 ALL: Faulty shapes in variables faulty_1 to faulty_"
-puts "TODO OCC26717 ALL: Error : operation bfuse is WRONG because number of SOLID"
+#puts "TODO OCC27024 ALL: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO OCC27024 ALL: Tcl Exception: result is not a topological shape!!!"
+puts "TODO OCC27024 All:TEST INCOMPLETE"
 
 puts "=========="
 puts "BUC60462"
diff --git a/tests/bugs/modalg_6/bug26132 b/tests/bugs/modalg_6/bug26132
new file mode 100755 (executable)
index 0000000..5793dc0
--- /dev/null
@@ -0,0 +1,31 @@
+puts "============"
+puts "OCC26132"
+puts "============"
+puts ""
+######################################################
+# Invalid result of boolean operation
+######################################################
+
+restore [locate_data_file bug26132_shape.brep] c
+
+explode c
+
+bcommon result c_1 c_2
+
+set square 947.358
+
+set nbshapes_expected "
+Number of shapes in shape
+ VERTEX    : 6
+ EDGE      : 11
+ WIRE      : 8
+ FACE      : 8
+ SHELL     : 2
+ SOLID     : 2
+ COMPSOLID : 0
+ COMPOUND  : 1
+ SHAPE     : 38
+"
+checknbshapes result -ref ${nbshapes_expected} -t -m "Boolean operations common"
+
+set 3dviewer 1