0028222: Intersection of two cylinders fails
authornbv <nbv@opencascade.com>
Thu, 15 Dec 2016 14:22:00 +0000 (17:22 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 26 May 2017 11:48:59 +0000 (14:48 +0300)
1. The reason of exception has been eliminated.

2. Algorithm in IntPatch_WLineTool::JoinWLines(...) method has been modified in order to forbid join curves in the point where more than two intersection lines meet. More over, joining is forbidden if local curvature in the connection point is too big (see function CheckArgumentsToJoin(...) in the file IntPatch_WLineTool.cxx).

3. Interface of IntPatch_WLineTool::JoinWLines(...) method has been modified in order to reduce number of arguments.

4. Small corrections in IsSeamOrBound(...) static function has been made. Namely, check has been added if two boundaries are in the same period region but are too far each to other (see IntPatch_WLineTool.cxx, IsSeamOrBound(...) function, line # 532).

5. "Reversed" flag has been made local. Now, it is pure local characteristic: the algorithm decides itself, shall we reverse the argument order. This correction makes the algorithm more commutative (see issue #25404). However, IntPatch_WLineTool::JoinWLines(...) method can return non-commutative result.

6. Algorithm of searching small intersection curves has been improved.

7. New methods have been added in Bnd_Range class.

Some test cases have been adjusted according to their new behavior.

1. tests\bugs\modalg_6\bug26310_3
   tests\bugs\modalg_6\bug26310_4
   tests\bugs\moddata_2\bug235
   tests\perf\modalg\bug26310_1
   tests\bugs\modalg_5\bug24915

Logic of these cases has been changed. Mover over, additional check has been added in "bug26310_1" test case. Therefore, its performance will be slower than on the current MASTER.

2. tests\bugs\modalg_5\bug25292*

Scripts have been rewritten in order to make it more readable. Logic of these cases has not been changed.

36 files changed:
src/Bnd/Bnd_Range.cxx
src/Bnd/Bnd_Range.hxx
src/ElCLib/ElCLib.cxx
src/IntPatch/IntPatch_ImpImpIntersection_1.gxx
src/IntPatch/IntPatch_ImpImpIntersection_2.gxx
src/IntPatch/IntPatch_ImpImpIntersection_4.gxx
src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_WLineTool.cxx
src/IntPatch/IntPatch_WLineTool.hxx
tests/bugs/modalg_5/bug24915
tests/bugs/modalg_5/bug25292_11
tests/bugs/modalg_5/bug25292_12
tests/bugs/modalg_5/bug25292_15
tests/bugs/modalg_5/bug25292_16
tests/bugs/modalg_5/bug25292_21
tests/bugs/modalg_5/bug25292_22
tests/bugs/modalg_5/bug25292_25
tests/bugs/modalg_5/bug25292_26
tests/bugs/modalg_5/bug25292_31
tests/bugs/modalg_5/bug25292_32
tests/bugs/modalg_5/bug25292_33
tests/bugs/modalg_5/bug25292_34
tests/bugs/modalg_5/bug25292_35
tests/bugs/modalg_5/bug25292_36
tests/bugs/modalg_6/bug26310_3
tests/bugs/modalg_6/bug26310_4
tests/bugs/modalg_6/bug27310_1
tests/bugs/modalg_6/bug27310_2
tests/bugs/modalg_6/bug27856_2
tests/bugs/modalg_6/bug28009_2
tests/bugs/modalg_6/bug28222_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug28222_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug28222_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug28706 [new file with mode: 0644]
tests/bugs/moddata_2/bug235
tests/perf/modalg/bug26310_1

index d79b211..63d0961 100644 (file)
@@ -35,3 +35,143 @@ void Bnd_Range::Common(const Bnd_Range& theOther)
   myFirst = Max(myFirst, theOther.myFirst);
   myLast = Min(myLast, theOther.myLast);
 }
+
+//=======================================================================
+//function : Union
+//purpose  : 
+//=======================================================================
+Standard_Boolean Bnd_Range::Union(const Bnd_Range& theOther)
+{
+  if (IsVoid() || theOther.IsVoid())
+    return Standard_False;
+
+  if (myLast < theOther.myFirst)
+    return Standard_False;
+
+  if (myFirst > theOther.myLast)
+    return Standard_False;
+
+  myFirst = Min(myFirst, theOther.myFirst);
+  myLast = Max(myLast, theOther.myLast);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : IsIntersected
+//purpose  : 
+//=======================================================================
+Standard_Integer Bnd_Range::IsIntersected(const Standard_Real theVal,
+                                          const Standard_Real thePeriod) const
+{
+  if (IsVoid())
+    return Standard_False;
+
+  const Standard_Real aPeriod = Abs(thePeriod);
+  const Standard_Real aDF = myFirst - theVal,
+                      aDL = myLast - theVal;
+
+  if (aPeriod <= RealSmall())
+  { 
+    const Standard_Real aDelta = aDF*aDL;
+    if (IsEqual(aDelta, 0.0))
+      return 2;
+
+    if (aDelta > 0.0)
+      return 0;
+
+    return 1;
+  }
+
+  //If <this> intersects theVal then there exists an integer
+  //number N such as 
+  //    (myFirst <= theVal+aPeriod*N <= myLast) <=>
+  //    ((myFirst-theVal)/aPeriod <= N <= (myLast-theVal)/aPeriod).
+  //I.e. the interval [aDF/aPeriod, aDL/aPeriod] must contain at least one
+  //integer number.
+  //In this case, Floor(aDF/aPeriod) and Floor(aDL/aPeriod)
+  //return different values or aDF/aPeriod (aDL/aPeriod)
+  //is strictly integer number.
+  //Examples:
+  //  1. (aDF/aPeriod==2.8, aDL/aPeriod==3.5 =>
+  //        Floor(aDF/aPeriod) == 2, Floor(aDL/aPeriod) == 3.
+  //  2. aDF/aPeriod==2.0, aDL/aPeriod==2.6 =>
+  //        Floor(aDF/aPeriod) == Floor(aDL/aPeriod) == 2.
+
+  const Standard_Real aVal1 = aDF / aPeriod,
+                      aVal2 = aDL / aPeriod;
+  const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
+  const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
+  if (aPar1 != aPar2)
+  {//Interval (myFirst, myLast] intersects seam-edge
+    if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
+    {//aVal2 is an integer number => myLast lies ON the "seam-edge"
+      return 2;
+    }
+
+    return 1;
+  }
+
+  //Here, aPar1 == aPar2. 
+
+  if (IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
+  {//aVal1 is an integer number => myFirst lies ON the "seam-edge"
+    return 2;
+  }
+
+#if 0
+  // This check is excess because always myFirst <= myLast.
+  // So, this condition is never satisfied.
+  if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
+  {//aVal2 is an integer number => myLast lies ON the "seam-edge"
+    return 2;
+  }
+#endif
+
+  return 0;
+}
+
+//=======================================================================
+//function : Split
+//purpose  : 
+//=======================================================================
+void Bnd_Range::Split(const Standard_Real theVal,
+                      NCollection_List<Bnd_Range>& theList,
+                      const Standard_Real thePeriod) const
+{
+  const Standard_Real aPeriod = Abs(thePeriod);
+  if (IsIntersected(theVal, aPeriod) != 1)
+  {
+    theList.Append(*this);
+    return;
+  }
+
+  const Standard_Boolean isPeriodic = (aPeriod > 0.0);
+
+  if (!isPeriodic)
+  {
+    theList.Append(Bnd_Range(myFirst, theVal));
+    theList.Append(Bnd_Range(theVal, myLast));
+    return;
+  }
+
+  Standard_Real aValPrev = theVal + aPeriod*Ceiling((myFirst - theVal) / aPeriod);
+
+  //Now, (myFirst <= aValPrev < myFirst+aPeriod).
+
+  if (aValPrev > myFirst)
+  {
+    theList.Append(Bnd_Range(myFirst, aValPrev));
+  }
+
+  for (Standard_Real aVal = aValPrev+aPeriod; aVal <= myLast; aVal += aPeriod)
+  {
+    theList.Append(Bnd_Range(aValPrev, aVal));
+    aValPrev = aVal;
+  }
+
+  if (aValPrev < myLast)
+  {
+    theList.Append(Bnd_Range(aValPrev, myLast));
+  }
+}
\ No newline at end of file
index 2afd47f..01021b1 100644 (file)
@@ -19,6 +19,8 @@
 #include <Standard_Real.hxx>
 #include <Standard_ConstructionError.hxx>
 
+#include <NCollection_List.hxx>
+
 //! This class describes a range in 1D space restricted
 //! by two real values.
 //! A range can be void indicating there is no point included in the range.
@@ -42,6 +44,39 @@ public:
 
   //! Replaces <this> with common-part of <this> and theOther
   Standard_EXPORT void Common(const Bnd_Range& theOther);
+  
+  //! Joins *this and theOther to one interval.
+  //! Replaces *this to the result.
+  //! Returns false if the operation cannot be done (e.g.
+  //! input arguments are empty or separated).
+  Standard_EXPORT Standard_Boolean Union(const Bnd_Range& theOther);
+
+  //! Splits <this> to several sub-ranges by theVal value
+  //! (e.g. range [3, 15] will be split by theVal==5 to the two
+  //! ranges: [3, 5] and [5, 15]). New ranges will be pushed to
+  //! theList (theList must be initialized correctly before
+  //! calling this method).
+  //! If thePeriod != 0.0 then at least one boundary of
+  //! new ranges (if <*this> intersects theVal+k*thePeriod) will be equal to
+  //! theVal+thePeriod*k, where k is an integer number (k = 0, +/-1, +/-2, ...).
+  //! (let thePeriod in above example be 4 ==> we will obtain
+  //! four ranges: [3, 5], [5, 9], [9, 13] and [13, 15].
+  Standard_EXPORT void Split(const Standard_Real theVal,
+                             NCollection_List<Bnd_Range>& theList,
+                             const Standard_Real thePeriod = 0.0) const;
+
+  //! Checks if <this> intersects values like
+  //!   theVal+k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...).
+  //! Returns:
+  //!     0 - if <this> does not intersect the theVal+k*thePeriod.
+  //!     1 - if <this> intersects theVal+k*thePeriod.
+  //!     2 - if myFirst or/and myLast are equal to theVal+k*thePeriod.
+  //!
+  //! ATTENTION!!!
+  //!  If (myFirst == myLast) then this function will return only either 0 or 2.
+  Standard_EXPORT Standard_Integer
+                      IsIntersected(const Standard_Real theVal,
+                                    const Standard_Real thePeriod = 0.0) const;
 
   //! Extends <this> to include theParameter
   void Add(const Standard_Real theParameter)
@@ -82,6 +117,21 @@ public:
     return Standard_True;
   }
 
+  //! Obtain first and last boundary of <this>.
+  //! If <this> is VOID the method returns false.
+  Standard_Boolean GetBounds(Standard_Real& theFirstPar,
+                             Standard_Real& theLastPar) const
+  {
+    if(IsVoid())
+    {
+      return Standard_False;
+    }
+
+    theFirstPar = myFirst;
+    theLastPar = myLast;
+    return Standard_True;
+  }
+  
   //! Returns range value (MAX-MIN). Returns negative value for VOID range.
   Standard_Real Delta() const
   {
@@ -113,6 +163,25 @@ public:
     myLast += theDelta;
   }
 
+  //! Returns the copy of <*this> shifted by theVal
+  Bnd_Range Shifted(const Standard_Real theVal) const
+  {
+    return Bnd_Range(myFirst + theVal, myLast + theVal);
+  }
+
+  //! Shifts <*this> by theVal
+  void Shift(const Standard_Real theVal)
+  {
+    myFirst += theVal;
+    myLast += theVal;
+  }
+
+  //! Returns TRUE if theOther is equal to <*this>
+  Standard_Boolean operator==(const Bnd_Range& theOther) const
+  {
+    return ((myFirst == theOther.myFirst) && (myLast == theOther.myLast));
+  }
+
 private:
   //! Start of range
   Standard_Real myFirst;
index 6bfb2de..8801ef8 100644 (file)
@@ -49,6 +49,22 @@ static Standard_Real PIPI = M_PI + M_PI;
 //=======================================================================
 //function : InPeriod
 //purpose  : Value theULast is never returned.
+//          Example of some case (checked on WIN64 platform)
+//          with some surface having period 2*PI = 6.2831853071795862.
+//            Let theUFirst be equal to 6.1645624650899675. Then,
+//          theULast must be equal to
+//              6.1645624650899675+6.2831853071795862=12.4477477722695537.
+//
+//          However, real result is 12.447747772269555.
+//          Therefore, new period value to adjust will be equal to
+//              12.447747772269555-6.1645624650899675=6.2831853071795871.
+//
+//          As we can see, (6.2831853071795871 != 6.2831853071795862).
+//
+//          According to above said, this method should be used carefully.
+//          In order to increase reliability of this method, input arguments
+//          needs to be replaced with following: 
+//            (theU, theUFirst, thePeriod). theULast parameter is excess.
 //=======================================================================
 Standard_Real  ElCLib::InPeriod(const Standard_Real theU, 
                                 const Standard_Real theUFirst, 
index 75d377d..9ab3fd0 100644 (file)
@@ -77,7 +77,6 @@ static
                                                  const Standard_Real theTol2D,
                                                  const Bnd_Box2d& theUVSurf1,
                                                  const Bnd_Box2d& theUVSurf2,
-                                                 const Standard_Boolean isTheReverse,
                                                  Standard_Boolean& isTheEmpty,
                                                  Standard_Boolean& isTheSameSurface,
                                                  Standard_Boolean& isTheMultiplePoint,
index 2567933..30d0aeb 100644 (file)
@@ -172,33 +172,13 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
         aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
 
         // Resolution is too big if the cylinder radius is
-        // too small. Therefore, we shall bounde its value above. 
+        // too small. Therefore, we shall bind its value above. 
         // Here, we use simple constant.
         const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
                                             S2->UResolution(TolTang)));
 
-        //The bigger range the bigger nunber of points in Walking-line (WLine)
-        //we will be able to add and, consequently, we will obtain more
-        //precise intersection line.
-        //Every point of WLine is determined as function from U1-parameter,
-        //where U1 is U-parameter on 1st quadric.
-        //Therefore, we should use quadric with bigger range as 1st parameter
-        //in IntCyCy() function.
-        //On the other hand, there is no point in reversing in case of
-        //analytical intersection (when result is line, ellipse, point...).
-        //This result is independent of the arguments order.
-        Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f));
-
-        if(isReversed)
-        {
-          myDone = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
-                                    Standard_True, empt, SameSurf, multpoint, slin, spnt);
-        }
-        else
-        {
-          myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
-                                    Standard_False, empt, SameSurf, multpoint, slin, spnt);
-        }
+        myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
+                                    empt, SameSurf, multpoint, slin, spnt);
 
         if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
         {
index 94bfab8..1a6cb9b 100644 (file)
 
 #include <algorithm>
 #include <Bnd_Range.hxx>
-#include <IntAna_ListIteratorOfListOfCurve.hxx>
 #include <IntAna_ListOfCurve.hxx>
-#include <IntPatch_WLine.hxx>
-#include <Standard_DivideByZero.hxx>
 #include <math_Matrix.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <Standard_DivideByZero.hxx>
 
 //If Abs(a) <= aNulValue then it is considered that a = 0.
 static const Standard_Real aNulValue = 1.0e-11;
@@ -372,7 +371,7 @@ public:
       myV2 = RealLast();
     }
 
-    //Equal to 0 for 1st surface non-zerro for 2nd one.
+    //Equal to 0 for 1st surface non-zero for 2nd one.
     Standard_Integer mySurfID;
 
     Standard_Real myU1;
@@ -413,8 +412,55 @@ public:
   {
   };
 
+  // Returns parameters of system solved while finding
+  // intersection line
+  const ComputationMethods::stCoeffsValue &SICoeffs() const
+  {
+    return myCoeffs;
+  }
+
+  // Returns quadric correspond to the index theIdx.
+  const IntSurf_Quadric& GetQSurface(const Standard_Integer theIdx) const
+  {
+    if (theIdx <= 1)
+      return myQuad1;
+
+    return myQuad2;
+  }
+
+  // Returns TRUE in case of reverting surfaces
+  Standard_Boolean IsReversed() const
+  {
+    return myIsReverse;
+  }
+
+  // Returns 2D-tolerance
+  Standard_Real Get2dTolerance() const
+  {
+    return myTol2D;
+  }
+
+  // Returns 3D-tolerance
+  Standard_Real Get3dTolerance() const
+  {
+    return myTol3D;
+  }
+
+  // Returns UV-bounds of 1st surface
+  const Bnd_Box2d& UVS1() const
+  {
+    return myUVSurf1;
+  }
+
+  // Returns UV-bounds of 2nd surface
+  const Bnd_Box2d& UVS2() const
+  {
+    return myUVSurf2;
+  }
+
   void AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
                         const Standard_Real theU1,
+                        const Standard_Real theU1Min,
                         const Standard_Real theU2,
                         const Standard_Real theV1,
                         const Standard_Real theV1Prev,
@@ -425,8 +471,9 @@ public:
                         Standard_Boolean& isTheFound1,
                         Standard_Boolean& isTheFound2) const;
   
-  Standard_Boolean BoundariesComputing(Standard_Real theU1f[],
-                                       Standard_Real theU1l[]) const;
+  static Standard_Boolean BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs,
+                                              const Standard_Real thePeriod,
+                                              Bnd_Range theURange[]);
   
   void BoundaryEstimation(const gp_Cylinder& theCy1,
                           const gp_Cylinder& theCy2,
@@ -898,7 +945,6 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
                                           const IntSurf_Quadric& Quad2,
                                           const IntAna_QuadQuadGeo& theInter,
                                           const Standard_Real Tol,
-                                          const Standard_Boolean isTheReverse,
                                           Standard_Boolean& Empty,
                                           Standard_Boolean& Same,
                                           Standard_Boolean& Multpoint,
@@ -943,17 +989,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
       ptsol.SetValue(psol,Tol,Standard_True);
 
       Standard_Real U1,V1,U2,V2;
-
-      if(isTheReverse)
-      {
-        Quad2.Parameters(psol, U1, V1);
-        Quad1.Parameters(psol, U2, V2);
-      }
-      else
-      {
-        Quad1.Parameters(psol, U1, V1);
-        Quad2.Parameters(psol, U2, V2);
-      }
+      Quad1.Parameters(psol, U1, V1);
+      Quad2.Parameters(psol, U2, V2);
 
       ptsol.SetParameters(U1,V1,U2,V2);
       spnt.Append(ptsol);
@@ -1100,30 +1137,12 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
       pmult2.SetMultiple(Standard_True);
 
       Standard_Real oU1,oV1,oU2,oV2;
-
-      if(isTheReverse)
-      {
-        Quad2.Parameters(pttang1,oU1,oV1);
-        Quad1.Parameters(pttang1,oU2,oV2);
-      }
-      else
-      {
-        Quad1.Parameters(pttang1,oU1,oV1);
-        Quad2.Parameters(pttang1,oU2,oV2);
-      }
+      Quad1.Parameters(pttang1, oU1, oV1);
+      Quad2.Parameters(pttang1, oU2, oV2);
 
       pmult1.SetParameters(oU1,oV1,oU2,oV2);
-
-      if(isTheReverse)
-      {
-        Quad2.Parameters(pttang2,oU1,oV1); 
-        Quad1.Parameters(pttang2,oU2,oV2);        
-      }
-      else
-      {
-        Quad1.Parameters(pttang2,oU1,oV1); 
-        Quad2.Parameters(pttang2,oU2,oV2);
-      }
+      Quad1.Parameters(pttang2,oU1,oV1); 
+      Quad2.Parameters(pttang2,oU2,oV2);
 
       pmult2.SetParameters(oU1,oV1,oU2,oV2);
 
@@ -1161,17 +1180,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
         aIP.SetValue(aP,Tol,Standard_False);
         aIP.SetMultiple(Standard_False);
         //
-
-        if(isTheReverse)
-        {
-          Quad2.Parameters(aP, aU1, aV1); 
-          Quad1.Parameters(aP, aU2, aV2);          
-        }
-        else
-        {
-          Quad1.Parameters(aP, aU1, aV1); 
-          Quad2.Parameters(aP, aU2, aV2);
-        }
+        Quad1.Parameters(aP, aU1, aV1); 
+        Quad2.Parameters(aP, aU2, aV2);
 
         aIP.SetParameters(aU1, aV1, aU2, aV2);
         //
@@ -1245,16 +1255,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1,
         aIP.SetMultiple(Standard_False);
         //
 
-        if(isTheReverse)
-        {
-          Quad2.Parameters(aP, aU1, aV1); 
-          Quad1.Parameters(aP, aU2, aV2);          
-        }
-        else
-        {
-          Quad1.Parameters(aP, aU1, aV1); 
-          Quad2.Parameters(aP, aU2, aV2);
-        }
+        Quad1.Parameters(aP, aU1, aV1);
+        Quad2.Parameters(aP, aU2, aV2);
 
         aIP.SetParameters(aU1, aV1, aU2, aV2);
         //
@@ -1418,7 +1420,7 @@ Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real theU
 //=======================================================================
 //function : CylCylComputeParameters
 //purpose  : Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0,
-//            esimates the tolerance of U2-computing (estimation result is
+//            estimates the tolerance of U2-computing (estimation result is
 //            assigned to *theDelta value).
 //=======================================================================
 Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par,
@@ -1439,14 +1441,14 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real
   Standard_Real anArg = cos(theU1par - theCoeffs.mFI1);
   anArg = theCoeffs.mB*anArg + theCoeffs.mC;
 
-  if(anArg > aTol)
+  if(anArg >= aTol)
   {
     if(theDelta)
       *theDelta = 0.0;
 
     anArg = 1.0;
   }
-  else if(anArg < -aTol)
+  else if(anArg <= -aTol)
   {
     if(theDelta)
       *theDelta = 0.0;
@@ -1494,6 +1496,10 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real
   return Standard_True;
 }
 
+//=======================================================================
+//function : CylCylComputeParameters
+//purpose  : Computes V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
+//=======================================================================
 Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1,
                                                 const Standard_Real theU2,
                                                 const stCoeffsValue& theCoeffs,
@@ -1513,7 +1519,11 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real
   return Standard_True;
 }
 
-
+//=======================================================================
+//function : CylCylComputeParameters
+//purpose  : Computes U2 (U-parameter of the 2nd cylinder),
+//            V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively).
+//=======================================================================
 Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par,
                                                 const Standard_Integer theWLIndex,
                                                 const stCoeffsValue& theCoeffs,
@@ -1728,31 +1738,42 @@ Standard_Boolean InscribePoint( const Standard_Real theUfTarget,
 
 //=======================================================================
 //function : InscribeInterval
-//purpose  : Adjusts theUfGiven and (after that) adjusts theUlGiven to the result
+//purpose  : Shifts theRange in order to make at least one of its 
+//            boundary in the range [theUfTarget, theUlTarget]
 //=======================================================================
 static Standard_Boolean InscribeInterval(const Standard_Real theUfTarget,
-                                      const Standard_Real theUlTarget,
-                                      Standard_Real& theUfGiven,
-                                      Standard_Real& theUlGiven,
-                                      const Standard_Real theTol2D,
-                                      const Standard_Real thePeriod)
+                                         const Standard_Real theUlTarget,
+                                         Bnd_Range &theRange,
+                                         const Standard_Real theTol2D,
+                                         const Standard_Real thePeriod)
 {
-  Standard_Real anUpar = theUfGiven;
-  const Standard_Real aDelta = theUlGiven - theUfGiven;
-  if(InscribePoint(theUfTarget, theUlTarget, anUpar,
-                        theTol2D, thePeriod, Standard_False))
+  Standard_Real anUpar = 0.0;
+  if (!theRange.GetMin(anUpar))
+  {
+    return Standard_False;
+  }
+
+  const Standard_Real aDelta = theRange.Delta();
+  if(InscribePoint(theUfTarget, theUlTarget, anUpar, 
+          theTol2D, thePeriod, (Abs(theUlTarget-anUpar) < theTol2D)))
   {
-    theUfGiven = anUpar;
-    theUlGiven = theUfGiven + aDelta;
+    theRange.SetVoid();
+    theRange.Add(anUpar);
+    theRange.Add(anUpar + aDelta);
   }
   else 
   {
-    anUpar = theUlGiven;
+    if (!theRange.GetMAX(anUpar))
+    {
+      return Standard_False;
+    }
+
     if(InscribePoint(theUfTarget, theUlTarget, anUpar,
-                        theTol2D, thePeriod, Standard_False))
+          theTol2D, thePeriod, (Abs(theUfTarget-anUpar) < theTol2D)))
     {
-      theUlGiven = anUpar;
-      theUfGiven = theUlGiven - aDelta;
+      theRange.SetVoid();
+      theRange.Add(anUpar);
+      theRange.Add(anUpar - aDelta);
     }
     else
     {
@@ -1811,6 +1832,11 @@ static Standard_Boolean ExcludeNearElements(Standard_Real theArr[],
 //=======================================================================
 //function : AddPointIntoWL
 //purpose  : Surf1 is a surface, whose U-par is variable.
+//           If theFlBefore == TRUE then we enable the U1-parameter
+//            of the added point to be less than U1-parameter of
+//           previously added point (in general U1-parameter is
+//           always increased; therefore, this situation is abnormal).
+//           If theOnlyCheck==TRUE then no point will be added to theLine.
 //=======================================================================
 static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
                                         const IntSurf_Quadric& theQuad2,
@@ -1832,8 +1858,8 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
                                         const Standard_Integer theWLIndex,
                                         const Standard_Real theTol3D,
                                         const Standard_Real theTol2D,
-                                        const Standard_Boolean theFlForce,
-                                        const Standard_Boolean theFlBefore = Standard_False)
+                                        const Standard_Boolean theFlBefore = Standard_False,
+                                        const Standard_Boolean theOnlyCheck = Standard_False)
 {
   //Check if the point is in the domain or can be inscribed in the domain after adjusting.
   
@@ -1841,10 +1867,39 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
           aPt2(theQuad2.Value(thePntOnSurf2.X(), thePntOnSurf2.Y()));
 
   Standard_Real aU1par = thePntOnSurf1.X();
+
+  // aU1par always increases. Therefore, we must reduce its
+  // value in order to continue creation of WLine.
   if(!InscribePoint(theUfSurf1, theUlSurf1, aU1par, theTol2D,
-                                    thePeriodOfSurf1, theFlForce))
+                  thePeriodOfSurf1, aU1par > 0.5*(theUfSurf1+theUlSurf1)))
     return Standard_False;
 
+  if ((theLine->NbPoints() > 0) &&
+      ((theUlSurf1 - theUfSurf1) >= thePeriodOfSurf1) &&      
+      (((aU1par + thePeriodOfSurf1 - theUlSurf1) <= theTol2D) ||
+       ((aU1par - thePeriodOfSurf1 - theUfSurf1) >= theTol2D)))
+  {
+    // aU1par can be adjusted to both theUlSurf1 and theUfSurf1
+    // with equal possibilities. This code fragment allows choosing
+    // correct parameter from these two variants.
+
+    Standard_Real aU1 = 0.0, aV1 = 0.0;
+    if (isTheReverse)
+    {
+      theLine->Value(theLine->NbPoints()).ParametersOnS2(aU1, aV1);
+    }
+    else
+    {
+      theLine->Value(theLine->NbPoints()).ParametersOnS1(aU1, aV1);
+    }
+
+    const Standard_Real aDelta = aU1 - aU1par;
+    if (2.0*Abs(aDelta) > thePeriodOfSurf1)
+    {
+      aU1par += Sign(thePeriodOfSurf1, aDelta);
+    }
+  }
+
   Standard_Real aU2par = thePntOnSurf2.X();
   if(!InscribePoint(theUfSurf2, theUlSurf2, aU2par, theTol2D,
                                     thePeriodOfSurf1, Standard_False))
@@ -1887,7 +1942,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
     if(!theFlBefore && (aU1par <= aUl))
     {
       //Parameter value must be increased if theFlBefore == FALSE.
-      
+
       aU1par += thePeriodOfSurf1;
 
       //The condition is as same as in
@@ -1902,6 +1957,9 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
       }
     }
 
+    if (theOnlyCheck)
+      return Standard_True;
+
     //theTol2D is minimal step along parameter changed. 
     //Therefore, if we apply this minimal step two 
     //neighbour points will be always "same". Consequently,
@@ -1913,6 +1971,9 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
     }
   }
 
+  if (theOnlyCheck)
+    return Standard_True;
+
   theLine->Add(aPnt);
 
   if(!isThePrecise)
@@ -1959,6 +2020,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
 //=======================================================================
 void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
                                           const Standard_Real theU1,
+                                          const Standard_Real theU1Min,
                                           const Standard_Real theU2,
                                           const Standard_Real theV1,
                                           const Standard_Real theV1Prev,
@@ -1995,7 +2057,6 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
 
     for(Standard_Integer anIDBound = 0; anIDBound < 2; anIDBound++)
     {
-
       const Standard_Integer anIndex = anIDSurf+anIDBound;
 
       aUVPoint[anIndex].mySurfID = anIDSurf;
@@ -2015,7 +2076,10 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL,
                                                     theU2, theU1,
                                                     aUVPoint[anIndex].myU1);
 
-      if(!aRes || aUVPoint[anIndex].myU1 >= theU1)
+      // aUVPoint[anIndex].myU1 is considered to be nearer to theU1 than
+      // to theU1+/-Period
+      if (!aRes || (aUVPoint[anIndex].myU1 >= theU1) ||
+                              (aUVPoint[anIndex].myU1 < theU1Min))
       {
         //Intersection point is not found or out of the domain
         aUVPoint[anIndex].myU1 = RealLast();
@@ -2218,8 +2282,10 @@ static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
 //purpose  : Computes true domain of future intersection curve (allows
 //            avoiding excess iterations)
 //=======================================================================
-Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[],
-                                                         Standard_Real theU1l[]) const
+Standard_Boolean WorkWithBoundaries::
+            BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs,
+                                const Standard_Real thePeriod,
+                                Bnd_Range theURange[])
 {
   //All comments to this method is related to the comment
   //to ComputationMethods class
@@ -2229,59 +2295,58 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[],
   //Evidently,
   //    -1 <= B*cos(U1-FI1)+C <= 1
 
-  if(myCoeffs.mB > 0.0)
+  if (theCoeffs.mB > 0.0)
   {
     // -(1+C)/B <= cos(U1-FI1) <= (1-C)/B
 
-    if(myCoeffs.mB + Abs(myCoeffs.mC) < -1.0)
+    if (theCoeffs.mB + Abs(theCoeffs.mC) < -1.0)
     {
       //(1-C)/B < -1 or -(1+C)/B > 1  ==> No solution
       
       return Standard_False;
     }
-    else if(myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0)
+    else if (theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
     {
       //(1-C)/B >= 1 and -(1+C)/B <= -1 ==> U=[0;2*PI]+aFI1
-
-      theU1f[0] = myCoeffs.mFI1;
-      theU1l[0] = myPeriod + myCoeffs.mFI1;
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(thePeriod + theCoeffs.mFI1);
     }
-    else if((1 + myCoeffs.mC <= myCoeffs.mB) &&
-            (myCoeffs.mB <= 1 - myCoeffs.mC))
+    else if ((1 + theCoeffs.mC <= theCoeffs.mB) &&
+             (theCoeffs.mB <= 1 - theCoeffs.mC))
     {
       //(1-C)/B >= 1 and -(1+C)/B >= -1 ==> 
       //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
       //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB)
 
-      Standard_Real anArg = -(myCoeffs.mC + 1) / myCoeffs.mB;
+      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
       if(anArg > 1.0)
         anArg = 1.0;
       if(anArg < -1.0)
         anArg = -1.0;
 
       const Standard_Real aDAngle = acos(anArg);
-      theU1f[0] = myCoeffs.mFI1;
-      theU1l[0] = aDAngle + myCoeffs.mFI1;
-      theU1f[1] = myPeriod - aDAngle + myCoeffs.mFI1;
-      theU1l[1] = myPeriod + myCoeffs.mFI1;
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod + theCoeffs.mFI1);
     }
-    else if((1 - myCoeffs.mC <= myCoeffs.mB) &&
-            (myCoeffs.mB <= 1 + myCoeffs.mC))
+    else if ((1 - theCoeffs.mC <= theCoeffs.mB) &&
+             (theCoeffs.mB <= 1 + theCoeffs.mC))
     {
       //(1-C)/B <= 1 and -(1+C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1
       //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
 
-      Standard_Real anArg = (1 - myCoeffs.mC) / myCoeffs.mB;
+      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
       if(anArg > 1.0)
         anArg = 1.0;
       if(anArg < -1.0)
         anArg = -1.0;
 
       const Standard_Real aDAngle = acos(anArg);
-      theU1f[0] = aDAngle + myCoeffs.mFI1;
-      theU1l[0] = myPeriod - aDAngle + myCoeffs.mFI1;
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
     }
-    else if(myCoeffs.mB - Abs(myCoeffs.mC) >= 1.0)
+    else if (theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
     {
       //(1-C)/B <= 1 and -(1+C)/B >= -1 ==>
       //(U=[aDAngle1;aDAngle2]+aFI1) ||
@@ -2289,8 +2354,8 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[],
       //where aDAngle1 = acos((1 - myCoeffs.mC) / myCoeffs.mB),
       //      aDAngle2 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
 
-      Standard_Real anArg1 = (1 - myCoeffs.mC) / myCoeffs.mB,
-                    anArg2 = -(myCoeffs.mC + 1) / myCoeffs.mB;
+      Standard_Real anArg1 = (1 - theCoeffs.mC) / theCoeffs.mB,
+                    anArg2 = -(theCoeffs.mC + 1) / theCoeffs.mB;
       if(anArg1 > 1.0)
         anArg1 = 1.0;
       if(anArg1 < -1.0)
@@ -2304,77 +2369,75 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[],
       const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
       //(U=[aDAngle1;aDAngle2]+aFI1) ||
       //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
-
-      theU1f[0] = aDAngle1 + myCoeffs.mFI1;
-      theU1l[0] = aDAngle2 + myCoeffs.mFI1;
-      theU1f[1] = myPeriod - aDAngle2 + myCoeffs.mFI1;
-      theU1l[1] = myPeriod - aDAngle1 + myCoeffs.mFI1;
+      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
+      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
     }
     else
     {
       return Standard_False;
     }
   }
-  else if(myCoeffs.mB < 0.0)
+  else if (theCoeffs.mB < 0.0)
   {
     // (1-C)/B <= cos(U1-FI1) <= -(1+C)/B
 
-    if(myCoeffs.mB + Abs(myCoeffs.mC) > 1.0)
+    if (theCoeffs.mB + Abs(theCoeffs.mC) > 1.0)
     {
       // -(1+C)/B < -1 or (1-C)/B > 1 ==> No solutions
       return Standard_False;
     }
-    else if(-myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0)
+    else if (-theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0)
     {
       //  -(1+C)/B >= 1 and (1-C)/B <= -1 ==> U=[0;2*PI]+aFI1
-      
-      theU1f[0] = myCoeffs.mFI1;
-      theU1l[0] = myPeriod + myCoeffs.mFI1;
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(thePeriod + theCoeffs.mFI1);
     }
-    else if((-myCoeffs.mC - 1 <= myCoeffs.mB) &&
-            ( myCoeffs.mB <= myCoeffs.mC - 1))
+    else if ((-theCoeffs.mC - 1 <= theCoeffs.mB) &&
+             (theCoeffs.mB <= theCoeffs.mC - 1))
     {
       //  -(1+C)/B >= 1 and (1-C)/B >= -1 ==> 
       //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1),
       //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB)
 
-      Standard_Real anArg = (1 - myCoeffs.mC) / myCoeffs.mB;
+      Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB;
       if(anArg > 1.0)
         anArg = 1.0;
       if(anArg < -1.0)
         anArg = -1.0;
 
       const Standard_Real aDAngle = acos(anArg);
-      theU1f[0] = myCoeffs.mFI1;
-      theU1l[0] = aDAngle + myCoeffs.mFI1;
-      theU1f[1] = myPeriod - aDAngle + myCoeffs.mFI1;
-      theU1l[1] = myPeriod + myCoeffs.mFI1;
+      theURange[0].Add(theCoeffs.mFI1);
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod + theCoeffs.mFI1);
     }
-    else if((myCoeffs.mC - 1 <= myCoeffs.mB) &&
-            (myCoeffs.mB <= -myCoeffs.mB - 1))
+    else if ((theCoeffs.mC - 1 <= theCoeffs.mB) &&
+             (theCoeffs.mB <= -theCoeffs.mB - 1))
     {
       //  -(1+C)/B <= 1 and (1-C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1,
       //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB).
 
-      Standard_Real anArg = -(myCoeffs.mC + 1) / myCoeffs.mB;
+      Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB;
       if(anArg > 1.0)
         anArg = 1.0;
       if(anArg < -1.0)
         anArg = -1.0;
 
       const Standard_Real aDAngle = acos(anArg);
-      theU1f[0] = aDAngle + myCoeffs.mFI1;
-      theU1l[0] = myPeriod - aDAngle + myCoeffs.mFI1;
+      theURange[0].Add(aDAngle + theCoeffs.mFI1);
+      theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1);
     }
-    else if(-myCoeffs.mB - Abs(myCoeffs.mC) >= 1.0)
+    else if (-theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0)
     {
       //  -(1+C)/B <= 1 and (1-C)/B >= -1 ==>
       //(U=[aDAngle1;aDAngle2]+aFI1) || (U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1),
       //where aDAngle1 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB),
       //      aDAngle2 = acos((1 - myCoeffs.mC) / myCoeffs.mB)
 
-      Standard_Real anArg1 = -(myCoeffs.mC + 1) / myCoeffs.mB,
-                    anArg2 = (1 - myCoeffs.mC) / myCoeffs.mB;
+      Standard_Real anArg1 = -(theCoeffs.mC + 1) / theCoeffs.mB,
+                    anArg2 = (1 - theCoeffs.mC) / theCoeffs.mB;
       if(anArg1 > 1.0)
         anArg1 = 1.0;
       if(anArg1 < -1.0)
@@ -2386,10 +2449,10 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[],
         anArg2 = -1.0;
 
       const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
-      theU1f[0] = aDAngle1 + myCoeffs.mFI1;
-      theU1l[0] = aDAngle2 + myCoeffs.mFI1;
-      theU1f[1] = myPeriod - aDAngle2 + myCoeffs.mFI1;
-      theU1l[1] = myPeriod - aDAngle1 + myCoeffs.mFI1;
+      theURange[0].Add(aDAngle1 + theCoeffs.mFI1);
+      theURange[0].Add(aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1);
+      theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1);
     }
     else
     {
@@ -2595,133 +2658,77 @@ void WorkWithBoundaries::BoundaryEstimation(const gp_Cylinder& theCy1,
 }
 
 //=======================================================================
-//function : IntCyCy
+//function : CyCyNoGeometric
 //purpose  : 
 //=======================================================================
-IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
-                                               const IntSurf_Quadric& theQuad2,
-                                               const Standard_Real theTol3D,
-                                               const Standard_Real theTol2D,
-                                               const Bnd_Box2d& theUVSurf1,
-                                               const Bnd_Box2d& theUVSurf2,
-                                               const Standard_Boolean isTheReverse,
-                                               Standard_Boolean& isTheEmpty,
-                                               Standard_Boolean& isTheSameSurface,
-                                               Standard_Boolean& isTheMultiplePoint,
-                                               IntPatch_SequenceOfLine& theSlin,
-                                               IntPatch_SequenceOfPoint& theSPnt)
+static IntPatch_ImpImpIntersection::IntStatus
+                    CyCyNoGeometric(const gp_Cylinder &theCyl1,
+                                    const gp_Cylinder &theCyl2,
+                                    const WorkWithBoundaries &theBW,
+                                    Bnd_Range theRange[],
+                                    const Standard_Integer theNbOfRanges /*=2*/,
+                                    Standard_Boolean& isTheEmpty,
+                                    IntPatch_SequenceOfLine& theSlin,
+                                    IntPatch_SequenceOfPoint& theSPnt)
 {
-  isTheEmpty = Standard_True;
-  isTheSameSurface = Standard_False;
-  isTheMultiplePoint = Standard_False;
-  theSlin.Clear();
-  theSPnt.Clear();
-
-  const gp_Cylinder &aCyl1 = theQuad1.Cylinder(),
-                    &aCyl2 = theQuad2.Cylinder();
-
-  IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D);
-
-  if (!anInter.IsDone())
-  {
-    return IntPatch_ImpImpIntersection::IntStatus_Fail;
-  }
-
-  if(anInter.TypeInter() != IntAna_NoGeometricSolution)
-  {
-    if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter,
-                                theTol3D, isTheReverse, isTheEmpty,
-                                isTheSameSurface, isTheMultiplePoint,
-                                theSlin, theSPnt))
-    {
-      return IntPatch_ImpImpIntersection::IntStatus_OK;
-    }
-  }
-  
-  //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.)
+  Standard_Real aUSurf1f = 0.0, aUSurf1l = 0.0,
+                aUSurf2f = 0.0, aUSurf2l = 0.0,
+                aVSurf1f = 0.0, aVSurf1l = 0.0,
+                aVSurf2f = 0.0, aVSurf2l = 0.0;
 
-  Standard_Real aUSurf1f = 0.0, //const
-                aUSurf1l = 0.0,
-                aVSurf1f = 0.0,
-                aVSurf1l = 0.0;
-  Standard_Real aUSurf2f = 0.0, //const
-                aUSurf2l = 0.0,
-                aVSurf2f = 0.0,
-                aVSurf2l = 0.0;
-
-  theUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
-  theUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
-
-  const Standard_Integer aNbMaxPoints = 2000;
-  const Standard_Integer aNbMinPoints = 200;
-  const Standard_Integer aNbPoints = Min(Max(aNbMinPoints, 
-                      RealToInt(20.0*aCyl1.Radius())), aNbMaxPoints);
-  const Standard_Real aPeriod = 2.0*M_PI;
-  const Standard_Real aStepMin = theTol2D, 
-                      aStepMax =  (aUSurf1l-aUSurf1f > M_PI/100.0) ?
-                                  (aUSurf1l-aUSurf1f)/IntToReal(aNbPoints) :
-                                  aUSurf1l-aUSurf1f;
-
-  const Standard_Integer aNbWLines = 2;
-
-  const ComputationMethods::stCoeffsValue anEquationCoeffs(aCyl1, aCyl2);
-
-  const WorkWithBoundaries aBoundWork(theQuad1, theQuad2, anEquationCoeffs,
-                                      theUVSurf1, theUVSurf2, aNbWLines,
-                                      aPeriod, theTol3D, theTol2D, isTheReverse);
+  theBW.UVS1().Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
+  theBW.UVS2().Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
 
   Bnd_Range aRangeS1, aRangeS2;
-  aBoundWork.BoundaryEstimation(aCyl1, aCyl2, aRangeS1, aRangeS2);
+  theBW.BoundaryEstimation(theCyl1, theCyl2, aRangeS1, aRangeS2);
   if (aRangeS1.IsVoid() || aRangeS2.IsVoid())
     return IntPatch_ImpImpIntersection::IntStatus_OK;
 
   {
-  //Quotation of the message from issue #26894 (author MSV):
-  //"We should return fail status from intersector if the result should be an
-  //infinite curve of non-analytical type... I propose to define the limit for the
-  //extent as the radius divided by 1e+2 and multiplied by 1e+7.
-  //Thus, taking into account the number of valuable digits (15), we provide reliable
-  //computations with an error not exceeding R/100."
+    //Quotation of the message from issue #26894 (author MSV):
+    //"We should return fail status from intersector if the result should be an
+    //infinite curve of non-analytical type... I propose to define the limit for the
+    //extent as the radius divided by 1e+2 and multiplied by 1e+7.
+    //Thus, taking into account the number of valuable digits (15), we provide reliable
+    //computations with an error not exceeding R/100."
     const Standard_Real aF = 1.0e+5;
-    const Standard_Real aMaxV1Range = aF*aCyl1.Radius(), aMaxV2Range = aF*aCyl2.Radius();
+    const Standard_Real aMaxV1Range = aF*theCyl1.Radius(), aMaxV2Range = aF*theCyl2.Radius();
     if ((aRangeS1.Delta() > aMaxV1Range) || (aRangeS2.Delta() > aMaxV2Range))
       return IntPatch_ImpImpIntersection::IntStatus_InfiniteSectionCurve;
   }
 
-  //Boundaries (it is good idea to use Bnd_Range in the future, instead of aU1f and aU1l)
-  //Intersection result can include two non-connected regions
-  //(see WorkWithBoundaries::BoundariesComputing(...) method).
-  const Standard_Integer aNbOfBoundaries = 2;
-  Standard_Real aU1f[aNbOfBoundaries] = {-Precision::Infinite(), -Precision::Infinite()};
-  Standard_Real aU1l[aNbOfBoundaries] = {Precision::Infinite(), Precision::Infinite()};
-
-  if(!aBoundWork.BoundariesComputing(aU1f, aU1l))
-    return IntPatch_ImpImpIntersection::IntStatus_OK;
+  const ComputationMethods::stCoeffsValue &anEquationCoeffs = theBW.SICoeffs();
+  const IntSurf_Quadric& aQuad1 = theBW.GetQSurface(1);
+  const IntSurf_Quadric& aQuad2 = theBW.GetQSurface(2);
+  const Standard_Boolean isReversed = theBW.IsReversed();
+  const Standard_Real aTol2D = theBW.Get2dTolerance();
+  const Standard_Real aTol3D = theBW.Get3dTolerance();
+  const Standard_Real aPeriod = 2.0*M_PI;
+  const Standard_Integer aNbMaxPoints = 2000;
+  const Standard_Integer aNbMinPoints = 200;
+  const Standard_Integer aNbPoints = Min(Max(aNbMinPoints,
+                                  RealToInt(20.0*theCyl1.Radius())), aNbMaxPoints);
+  const Standard_Real aStepMin = aTol2D,
+                                  aStepMax = (aUSurf1l - aUSurf1f > M_PI / 100.0) ?
+                                  (aUSurf1l - aUSurf1f) / IntToReal(aNbPoints) :
+                                  aUSurf1l - aUSurf1f;
 
   //The main idea of the algorithm is to change U1-parameter
-  //(U-parameter of aCyl1) from aU1f to aU1l with some step
+  //(U-parameter of theCyl1) from aU1f to aU1l with some step
   //(step is adaptive) and to obtain set of intersection points.
 
-  for(Standard_Integer i = 0; i < aNbOfBoundaries; i++)
+  for (Standard_Integer i = 0; i < theNbOfRanges; i++)
   {
-    if(Precision::IsInfinite(aU1f[i]) && Precision::IsInfinite(aU1l[i]))
+    if (theRange[i].IsVoid())
       continue;
 
-    InscribeInterval(aUSurf1f, aUSurf1l, aU1f[i], aU1l[i], theTol2D, aPeriod);
+    InscribeInterval(aUSurf1f, aUSurf1l, theRange[i], aTol2D, aPeriod);
   }
 
-  if( !Precision::IsInfinite(aU1f[0]) && !Precision::IsInfinite(aU1f[1]) &&
-      !Precision::IsInfinite(aU1l[0]) && !Precision::IsInfinite(aU1l[1]))
+  if (theRange[0].Union(theRange[1]))
   {
-    if( ((aU1f[1] <= aU1l[0]) || (aU1l[1] <= aU1l[0])) && 
-        ((aU1f[0] <= aU1l[1]) || (aU1l[0] <= aU1l[1])))
-    {//Join all intervals to one
-      aU1f[0] = Min(aU1f[0], aU1f[1]);
-      aU1l[0] = Max(aU1l[0], aU1l[1]);
-
-      aU1f[1] = -Precision::Infinite();
-      aU1l[1] = Precision::Infinite();
-    }
+    // Works only if (theNbOfRanges == 2).
+    theRange[1].SetVoid();
   }
 
   //Critical points are the value of U1-parameter in the points
@@ -2733,18 +2740,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
   //See CriticalPointsComputing(...) function to get detail information about this array.
   const Standard_Integer aNbCritPointsMax = 12;
-  Standard_Real anU1crit[aNbCritPointsMax] = {Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite(),
-                                              Precision::Infinite()};
+  Standard_Real anU1crit[aNbCritPointsMax] = { Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite(),
+                                               Precision::Infinite() };
 
   //This list of critical points is not full because it does not contain any points
   //which intersection line goes through V-bounds of cylinders in.
@@ -2753,7 +2760,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
   Standard_Integer aNbCritPoints = aNbCritPointsMax;
   CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                                      aPeriod, theTol2D, aNbCritPoints, anU1crit);
+                          aPeriod, aTol2D, aNbCritPoints, anU1crit);
 
   //Getting Walking-line
 
@@ -2762,35 +2769,35 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
     // No points have been added in WL
     WLFStatus_Absent = 0,
     // WL contains at least one point
-    WLFStatus_Exist  = 1,
+    WLFStatus_Exist = 1,
     // WL has been finished in some critical point
     // We should start new line
     WLFStatus_Broken = 2
   };
 
-  for(Standard_Integer aCurInterval = 0; aCurInterval < aNbOfBoundaries; aCurInterval++)
+  const Standard_Integer aNbWLines = 2;
+  for (Standard_Integer aCurInterval = 0; aCurInterval < theNbOfRanges; aCurInterval++)
   {
     //Process every continuous region
-
-    if(Precision::IsInfinite(aU1f[aCurInterval]) && Precision::IsInfinite(aU1l[aCurInterval]))
-      continue;
-
     Standard_Boolean isAddedIntoWL[aNbWLines];
-    for(Standard_Integer i = 0; i < aNbWLines; i++)
+    for (Standard_Integer i = 0; i < aNbWLines; i++)
       isAddedIntoWL[i] = Standard_False;
 
-    Standard_Real anUf = aU1f[aCurInterval], anUl = aU1l[aCurInterval];
-    const Standard_Boolean isDeltaPeriod  = IsEqual(anUl-anUf, aPeriod);
+    Standard_Real anUf = 1.0, anUl = 0.0;
+    if (!theRange[aCurInterval].GetBounds(anUf, anUl))
+      continue;
+
+    const Standard_Boolean isDeltaPeriod = IsEqual(anUl - anUf, aPeriod);
 
     //Inscribe and sort critical points
-    for(Standard_Integer i = 0; i < aNbCritPoints; i++)
+    for (Standard_Integer i = 0; i < aNbCritPoints; i++)
     {
-      InscribePoint(anUf, anUl, anU1crit[i], theTol2D, aPeriod, Standard_False);
+      InscribePoint(anUf, anUl, anU1crit[i], 0.0, aPeriod, Standard_False);
     }
 
     std::sort(anU1crit, anU1crit + aNbCritPoints);
 
-    while(anUf < anUl)
+    while (anUf < anUl)
     {
       //Change value of U-parameter on the 1st surface from anUf to anUl
       //(anUf will be modified in the cycle body).
@@ -2804,7 +2811,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
       Handle(IntSurf_LineOn2S) aL2S[aNbWLines];
       Handle(IntPatch_WLine) aWLine[aNbWLines];
-      for(Standard_Integer i = 0; i < aNbWLines; i++)
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
       {
         aL2S[i] = new IntSurf_LineOn2S();
         aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False);
@@ -2814,33 +2821,33 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
         aV1Prev[i] = aV2Prev[i] = 0.0;
         anUexpect[i] = anUf;
       }
-      
-      Standard_Real aCriticalDelta[aNbCritPointsMax] = {0};
-      for(Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++)
+
+      Standard_Real aCriticalDelta[aNbCritPointsMax] = { 0 };
+      for (Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++)
       { //We are not interested in elements of aCriticalDelta array
         //if their index is greater than or equal to aNbCritPoints
 
         aCriticalDelta[aCritPID] = anUf - anU1crit[aCritPID];
       }
 
-      Standard_Real anU1 = anUf;
+      Standard_Real anU1 = anUf, aMinCriticalParam = anUf;
       Standard_Boolean isFirst = Standard_True;
-      
-      while(anU1 <= anUl)
+
+      while (anU1 <= anUl)
       {
         //Change value of U-parameter on the 1st surface from anUf to anUl
         //(anUf will be modified in the cycle body). However, this cycle
         //can be broken if WL goes though some critical point.
         //Step is computed adaptively (see comments below).
 
-        for(Standard_Integer i = 0; i < aNbCritPoints; i++)
+        for (Standard_Integer i = 0; i < aNbCritPoints; i++)
         {
-          if((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0)
+          if ((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0)
           {
             //WL has gone through i-th critical point
             anU1 = anU1crit[i];
 
-            for(Standard_Integer j = 0; j < aNbWLines; j++)
+            for (Standard_Integer j = 0; j < aNbWLines; j++)
             {
               aWLFindStatus[j] = WLFStatus_Broken;
               anUexpect[j] = anU1;
@@ -2850,14 +2857,14 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           }
         }
 
-        if(IsEqual(anU1, anUl))
+        if (IsEqual(anU1, anUl))
         {
-          for(Standard_Integer i = 0; i < aNbWLines; i++)
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
           {
             aWLFindStatus[i] = WLFStatus_Broken;
             anUexpect[i] = anU1;
 
-            if(isDeltaPeriod)
+            if (isDeltaPeriod)
             {
               //if isAddedIntoWL[i] == TRUE WLine contains only one point
               //(which was end point of previous WLine). If we will
@@ -2871,57 +2878,57 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
             }
             else
             {
-              isAddingWLEnabled[i] = ((theTol2D >= (anUexpect[i] - anU1)) ||
+              isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) ||
                                       (aWLFindStatus[i] == WLFStatus_Absent));
             }
           }//for(Standard_Integer i = 0; i < aNbWLines; i++)
         }
         else
         {
-          for(Standard_Integer i = 0; i < aNbWLines; i++)
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
           {
-            isAddingWLEnabled[i] = ((theTol2D >= (anUexpect[i] - anU1)) ||
+            isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) ||
                                     (aWLFindStatus[i] == WLFStatus_Absent));
           }//for(Standard_Integer i = 0; i < aNbWLines; i++)
         }
 
-        for(Standard_Integer i = 0; i < aNbWLines; i++)
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
         {
-          const Standard_Integer aNbPntsWL =  aWLine[i].IsNull() ? 0 :
-                                              aWLine[i]->Curve()->NbPoints();
-          
-          if( (aWLFindStatus[i] == WLFStatus_Broken) ||
-              (aWLFindStatus[i] == WLFStatus_Absent))
+          const Standard_Integer aNbPntsWL = aWLine[i].IsNull() ? 0 :
+            aWLine[i]->Curve()->NbPoints();
+
+          if ((aWLFindStatus[i] == WLFStatus_Broken) ||
+            (aWLFindStatus[i] == WLFStatus_Absent))
           {//Begin and end of WLine must be on boundary point
            //or on seam-edge strictly (if it is possible).
 
-            Standard_Real aTol = theTol2D;
+            Standard_Real aTol = aTol2D;
             ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs,
                                                         aU2[i], &aTol);
-            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], theTol2D, aPeriod, Standard_False);
+            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
 
-            aTol = Max(aTol, theTol2D);
+            aTol = Max(aTol, aTol2D);
 
-            if(Abs(aU2[i]) <= aTol)
+            if (Abs(aU2[i]) <= aTol)
               aU2[i] = 0.0;
-            else if(Abs(aU2[i] - aPeriod) <= aTol)
+            else if (Abs(aU2[i] - aPeriod) <= aTol)
               aU2[i] = aPeriod;
-            else if(Abs(aU2[i] - aUSurf2f) <= aTol)
+            else if (Abs(aU2[i] - aUSurf2f) <= aTol)
               aU2[i] = aUSurf2f;
-            else if(Abs(aU2[i] - aUSurf2l) <= aTol)
+            else if (Abs(aU2[i] - aUSurf2l) <= aTol)
               aU2[i] = aUSurf2l;
           }
           else
           {
             ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i]);
-            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], theTol2D, aPeriod, Standard_False);
+            InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False);
           }
-          
-          if(aNbPntsWL == 0)
+
+          if (aNbPntsWL == 0)
           {//the line has not contained any points yet
-            if(((aUSurf2f + aPeriod - aUSurf2l) <= 2.0*theTol2D) && 
-                ((Abs(aU2[i] - aUSurf2f) < theTol2D) ||
-                  (Abs(aU2[i]-aUSurf2l) < theTol2D)))
+            if (((aUSurf2f + aPeriod - aUSurf2l) <= 2.0*aTol2D) &&
+                ((Abs(aU2[i] - aUSurf2f) < aTol2D) ||
+                  (Abs(aU2[i] - aUSurf2l) < aTol2D)))
             {
               //In this case aU2[i] can have two values: current aU2[i] or
               //aU2[i]+aPeriod (aU2[i]-aPeriod). It is necessary to choose
@@ -2936,7 +2943,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
               //increased too. And we will go out of surface boundary.
               //Therefore, If U2(U1) is increasing then U2 must be equal aUSurf2f.
               //Analogically, if U2(U1) is decreasing.
-              if(isIncreasing)
+              if (isIncreasing)
               {
                 aU2[i] = aUSurf2f;
               }
@@ -2948,19 +2955,19 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           }
           else
           {//aNbPntsWL > 0
-            if(((aUSurf2l - aUSurf2f) >= aPeriod) && 
-                ((Abs(aU2[i] - aUSurf2f) < theTol2D) ||
-                  (Abs(aU2[i]-aUSurf2l) < theTol2D)))
+            if (((aUSurf2l - aUSurf2f) >= aPeriod) &&
+                ((Abs(aU2[i] - aUSurf2f) < aTol2D) ||
+                  (Abs(aU2[i] - aUSurf2l) < aTol2D)))
             {//end of the line
               Standard_Real aU2prev = 0.0, aV2prev = 0.0;
-              if(isTheReverse)
+              if (isReversed)
                 aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS1(aU2prev, aV2prev);
               else
                 aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS2(aU2prev, aV2prev);
 
-              if(2.0*Abs(aU2prev - aU2[i]) > aPeriod)
+              if (2.0*Abs(aU2prev - aU2[i]) > aPeriod)
               {
-                if(aU2prev > aU2[i])
+                if (aU2prev > aU2[i])
                   aU2[i] += aPeriod;
                 else
                   aU2[i] -= aPeriod;
@@ -2971,7 +2978,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           ComputationMethods::CylCylComputeParameters(anU1, aU2[i], anEquationCoeffs,
                                                               aV1[i], aV2[i]);
 
-          if(isFirst)
+          if (isFirst)
           {
             aV1Prev[i] = aV1[i];
             aV2Prev[i] = aV2[i];
@@ -2982,36 +2989,36 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
         //Looking for points into WLine
         Standard_Boolean isBroken = Standard_False;
-        for(Standard_Integer i = 0; i < aNbWLines; i++)
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
         {
-          if(!isAddingWLEnabled[i])
+          if (!isAddingWLEnabled[i])
           {
             Standard_Boolean isBoundIntersect = Standard_False;
-            if( (Abs(aV1[i] - aVSurf1f) <= theTol2D) ||
-                ((aV1[i]-aVSurf1f)*(aV1Prev[i]-aVSurf1f) < 0.0))
+            if ((Abs(aV1[i] - aVSurf1f) <= aTol2D) ||
+                ((aV1[i] - aVSurf1f)*(aV1Prev[i] - aVSurf1f) < 0.0))
             {
               isBoundIntersect = Standard_True;
             }
-            else if(  (Abs(aV1[i] - aVSurf1l) <= theTol2D) ||
-                    ( (aV1[i]-aVSurf1l)*(aV1Prev[i]-aVSurf1l) < 0.0))
+            else if ((Abs(aV1[i] - aVSurf1l) <= aTol2D) ||
+                    ((aV1[i] - aVSurf1l)*(aV1Prev[i] - aVSurf1l) < 0.0))
             {
               isBoundIntersect = Standard_True;
             }
-            else if(  (Abs(aV2[i] - aVSurf2f) <= theTol2D) ||
-                    ( (aV2[i]-aVSurf2f)*(aV2Prev[i]-aVSurf2f) < 0.0))
+            else if ((Abs(aV2[i] - aVSurf2f) <= aTol2D) ||
+                    ((aV2[i] - aVSurf2f)*(aV2Prev[i] - aVSurf2f) < 0.0))
             {
               isBoundIntersect = Standard_True;
             }
-            else if(  (Abs(aV2[i] - aVSurf2l) <= theTol2D) ||
-                    ( (aV2[i]-aVSurf2l)*(aV2Prev[i]-aVSurf2l) < 0.0))
+            else if ((Abs(aV2[i] - aVSurf2l) <= aTol2D) ||
+                    ((aV2[i] - aVSurf2l)*(aV2Prev[i] - aVSurf2l) < 0.0))
             {
               isBoundIntersect = Standard_True;
             }
 
-            if(aWLFindStatus[i] == WLFStatus_Broken)
+            if (aWLFindStatus[i] == WLFStatus_Broken)
               isBroken = Standard_True;
 
-            if(!isBoundIntersect)
+            if (!isBoundIntersect)
             {
               continue;
             }
@@ -3022,19 +3029,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           }
 
           // True if the current point already in the domain
-          const Standard_Boolean isInscribe = 
-              ((aUSurf2f-aU2[i]) <= theTol2D) && ((aU2[i]-aUSurf2l) <= theTol2D) &&
-              ((aVSurf1f - aV1[i]) <= theTol2D) && ((aV1[i] - aVSurf1l) <= theTol2D) &&
-              ((aVSurf2f - aV2[i]) <= theTol2D) && ((aV2[i] - aVSurf2l) <= theTol2D);
+          const Standard_Boolean isInscribe =
+              ((aUSurf2f - aU2[i]) <= aTol2D) && ((aU2[i] - aUSurf2l) <= aTol2D) &&
+              ((aVSurf1f - aV1[i]) <= aTol2D) && ((aV1[i] - aVSurf1l) <= aTol2D) &&
+              ((aVSurf2f - aV2[i]) <= aTol2D) && ((aV2[i] - aVSurf2l) <= aTol2D);
 
           //isVIntersect == TRUE if intersection line intersects two (!)
           //V-bounds of cylinder (1st or 2nd - no matter)
           const Standard_Boolean isVIntersect =
-              ( ((aVSurf1f-aV1[i])*(aVSurf1f-aV1Prev[i]) < RealSmall()) &&
-                ((aVSurf1l-aV1[i])*(aVSurf1l-aV1Prev[i]) < RealSmall())) ||
-              ( ((aVSurf2f-aV2[i])*(aVSurf2f-aV2Prev[i]) < RealSmall()) &&
-                ((aVSurf2l-aV2[i])*(aVSurf2l-aV2Prev[i]) < RealSmall()));
-
+              (((aVSurf1f - aV1[i])*(aVSurf1f - aV1Prev[i]) < RealSmall()) &&
+                ((aVSurf1l - aV1[i])*(aVSurf1l - aV1Prev[i]) < RealSmall())) ||
+              (((aVSurf2f - aV2[i])*(aVSurf2f - aV2Prev[i]) < RealSmall()) &&
+                ((aVSurf2l - aV2[i])*(aVSurf2l - aV2Prev[i]) < RealSmall()));
 
           //isFound1 == TRUE if intersection line intersects V-bounds
           //  (First or Last - no matter) of the 1st cylynder
@@ -3045,52 +3051,52 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
           if (aWLFindStatus[i] == WLFStatus_Absent)
           {
-            if(((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1-aUSurf1l) < theTol2D))
+            if (((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1 - aUSurf1l) < aTol2D))
             {
               isForce = Standard_True;
             }
           }
 
-          aBoundWork.AddBoundaryPoint(aWLine[i], anU1, aU2[i], aV1[i], aV1Prev[i],
-                                      aV2[i], aV2Prev[i], i, isForce,
-                                      isFound1, isFound2);
+          theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i],
+                                 aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i, isForce,
+                                 isFound1, isFound2);
 
           const Standard_Boolean isPrevVBound = !isVIntersect &&
-                                                ((Abs(aV1Prev[i] - aVSurf1f) <= theTol2D) ||
-                                                 (Abs(aV1Prev[i] - aVSurf1l) <= theTol2D) ||
-                                                 (Abs(aV2Prev[i] - aVSurf2f) <= theTol2D) ||
-                                                 (Abs(aV2Prev[i] - aVSurf2l) <= theTol2D));
+                                                ((Abs(aV1Prev[i] - aVSurf1f) <= aTol2D) ||
+                                                 (Abs(aV1Prev[i] - aVSurf1l) <= aTol2D) ||
+                                                 (Abs(aV2Prev[i] - aVSurf2f) <= aTol2D) ||
+                                                 (Abs(aV2Prev[i] - aVSurf2l) <= aTol2D));
 
           aV1Prev[i] = aV1[i];
           aV2Prev[i] = aV2[i];
 
-          if((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound)
+          if ((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound)
           {
             aWLFindStatus[i] = WLFStatus_Broken; //start a new line
           }
-          else if(isInscribe)
+          else if (isInscribe)
           {
-            if((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2))
+            if ((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2))
             {
               aWLFindStatus[i] = WLFStatus_Exist;
             }
 
-            if( (aWLFindStatus[i] != WLFStatus_Broken) ||
-                (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl))
+            if ((aWLFindStatus[i] != WLFStatus_Broken) ||
+              (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl))
             {
-              if(aWLine[i]->NbPnts() > 0)
+              if (aWLine[i]->NbPnts() > 0)
               {
                 Standard_Real aU2p = 0.0, aV2p = 0.0;
-                if(isTheReverse)
+                if (isReversed)
                   aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
                 else
                   aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
 
                 const Standard_Real aDelta = aU2[i] - aU2p;
 
-                if(2*Abs(aDelta) > aPeriod)
+                if (2.0 * Abs(aDelta) > aPeriod)
                 {
-                  if(aDelta > 0.0)
+                  if (aDelta > 0.0)
                   {
                     aU2[i] -= aPeriod;
                   }
@@ -3101,47 +3107,47 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
                 }
               }
 
-              if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse, Standard_True,
+              if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True,
                                 gp_Pnt2d(anU1, aV1[i]), gp_Pnt2d(aU2[i], aV2[i]),
                                 aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
                                 aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod,
-                                aWLine[i]->Curve(), i, theTol3D, theTol2D, isForce))
+                                aWLine[i]->Curve(), i, aTol3D, aTol2D, isForce))
               {
-                if(aWLFindStatus[i] == WLFStatus_Absent)
+                if (aWLFindStatus[i] == WLFStatus_Absent)
                 {
                   aWLFindStatus[i] = WLFStatus_Exist;
                 }
               }
-              else if(!isFound1 && !isFound2)
+              else if (!isFound1 && !isFound2)
               {//We do not add any point while doing this iteration
-                if(aWLFindStatus[i] == WLFStatus_Exist)
+                if (aWLFindStatus[i] == WLFStatus_Exist)
                 {
                   aWLFindStatus[i] = WLFStatus_Broken;
-                } 
+                }
               }
             }
           }
           else
           {//We do not add any point while doing this iteration
-            if(aWLFindStatus[i] == WLFStatus_Exist)
+            if (aWLFindStatus[i] == WLFStatus_Exist)
             {
               aWLFindStatus[i] = WLFStatus_Broken;
             }
           }
-          
-          if(aWLFindStatus[i] == WLFStatus_Broken)
+
+          if (aWLFindStatus[i] == WLFStatus_Broken)
             isBroken = Standard_True;
         }//for(Standard_Integer i = 0; i < aNbWLines; i++)
 
-        if(isBroken)
+        if (isBroken)
         {//current lines are filled. Go to the next lines
           anUf = anU1;
 
           Standard_Boolean isAdded = Standard_True;
 
-          for(Standard_Integer i = 0; i < aNbWLines; i++)
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
           {
-            if(isAddingWLEnabled[i])
+            if (isAddingWLEnabled[i])
             {
               continue;
             }
@@ -3150,28 +3156,28 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
             Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
 
-            aBoundWork.AddBoundaryPoint(aWLine[i], anU1, aU2[i], aV1[i], aV1Prev[i],
-                                        aV2[i], aV2Prev[i], i,
-                                        Standard_False, isFound1, isFound2);
+            theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i],
+                                   aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i,
+                                   Standard_False, isFound1, isFound2);
 
-            if(isFound1 || isFound2)
+            if (isFound1 || isFound2)
             {
               isAdded = Standard_True;
             }
 
-            if(aWLine[i]->NbPnts() > 0)
+            if (aWLine[i]->NbPnts() > 0)
             {
               Standard_Real aU2p = 0.0, aV2p = 0.0;
-              if(isTheReverse)
+              if (isReversed)
                 aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p);
               else
                 aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p);
 
               const Standard_Real aDelta = aU2[i] - aU2p;
 
-              if(2*Abs(aDelta) > aPeriod)
+              if (2 * Abs(aDelta) > aPeriod)
               {
-                if(aDelta > 0.0)
+                if (aDelta > 0.0)
                 {
                   aU2[i] -= aPeriod;
                 }
@@ -3182,18 +3188,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
               }
             }
 
-            if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse,
+            if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
                               Standard_True, gp_Pnt2d(anU1, aV1[i]),
                               gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l,
                               aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l,
                               aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(),
-                              i, theTol3D, theTol2D, Standard_False))
+                              i, aTol3D, aTol2D, Standard_False))
             {
               isAdded = Standard_True;
             }
           }
 
-          if(!isAdded)
+          if (!isAdded)
           {
             //Before breaking WL, we must complete it correctly
             //(e.g. to prolong to the surface boundary).
@@ -3201,16 +3207,16 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
             //(have maximal U1-parameter) and try to add it in
             //the current WL.
             Standard_Real anUmaxAdded = RealFirst();
-            
+
             {
               Standard_Boolean isChanged = Standard_False;
-              for(Standard_Integer i = 0; i < aNbWLines; i++)
+              for (Standard_Integer i = 0; i < aNbWLines; i++)
               {
-                if(aWLFindStatus[i] == WLFStatus_Absent)
+                if (aWLFindStatus[i] == WLFStatus_Absent)
                   continue;
 
                 Standard_Real aU1c = 0.0, aV1c = 0.0;
-                if(isTheReverse)
+                if (isReversed)
                   aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS2(aU1c, aV1c);
                 else
                   aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS1(aU1c, aV1c);
@@ -3219,29 +3225,29 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
                 isChanged = Standard_True;
               }
 
-              if(!isChanged)
+              if (!isChanged)
               { //If anUmaxAdded were not changed in previous cycle then
                 //we would break existing WLines.
                 break;
               }
             }
 
-            for(Standard_Integer i = 0; i < aNbWLines; i++)
+            for (Standard_Integer i = 0; i < aNbWLines; i++)
             {
-              if(isAddingWLEnabled[i])
+              if (isAddingWLEnabled[i])
               {
                 continue;
               }
 
               ComputationMethods::CylCylComputeParameters(anUmaxAdded, i, anEquationCoeffs,
-                                                                aU2[i], aV1[i], aV2[i]);
-
-              AddPointIntoWL( theQuad1, theQuad2, anEquationCoeffs, isTheReverse,
-                              Standard_True, gp_Pnt2d(anUmaxAdded, aV1[i]),
-                              gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l,
-                              aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l,
-                              aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(),
-                              i, theTol3D, theTol2D, Standard_False);
+                aU2[i], aV1[i], aV2[i]);
+
+              AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
+                             Standard_True, gp_Pnt2d(anUmaxAdded, aV1[i]),
+                             gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l,
+                             aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l,
+                             aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(),
+                             i, aTol3D, aTol2D, Standard_False);
             }
           }
 
@@ -3257,21 +3263,21 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           //in every iteration. It allows avoiding "flying" intersection
           //points too far each from other (see issue #24915).
 
-          const Standard_Real aDeltaV1 = aRangeS1.Delta()/IntToReal(aNbPoints),
-                              aDeltaV2 = aRangeS2.Delta()/IntToReal(aNbPoints);
-        
+          const Standard_Real aDeltaV1 = aRangeS1.Delta() / IntToReal(aNbPoints),
+                              aDeltaV2 = aRangeS2.Delta() / IntToReal(aNbPoints);
+
           math_Matrix aMatr(1, 3, 1, 5);
 
           Standard_Real aMinUexp = RealLast();
-        
-          for(Standard_Integer i = 0; i < aNbWLines; i++)
+
+          for (Standard_Integer i = 0; i < aNbWLines; i++)
           {
-            if(theTol2D < (anUexpect[i] - anU1))
+            if (aTol2D < (anUexpect[i] - anU1))
             {
               continue;
             }
 
-            if(aWLFindStatus[i] == WLFStatus_Absent)
+            if (aWLFindStatus[i] == WLFStatus_Absent)
             {
               anUexpect[i] += aStepMax;
               aMinUexp = Min(aMinUexp, anUexpect[i]);
@@ -3309,7 +3315,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
             //The solution is approximate. More over, all requirements to the
             //linearization must be satisfied in order to obtain quality result.
 
-            if(!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp))
+            if (!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp))
             {
               //To avoid cycling-up
               anUexpect[i] += aStepMax;
@@ -3318,10 +3324,10 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
               continue;
             }
 
-            if(aStepTmp < aStepMin)
+            if (aStepTmp < aStepMin)
               aStepTmp = aStepMin;
-      
-            if(aStepTmp > aStepMax)
+
+            if (aStepTmp > aStepMax)
               aStepTmp = aStepMax;
 
             anUexpect[i] = anU1 + aStepTmp;
@@ -3331,26 +3337,26 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           anU1 = aMinUexp;
         }
 
-        if(Precision::PConfusion() >= (anUl - anU1))
+        if (Precision::PConfusion() >= (anUl - anU1))
           anU1 = anUl;
 
         anUf = anU1;
 
-        for(Standard_Integer i = 0; i < aNbWLines; i++)
+        for (Standard_Integer i = 0; i < aNbWLines; i++)
         {
-          if(aWLine[i]->NbPnts() != 1)
+          if (aWLine[i]->NbPnts() != 1)
             isAddedIntoWL[i] = Standard_False;
 
-          if(anU1 == anUl)
+          if (anU1 == anUl)
           {//strictly equal. Tolerance is considered above.
             anUexpect[i] = anUl;
           }
         }
       }
 
-      for(Standard_Integer i = 0; i < aNbWLines; i++)
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
       {
-        if((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i]))
+        if ((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i]))
         {
           isTheEmpty = Standard_False;
           Standard_Real u1, v1, u2, v2;
@@ -3358,34 +3364,34 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
           IntPatch_Point aP;
           aP.SetParameter(u1);
           aP.SetParameters(u1, v1, u2, v2);
-          aP.SetTolerance(theTol3D);
+          aP.SetTolerance(aTol3D);
           aP.SetValue(aWLine[i]->Point(1).Value());
 
           theSPnt.Append(aP);
         }
-        else if(aWLine[i]->NbPnts() > 1)
+        else if (aWLine[i]->NbPnts() > 1)
         {
           Standard_Boolean isGood = Standard_True;
 
-          if(aWLine[i]->NbPnts() == 2)
+          if (aWLine[i]->NbPnts() == 2)
           {
             const IntSurf_PntOn2S& aPf = aWLine[i]->Point(1);
             const IntSurf_PntOn2S& aPl = aWLine[i]->Point(2);
-            
-            if(aPf.IsSame(aPl, Precision::Confusion()))
+
+            if (aPf.IsSame(aPl, Precision::Confusion()))
               isGood = Standard_False;
           }
 
-          if(isGood)
+          if (isGood)
           {
             isTheEmpty = Standard_False;
             isAddedIntoWL[i] = Standard_True;
-            SeekAdditionalPoints( theQuad1, theQuad2, aWLine[i]->Curve(), 
-                                  anEquationCoeffs, i, aNbPoints, 1,
-                                  aWLine[i]->NbPnts(), theTol2D, aPeriod,
-                                  isTheReverse);
+            SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(),
+                                 anEquationCoeffs, i, aNbPoints, 1,
+              aWLine[i]->NbPnts(), aTol2D, aPeriod,
+              isReversed);
 
-            aWLine[i]->ComputeVertexParameters(theTol3D);
+            aWLine[i]->ComputeVertexParameters(aTol3D);
             theSlin.Append(aWLine[i]);
           }
         }
@@ -3404,19 +3410,19 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
   //Delete the points in theSPnt, which
   //lie at least in one of the line in theSlin.
-  for(Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
+  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
   {
-    for(Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++)
+    for (Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++)
     {
-      Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::
-                                            DownCast(theSlin.Value(aNbLin)));
+      Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine)::
+        DownCast(theSlin.Value(aNbLin)));
 
       const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
       const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aWLine1->NbPnts());
 
       const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNbPnt).PntOn2S();
-      if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) ||
-          aPntCur.IsSame(aPntLWL1, Precision::Confusion()))
+      if (aPntCur.IsSame(aPntFWL1, Precision::Confusion()) ||
+        aPntCur.IsSame(aPntLWL1, Precision::Confusion()))
       {
         theSPnt.Remove(aNbPnt);
         aNbPnt--;
@@ -3425,10 +3431,20 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
     }
   }
 
-  const Standard_Real aDU = aStepMin + Epsilon(aStepMin);
-  //Try to add new points in the neighbourhood of existing point
-  for(Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
+  //Try to add new points in the neighborhood of existing point
+  for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++)
   {
+    // Standard algorithm (implemented above) could not find any
+    // continuous curve in neighborhood of aPnt2S (e.g. because
+    // this curve is too small; see tests\bugs\modalg_5\bug25292_35 and _36).
+    // Here, we will try to find several new points nearer to aPnt2S.
+
+    // The algorithm below tries to find two points in every
+    // intervals [u1 - aStepMax, u1] and [u1, u1 + aStepMax]
+    // and every new point will be in maximal distance from
+    // u1. If these two points exist they will be joined
+    // by the intersection curve.
+
     const IntPatch_Point& aPnt2S = theSPnt.Value(aNbPnt);
 
     Standard_Real u1, v1, u2, v2;
@@ -3436,82 +3452,332 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
 
     Handle(IntSurf_LineOn2S) aL2S = new IntSurf_LineOn2S();
     Handle(IntPatch_WLine) aWLine = new IntPatch_WLine(aL2S, Standard_False);
-    aWLine->Curve()->Add(aPnt2S.PntOn2S());
 
     //Define the index of WLine, which lies the point aPnt2S in.
-    Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0;
     Standard_Integer anIndex = 0;
-    if(isTheReverse)
+
+    Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0;
+    if (isReversed)
     {
       anUf = Max(u2 - aStepMax, aUSurf1f);
-      anUl = u2;
+      anUl = Min(u2 + aStepMax, aUSurf1l);
       aCurU2 = u1;
     }
     else
     {
       anUf = Max(u1 - aStepMax, aUSurf1f);
-      anUl = u1;
+      anUl = Min(u1 + aStepMax, aUSurf1l);
       aCurU2 = u2;
     }
-    Standard_Real aDelta = RealLast();
-    for (Standard_Integer i = 0; i < aNbWLines; i++)
-    {
-      Standard_Real anU2t = 0.0;
-      if(!ComputationMethods::CylCylComputeParameters(anUl, i, anEquationCoeffs, anU2t))
-        continue;
 
-      const Standard_Real aDU2 = Abs(anU2t - aCurU2);
-      if(aDU2 < aDelta)
+    const Standard_Real anUinf = anUf, anUsup = anUl, anUmid = 0.5*(anUf + anUl);
+
+    {
+      //Find the value of anIndex variable.
+      Standard_Real aDelta = RealLast();
+      for (Standard_Integer i = 0; i < aNbWLines; i++)
       {
-        aDelta = aDU2; 
-        anIndex = i;
+        Standard_Real anU2t = 0.0;
+        if (!ComputationMethods::CylCylComputeParameters(anUmid, i, anEquationCoeffs, anU2t))
+          continue;
+
+        Standard_Real aDU2 = fmod(Abs(anU2t - aCurU2), aPeriod);
+        aDU2 = Min(aDU2, Abs(aDU2 - aPeriod));
+        if (aDU2 < aDelta)
+        {
+          aDelta = aDU2;
+          anIndex = i;
+        }
       }
     }
 
-    //Try to fill aWLine by additional points
-    while(anUl - anUf > RealSmall())
-    {
-      Standard_Real anU2 = 0.0, anV1 = 0.0, anV2 = 0.0;
-      Standard_Boolean isDone = 
-            ComputationMethods::CylCylComputeParameters(anUf, anIndex, anEquationCoeffs,
-                                    anU2, anV1, anV2);
-      anUf += aDU;
+    // Bisection method is used in order to find every new point.
+    // I.e. if we need to find intersection point in the interval [anUinf, anUmid]
+    // we check the point anUC = 0.5*(anUinf+anUmid). If it is an intersection point
+    // we try to find another point in the interval [anUinf, anUC] (because we find the point in
+    // maximal distance from anUmid). If it is not then we try to find another point in the
+    // interval [anUC, anUmid]. Next iterations will be made analogically.
+    // When we find intersection point in the interval [anUmid, anUsup] we try to find
+    // another point in the interval [anUC, anUsup] if anUC is intersection point and
+    // in the interval [anUmid, anUC], otherwise.
+
+    Standard_Real anAddedPar[2] = { anUmid, anUmid };
 
-      if(!isDone)
+    for (Standard_Integer aParID = 0; aParID < 2; aParID++)
+    {
+      if (aParID == 0)
       {
-        continue;
+        anUf = anUinf;
+        anUl = anUmid;
+      }
+      else // if(aParID == 1)
+      {
+        anUf = anUmid;
+        anUl = anUsup;
       }
 
-      if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse,
-                        Standard_True, gp_Pnt2d(anUf, anV1), gp_Pnt2d(anU2, anV2),
-                        aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
-                        aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l,
-                        aPeriod, aWLine->Curve(), anIndex, theTol3D,
-                        theTol2D, Standard_False, Standard_True))
+      Standard_Real &aPar1 = (aParID == 0) ? anUf : anUl,
+                    &aPar2 = (aParID == 0) ? anUl : anUf;
+
+      while (Abs(aPar2 - aPar1) > aStepMin)
       {
-        break;
+        Standard_Real anUC = 0.5*(anUf + anUl);
+        Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
+        Standard_Boolean isDone = ComputationMethods::
+                CylCylComputeParameters(anUC, anIndex, anEquationCoeffs, aU2, aV1, aV2);
+
+        if (isDone)
+        {
+          if (Abs(aV1 - aVSurf1f) <= aTol2D)
+            aV1 = aVSurf1f;
+
+          if (Abs(aV1 - aVSurf1l) <= aTol2D)
+            aV1 = aVSurf1l;
+
+          if (Abs(aV2 - aVSurf2f) <= aTol2D)
+            aV2 = aVSurf2f;
+
+          if (Abs(aV2 - aVSurf2l) <= aTol2D)
+            aV2 = aVSurf2l;
+
+          isDone = AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed,
+                                  Standard_True, gp_Pnt2d(anUC, aV1), gp_Pnt2d(aU2, aV2),
+                                  aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
+                                  aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l,
+                                  aPeriod, aWLine->Curve(), anIndex, aTol3D,
+                                  aTol2D, Standard_False, Standard_True);
+        }
+
+        if (isDone)
+        {
+          anAddedPar[0] = Min(anAddedPar[0], anUC);
+          anAddedPar[1] = Max(anAddedPar[1], anUC);
+          aPar2 = anUC;
+        }
+        else
+        {
+          aPar1 = anUC;
+        }
       }
     }
 
-    if(aWLine->NbPnts() > 1)
+    //Fill aWLine by additional points
+    if (anAddedPar[1] - anAddedPar[0] > aStepMin)
     {
-      SeekAdditionalPoints( theQuad1, theQuad2, aWLine->Curve(), 
+      for (Standard_Integer aParID = 0; aParID < 2; aParID++)
+      {
+        Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
+        ComputationMethods::CylCylComputeParameters(anAddedPar[aParID], anIndex,
+                                                  anEquationCoeffs, aU2, aV1, aV2);
+
+        AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True,
+                        gp_Pnt2d(anAddedPar[aParID], aV1), gp_Pnt2d(aU2, aV2),
+                        aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
+                        aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod, aWLine->Curve(),
+                        anIndex, aTol3D, aTol2D, Standard_False, Standard_False);
+      }
+
+      SeekAdditionalPoints(aQuad1, aQuad2, aWLine->Curve(),
                             anEquationCoeffs, anIndex, aNbMinPoints,
-                            1, aWLine->NbPnts(), theTol2D, aPeriod,
-                            isTheReverse);
+                            1, aWLine->NbPnts(), aTol2D, aPeriod,
+                            isReversed);
 
-      aWLine->ComputeVertexParameters(theTol3D);
+      aWLine->ComputeVertexParameters(aTol3D);
       theSlin.Append(aWLine);
-  
+
       theSPnt.Remove(aNbPnt);
       aNbPnt--;
     }
   }
-  
+
   return IntPatch_ImpImpIntersection::IntStatus_OK;
 }
 
 //=======================================================================
+//function : IntCyCy
+//purpose  : 
+//=======================================================================
+IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
+                                               const IntSurf_Quadric& theQuad2,
+                                               const Standard_Real theTol3D,
+                                               const Standard_Real theTol2D,
+                                               const Bnd_Box2d& theUVSurf1,
+                                               const Bnd_Box2d& theUVSurf2,
+                                               Standard_Boolean& isTheEmpty,
+                                               Standard_Boolean& isTheSameSurface,
+                                               Standard_Boolean& isTheMultiplePoint,
+                                               IntPatch_SequenceOfLine& theSlin,
+                                               IntPatch_SequenceOfPoint& theSPnt)
+{
+  isTheEmpty = Standard_True;
+  isTheSameSurface = Standard_False;
+  isTheMultiplePoint = Standard_False;
+  theSlin.Clear();
+  theSPnt.Clear();
+
+  const gp_Cylinder aCyl1 = theQuad1.Cylinder(),
+                    aCyl2 = theQuad2.Cylinder();
+
+  IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D);
+
+  if (!anInter.IsDone())
+  {
+    return IntPatch_ImpImpIntersection::IntStatus_Fail;
+  }
+
+  if(anInter.TypeInter() != IntAna_NoGeometricSolution)
+  {
+    if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter,
+                                theTol3D, isTheEmpty,
+                                isTheSameSurface, isTheMultiplePoint,
+                                theSlin, theSPnt))
+    {
+      return IntPatch_ImpImpIntersection::IntStatus_OK;
+    }
+  }
+  
+  //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.)
+
+  Standard_Real aUSBou[2][2], aVSBou[2][2]; //const
+
+  theUVSurf1.Get(aUSBou[0][0], aVSBou[0][0], aUSBou[0][1], aVSBou[0][1]);
+  theUVSurf2.Get(aUSBou[1][0], aVSBou[1][0], aUSBou[1][1], aVSBou[1][1]);
+
+  const Standard_Real aPeriod = 2.0*M_PI;
+  const Standard_Integer aNbWLines = 2;
+
+  const ComputationMethods::stCoeffsValue anEquationCoeffs1(aCyl1, aCyl2);
+  const ComputationMethods::stCoeffsValue anEquationCoeffs2(aCyl2, aCyl1);
+
+  //Boundaries. 
+  //Intersection result can include two non-connected regions
+  //(see WorkWithBoundaries::BoundariesComputing(...) method).
+  const Standard_Integer aNbOfBoundaries = 2;
+  Bnd_Range anURange[2][aNbOfBoundaries];   //const
+
+  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs1, aPeriod, anURange[0]))
+    return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+  if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs2, aPeriod, anURange[1]))
+    return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+  //anURange[*] can be in different periodic regions in
+  //compare with First-Last surface. E.g. the surface
+  //is full cylinder [0, 2*PI] but anURange is [5, 7].
+  //Trivial common range computation returns [5, 2*PI] and
+  //its summary length is 2*PI-5 == 1.28... only. That is wrong.
+  //This problem can be solved by the following
+  //algorithm:
+  // 1. split anURange[*] by the surface boundary;
+  // 2. shift every new range in order to inscribe it
+  //      in [Ufirst, Ulast] of cylinder;
+  // 3. consider only common ranges between [Ufirst, Ulast]
+  //    and new ranges.
+  //
+  // In above example, we obtain following:
+  // 1. two ranges: [5, 2*PI] and [2*PI, 7];
+  // 2. after shifting: [5, 2*PI] and [0, 7-2*PI];
+  // 3. Common ranges: ([5, 2*PI] and [0, 2*PI]) == [5, 2*PI],
+  //                   ([0, 7-2*PI] and [0, 2*PI]) == [0, 7-2*PI];
+  // 4. Their summary length is (2*PI-5)+(7-2*PI-0)==7-5==2 ==> GOOD.
+
+  Standard_Real aSumRange[2] = { 0.0, 0.0 };
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  for (Standard_Integer aCID = 0; aCID < 2; aCID++)
+  {
+    anAlloc->Reset();
+    NCollection_List<Bnd_Range> aListOfRng(anAlloc);
+    
+    aListOfRng.Append(anURange[aCID][0]);
+    aListOfRng.Append(anURange[aCID][1]);
+
+    const Standard_Real aSplitArr[3] = {aUSBou[aCID][0], aUSBou[aCID][1], 0.0};
+
+    NCollection_List<Bnd_Range>::Iterator anITrRng;
+    for (Standard_Integer aSInd = 0; aSInd < 3; aSInd++)
+    {
+      NCollection_List<Bnd_Range> aLstTemp(aListOfRng);
+      aListOfRng.Clear();
+      for (anITrRng.Init(aLstTemp); anITrRng.More(); anITrRng.Next())
+      {
+        Bnd_Range& aRng = anITrRng.Value();
+        aRng.Split(aSplitArr[aSInd], aListOfRng, aPeriod);
+      }
+    }
+
+    anITrRng.Init(aListOfRng);
+    for (; anITrRng.More(); anITrRng.Next())
+    {
+      Bnd_Range& aCurrRange = anITrRng.Value();
+
+      Bnd_Range aBoundR;
+      aBoundR.Add(aUSBou[aCID][0]);
+      aBoundR.Add(aUSBou[aCID][1]);
+
+      if (!InscribeInterval(aUSBou[aCID][0], aUSBou[aCID][1],
+                                          aCurrRange, theTol2D, aPeriod))
+      {
+        //If aCurrRange does not have common block with
+        //[Ufirst, Ulast] of cylinder then we will try
+        //to inscribe [Ufirst, Ulast] in the boundaries of aCurrRange.
+        Standard_Real aF = 1.0, aL = 0.0;
+        if (!aCurrRange.GetBounds(aF, aL))
+          continue;
+
+        if ((aL < aUSBou[aCID][0]))
+        {
+          aCurrRange.Shift(aPeriod);
+        }
+        else if (aF > aUSBou[aCID][1])
+        {
+          aCurrRange.Shift(-aPeriod);
+        }
+      }
+
+      aBoundR.Common(aCurrRange);
+
+      const Standard_Real aDelta = aBoundR.Delta();
+
+      if (aDelta > 0.0)
+      {
+        aSumRange[aCID] += aDelta;
+      }
+    }
+  }
+
+  //The bigger range the bigger number of points in Walking-line (WLine)
+  //we will be able to add and consequently we will obtain more
+  //precise intersection line.
+  //Every point of WLine is determined as function from U1-parameter,
+  //where U1 is U-parameter on 1st quadric.
+  //Therefore, we should use quadric with bigger range as 1st parameter
+  //in IntCyCy() function.
+  //On the other hand, there is no point in reversing in case of
+  //analytical intersection (when result is line, ellipse, point...).
+  //This result is independent of the arguments order.
+  const Standard_Boolean isToReverse = (aSumRange[1] > aSumRange[0]);
+
+  if (isToReverse)
+  {
+    const WorkWithBoundaries aBoundWork(theQuad2, theQuad1, anEquationCoeffs2,
+                                        theUVSurf2, theUVSurf1, aNbWLines,
+                                        aPeriod, theTol3D, theTol2D, Standard_True);
+
+    return CyCyNoGeometric(aCyl2, aCyl1, aBoundWork, anURange[1], aNbOfBoundaries,
+                              isTheEmpty, theSlin, theSPnt);
+  }
+  else
+  {
+    const WorkWithBoundaries aBoundWork(theQuad1, theQuad2, anEquationCoeffs1,
+                                        theUVSurf1, theUVSurf2, aNbWLines,
+                                        aPeriod, theTol3D, theTol2D, Standard_False);
+
+    return CyCyNoGeometric(aCyl1, aCyl2, aBoundWork, anURange[0], aNbOfBoundaries,
+                              isTheEmpty, theSlin, theSPnt);
+  }
+}
+
+//=======================================================================
 //function : IntCySp
 //purpose  : 
 //=======================================================================
index 6213b35..d1c3173 100644 (file)
@@ -1405,19 +1405,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
 
   if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
   {
-    IntPatch_WLineTool::JoinWLines( slin, spnt, TolTang,
-                                    theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
-                                    theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
-                                    theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
-                                    theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
-                                    theS1->FirstUParameter(),
-                                    theS1->LastUParameter(),
-                                    theS1->FirstVParameter(),
-                                    theS1->LastVParameter(),
-                                    theS2->FirstUParameter(),
-                                    theS2->LastUParameter(),
-                                    theS2->FirstVParameter(),
-                                    theS2->LastVParameter());
+    IntPatch_WLineTool::JoinWLines(slin, spnt, theS1, theS2, TolTang);
   }
 
   if(isWLExist)
index 5ac700a..78148f6 100644 (file)
 
 #include <Adaptor3d_HSurface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
+#include <Bnd_Range.hxx>
 #include <ElCLib.hxx>
 #include <ElSLib.hxx>
 #include <IntPatch_SpecialPoints.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <TopAbs_State.hxx>
 
 // It is pure empirical value.
 const Standard_Real IntPatch_WLineTool::myMaxConcatAngle = M_PI/6;
@@ -484,64 +487,6 @@ static Handle(IntPatch_WLine)
 }
 
 //=======================================================================
-//function : IsOnPeriod
-//purpose  : Checks, if [theU1, theU2] intersects the period-value
-//            (k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...).
-//
-//           Returns:
-//            0 - if interval [theU1, theU2] does not intersect the "period-value"
-//                or if thePeriod == 0.0;
-//            1 - if interval (theU1, theU2) intersect the "period-value".
-//            2 - if theU1 or/and theU2 lie ON the "period-value"
-//
-//ATTENTION!!!
-//  If (theU1 == theU2) then this function will return only both 0 or 2.
-//=======================================================================
-static Standard_Integer IsOnPeriod(const Standard_Real theU1,
-                                   const Standard_Real theU2,
-                                   const Standard_Real thePeriod)
-{
-  if(thePeriod < RealSmall())
-    return 0;
-
-  //If interval [theU1, theU2] intersect seam-edge then there exists an integer
-  //number N such as 
-  //    (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T),
-  //where T is the period.
-  //I.e. the inerval [theU1/T, theU2/T] must contain at least one
-  //integer number. In this case, Floor(theU1/T) and Floor(theU2/T)
-  //return different values or theU1/T is strictly integer number.
-  //Examples:
-  //  1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3.
-  //  2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2.
-
-  const Standard_Real aVal1 = theU1/thePeriod,
-                      aVal2 = theU2/thePeriod;
-  const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
-  const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
-  if(aPar1 != aPar2)
-  {//Interval (theU1, theU2] intersects seam-edge
-    if(IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
-    {//aVal2 is an integer number => theU2 lies ON the "seam-edge"
-      return 2;
-    }
-
-    return 1;
-  }
-
-  //Here, aPar1 == aPar2. 
-
-  if(IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
-  {//aVal1 is an integer number => theU1 lies ON the "seam-edge"
-    return 2;
-  }
-
-  //If aVal2 is a true integer number then always (aPar1 != aPar2).
-
-  return 0;
-}
-
-//=======================================================================
 //function : IsSeamOrBound
 //purpose  : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge"
 //            (if it exist) or surface boundaries and both thePtf and thePtl do
@@ -550,128 +495,89 @@ static Standard_Integer IsOnPeriod(const Standard_Real theU1,
 //           If thePtmid match "seam-edge" or boundaries strictly 
 //            (without any tolerance) then the function will return TRUE.
 //            See comments in function body for detail information.
+//
+//          Arrays theArrPeriods, theFBound and theLBound must be filled
+//            as follows:
+//          [0] - U-parameter of 1st surface;
+//          [1] - V-parameter of 1st surface;
+//          [2] - U-parameter of 2nd surface;
+//          [3] - V-parameter of 2nd surface.
 //=======================================================================
 static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
                                       const IntSurf_PntOn2S& thePtl,
                                       const IntSurf_PntOn2S& thePtmid,
-                                      const Standard_Real theU1Period,
-                                      const Standard_Real theU2Period,
-                                      const Standard_Real theV1Period,
-                                      const Standard_Real theV2Period,
-                                      const Standard_Real theUfSurf1,
-                                      const Standard_Real theUlSurf1,
-                                      const Standard_Real theVfSurf1,
-                                      const Standard_Real theVlSurf1,
-                                      const Standard_Real theUfSurf2,
-                                      const Standard_Real theUlSurf2,
-                                      const Standard_Real theVfSurf2,
-                                      const Standard_Real theVlSurf2)
+                                      const Standard_Real theArrPeriods[4],
+                                      const Standard_Real theFBound[4],
+                                      const Standard_Real theLBound[4])
 {
-  Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-  Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-  thePtf.Parameters(aU11, aV11, aU12, aV12);
-  thePtl.Parameters(aU21, aV21, aU22, aV22);
-
-  MinMax(aU11, aU21);
-  MinMax(aV11, aV21);
-  MinMax(aU12, aU22);
-  MinMax(aV12, aV22);
-
-  if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0)
-  {//Interval [aU11, aU21] intersects theUfSurf1
-    return Standard_True;
-  }
+  Standard_Real aParF[4] = { 0.0, 0.0, 0.0, 0.0 };
+  Standard_Real aParL[4] = { 0.0, 0.0, 0.0, 0.0 };
+  thePtf.Parameters(aParF[0], aParF[1], aParF[2], aParF[3]);
+  thePtl.Parameters(aParL[0], aParL[1], aParL[2], aParL[3]);
 
-  if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0)
-  {//Interval [aU11, aU21] intersects theUlSurf1
-    return Standard_True;
-  }
+  Bnd_Range aBndR[4];
 
-  if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0)
-  {//Interval [aV11, aV21] intersects theVfSurf1
-    return Standard_True;
-  }
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    aBndR[i].Add(aParF[i]);
+    aBndR[i].Add(aParL[i]);
 
-  if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0)
-  {//Interval [aV11, aV21] intersects theVlSurf1
-    return Standard_True;
-  }
+    if (aBndR[i].IsIntersected(theFBound[i], theArrPeriods[i]) == 1)
+      return Standard_True;
 
-  if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0)
-  {//Interval [aU12, aU22] intersects theUfSurf2
-    return Standard_True;
+    if (aBndR[i].IsIntersected(theLBound[i], theArrPeriods[i]) == 1)
+      return Standard_True;
   }
 
-  if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0)
-  {//Interval [aU12, aU22] intersects theUlSurf2
-    return Standard_True;
-  }
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    if (theArrPeriods[i] == 0.0)
+    {
+      //Strictly equal
+      continue;
+    }
 
-  if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0)
-  {//Interval [aV12, aV22] intersects theVfSurf2
-    return Standard_True;
-  }
+    const Standard_Real aDelta = Abs(aParL[i] - aParF[i]);
+    if (2.0*aDelta > theArrPeriods[i])
+    {
+      //Most likely, seam is intersected.
+      return Standard_True;
+    }
 
-  if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0)
-  {//Interval [aV12, aV22] intersects theVlSurf2
-    return Standard_True;
+    if (aBndR[i].IsIntersected(0.0, theArrPeriods[i]) == 1)
+      return Standard_True;
   }
 
-  if(IsOnPeriod(aU11, aU21, theU1Period))
-    return Standard_True;
-
-  if(IsOnPeriod(aV11, aV21, theV1Period))
-    return Standard_True;
-
-  if(IsOnPeriod(aU12, aU22, theU2Period))
-    return Standard_True;
+  //The segment [thePtf, thePtl] does not intersect the boundaries and
+  //the seam-edge of the surfaces.
+  //Nevertheless, following situation is possible:
 
-  if(IsOnPeriod(aV12, aV22, theV2Period))
-    return Standard_True;
+  //              seam or
+  //               bound
+  //                 |
+  //    thePtf  *    |
+  //                 |
+  //                 * thePtmid
+  //      thePtl  *  |
+  //                 |
 
-  /*
-    The segment [thePtf, thePtl] does not intersect the boundaries and
-    the seam-edge of the surfaces.
-    Nevertheless, following situation is possible:
+  //This case must be processed, too.
 
-                  seam or
-                   bound
-                     |
-        thePtf  *    |
-                     |
-                     * thePtmid
-          thePtl  *  |
-                     |
+  Standard_Real aMPar[4] = { 0.0, 0.0, 0.0, 0.0 };
+  thePtmid.Parameters(aMPar[0], aMPar[1], aMPar[2], aMPar[3]);
 
-    This case must be processed, too.
-  */
-
-  Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
-  thePtmid.Parameters(aU1, aV1, aU2, aV2);
-
-  if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1))
-    return Standard_True;
-
-  if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2))
-    return Standard_True;
-
-  if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1))
-    return Standard_True;
-
-  if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2))
-    return Standard_True;
-
-  if(IsOnPeriod(aU1, aU1, theU1Period))
-    return Standard_True;
-
-  if(IsOnPeriod(aU2, aU2, theU2Period))
-    return Standard_True;
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    const Bnd_Range aBR(aMPar[i], aMPar[i]);
+    if (aBR.IsIntersected(theFBound[i], theArrPeriods[i]))
+      return Standard_True;
 
-  if(IsOnPeriod(aV1, aV1, theV1Period))
-    return Standard_True;
+    if (aBR.IsIntersected(theLBound[i], theArrPeriods[i]))
+      return Standard_True;
 
-  if(IsOnPeriod(aV2, aV2, theV2Period))
-    return Standard_True;
+    if (aBR.IsIntersected(0.0, theArrPeriods[i]))
+      return Standard_True;
+  }
 
   return Standard_False;
 }
@@ -919,59 +825,75 @@ static IntPatchWT_WLsConnectionType
   thePtWL2.Parameters(aParWL2[0], aParWL2[1], aParWL2[2], aParWL2[3]);
   theNewPoint.Parameters(aNewPar[0], aNewPar[1], aNewPar[2], aNewPar[3]);
 
+  Bnd_Range aR1, aR2;
+
   Standard_Boolean isOnBoundary = Standard_False;
   for(Standard_Integer i = 0; i < 4; i++)
   {
-    if(IsOnPeriod(aParWL1[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[i]))
+    if (theArrPeriods[i] == 0.0)
+    {
+      //Strictly equal
+      continue;
+    }
+
+    aR1.SetVoid();
+    aR1.Add(aParWL1[i]);
+    aR1.Add(aParWL2[i]);
+
+    if (aR1.IsIntersected(aParLBC[i],theArrPeriods[i]))
     {
       //Check, if we intersect surface boundary when we will extend Wline1 or Wline2
       //to theNewPoint
       MinMax(aParWL1[i], aParWL2[i]);
-      if(theArrPeriods[i] > 0.0)
+      if(aNewPar[i] > aParWL2[i])
       {
-        if(aNewPar[i] > aParWL2[i])
-        {
-          //Source situation:
-          //
-          //---*---------------*------------*-----
-          // aParWL1[i]   aParWL2[i]    aNewPar[i]
-          //
-          //After possible adjusting:
-          //
-          //---*---------------*------------*-----
-          // aParWL1[i]   aNewPar[i]    aParWL2[i]
-          //
-          //Now we will be able to extend every WLine to
-          //aNewPar[i] to make them close to each other.
-          //However, it is necessary to add check if we
-          //intersect boundary.
-          const Standard_Real aPar = aParWL1[i] +
+        //Source situation:
+        //
+        //---*---------------*------------*-----
+        // aParWL1[i]   aParWL2[i]    aNewPar[i]
+        //
+        //After possible adjusting:
+        //
+        //---*---------------*------------*-----
+        // aParWL1[i]   aNewPar[i]    aParWL2[i]
+        //
+        //Now we will be able to extend every WLine to
+        //aNewPar[i] to make them close to each other.
+        //However, it is necessary to add check if we
+        //intersect boundary.
+        const Standard_Real aPar = aParWL1[i] +
                 theArrPeriods[i]*Ceiling((aNewPar[i]-aParWL1[i])/theArrPeriods[i]);
-          aParWL1[i] = aParWL2[i];
-          aParWL2[i] = aPar;
-        }
-        else if(aNewPar[i] < aParWL1[i])
-        {
-          //See comments to main "if".
-          //Source situation:
-          //
-          //---*---------------*------------*-----
-          // aNewPar[i]    aParWL1[i]   aParWL2[i]    
-          //
-          //After possible adjusting:
-          //
-          //---*---------------*------------*-----
-          // aParWL1[i]   aNewPar[i]    aParWL2[i]
+        aParWL1[i] = aParWL2[i];
+        aParWL2[i] = aPar;
+      }
+      else if(aNewPar[i] < aParWL1[i])
+      {
+        //See comments to main "if".
+        //Source situation:
+        //
+        //---*---------------*------------*-----
+        // aNewPar[i]    aParWL1[i]   aParWL2[i]    
+        //
+        //After possible adjusting:
+        //
+        //---*---------------*------------*-----
+        // aParWL1[i]   aNewPar[i]    aParWL2[i]
           
-          const Standard_Real aPar = aParWL2[i] - 
+        const Standard_Real aPar = aParWL2[i] - 
                 theArrPeriods[i]*Ceiling((aParWL2[i]-aNewPar[i])/theArrPeriods[i]);
-          aParWL2[i] = aParWL1[i];
-          aParWL1[i] = aPar;
-        }
+        aParWL2[i] = aParWL1[i];
+        aParWL1[i] = aPar;
       }
 
-      if( IsOnPeriod(aParWL1[i] - aParLBC[i], aNewPar[i] - aParLBC[i], theArrPeriods[i]) ||
-          IsOnPeriod(aNewPar[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[i]))
+      aR1.SetVoid();
+      aR2.SetVoid();
+      aR1.Add(aParWL1[i]);
+      aR1.Add(aNewPar[i]);
+      aR2.Add(aNewPar[i]);
+      aR2.Add(aParWL2[i]);
+
+      if (aR1.IsIntersected(aParLBC[i], theArrPeriods[i]) ||
+          aR2.IsIntersected(aParLBC[i], theArrPeriods[i]))
       {
         return IntPatchWT_NotConnected;
       }
@@ -995,13 +917,15 @@ static IntPatchWT_WLsConnectionType
 //purpose  : Check if joining is possible
 //            (see IntPatch_WLineTool::JoinWLines(...))
 //=======================================================================
-Standard_Boolean CheckArgumentsToJoin(const gp_Vec& theVec1,
-                                      const gp_Vec& theVec2)
+Standard_Boolean CheckArgumentsToJoin(const Handle(Adaptor3d_HSurface)& theS1,
+                                      const Handle(Adaptor3d_HSurface)& theS2,
+                                      const IntSurf_PntOn2S& thePnt,
+                                      const Standard_Real theMinRad)
 {
-  // [0, PI] - range
-  const Standard_Real anAngle = theVec1.Angle(theVec2);
+  const Standard_Real aRad = 
+        IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt);
 
-  return (anAngle < IntPatch_WLineTool::myMaxConcatAngle);
+  return (aRad > theMinRad);
 }
 
 //=======================================================================
@@ -1415,33 +1339,38 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
   return aResult;
 }
 
-
 //=======================================================================
 //function : JoinWLines
 //purpose  :
 //=======================================================================
 void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
                                     IntPatch_SequenceOfPoint& theSPnt,
-                                    const Standard_Real theTol3D,
-                                    const Standard_Real theU1Period,
-                                    const Standard_Real theU2Period,
-                                    const Standard_Real theV1Period,
-                                    const Standard_Real theV2Period,
-                                    const Standard_Real theUfSurf1,
-                                    const Standard_Real theUlSurf1,
-                                    const Standard_Real theVfSurf1,
-                                    const Standard_Real theVlSurf1,
-                                    const Standard_Real theUfSurf2,
-                                    const Standard_Real theUlSurf2,
-                                    const Standard_Real theVfSurf2,
-                                    const Standard_Real theVlSurf2)
+                                    Handle(Adaptor3d_HSurface) theS1,
+                                    Handle(Adaptor3d_HSurface) theS2,
+                                    const Standard_Real theTol3D)
 {
   if(theSlin.Length() == 0)
     return;
 
-  for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
+  // For two cylindrical surfaces only
+  const Standard_Real aMinRad = 1.0e-3*Min(theS1->Cylinder().Radius(),
+                                              theS2->Cylinder().Radius());
+
+  const Standard_Real anArrPeriods[4] = {theS1->IsUPeriodic() ? theS1->UPeriod() : 0.0,
+                                         theS1->IsVPeriodic() ? theS1->VPeriod() : 0.0,
+                                         theS2->IsUPeriodic() ? theS2->UPeriod() : 0.0,
+                                         theS2->IsVPeriodic() ? theS2->VPeriod() : 0.0};
+
+  const Standard_Real anArrFBonds[4] = {theS1->FirstUParameter(), theS1->FirstVParameter(),
+                                        theS2->FirstUParameter(), theS2->FirstVParameter()};
+  const Standard_Real anArrLBonds[4] = {theS1->LastUParameter(), theS1->LastVParameter(),
+                                        theS2->LastUParameter(), theS2->LastVParameter()};
+
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator();
+
+  for(Standard_Integer aN1 = 1; aN1 <= theSlin.Length(); aN1++)
   {
-    Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1)));
+    Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine)::DownCast(theSlin.Value(aN1)));
 
     if(aWLine1.IsNull())
     {//We must have failed to join not-point-lines
@@ -1449,184 +1378,169 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
     }
 
     const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
-    const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1);
-    const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1);
+    const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
+    const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
 
     for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
     {
       const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
 
-      if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) ||
-        aPntCur.IsSame(aPntLW1, Precision::Confusion()))
+      if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) ||
+        aPntCur.IsSame(aPntLWL1, Precision::Confusion()))
       {
         theSPnt.Remove(aNPt);
         aNPt--;
       }
     }
 
-    Standard_Boolean hasBeenRemoved = Standard_False;
-    for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
+    anAlloc->Reset();
+    NCollection_List<Standard_Integer> aListFC(anAlloc),
+                                       aListLC(anAlloc);
+    
+    Standard_Boolean isFirstConnected = Standard_False, isLastConnected = Standard_False;
+
+    for (Standard_Integer aN2 = 1; aN2 <= theSlin.Length(); aN2++)
     {
-      Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2)));
+      if (aN2 == aN1)
+        continue;
 
-      if(aWLine2.IsNull())
+      Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(aN2)));
+
+      if (aWLine2.IsNull())
         continue;
 
-      const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
+      isFirstConnected = isLastConnected = Standard_False;
 
-      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
+      const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
 
       const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
       const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
 
-      if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
+      Standard_Real aSqDistF = aPntFWL1.Value().SquareDistance(aPntFWL2.Value());
+      Standard_Real aSqDistL = aPntFWL1.Value().SquareDistance(aPntLWL2.Value());
+
+      const Standard_Real aSqMinFDist = Min(aSqDistF, aSqDistL);
+      if (aSqMinFDist < Precision::SquareConfusion())
       {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
-
-        Standard_Boolean aCond = 
-              CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()),
-                                   gp_Vec(aPt2.Value(), aPntFWL2.Value()));
-
-        aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1,
-                                        theU1Period, theU2Period,
-                                        theV1Period, theV2Period,
-                                        theUfSurf1, theUlSurf1,
-                                        theVfSurf1, theVlSurf1,
-                                        theUfSurf2, theUlSurf2,
-                                        theVfSurf2, theVlSurf2);
-          
-        if(aCond)
+        if (CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aMinRad))
         {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
+          const Standard_Boolean isFM = (aSqDistF < aSqDistL);
+          const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
+          const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
+                                                      aWLine2->Point(aNbPntsWL2 - 1);
+
+          if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1,
+                              anArrPeriods, anArrFBonds, anArrLBonds))
           {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
+            isFirstConnected = Standard_True;
           }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
         }
       }
 
-      if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
+      aSqDistF = aPntLWL1.Value().SquareDistance(aPntFWL2.Value());
+      aSqDistL = aPntLWL1.Value().SquareDistance(aPntLWL2.Value());
+
+      const Standard_Real aSqMinLDist = Min(aSqDistF, aSqDistL);
+      if (aSqMinLDist < Precision::SquareConfusion())
       {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
-
-        Standard_Boolean aCond = 
-              CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()),
-                                   gp_Vec(aPt2.Value(), aPntLWL2.Value()));
-
-        aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1,
-                                        theU1Period, theU2Period,
-                                        theV1Period, theV2Period,
-                                        theUfSurf1, theUlSurf1,
-                                        theVfSurf1, theVlSurf1,
-                                        theUfSurf2, theUlSurf2,
-                                        theVfSurf2, theVlSurf2);
-
-        if(aCond)
+        if (CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aMinRad))
         {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
+          const Standard_Boolean isFM = (aSqDistF < aSqDistL);
+          const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1);
+          const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) :
+                                               aWLine2->Point(aNbPntsWL2 - 1);
+
+          if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1,
+                              anArrPeriods, anArrFBonds, anArrLBonds))
           {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
+            isLastConnected = Standard_True;
           }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
         }
       }
 
-      if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
+      if (isFirstConnected && isLastConnected)
       {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
-
-        Standard_Boolean aCond = 
-              CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()),
-                                   gp_Vec(aPntFWL2.Value(), aPt2.Value()));
-
-        aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1,
-                                        theU1Period, theU2Period,
-                                        theV1Period, theV2Period,
-                                        theUfSurf1, theUlSurf1,
-                                        theVfSurf1, theVlSurf1,
-                                        theUfSurf2, theUlSurf2,
-                                        theVfSurf2, theVlSurf2);
-
-        if(aCond)
+        if (aSqMinFDist < aSqMinLDist)
         {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
+          aListFC.Append(aN2);
+        }
+        else
+        {
+          aListLC.Append(aN2);
+        }
+      }
+      else if (isFirstConnected)
+      {
+        aListFC.Append(aN2);
+      }
+      else if (isLastConnected)
+      {
+        aListLC.Append(aN2);
+      }
+    }
+
+    isFirstConnected = (aListFC.Extent() == 1);
+    isLastConnected = (aListLC.Extent() == 1);
+
+    if (!(isFirstConnected || isLastConnected))
+    {
+      continue;
+    }
 
-          aWLine1->ComputeVertexParameters(theTol3D);
+    const Standard_Integer anIndexWL2 = isFirstConnected ? aListFC.First() : aListLC.First();
+    Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(anIndexWL2)));
+    
+    const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
+    const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
 
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
+    aWLine1->ClearVertexes();
 
-          continue;
+    if (isFirstConnected)
+    {
+      if (aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
+      {
+        //First-First-connection
+        for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
+        {
+          const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
+          aWLine1->Curve()->InsertBefore(1, aPt);
         }
       }
-
-      if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
+      else
       {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
-
-        Standard_Boolean aCond = 
-              CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()),
-                                   gp_Vec(aPntLWL2.Value(), aPt2.Value()));
-
-        aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1, 
-                                        theU1Period, theU2Period,
-                                        theV1Period, theV2Period,
-                                        theUfSurf1, theUlSurf1,
-                                        theVfSurf1, theVlSurf1,
-                                        theUfSurf2, theUlSurf2,
-                                        theVfSurf2, theVlSurf2);
-
-        if(aCond)
+        //First-Last-connection
+        for (Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
         {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
+          const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
+          aWLine1->Curve()->InsertBefore(1, aPt);
+        }
+      }
+    }
+    else //if (isLastConnected)
+    {
+      if (aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
+      {
+        //Last-First connection
+        for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
+        {
+          const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
+          aWLine1->Curve()->Add(aPt);
+        }
+      }
+      else
+      {
+        //Last-Last connection
+        for (Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
+        {
+          const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
+          aWLine1->Curve()->Add(aPt);
         }
       }
     }
 
-    if(hasBeenRemoved)
-      aNumOfLine1--;
+    aWLine1->ComputeVertexParameters(theTol3D);
+    theSlin.Remove(anIndexWL2);
+    aN1--;
   }
 }
 
index 9a40853..6f72a22 100644 (file)
 #ifndef _IntPatch_WLineTool_HeaderFile
 #define _IntPatch_WLineTool_HeaderFile
 
+#include <Standard_DefineAlloc.hxx>
+
 #include <IntPatch_SequenceOfLine.hxx>
 #include <IntPatch_WLine.hxx>
-#include <Standard_Macro.hxx>
 
 class Adaptor3d_TopolTool;
 
@@ -59,20 +60,9 @@ public:
 //! this point will be deleted.
   Standard_EXPORT static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
                                          IntPatch_SequenceOfPoint& theSPnt,
-                                         const Standard_Real theTol3D,
-                                         const Standard_Real theU1Period,
-                                         const Standard_Real theU2Period,
-                                         const Standard_Real theV1Period,
-                                         const Standard_Real theV2Period,
-                                         const Standard_Real theUfSurf1,
-                                         const Standard_Real theUlSurf1,
-                                         const Standard_Real theVfSurf1,
-                                         const Standard_Real theVlSurf1,
-                                         const Standard_Real theUfSurf2,
-                                         const Standard_Real theUlSurf2,
-                                         const Standard_Real theVfSurf2,
-                                         const Standard_Real theVlSurf2);
-
+                                         Handle(Adaptor3d_HSurface) theS1,
+                                         Handle(Adaptor3d_HSurface) theS2,
+                                         const Standard_Real theTol3D);
 
 //! Extends every line from theSlin (if it is possible) to be started/finished
 //! in strictly determined point (in the place of joint of two lines).
@@ -80,7 +70,8 @@ public:
 //! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
 //! to be computed as a result of intersection. Both theS1 and theS2 
 //! must be quadrics. Other cases are not supported.
-//! theArrPeriods must be filled as follows:
+//! theArrPeriods must be filled as follows (every value must not be negative;
+//! if the surface is not periodic the period must be equal to 0.0 strictly):
 //! {<U-period of 1st surface>, <V-period of 1st surface>,
 //!               <U-period of 2nd surface>, <V-period of 2nd surface>}.
   Standard_EXPORT static void
index b7a3688..2c25dd4 100755 (executable)
@@ -25,17 +25,26 @@ checkshape r
 
 # 2. geometry
 set MaxTol 1.0e-7
+set GoodNBCurv 3
+
 set log [bopcurves b1 b2 -2d]
 
 if { ! [regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv] } {
   puts "Error: Cannot find tolerance value in output of bopcurve command"
 }
 
+if { $NbCurv != $GoodNBCurv } {
+  puts "Error: Number of curves is wrong!"  
+}
+
 if {${Toler} > ${MaxTol}} {
   puts "Error: Tolerance is too big!"
 }
 
 smallview
-donly b2 c_2
-fit
-checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
+for {set i 1} {$i <= $GoodNBCurv} {incr i} {
+  donly b2 c_$i
+  fit
+  checkview -screenshot -2d -path ${imagedir}/${test_image}_$i.png
+}
index d231020..de9171d 100644 (file)
@@ -44,38 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
-# 1
 puts ""
 
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  bounds c_$i U1 U2
+
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 v2d
index 264b1ab..61e028a 100644 (file)
@@ -44,38 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
-# 1
 puts ""
 
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  bounds c_$i U1 U2
+
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 v2d
index fe414df..efc2c83 100644 (file)
@@ -6,27 +6,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -51,62 +30,42 @@ mksurface s2 f2
 #################
 intersect res s1 s2
 #################
+
 set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
+  renamevar res res_1
+}
+
+set ic 1
+set AllowRepeate 1
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
   } else {
-    puts "Error: Curve Number is bad!"
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
-  
-  set U1 0.0
-  set U2 0.0
-  
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
+}
 
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
-  }
-  
-  xdistcs res s1 ${U1} ${U2} 10 1e-7  
-  xdistcs res s2 ${U1} ${U2} 10 1e-7
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Curve Number is good!"
 } else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-7
-      
-      incr ic
-    }
-  }
-  
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
+  puts "Error: Curve Number is bad!"
 }
index 7eaf3a7..8f791a4 100644 (file)
@@ -6,27 +6,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -56,58 +35,37 @@ set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
+  renamevar res res_1
+}
+
+set ic 1
+set AllowRepeate 1
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
   } else {
-    puts "Error: Curve Number is bad!"
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
-  
-  set U1 0.0
-  set U2 0.0
-  
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
+}
 
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
-  }
-  
-  xdistcs res s1 ${U1} ${U2} 10 1e-7
-  xdistcs res s2 ${U1} ${U2} 10 1e-7
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Curve Number is good!"
 } else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-7
-      
-      incr ic
-    }
-  }
-  
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
+  puts "Error: Curve Number is bad!"
 }
index fefe969..516f96d 100644 (file)
@@ -44,35 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
+puts ""
+
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  bounds c_$i U1 U2
+
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 smallview
index 9f59bd0..b641b0a 100644 (file)
@@ -44,35 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
+puts ""
+
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  bounds c_$i U1 U2
+
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 smallview
index ac1987c..dd0effa 100644 (file)
@@ -6,27 +6,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -56,59 +35,37 @@ set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
-  
-  set U1 0.0
-  set U2 0.0
-  
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
+  renamevar res res_1
+}
 
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
-  }
-  
-  xdistcs res s1 ${U1} ${U2} 10 1e-7
-  xdistcs res s2 ${U1} ${U2} 10 1e-7
-} else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-7
-      
-      incr ic
-    }
-  }
-  
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
+set ic 1
+set AllowRepeate 1
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
   } else {
-    puts "Error: Curve Number is bad!"
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
 }
 
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Curve Number is good!"
+} else {
+  puts "Error: Curve Number is bad!"
+}
index 332ec45..0a75614 100644 (file)
@@ -6,27 +6,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -56,58 +35,37 @@ set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
+  renamevar res res_1
+}
+
+set ic 1
+set AllowRepeate 1
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
   } else {
-    puts "Error: Curve Number is bad!"
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
-  
-  set U1 0.0
-  set U2 0.0
-  
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
+}
 
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
-  }
-  
-  xdistcs res s1 ${U1} ${U2} 10 1e-7
-  xdistcs res s2 ${U1} ${U2} 10 1e-7
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Curve Number is good!"
 } else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-7
-      
-      incr ic
-    }
-  }
-  
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
+  puts "Error: Curve Number is bad!"
 }
index c081b07..b807823 100644 (file)
@@ -38,35 +38,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
+puts ""
+
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
+  bounds c_$i U1 U2
 
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 1e-8
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 1e-8
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 smallview
index 9b1e241..04a5a0e 100644 (file)
@@ -38,35 +38,23 @@ if {${NbCurv} != ${GoodNbCurv}} {
 
 #-------------
 
+puts ""
+
 mksurface s1 f1
 mksurface s2 f2
 
 for {set i 1} {$i <= ${NbCurv}} {incr i} {
-  set log [dump c_$i]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
+  bounds c_$i U1 U2
 
-  puts "U1=${U1}"
-  puts "U2=${U2}"
+  puts "U2=[dval U1]"
+  puts "U2=[dval U2]"
   
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval U2-U1] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
 
-  xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 1e-8
-  xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 1e-8
+  xdistcs c_$i s1 U1 U2 10 ${Toler}
+  xdistcs c_$i s2 U1 U2 10 ${Toler}
 }
 
 smallview
index 4c9a5ca..4dc56b4 100644 (file)
@@ -28,37 +28,39 @@ intersect res s1 s2
 
 set che [whatis res]
 set ind [string first "3d curve" $che]
-
-set AllowRepeate 1
-set ic 1
-
 if {${ind} >= 0} {
   #Only variable "res" exists
   renamevar res res_1
 }
 
+set ic 1
+set AllowRepeate 1
 while { $AllowRepeate != 0 } {
   set che [whatis res_$ic]
   set ind [string first "3d curve" $che]
   if {${ind} < 0} {
     set AllowRepeate 0
-    break
-  }
-  
-  bounds res_$ic U1 U2
-  
-  if {[dval (U2-U1)] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
+  } else {
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
-  
-  xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7
-  xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7
-  
-  incr ic
 }
-  
+
 if {[expr {$ic - 1}] == $GoodNbCurv} {
-  puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm"
+  puts "OK: Curve Number is good!"
 } else {
-  puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found"
-}
\ No newline at end of file
+  puts "Error: Curve Number is bad!"
+}
index 9d23d65..628a446 100644 (file)
@@ -29,37 +29,39 @@ intersect res s2 s1
 
 set che [whatis res]
 set ind [string first "3d curve" $che]
-
-set AllowRepeate 1
-set ic 1
-
 if {${ind} >= 0} {
   #Only variable "res" exists
   renamevar res res_1
 }
 
+set ic 1
+set AllowRepeate 1
 while { $AllowRepeate != 0 } {
   set che [whatis res_$ic]
   set ind [string first "3d curve" $che]
   if {${ind} < 0} {
     set AllowRepeate 0
-    break
-  }
-  
-  bounds res_$ic U1 U2
-  
-  if {[dval (U2-U1)] < 1.0e-20} {
-    puts "Error: Wrong curve's range!"
+  } else {
+    display res_$ic
+    
+    bounds res_$ic U1 U2
+    
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
+      puts "Error: Wrong curve's range!"
+    }
+    
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
+    
+    incr ic
   }
-  
-  xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7
-  xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7
-  
-  incr ic
 }
-  
+
 if {[expr {$ic - 1}] == $GoodNbCurv} {
-  puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm"
+  puts "OK: Curve Number is good!"
 } else {
-  puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found"
-}
\ No newline at end of file
+  puts "Error: Curve Number is bad!"
+}
index aaea2c2..fd20ff2 100644 (file)
@@ -37,8 +37,7 @@ set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  copy res res_1
+  renamevar res res_1
 }
 
 set ic 1
@@ -49,26 +48,24 @@ while { $AllowRepeate != 0 } {
   if {${ind} < 0} {
     set AllowRepeate 0
   } else {
-    set le [length res_$ic]
-    regexp "The length res_$ic is +(\[-0-9.+eE\]+)" ${le} full ll
-    
-    if { $ll < 1.0e-7 } {
-      puts "Error: Curve is too small!"
-    }
+    display res_$ic
     
     bounds res_$ic U1 U2
     
-    if {[dval U2-U1] < 1.0e-9} {
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
       puts "Error: Wrong curve's range!"
     }
     
-    xdistcs res_$ic s1 U1 U2 10 1e-7
-    xdistcs res_$ic s2 U1 U2 10 1e-7
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
     
     incr ic
   }
 }
-  
+
 if {[expr {$ic - 1}] == $GoodNbCurv} {
   puts "OK: Curve Number is good!"
 } else {
index a7a1d58..dd3cac8 100644 (file)
@@ -37,8 +37,7 @@ set che [whatis res]
 set ind [string first "3d curve" $che]
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  copy res res_1
+  renamevar res res_1
 }
 
 set ic 1
@@ -49,19 +48,24 @@ while { $AllowRepeate != 0 } {
   if {${ind} < 0} {
     set AllowRepeate 0
   } else {
+    display res_$ic
+    
     bounds res_$ic U1 U2
     
-    if {[dval U2-U1] < 1.0e-9} {
+    dval U1
+    dval U2
+    
+    if {[dval U2-U1] < 1.0e-20} {
       puts "Error: Wrong curve's range!"
     }
     
-    xdistcs res_$ic s1 U1 U2 10 1e-7
-    xdistcs res_$ic s2 U1 U2 10 1e-7
+    xdistcs res_$ic s1 U1 U2 10 1.0e-7
+    xdistcs res_$ic s2 U1 U2 10 1.0e-7
     
     incr ic
   }
 }
-  
+
 if {[expr {$ic - 1}] == $GoodNbCurv} {
   puts "OK: Curve Number is good!"
 } else {
index 3879f7c..771fb12 100644 (file)
@@ -9,10 +9,21 @@ puts ""
 restore [locate_data_file OCC26310-b1.brep] b1 
 restore [locate_data_file OCC26310-b2.brep] b2 
 
-bop b1 b2
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
 
-bopcut res1
-boptuc res2
+
+# SECTION
+bbop rr 4
+
+# CUT 1-2
+bbop res1 2
+
+# CUT 2-1
+bbop res2 3
 
 checkshape res1
 checkshape res2
@@ -28,9 +39,13 @@ if { [string compare -nocase $log2 "Shape(s) seem(s) to be valid for BOP.\n"] }
   puts "ERROR. res2 is not valid for BOP"
 }
 
+checknbshapes res1 -wire 6 -face 6 -shell 1 -solid 1 -t
+checknbshapes res2 -wire 6 -face 6 -shell 1 -solid 1 -t
+
 smallview
-donly res1
+donly rr
 fit
+donly res1
 xwd ${imagedir}/${casename}_1.png
 donly res2
 fit
index b5a9c36..80823e2 100644 (file)
@@ -9,10 +9,21 @@ puts ""
 restore [locate_data_file OCC26310-b1.brep] b1 
 restore [locate_data_file OCC26310-b2.brep] b2 
 
-bop b2 b1
+bclearobjects
+bcleartools
+baddobjects b2
+baddtools b1
+bfillds
 
-bopcut res1
-boptuc res2
+
+# SECTION
+bbop rr 4
+
+# CUT 1-2
+bbop res1 2
+
+# CUT 2-1
+bbop res2 3
 
 checkshape res1
 checkshape res2
@@ -20,26 +31,22 @@ checkshape res2
 set log1 [bopargcheck res1 #F]
 set log2 [bopargcheck res2 #F]
 
-if { [string first "Faulties for FIRST  shape found : 2" $log1] >= 0 } {
-  puts "ERROR in bopargcheck res1"
-}
-
-if { [string first "Shapes with Continuity C0       : YES  Cases(2)  Total shapes(2)" $log1] >= 0 } {
-  puts "ERROR. res1 with continuity C0."
+if { [string compare -nocase $log1 "Shape(s) seem(s) to be valid for BOP.\n"] } {
+  puts "ERROR. res1 is not valid for BOP"
 }
 
-if { [string first "Faulties for FIRST  shape found : 2" $log2] >= 0 } {
-  puts "ERROR in bopargcheck res2"
+if { [string compare -nocase $log2 "Shape(s) seem(s) to be valid for BOP.\n"] } {
+  puts "ERROR. res2 is not valid for BOP"
 }
 
-if { [string first "Shapes with Continuity C0       : YES  Cases(2)  Total shapes(2)" $log2] >= 0 } {
-  puts "ERROR. res2 with continuity C0."
-}
+checknbshapes res1 -wire 6 -face 6 -shell 1 -solid 1 -t
+checknbshapes res2 -wire 6 -face 6 -shell 1 -solid 1 -t
 
 smallview
 donly res1
 fit
 xwd ${imagedir}/${casename}_1.png
-donly res2
+donly rr
 fit
+donly res2
 xwd ${imagedir}/${casename}_2.png
index 3aff9cf..146b73d 100644 (file)
@@ -6,8 +6,11 @@ puts ""
 # Huge tolerance obtained in the result of intersection of two cylindrical faces
 #################################################
 
+# Number of intersection curves cannot be subject to anything (indeed, output result can be empty).
+# The main reason of the bug #27310 was a HUGE TOLERANCE VALUE (TolReached > 10).
+# See test "bugs moddata_2 bug496" in case of doubt.
+
 set ExpTol 1.0e-7
-set GoodNbCurv 2
 
 restore [locate_data_file OCC496a.brep] a 
 restore [locate_data_file OCC496b.brep] b
@@ -19,15 +22,4 @@ set log [bopcurves a_8 b_2 -2d]
 
 regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
 
-if {${NbCurv} != ${GoodNbCurv}} {
-  puts "Error: Number of curves is bad!"
-}
-
-checkreal TolReached $Toler $ExpTol 0.0 0.1
-
-smallview
-don c_*
-fit
-disp a_8 b_2
-
-checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+checkreal TolReached $Toler $ExpTol 0.0 0.1
\ No newline at end of file
index 8c57872..38eda85 100644 (file)
@@ -6,8 +6,11 @@ puts ""
 # Huge tolerance obtained in the result of intersection of two cylindrical faces
 #################################################
 
-set ExpTol 6.9230965382090094e-006
-set GoodNbCurv 2
+# Number of intersection curves cannot be subject to anything (indeed, output result can be empty).
+# The main reason of the bug #27310 was a HUGE TOLERANCE VALUE (TolReached > 10).
+# See test "bugs moddata_2 bug496" in case of doubt.
+
+set ExpTol 1.3609186093470008e-005
 
 restore [locate_data_file OCC496a.brep] a 
 restore [locate_data_file OCC496b.brep] b
@@ -19,15 +22,4 @@ set log [bopcurves a_10 b_4 -2d]
 
 regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
 
-if {${NbCurv} != ${GoodNbCurv}} {
-  puts "Error: Number of curves is bad!"
-}
-
-checkreal TolReached $Toler $ExpTol 0.0 0.1
-
-smallview
-don c_*
-fit
-disp a_10 b_4
-
-checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+checkreal TolReached $Toler $ExpTol 0.0 0.1
\ No newline at end of file
index 17e72d7..aabc7a1 100644 (file)
@@ -23,7 +23,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_1_2 b_2_2
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 0.00026943844817627679 0.0 1.0e-3
+checkreal TolReached $Toler 0.00026207823091004516 0.0 1.0e-3
 
 # ----
 
@@ -33,7 +33,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_1_4 b_2_4
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 6.5039065434503992e-005 0.0 1.0e-2
+checkreal TolReached $Toler 6.5053102894636701e-005 0.0 1.0e-2
 
 # ----
 
@@ -50,7 +50,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_3_2 b_4_2
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 0.00030603795647549098 0.0 1.0e-3
+checkreal TolReached $Toler 0.00029706239430643614 0.0 1.0e-3
 
 # ----
 
@@ -60,7 +60,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_3_4 b_4_4
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 0.00029242900088525842 0.0 1.0e-3
+checkreal TolReached $Toler 0.00029242389138280588 0.0 1.0e-3
 
 # ----
 
@@ -77,7 +77,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_5_2 b_6_2
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 2.0312181042800029e-005 0.0 1.0e-2
+checkreal TolReached $Toler 1.4980089259007279e-005 0.0 1.0e-2
 
 # ----
 
@@ -87,7 +87,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_5_4 b_6_4
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 0.00023415774730871651 0.0 1.0e-3
+checkreal TolReached $Toler 0.00023417493528435788 0.0 1.0e-3
 
 # ----
 
@@ -104,7 +104,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_7_2 b_8_2
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 0.00028209392756607551 0.0 1.0e-3
+checkreal TolReached $Toler 0.00027445924390073518 0.0 1.0e-3
 
 # ----
 
@@ -114,5 +114,5 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_7_4 b_8_4
 if {${NbCurv} != 1} {
   puts "Error: Number of curves is bad!"
 }
-checkreal TolReached $Toler 2.497244318171703e-005 0.0 1.0e-2
+checkreal TolReached $Toler 1.867918118939262e-005 0.0 1.0e-2
 
index f5b6817..4a80364 100644 (file)
@@ -7,7 +7,7 @@ puts ""
 #######################################################################
 
 set NbCurvGood 1
-set ExpToler 9.0002189481237598e-008
+set ExpToler 7.1928004468800293e-008
 
 restore [locate_data_file bug28009_shape.brep] a
 
diff --git a/tests/bugs/modalg_6/bug28222_1 b/tests/bugs/modalg_6/bug28222_1
new file mode 100644 (file)
index 0000000..d6bf565
--- /dev/null
@@ -0,0 +1,45 @@
+puts "================"
+puts "OCC28222"
+puts "================"
+puts ""
+#######################################################################
+#  Intersection of two cylinders fails
+#######################################################################
+
+dsetsignal 1
+
+set GoodNbCurv 4
+
+foreach c [directory result*] {
+  unset $c
+}
+
+restore [locate_data_file bug28222_s1_cyl_read_d2.draw] s1
+restore [locate_data_file bug28222_s2_cyl_read_d2.draw] s2
+
+intersect result s1 s2
+
+foreach c [directory result*] {
+  bounds $c U1 U2
+  
+  if {[dval U2-U1] < 1.0e-9} {
+    puts "Error: Wrong curve's range!"
+  }
+  
+  xdistcs $c s1 U1 U2 10 2.0e-7
+  xdistcs $c s2 U1 U2 10 2.0e-7    
+}
+
+set NbCurv [llength [directory result*]]
+
+if { $NbCurv == $GoodNbCurv } {
+  puts "OK: Number of curves is good!"
+} else {
+  puts "Error: $GoodNbCurv is expected but $NbCurv is found!"
+}
+
+smallview
+don result*
+fit
+disp s1 s2
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug28222_2 b/tests/bugs/modalg_6/bug28222_2
new file mode 100644 (file)
index 0000000..3fd838d
--- /dev/null
@@ -0,0 +1,45 @@
+puts "================"
+puts "OCC28222"
+puts "================"
+puts ""
+#######################################################################
+#  Intersection of two cylinders fails
+#######################################################################
+
+dsetsignal 1
+
+set GoodNbCurv 4
+
+foreach c [directory result*] {
+  unset $c
+}
+
+cylinder s1 -35 13.3706576198285 30.5814570420266 0 -0.258819045102521 -0.965925826289068 0 0.965925826289068 -0.258819045102521 11
+cylinder s2 0 0 0 1 0 0 0 0 -1 16.5
+
+intersect result s1 s2
+
+foreach c [directory result*] {
+  bounds $c U1 U2
+  
+  if {[dval U2-U1] < 1.0e-9} {
+    puts "Error: Wrong curve's range!"
+  }
+  
+  xdistcs $c s1 U1 U2 10 2.0e-7
+  xdistcs $c s2 U1 U2 10 2.0e-7    
+}
+
+set NbCurv [llength [directory result*]]
+
+if { $NbCurv == $GoodNbCurv } {
+  puts "OK: Number of curves is good!"
+} else {
+  puts "Error: $GoodNbCurv is expected but $NbCurv is found!"
+}
+
+smallview
+don result*
+fit
+disp s1 s2
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug28222_3 b/tests/bugs/modalg_6/bug28222_3
new file mode 100644 (file)
index 0000000..3e1f0ac
--- /dev/null
@@ -0,0 +1,46 @@
+puts "================"
+puts "OCC28222"
+puts "================"
+puts ""
+#######################################################################
+#  Intersection of two cylinders fails
+#######################################################################
+
+dsetsignal 1
+
+set GoodNbCurv 2
+
+foreach c [directory result*] {
+  unset $c
+}
+
+cylinder s1 -9 -5 -2.2058 0 -1 0 0.001
+cylinder s2 0 0 -2.2058 0 0 -1 9
+
+intersect result s1 s2
+
+foreach c [directory result*] {
+  bounds $c U1 U2
+  
+  if {[dval U2-U1] < 1.0e-9} {
+    puts "Error: Wrong curve's range!"
+  }
+  
+  xdistcs $c s1 U1 U2 10 2.0e-7
+  xdistcs $c s2 U1 U2 10 2.0e-7    
+}
+
+set NbCurv [llength [directory result*]]
+
+if { $NbCurv == $GoodNbCurv } {
+  puts "OK: Number of curves is good!"
+} else {
+  puts "Error: $GoodNbCurv is expected but $NbCurv is found!"
+}
+
+smallview
+don result*
+fit
+don  s1 s2
+disp result*
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug28706 b/tests/bugs/modalg_6/bug28706
new file mode 100644 (file)
index 0000000..6c8fdf1
--- /dev/null
@@ -0,0 +1,32 @@
+puts "================"
+puts "OCC28706"
+puts "================"
+puts ""
+#######################################################################
+#  Incomplete result of section operation between attached shapes
+#######################################################################
+
+dsetsignal 1
+
+# Before the fix, section curve was incomplete
+
+restore [locate_data_file bug28706_ar_shape.brep] s1
+restore [locate_data_file bug28706_Prism.brep] s2
+
+bsection result s1 s2
+
+regexp {nb alone Vertices : ([-0-9.+eE]+)} [checksection result] full nbv
+
+if { $nbv != 0 } { 
+  puts "Error : Section is incorrect" 
+} else {
+  puts "Section is correct" 
+}
+
+checkprops result -l 6.16832
+
+smallview
+don result
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 22a8029..81d1fa0 100755 (executable)
@@ -36,6 +36,9 @@ if { $nb_result != 2 } {
     }
 }
 
-checkview -display result -2d -path ${imagedir}/${test_image}.png
+smallview
+don result*
+fit
 
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
 
index 826d182..eda200d 100644 (file)
@@ -6,27 +6,32 @@ puts ""
 # Very slow boolean cut operations on cylinders
 #################################################
 
-if { [regexp {Debug mode} [dversion]] } {
-    set max_time 0.3
-} else {
-    set max_time 0.15
-}
+set ExpTol1 3.2300230820477792e-007
+set ExpTol2 3.2198007889220219e-007
 
-set maxToler 1.5e-5
+set GoodNbCurv 4
 
 restore [locate_data_file OCC26310-b1.brep] b1 
-restore [locate_data_file OCC26310-b2.brep] b2 
+restore [locate_data_file OCC26310-b2.brep] b2
 
 explode b1 f
 explode b2 f
 
-dchrono cr restart
-set log1 [bopcurves b1_1 b2_1 -2d]
-dchrono cr stop counter bopcurves
+set log [bopcurves b1_1 b2_1 -2d]
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+checkreal ToleranceReached ${Toler} ${ExpTol1} 0.0 0.01
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: Number of curves is bad!"
+}
 
-regexp {Tolerance Reached=+([-0-9.+eE]+)} ${log1} full Toler
-puts "TolReached = $Toler"
+set log [bopcurves b2_1 b1_1 -2d]
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+checkreal ToleranceReached ${Toler} ${ExpTol2} 0.0 0.01
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: Number of curves is bad!"
+}
 
-if { $Toler > $maxToler } {
-  puts "Error: Tolerance is too big ($Toler > $maxToler)"
-}
\ No newline at end of file