0026938: Boolean operations fail between two ellipsoids
authoraml <aml@opencascade.com>
Fri, 13 May 2016 10:36:33 +0000 (13:36 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 May 2016 12:07:44 +0000 (15:07 +0300)
Treatment for single singular point is added.
Test cases are updated to the new behavior.
New test cases are added,
Message of "bad" state is corrected.

14 files changed:
src/IntPatch/IntPatch_PrmPrmIntersection.cxx
src/IntPatch/IntPatch_RstInt.cxx
src/IntPatch/IntPatch_RstInt.hxx
src/IntPatch/IntPatch_WLine.cxx
src/IntPatch/IntPatch_WLine.hxx
src/IntWalk/IntWalk_PWalking.cxx
src/IntWalk/IntWalk_PWalking.hxx
tests/boolean/bcommon_complex/C7
tests/boolean/bcut_complex/Q1
tests/bugs/modalg_1/buc60532_2
tests/bugs/modalg_6/bug26938_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug26938_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug26938_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug26938_4 [new file with mode: 0644]

index 72c7102..4e8f595 100644 (file)
@@ -1716,8 +1716,8 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
         if(PW.IsDone())        {
           if(PW.NbPoints()>2)
           {
-            //Try to extend the intersection line to boundary, if it is possibly
-            Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
+            //Try to extend the intersection line to boundary, if it is possible.
+            PW.PutToBoundary(Surf1, Surf2);
 
             RejetLigne = Standard_False;
             Point3dDebut = PW.Value(1).Value();
@@ -1773,8 +1773,8 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
               Standard_Real TolTang = TolTangency;
               Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
               if (RestrictLine){
-                IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
-                IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
+                IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
+                IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
               }
 
               if(wline->NbVertex() == 0) {
@@ -2345,13 +2345,12 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
                   if( iPWNbPoints > 2 )
                   {
                     //Try to extend the intersection line to boundary, if it is possibly
-                    Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
+                    PW.PutToBoundary(Surf1, Surf2);
 
                     const Standard_Integer aMinNbPoints = 40;
                     if(iPWNbPoints < aMinNbPoints)
                     {
-                      hasBeenAdded = 
-                        PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints) || hasBeenAdded;
+                      PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints);
                       iPWNbPoints = PW.NbPoints();
                     }
                     
@@ -2453,9 +2452,8 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
                       Standard_Real TolTang = TolTangency;
                       Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
-                      IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
-                      IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
-
+                      IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
+                      IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
                       if(wline->NbVertex() == 0)
                       {
                         IntPatch_Point vtx;
index 1e00a42..c2d9a98 100644 (file)
@@ -442,12 +442,11 @@ static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
 //=======================================================================
 
 void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
-                                      const Handle(Adaptor3d_HSurface)& Surf,
-                                      const Handle(Adaptor3d_TopolTool)& Domain,
-                                      const Handle(Adaptor3d_HSurface)& OtherSurf,
-                                      const Standard_Boolean OnFirst,
-                                      const Standard_Real Tol,
-                                       const Standard_Boolean hasBeenAdded)
+                                       const Handle(Adaptor3d_HSurface)& Surf,
+                                       const Handle(Adaptor3d_TopolTool)& Domain,
+                                       const Handle(Adaptor3d_HSurface)& OtherSurf,
+                                       const Standard_Boolean OnFirst,
+                                       const Standard_Real Tol)
  {
 
 // Domain est le domaine de restriction de la surface Surf.
@@ -1243,7 +1242,7 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
 */
 
     wlin->SetPeriod(pu1,pv1,pu2,pv2);
-    wlin->ComputeVertexParameters(Tol, hasBeenAdded);
+    wlin->ComputeVertexParameters(Tol);
   }
   else {
     rlin->ComputeVertexParameters(Tol);
index 64b994d..885abd2 100644 (file)
@@ -38,7 +38,12 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT static void PutVertexOnLine (const Handle(IntPatch_Line)& L, const Handle(Adaptor3d_HSurface)& Surf, const Handle(Adaptor3d_TopolTool)& Domain, const Handle(Adaptor3d_HSurface)& OtherSurf, const Standard_Boolean OnFirst, const Standard_Real Tol, const Standard_Boolean hasBeenAdded = Standard_False);
+  Standard_EXPORT static void PutVertexOnLine (const Handle(IntPatch_Line)& L,
+                                               const Handle(Adaptor3d_HSurface)& Surf,
+                                               const Handle(Adaptor3d_TopolTool)& Domain,
+                                               const Handle(Adaptor3d_HSurface)& OtherSurf,
+                                               const Standard_Boolean OnFirst,
+                                               const Standard_Real Tol);
 
 };
 
index e8da3d7..f570a56 100644 (file)
@@ -255,8 +255,7 @@ inline Standard_Boolean CompareVerticesOnS2(const IntPatch_Point& vtx1, const In
 {return CompareVerticesOnSurf (vtx1, vtx2, Standard_False);}
 
 
-void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol,
-                                              const Standard_Boolean hasBeenAdded)
+void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
 {
   // MSV Oct 15, 2001: use tolerance of vertex instead of RTol where 
   //                   it is possible
@@ -505,30 +504,8 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol,
   for(i=1; i<=nbvtx; i++) {
     const gp_Pnt& P    = svtx.Value(i).Value();
     Standard_Real vTol = svtx.Value(i).Tolerance();
-    
-    if(hasBeenAdded)
-    {
-      if(nbvtx == 2)
-      {
-        if(i == nbvtx)
-        {
-          indicevertex = curv->NbPoints();
-        }
-        else
-        {
-          indicevertex = svtx.Value(i).ParameterOnLine();
-        }
-      }
-      else
-      {
-        indicevertex = svtx.Value(i).ParameterOnLine();
-      }
-    }
-    else
-    {
-      indicevertex = svtx.Value(i).ParameterOnLine();
-    }
-    
+
+    indicevertex = svtx.Value(i).ParameterOnLine();
     indicevertexonline = (Standard_Integer)indicevertex;
     //--------------------------------------------------
     //-- On Compare le vertex avec les points de la ligne
index 1dba818..642e0e2 100644 (file)
@@ -124,7 +124,7 @@ public:
   //! if a vertex is already in the line,
   //! its parameter is modified
   //! else a new point in the line is inserted.
-  Standard_EXPORT void ComputeVertexParameters (const Standard_Real Tol, const Standard_Boolean hasBeenAdded = Standard_False);
+  Standard_EXPORT void ComputeVertexParameters (const Standard_Real Tol);
   
   //! Returns set of intersection points
   Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const Standard_OVERRIDE;
index bf57d64..244c5d1 100644 (file)
@@ -113,7 +113,8 @@ static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
 
   theIsUparallel = theIsVparallel = Standard_True;
 
-  Standard_Integer aNbPoints = theLine->NbPoints();
+  const Standard_Integer aNbLinePnts = theLine->NbPoints();
+  Standard_Integer aNbPoints = aNbLinePnts;
   if(aNbPoints > aNbPointsMAX)
   {
     aNbPoints = aNbPointsMAX;
@@ -131,10 +132,9 @@ static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
   Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
   for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
   {
-    if(aNPoint > aNbPoints)
-    {
-      aNPoint = aNbPoints;
-    }
+    // Fix possible "out of parameter" case.
+    if (aNPoint > aNbLinePnts)
+      aNPoint = aNbLinePnts;
 
     Standard_Real u, v;
     if(theCheckSurf1)
@@ -159,100 +159,6 @@ static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine,
   theIsUparallel = ((aVmax - aVmin) < theToler);
 }
 
-//=======================================================================
-//function : Checking
-//purpose  : Check, if given point is in surface's boundaries.
-//            If "yes" then theFactTol = 0.0, else theFactTol is
-//            equal maximal deviation.
-//=======================================================================
-static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
-                                 const Handle(Adaptor3d_HSurface)& theASurf2,
-                                 Standard_Real& theU1,
-                                 Standard_Real& theV1,
-                                 Standard_Real& theU2,
-                                 Standard_Real& theV2,
-                                 Standard_Real& theFactTol)
-{
-  const Standard_Real aTol = Precision::PConfusion();
-  const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
-  const Standard_Real aU1bLast = theASurf1->LastUParameter();
-  const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
-  const Standard_Real aU2bLast = theASurf2->LastUParameter();
-  const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
-  const Standard_Real aV1bLast = theASurf1->LastVParameter();
-  const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
-  const Standard_Real aV2bLast = theASurf2->LastVParameter();
-
-  Standard_Boolean isOnOrIn = Standard_True;
-  theFactTol = 0.0;
-
-  Standard_Real aDelta = aU1bFirst - theU1;
-  if(aDelta > aTol)
-  {
-    theU1 = aU1bFirst;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = theU1 - aU1bLast;
-  if(aDelta > aTol)
-  {
-    theU1 = aU1bLast;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = aV1bFirst - theV1;
-  if(aDelta > aTol)
-  {
-    theV1 = aV1bFirst;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = theV1 - aV1bLast;
-  if(aDelta > aTol)
-  {
-    theV1 = aV1bLast;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = aU2bFirst - theU2;
-  if(aDelta > aTol)
-  {
-    theU2 = aU2bFirst;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = theU2 - aU2bLast;
-  if(aDelta > aTol)
-  {
-    theU2 = aU2bLast;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = aV2bFirst - theV2;
-  if(aDelta > aTol)
-  {
-    theV2 = aV2bFirst;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  aDelta = theV2 - aV2bLast;
-  if(aDelta > aTol)
-  {
-    theV2 = aV2bLast;
-    theFactTol = Max(theFactTol, aDelta);
-    isOnOrIn = Standard_False;
-  }
-
-  return isOnOrIn;
-}
-
 //==================================================================================
 // function : IntWalk_PWalking::IntWalk_PWalking
 // purpose  : 
@@ -2260,6 +2166,55 @@ DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf,
   return (aSQDistPrev < aTol);
 }
 
+//=======================================================================
+//function : HandleSingleSingularPoint
+//purpose  : 
+//=======================================================================
+Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adaptor3d_HSurface)& theASurf1,
+                                                             const Handle(Adaptor3d_HSurface)& theASurf2,
+                                                             const Standard_Real the3DTol,
+                                                             TColStd_Array1OfReal &thePnt)
+{
+  // u1, v1, u2, v2 order is used.
+  Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
+                                 theASurf1->FirstVParameter(),
+                                 theASurf2->FirstUParameter(),
+                                 theASurf2->FirstVParameter()};
+  Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
+                                 theASurf1->LastVParameter(),
+                                 theASurf2->LastUParameter(),
+                                 theASurf2->LastVParameter()};
+  IntImp_ConstIsoparametric aLockedDir[4] = {IntImp_UIsoparametricOnCaro1,
+                                             IntImp_VIsoparametricOnCaro1,
+                                             IntImp_UIsoparametricOnCaro2,
+                                             IntImp_VIsoparametricOnCaro2};
+
+  // Create new intersector with new tolerance.
+  IntWalk_TheInt2S anInt(theASurf1, theASurf2, the3DTol);
+  math_FunctionSetRoot aRsnld(anInt.Function());
+
+  for (Standard_Integer i = 1; i <= 4; ++i)
+  {
+    if ( Abs(thePnt(i) - aLowBorder[i - 1]) < Precision::PConfusion() ||
+         Abs(thePnt(i) - aUppBorder[i - 1]) < Precision::PConfusion())
+    {
+
+      anInt.Perform(thePnt,aRsnld, aLockedDir[i - 1]);
+
+      if (!anInt.IsDone())
+        continue;
+
+      if (anInt.IsEmpty())
+        continue;
+
+      anInt.Point().Parameters(thePnt(1), thePnt(2), thePnt(3), thePnt(4));
+      return Standard_True;
+    }
+  }
+
+  return Standard_False;
+}
+
 //=======================================================================
 //function : SeekPointOnBoundary
 //purpose  : 
@@ -2273,79 +2228,64 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
                     const Standard_Real theV2,
                     const Standard_Boolean isTheFirst)
 {
-  const Standard_Real aTol = 1.0e-14;
   Standard_Boolean isOK = Standard_False;
-  Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
 
-  Standard_Boolean flFinish = Standard_False;
+  // Tune solution tolerance according with object size.
+  const Standard_Real aRes1 = Max(Precision::PConfusion() / theASurf1->UResolution(1.0),
+                                  Precision::PConfusion() / theASurf1->VResolution(1.0));
+  const Standard_Real aRes2 = Max(Precision::PConfusion() / theASurf2->UResolution(1.0),
+                                  Precision::PConfusion() / theASurf2->VResolution(1.0));
+  const Standard_Real a3DTol = Max(aRes1, aRes2);
+  const Standard_Real aTol = Max(Precision::Confusion(), a3DTol);
+
+  // u1, v1, u2, v2 order is used.
+  TColStd_Array1OfReal aPnt(1,4);
+  aPnt(1) = theU1; aPnt(2) = theV1; aPnt(3) = theU2; aPnt(4) = theV2;
+  TColStd_Array1OfReal aSingularPnt(aPnt);
 
   Standard_Integer aNbIter = 20;
-  while(!flFinish)
+  Standard_Boolean aStatus = Standard_False;
+  do
   {
-    flFinish = Standard_False;
-    Standard_Boolean aStatus = Standard_False;
-
-    do
-    {
-      aNbIter--;
-      aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
-      if(aStatus)
-      {
-        break;
-      }
-
-      aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
-      if(aStatus)
-      {
-        break;
-      }
-
-      aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
-      if(aStatus)
-      {
-        break;
-      }
-    }
-    while(!aStatus && (aNbIter > 0));
+    aNbIter--;
+    aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
+    if(aStatus)
+      break;
 
+    aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), aPnt(1), aPnt(2));
     if(aStatus)
-    {
-      const Standard_Real aTolMax = 1.0e-8;
-      Standard_Real aTolF = 0.0;
+      break;
 
-      Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
+    aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), aPnt(3), aPnt(4));
+    if(aStatus)
+      break;
+  }
+  while(!aStatus && (aNbIter > 0));
 
-      flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
+  // Handle singular points.
+  Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1, theASurf2, aTol, aSingularPnt);
+  if (aSingularStatus)
+    aPnt = aSingularPnt;
 
-      if(aTolF <= aTolMax)
-      {
-        gp_Pnt  aP1 = theASurf1->Value(u1, v1),
-          aP2 = theASurf2->Value(u2, v2);
-        gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
+  if(aStatus || aSingularStatus)
+  {
+    gp_Pnt  aP1 = theASurf1->Value(aPnt(1), aPnt(2)),
+            aP2 = theASurf2->Value(aPnt(3), aPnt(4));
+    gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
 
-        const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
-          aSQDist2 = aPInt.SquareDistance(aP2);
-        if((aSQDist1 < aTol) && (aSQDist2 < aTol))
-        {
-          IntSurf_PntOn2S anIP;
-          anIP.SetValue(aPInt, u1, v1, u2, v2);
+    const Standard_Real aSQDist = aPInt.SquareDistance(aP1);
+    if (aSQDist < aTol * aTol)
+    {
+      IntSurf_PntOn2S anIP;
+      anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
 
-          if(isTheFirst)
-            line->InsertBefore(1,anIP);
-          else
-            line->Add(anIP);
+      if(isTheFirst)
+        line->InsertBefore(1,anIP);
+      else
+        line->Add(anIP);
 
-          isOK = Standard_True;
-        }
-      }
+      isOK = Standard_True;
     }
-    else
-    {
-      break;
-    }
-
-    if(aNbIter < 0)
-      break;
   }
 
   return isOK;
@@ -2396,7 +2336,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = u1 - aU1bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      u1 = aU1bFirst - aDelta;
+      u1 = aU1bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2404,7 +2344,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aU1bLast - u1;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        u1 = aU1bLast + aDelta;
+        u1 = aU1bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2415,7 +2355,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = u2 - aU2bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      u2 = aU2bFirst - aDelta;
+      u2 = aU2bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2423,7 +2363,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aU2bLast - u2;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        u2 = aU2bLast + aDelta;
+        u2 = aU2bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2434,7 +2374,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = v1 - aV1bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      v1 = aV1bFirst - aDelta;
+      v1 = aV1bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2442,7 +2382,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aV1bLast - v1;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        v1 = aV1bLast + aDelta;
+        v1 = aV1bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2453,7 +2393,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = v2 - aV2bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      v2 = aV2bFirst - aDelta;
+      v2 = aV2bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2461,7 +2401,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aV2bLast - v2;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        v2 = aV2bLast + aDelta;
+        v2 = aV2bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2483,7 +2423,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = u1 - aU1bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      u1 = aU1bFirst - aDelta;
+      u1 = aU1bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2491,7 +2431,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aU1bLast - u1;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        u1 = aU1bLast + aDelta;
+        u1 = aU1bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2502,7 +2442,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = u2 - aU2bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      u2 = aU2bFirst - aDelta;
+      u2 = aU2bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2510,7 +2450,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aU2bLast - u2;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        u2 = aU2bLast + aDelta;
+        u2 = aU2bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2521,7 +2461,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = v1 - aV1bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      v1 = aV1bFirst - aDelta;
+      v1 = aV1bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2529,7 +2469,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aV1bLast - v1;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        v1 = aV1bLast + aDelta;
+        v1 = aV1bLast;
         isNeedAdding = Standard_True;
       }
     }
@@ -2540,7 +2480,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
     aDelta = v2 - aV2bFirst;
     if((aTolMin < aDelta) && (aDelta < aTol))
     {
-      v2 = aV2bFirst - aDelta;
+      v2 = aV2bFirst;
       isNeedAdding = Standard_True;
     }
     else
@@ -2548,7 +2488,7 @@ PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
       aDelta = aV2bLast - v2;
       if((aTolMin < aDelta) && (aDelta < aTol))
       {
-        v2 = aV2bLast + aDelta;
+        v2 = aV2bLast;
         isNeedAdding = Standard_True;
       }
     }
index 81d8261..4ce317b 100644 (file)
@@ -167,6 +167,11 @@ private:
   
   Standard_EXPORT Standard_Boolean SeekPointOnBoundary (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Real theU1, const Standard_Real theV1, const Standard_Real theU2, const Standard_Real theV2, const Standard_Boolean isTheFirst);
 
+  // Method to handle single singular point. Sub-method in SeekPointOnBoundary.
+  Standard_Boolean HandleSingleSingularPoint(const Handle(Adaptor3d_HSurface) &theASurf1,
+                                             const Handle(Adaptor3d_HSurface) &theASurf2,
+                                             const Standard_Real the3DTol,
+                                             TColStd_Array1OfReal &thePnt);
 
   Standard_Boolean done;
   Handle(IntSurf_LineOn2S) line;
index f35a906..dd95968 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC1111 Windows: Error : The area of result shape is"
-puts "BUC60290 (the same problem with cut and common)"
 
 restore [locate_data_file buc60290a.rle] sol1
 restore [locate_data_file buc60290b.rle] sol2
index b2bea7c..0467de1 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC1111 Windows: Error : The area of result shape is"
-puts "BUC60290 (the same problem with cut and common)"
 
 restore [locate_data_file buc60290a.rle] sol1
 restore [locate_data_file buc60290b.rle] sol2
index 6e5cc62..78d482d 100755 (executable)
@@ -39,7 +39,6 @@ mkcurve cu21 res2_1
 mkcurve cu22 res2_2
 mkcurve cu23 res2_3
 mkcurve cu24 res2_4
-mkcurve cu25 res2_5
 
 explode res2 face
 
diff --git a/tests/bugs/modalg_6/bug26938_1 b/tests/bugs/modalg_6/bug26938_1
new file mode 100644 (file)
index 0000000..5da2404
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC26938  "
+puts "=========="
+puts ""
+#####################################################
+# Boolean operations fail between two ellipsoids
+#####################################################
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bfuse result a_1 a_2
+
+# Check shape validity
+checkshape result
+
+# Check area
+checkprops result -s 1.00773e+007
+
+# Check self-intersection
+set info [bopcheck result]
+if { [regexp "This shape seems to be OK" ${info}] != 1 } {
+    puts "Error : The result of General Fuse operation is self-interfered shape"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug26938_2 b/tests/bugs/modalg_6/bug26938_2
new file mode 100644 (file)
index 0000000..ad0544d
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC26938  "
+puts "=========="
+puts ""
+#####################################################
+# Boolean operations fail between two ellipsoids
+#####################################################
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bcommon result a_1 a_2
+
+# Check shape validity
+checkshape result
+
+# Check area
+checkprops result -s 3.52497e+006
+
+# Check self-intersection
+set info [bopcheck result]
+if { [regexp "This shape seems to be OK" ${info}] != 1 } {
+    puts "Error : The result of General Fuse operation is self-interfered shape"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug26938_3 b/tests/bugs/modalg_6/bug26938_3
new file mode 100644 (file)
index 0000000..76c5619
--- /dev/null
@@ -0,0 +1,27 @@
+puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape"
+puts "=========="
+puts "OCC26938  "
+puts "=========="
+puts ""
+#####################################################
+# Boolean operations fail between two ellipsoids
+#####################################################
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bcut result a_1 a_2
+
+# Check shape validity
+checkshape result
+
+# Check area
+checkprops result -s 8.7408e+006
+
+# Check self-intersection
+set info [bopcheck result]
+if { [regexp "This shape seems to be OK" ${info}] != 1 } {
+    puts "Error : The result of cut operation is self-interfered shape"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug26938_4 b/tests/bugs/modalg_6/bug26938_4
new file mode 100644 (file)
index 0000000..83ce69c
--- /dev/null
@@ -0,0 +1,27 @@
+puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape"
+puts "=========="
+puts "OCC26938  "
+puts "=========="
+puts ""
+#####################################################
+# Boolean operations fail between two ellipsoids
+#####################################################
+
+restore [locate_data_file bug26938.brep] a
+explode a
+
+bcut result a_2 a_1
+
+# Check shape validity
+checkshape result
+
+# Check area
+checkprops result -s 4.86143e+006
+
+# Check self-intersection
+set info [bopcheck result]
+if { [regexp "This shape seems to be OK" ${info}] != 1 } {
+    puts "Error : The result of cut operation is self-interfered shape"
+}
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png