0029712: Extrema algorithm raises exception
authornbv <nbv@opencascade.com>
Fri, 20 Apr 2018 14:00:48 +0000 (17:00 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Jun 2018 11:03:05 +0000 (14:03 +0300)
1. Extrema algorithm calls Curve-surface intersector. This intersector returns flag about infinite solution (in spite of extrema's returning not-parallel status correctly - axes of considered cylinder and circle are not parallel). In this case, attempt of obtaining number of intersection points leads to exception.

So, the fix adds check of infinite solution after the intersection algorithm.

2. The methods IsDone(), IsParallel(), NbExt(), SquareDistance() and Points() (of Extrema_* classes) have been corrected to make them consistent to the documentation.

3. Revision of some Extrema_* classes has been made in order to avoid places with uninitialized variables.

4. Currently Extrema does not store any points in case when the arguments are parallel. It stores the distance only.

5. Some cases on Extrema-algo have been moved from "fclasses"-group to "modalg"-group.

80 files changed:
dox/dev_guides/upgrade/upgrade.md
src/BRepClass3d/BRepClass3d_BndBoxTree.cxx
src/BRepClass3d/BRepClass3d_BndBoxTree.hxx
src/BRepClass3d/BRepClass3d_SClassifier.cxx
src/Bnd/Bnd_Range.hxx
src/Extrema/Extrema_ExtCC.cxx
src/Extrema/Extrema_ExtCC.hxx
src/Extrema/Extrema_ExtCS.cxx
src/Extrema/Extrema_ExtElC.cxx
src/Extrema/Extrema_ExtElC2d.cxx
src/Extrema/Extrema_ExtElCS.cxx
src/Extrema/Extrema_ExtElSS.cxx
src/Extrema/Extrema_ExtPElC.cxx
src/Extrema/Extrema_ExtPElC2d.cxx
src/Extrema/Extrema_ExtPElS.cxx
src/Extrema/Extrema_ExtPExtS.cxx
src/Extrema/Extrema_ExtPRevS.cxx
src/Extrema/Extrema_ExtPS.cxx
src/Extrema/Extrema_ExtSS.cxx
src/Extrema/Extrema_GExtPC.gxx
src/Extrema/Extrema_GLocateExtPC.gxx
src/Extrema/Extrema_GenExtCC.gxx
src/Extrema/Extrema_GenExtCS.cxx
src/Extrema/Extrema_GenExtPC.gxx
src/Extrema/Extrema_GenExtPS.cxx
src/Extrema/Extrema_GenExtSS.cxx
src/Extrema/Extrema_GenLocateExtPC.gxx
src/Extrema/Extrema_LocateExtCC.cxx
src/Extrema/Extrema_LocateExtCC2d.cxx
src/Extrema/Extrema_Point.gxx
src/GeometryTest/GeometryTest_APICommands.cxx
src/ProjLib/ProjLib_CompProjectedCurve.cxx
tests/bugs/modalg_7/bug29712_1 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_10 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_11 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_12 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_13 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_14 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_15 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_16 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_17 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_18 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_19 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_2 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_20 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_21 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_22 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_23 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_24 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_25 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_26 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_27 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_28 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_29 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_3 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_30 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_31 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_32 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_33 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_34 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_35 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_36 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_37 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_38 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_39 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_4 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_40 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_41 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_42 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_43 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_5 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_6 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_7 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_8 [new file with mode: 0644]
tests/lowalgos/extcc/bug29712_9 [new file with mode: 0644]
tests/lowalgos/extss/bug29712_44 [new file with mode: 0644]
tests/perf/modalg/bug26184_1 [moved from tests/perf/fclasses/bug26184_1 with 100% similarity]
tests/perf/modalg/bug26184_2 [moved from tests/perf/fclasses/bug26184_2 with 100% similarity]
tests/perf/modalg/bug27131 [moved from tests/perf/fclasses/bug27131 with 100% similarity]
tests/perf/modalg/bug27371 [moved from tests/perf/fclasses/bug27371 with 100% similarity]

index f4c3e36..0ab9b28 100644 (file)
@@ -1583,3 +1583,7 @@ To use the custom printer in OCAF, it can be either added to default messenger o
 
 @subsection upgrade_740_BRepPrimAPI_MakeRevol Changes in BRepPrimAPI_MakeRevol algorithm
 Previously the algorithm could create a shape with the same degenerated edge shared between some faces. Now it is prevented. The algorithm creates the different copy of this edge for each face. The method *Generated(...)* has been changed in order to apply restriction to the input shape: input shape can be only of type VERTEX, EDGE, FACE or SOLID. For input shape of another type the method always returns empty list.
+
+@subsection upgrade_740_extremaalgo Changes in behavior of Extrema algorithms
+
+Since OCCT 7.4.0 exception is thrown on the attempt of taking points in case of infinite number of solution (IsParallel status). Request of distances is available as before. Method NbExt() always returns 1 in such cases. 
index a573225..eb01f8f 100644 (file)
@@ -83,35 +83,43 @@ Standard_Boolean BRepClass3d_BndBoxTreeSelectorLine::Accept (const Standard_Inte
   if (sht == TopAbs_EDGE)
   {
     const TopoDS_Edge& E = TopoDS::Edge(shp);
-    Standard_Real EdgeTSq  = BRep_Tool::Tolerance(E);
+    Standard_Real EdgeTSq = BRep_Tool::Tolerance(E);
     EdgeTSq *= EdgeTSq;
     Standard_Real f, l;
     BRepAdaptor_Curve C(E);
-    BRep_Tool::Range(E,f,l);
+    BRep_Tool::Range(E, f, l);
 
     // Edge-Line interference.
     Extrema_ExtCC ExtCC(C, myLC, f, l, myLC.FirstParameter(), myLC.LastParameter());
-    if (ExtCC.IsDone() && ExtCC.NbExt() > 0)
-    { 
-      Standard_Boolean IsInside = Standard_False;
-      for (Standard_Integer i = 1; i <= ExtCC.NbExt(); i++)
+    if (ExtCC.IsDone())
+    {
+      if (ExtCC.IsParallel())
       {
-        if (ExtCC.SquareDistance(i) < EdgeTSq)
+        // Tangent case is invalid for classification
+        myIsValid = Standard_False;
+      }
+      else if (ExtCC.NbExt() > 0)
+      {
+        Standard_Boolean IsInside = Standard_False;
+        for (Standard_Integer i = 1; i <= ExtCC.NbExt(); i++)
         {
-          Extrema_POnCurv P1, P2;
-          ExtCC.Points(i,P1, P2);
+          if (ExtCC.SquareDistance(i) < EdgeTSq)
+          {
+            Extrema_POnCurv P1, P2;
+            ExtCC.Points(i, P1, P2);
 
-          EdgeParam EP;
-          EP.myE = E;
-          EP.myParam = P1.Parameter(); // Original curve is the first parameter.
-          EP.myLParam = P2.Parameter(); // Linear curve is the second parameter.
+            EdgeParam EP;
+            EP.myE = E;
+            EP.myParam = P1.Parameter(); // Original curve is the first parameter.
+            EP.myLParam = P2.Parameter(); // Linear curve is the second parameter.
 
-          myEP.Append(EP);
-          IsInside = Standard_True;
+            myEP.Append(EP);
+            IsInside = Standard_True;
+          }
         }
+        if (IsInside)
+          return Standard_True;
       }
-      if (IsInside)
-        return Standard_True;
     }
   }
   else if (sht == TopAbs_VERTEX)
index 8f6174d..5050a74 100644 (file)
@@ -83,7 +83,9 @@ public:
 
 public:
   BRepClass3d_BndBoxTreeSelectorLine(const TopTools_IndexedMapOfShape& theMapOfShape) 
-    : BRepClass3d_BndBoxTreeSelectorLine::Selector(), myMapOfShape (theMapOfShape)
+    : BRepClass3d_BndBoxTreeSelectorLine::Selector(),
+      myMapOfShape(theMapOfShape),
+      myIsValid(Standard_True)
   {}
 
   Standard_Boolean Reject (const Bnd_Box& theBox) const
@@ -135,6 +137,13 @@ public:
   {
     myEP.Clear();
     myVP.Clear();
+    myIsValid = Standard_True;
+  }
+
+  //! Returns TRUE if correct classification is possible
+  Standard_Boolean IsCorrect() const
+  {
+    return myIsValid;
   }
 
 private:
@@ -147,6 +156,7 @@ private:
   NCollection_Sequence<EdgeParam> myEP; //output result (edge vs line)
   NCollection_Sequence<VertParam> myVP; //output result (vertex vs line)
   GeomAdaptor_Curve myLC;
+  Standard_Boolean myIsValid;
 };
 
 #endif
index 9db128c..d342f18 100644 (file)
@@ -285,6 +285,14 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
     aSelectorLine.SetCurrentLine(L, Par);
     Standard_Integer SelsEVL = 0;
     SelsEVL = aTree.Select(aSelectorLine); //SelsEE > 0 => Line/Edges & Line/Vertex intersection
+
+    if (!aSelectorLine.IsCorrect())
+    {
+      // Go to the next segment
+      isFaultyLine = Standard_True;
+      continue;
+    }
+
     if (SelsEVL > 0 )
     {    
       // Line and edges / vertices interference.
index 8873824..0c006d2 100644 (file)
@@ -145,6 +145,26 @@ public:
     theLastPar = myLast;
     return Standard_True;
   }
+
+  //! Obtain theParameter satisfied to the equation
+  //!     (theParameter-MIN)/(MAX-MIN) == theLambda.
+  //!   *  theLambda == 0 --> MIN boundary will be returned;
+  //!   *  theLambda == 0.5 --> Middle point will be returned;
+  //!   *  theLambda == 1 --> MAX boundary will be returned;
+  //!   *  theLambda < 0 --> the value less than MIN will be returned;
+  //!   *  theLambda > 1 --> the value greater than MAX will be returned.
+  //! If <this> is VOID the method returns false.
+  Standard_Boolean GetIntermediatePoint(const Standard_Real theLambda,
+                                        Standard_Real& theParameter) const
+  {
+    if (IsVoid())
+    {
+      return Standard_False;
+    }
+
+    theParameter = myFirst + theLambda*(myLast - myFirst);
+    return Standard_True;
+  }
   
   //! Returns range value (MAX-MIN). Returns negative value for VOID range.
   Standard_Real Delta() const
index 211dd84..da1d000 100644 (file)
@@ -20,6 +20,7 @@
 //                            fois la meme solution 
 
 #include <Adaptor3d_Curve.hxx>
+#include <Bnd_Range.hxx>
 #include <ElCLib.hxx>
 #include <Extrema_CurveTool.hxx>
 #include <Extrema_ECC.hxx>
@@ -58,7 +59,10 @@ Extrema_ExtCC::Extrema_ExtCC (const Standard_Real TolC1,
   myDone (Standard_False)
 {
   myC[0] = 0; myC[1] = 0;
+  myInf[0] = myInf[1] = -Precision::Infinite();
+  mySup[0] = mySup[1] = Precision::Infinite();
   myTol[0] = TolC1; myTol[1] = TolC2;
+  mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
 }
 
 //=======================================================================
@@ -82,6 +86,7 @@ Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1,
   SetCurve (2, C2, V1, V2);
   SetTolerance (1, TolC1);
   SetTolerance (2, TolC2);
+  mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
   Perform();
 }
 
@@ -103,6 +108,7 @@ Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1,
   SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter());
   SetTolerance (1, TolC1);
   SetTolerance (2, TolC2);
+  mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
   Perform();
 }
 
@@ -177,8 +183,6 @@ void Extrema_ExtCC::Perform()
   GeomAbs_CurveType type1 = (*((Adaptor3d_Curve*)myC[0])).GetType();
   GeomAbs_CurveType type2 = (*((Adaptor3d_Curve*)myC[1])).GetType();
   Standard_Real U11, U12, U21, U22, Tol = Min(myTol[0], myTol[1]);
-  mynbext = 0;
-  inverse = Standard_False;
 
   U11 = myInf[0];
   U12 = mySup[0];
@@ -209,8 +213,9 @@ void Extrema_ExtCC::Perform()
     //analytical case - one curve is always a line
     Standard_Integer anInd1 = 0, anInd2 = 1;
     GeomAbs_CurveType aType2 = type2;
-    inverse = (type1 > type2);
-    if (inverse) {
+    Standard_Boolean isInverse = (type1 > type2);
+    if (isInverse)
+    {
       //algorithm uses inverse order of arguments
       anInd1 = 1;
       anInd2 = 0;
@@ -219,27 +224,27 @@ void Extrema_ExtCC::Perform()
     switch (aType2) {
     case GeomAbs_Line: {
       Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Line(), Tol);
-      Results(Xtrem, U11, U12, U21, U22);
+      PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
       break;
     }
     case GeomAbs_Circle: {
       Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Circle(), Tol);
-      Results(Xtrem, U11, U12, U21, U22);
+      PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
       break;
     }
     case GeomAbs_Ellipse: {
       Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Ellipse());
-      Results(Xtrem, U11, U12, U21, U22);
+      PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
       break;
     }
     case GeomAbs_Hyperbola: {
       Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Hyperbola());
-      Results(Xtrem, U11, U12, U21, U22);
+      PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
       break;
     }
     case GeomAbs_Parabola: {
       Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Parabola());
-      Results(Xtrem, U11, U12, U21, U22);
+      PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
       break;
     }
     default: break;
@@ -250,15 +255,15 @@ void Extrema_ExtCC::Perform()
     Extrema_ExtElC CCXtrem ((*((Adaptor3d_Curve*)myC[0])).Circle(), (*((Adaptor3d_Curve*)myC[1])).Circle());
     bIsDone = CCXtrem.IsDone();
     if(bIsDone) {
-      Results(CCXtrem, U11, U12, U21, U22);
+      PrepareResults(CCXtrem, Standard_False, U11, U12, U21, U22);
     }
     else {
       myECC.Perform();
-      Results(myECC, U11, U12, U21, U22);
+      PrepareResults(myECC, U11, U12, U21, U22);
     }
   } else {
     myECC.Perform();
-    Results(myECC, U11, U12, U21, U22);
+    PrepareResults(myECC, U11, U12, U21, U22);
   }
 }
 
@@ -280,6 +285,11 @@ Standard_Boolean Extrema_ExtCC::IsDone() const
 
 Standard_Boolean Extrema_ExtCC::IsParallel() const
 {
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+
   return myIsPar;
 }
 
@@ -291,8 +301,7 @@ Standard_Boolean Extrema_ExtCC::IsParallel() const
 
 Standard_Real Extrema_ExtCC::SquareDistance(const Standard_Integer N) const 
 {
-  if(!myDone) throw StdFail_NotDone();
-  if ((N <= 0) || (N > mynbext)) throw Standard_OutOfRange();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return mySqDist.Value(N);
 }
 
@@ -305,7 +314,7 @@ Standard_Real Extrema_ExtCC::SquareDistance(const Standard_Integer N) const
 Standard_Integer Extrema_ExtCC::NbExt() const
 {
   if(!myDone) throw StdFail_NotDone();
-  return mynbext;
+  return mySqDist.Length();
 }
 
 
@@ -318,10 +327,18 @@ void Extrema_ExtCC::Points(const Standard_Integer N,
                            Extrema_POnCurv& P1,
                            Extrema_POnCurv& P2) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if ((N <= 0) || (N > mynbext)) throw Standard_OutOfRange();
-  P1 = mypoints.Value(2*N-1);
-  P2 = mypoints.Value(2*N);
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
+  P1 = mypoints.Value(2 * N - 1);
+  P2 = mypoints.Value(2 * N);
 }
 
 
@@ -350,18 +367,339 @@ void Extrema_ExtCC::TrimmedSquareDistances(Standard_Real& dist11,
   P22 = P2l;
 }
 
+//=======================================================================
+//function : ParallelResult
+//purpose  : 
+//=======================================================================
+void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
+                                          const Standard_Real theUt12,
+                                          const Standard_Real theUt21,
+                                          const Standard_Real theUt22,
+                                          const Standard_Real theSqDist)
+{
+  if (!myIsPar)
+    return;
 
+  const GeomAbs_CurveType aType1 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[0]));
+  const GeomAbs_CurveType aType2 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[1]));
+  
+  if (((aType1 != GeomAbs_Line) && (aType1 != GeomAbs_Circle)) ||
+      ((aType2 != GeomAbs_Line) && (aType2 != GeomAbs_Circle)))
+  {
+    mySqDist.Append(theSqDist);
+    myDone = Standard_True;
+    myIsPar = Standard_True;
+    return;
+  }
+  
+  // Parallel case is only for line-line, circle-circle and circle-line!!!
+  // But really for trimmed curves extremas can not exist!
+  if (aType1 != aType2)
+  {
+    //The projection of the circle's location to the trimmed line must exist.
+    const Standard_Boolean isReversed = (aType1 != GeomAbs_Circle);
+    const gp_Pnt aPonC = !isReversed ?
+                      Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt11) :
+                      Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[1]), theUt21);
+
+    const gp_Lin aL = !isReversed ? ((Adaptor3d_Curve*) myC[1])->Line() :
+                                    ((Adaptor3d_Curve*) myC[0])->Line();
+    const Extrema_ExtPElC ExtPLin(aPonC, aL, Precision::Confusion(),
+                                  !isReversed ? theUt21 : theUt11,
+                                  !isReversed ? theUt22 : theUt12);
+
+    if (ExtPLin.IsDone())
+    {
+      mySqDist.Append(theSqDist);
+    }
+    else
+    {
+      myIsPar = Standard_False;
+    }
+
+    return;
+  }
+
+  if (aType1 == GeomAbs_Line)
+  {
+    // Line - Line
+
+    const Standard_Real isFirstInfinite = (Precision::IsInfinite(theUt11) &&
+                                           Precision::IsInfinite(theUt12));
+    const Standard_Real isLastInfinite = (Precision::IsInfinite(theUt21) &&
+                                          Precision::IsInfinite(theUt22));
+
+    if (isFirstInfinite || isLastInfinite)
+    {
+      // Infinite number of solution
+
+      mySqDist.Append(theSqDist);
+    }
+    else
+    {
+      // The range created by projection of both ends of the 1st line
+      // to the 2nd one must intersect the (native) trimmed range of
+      // the 2nd line.
+
+      myIsPar = Standard_False;
+
+      const gp_Lin aLin1 = ((Adaptor3d_Curve*) myC[0])->Line();
+      const gp_Lin aLin2 = ((Adaptor3d_Curve*) myC[1])->Line();
+      const Standard_Boolean isOpposite(aLin1.Direction().Dot(aLin2.Direction()) < 0.0);
+
+      Bnd_Range aRange2(theUt21, theUt22);
+      Bnd_Range aProjRng12;
+
+      if (Precision::IsInfinite(theUt11))
+      {
+        if (isOpposite)
+          aProjRng12.Add(Precision::Infinite());
+        else
+          aProjRng12.Add(-Precision::Infinite());
+      }
+      else
+      {
+        const gp_Pnt aPonC1 = ElCLib::Value(theUt11, aLin1);
+        const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
+        aProjRng12.Add(aPar);
+      }
+
+      if (Precision::IsInfinite(theUt12))
+      {
+        if (isOpposite)
+          aProjRng12.Add(-Precision::Infinite());
+        else
+          aProjRng12.Add(Precision::Infinite());
+      }
+      else
+      {
+        const gp_Pnt aPonC1 = ElCLib::Value(theUt12, aLin1);
+        const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
+        aProjRng12.Add(aPar);
+      }
+
+      aRange2.Common(aProjRng12);
+      if (aRange2.Delta() > Precision::Confusion())
+      {
+        ClearSolutions();
+        mySqDist.Append(theSqDist);
+        myIsPar = Standard_True;
+      }
+      else if (!aRange2.IsVoid())
+      {
+        //Case like this:
+
+        //  **************     aLin1
+        //               o
+        //               o
+        //               ***************  aLin2
+
+        ClearSolutions();
+        Standard_Real aPar1 = 0.0, aPar2 = 0.0;
+        aRange2.GetBounds(aPar1, aPar2);
+        aPar2 = 0.5*(aPar1 + aPar2);
+        gp_Pnt aP = ElCLib::Value(aPar2, aLin2);
+        const Extrema_POnCurv aP2(aPar2, aP);
+        aPar1 = ElCLib::Parameter(aLin1, aP);
+        aP = ElCLib::Value(aPar1, aLin1);
+        const Extrema_POnCurv aP1(aPar1, aP);
+        mypoints.Append(aP1);
+        mypoints.Append(aP2);
+        mySqDist.Append(theSqDist);
+      }
+    }
+  }
+  else
+  {
+    // Circle - Circle
+    myIsPar = Standard_False;
+
+    //Two arcs with ranges [U1, U2] and [V1, V2] correspondingly are
+    //considered to be parallel in the following case:
+    //  The range created by projection both points U1 and U2 of the
+    //  1st circle to the 2nd one intersects either the range [V1, V2] or
+    //  the range [V1-PI, V2-PI]. All ranges must be adjusted to correspond
+    //  periodic range before checking of intersection.
+
+    const gp_Circ aWorkCirc = ((Adaptor3d_Curve*) myC[1])->Circle();
+    const Standard_Real aPeriod = M_PI + M_PI;
+    gp_Vec aVTg1;
+    gp_Pnt aP11;
+    const gp_Pnt aP12 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt12);
+    Extrema_CurveTool::D1(*((Adaptor3d_Curve*) myC[0]), theUt11, aP11, aVTg1);
+
+    const Bnd_Range aRange(theUt21, theUt22);
+    Bnd_Range aProjRng1;
+
+    // Project arc of the 1st circle between points theUt11 and theUt12 to the
+    // 2nd circle. It is necessary to chose correct arc from two possible ones.
+
+    Standard_Real aPar1 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP11),
+                                           theUt21, theUt21 + aPeriod);
+    const gp_Vec aVTg2 = Extrema_CurveTool::DN(*((Adaptor3d_Curve*) myC[1]), aPar1, 1);
+    
+    // Check if circles have same/opposite directions
+    const Standard_Boolean isOpposite(aVTg1.Dot(aVTg2) < 0.0);
+
+    Standard_Real aPar2 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP12),
+                                           theUt21, theUt21 + aPeriod);
+
+    if (isOpposite)
+    {
+      // Must be aPar2 < aPar1
+      if ((aRange.Delta() > Precision::Angular()) &&
+          ((aPar1 - aPar2) < Precision::Angular()))
+      {
+        aPar2 -= aPeriod;
+      }
+    }
+    else
+    {
+      // Must be aPar2 > aPar1
+      if ((aRange.Delta() > Precision::Angular()) &&
+          ((aPar2 - aPar1) < Precision::Angular()))
+      {
+        aPar1 -= aPeriod;
+      }
+    }
+
+    // Now the projection result is the range [aPar1, aPar2]
+    // if aPar1 < aPar2 or the range [aPar2, aPar1], otherwise.
+
+    Standard_Real aMinSquareDist = RealLast();
+
+    aProjRng1.Add(aPar1 - M_PI);
+    aProjRng1.Add(aPar2 - M_PI);
+    for (Standard_Integer i = 0; i < 2; i++)
+    {
+      // Repeat computation twice
+
+      Bnd_Range aRng = aProjRng1;
+      aRng.Common(aRange);
+
+      //Cases are possible and processed below:
+      //1. Extrema does not exist. In this case all common ranges are VOID.
+      //2. Arcs are parallel and distance between them is equal to sqrt(theSqDist).
+      //    In this case myIsPar = TRUE definitely.
+      //3. Arcs are parallel and distance between them is equal to (sqrt(theSqDist) + R),
+      //    where R is the least radius of the both circles. In this case myIsPar flag
+      //    will temporary be set to TRUE but check will be continued until less
+      //    distance will be found. At that, region with the least distance can be
+      //    either a local point or continuous range. In 1st case myIsPar = FALSE and
+      //    several (or single) extremas will be returned. In the 2nd one
+      //    myIsPar = TRUE and only the least distance will be returned.
+      //4. Arcs are not parallel. Then several (or single) extremas will be returned.
+
+      if (aRng.Delta() > Precision::Angular())
+      {
+        Standard_Real aPar = 0.0;
+        aRng.GetIntermediatePoint(0.5, aPar);
+        const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
+        Extrema_ExtPElC ExtPCir(aPCirc2,
+                                Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
+                                Precision::Confusion(), theUt11, theUt12);
+
+        Standard_Real aMinSqD = ExtPCir.SquareDistance(1);
+        for (Standard_Integer anExtID = 2; anExtID <= ExtPCir.NbExt(); anExtID++)
+        {
+          aMinSqD = Min(aMinSqD, ExtPCir.SquareDistance(anExtID));
+        }
+
+        if (aMinSqD <= aMinSquareDist)
+        {
+          ClearSolutions();
+          mySqDist.Append(aMinSqD);
+          myIsPar = Standard_True;
+
+          const Standard_Real aDeltaSqDist = aMinSqD - theSqDist;
+          const Standard_Real aSqD = Max(aMinSqD, theSqDist);
+
+          //  0 <= Dist1-Dist2 <= Eps
+          //  0 <= Dist1^2 - Dist2^2 < Eps*(Dist1+Dist2)
+
+          //If Dist1 ~= Dist2 ==> Dist1+Dist2 ~= 2*Dist2.
+          //Consequently,
+          //  0 <= Dist1^2 - Dist2^2 <= 2*Dist2*Eps
+
+          //Or
+          //  (Dist1^2 - Dist2^2)^2 <= 4*Dist2^2*Eps^2
+
+          if (aDeltaSqDist*aDeltaSqDist < 4.0*aSqD*Precision::SquareConfusion())
+          {
+            // New solution is found
+            break;
+          }
+        }
+
+        //Nearer solution can be found
+      }
+      else if (!aRng.IsVoid())
+      {
+        //Check cases like this:
+
+        //  **************     aCirc1
+        //               o
+        //               o
+        //               ***************  aCirc2
+
+        Standard_Real aPar = 0.0;
+        aRng.GetIntermediatePoint(0.5, aPar);
+        const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
+        const Extrema_POnCurv aP2(aPar, aPCirc2);
+
+        Extrema_ExtPElC ExtPCir(aPCirc2,
+                                Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
+                                Precision::Confusion(), theUt11, theUt12);
+
+        Standard_Boolean isFound = !myIsPar;
+
+        if (!isFound)
+        {
+          //If the flag myIsPar was set earlier then it does not mean that
+          //we have found the minimal distance. Here we check it. If there is
+          //a pair of points, which are in less distance then myIsPar flag
+          //was unset and the algorithm will return these nearest points.
+
+          for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
+          {
+            if (ExtPCir.SquareDistance(anExtID) < aMinSquareDist)
+            {
+              isFound = Standard_True;
+              break;
+            }
+          }
+        }
+
+        if (isFound)
+        {
+          ClearSolutions();
+          myIsPar = Standard_False;
+          for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
+          {
+            mypoints.Append(ExtPCir.Point(anExtID));
+            mypoints.Append(aP2);
+            mySqDist.Append(ExtPCir.SquareDistance(anExtID));
+            aMinSquareDist = Min(aMinSquareDist, ExtPCir.SquareDistance(anExtID));
+          }
+        }
+      }
+
+      aProjRng1.Shift(M_PI);
+    }
+  }
+}
 
 //=======================================================================
 //function : Results
 //purpose  : 
 //=======================================================================
 
-void Extrema_ExtCC::Results(const Extrema_ExtElC&  AlgExt,
-                            const Standard_Real    Ut11,
-                            const Standard_Real    Ut12,
-                            const Standard_Real    Ut21,
-                            const Standard_Real    Ut22)
+void Extrema_ExtCC::PrepareResults(const Extrema_ExtElC&  AlgExt,
+                                   const Standard_Boolean theIsInverse,
+                                   const Standard_Real    Ut11,
+                                   const Standard_Real    Ut12,
+                                   const Standard_Real    Ut21,
+                                   const Standard_Real    Ut22)
 {
   Standard_Integer i, NbExt;
   Standard_Real Val, U, U2;
@@ -371,265 +709,15 @@ void Extrema_ExtCC::Results(const Extrema_ExtElC&  AlgExt,
   if (myDone) {
     myIsPar = AlgExt.IsParallel();
     if (myIsPar) {
-      GeomAbs_CurveType type = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*)myC[0]));
-      GeomAbs_CurveType type2 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*)myC[1]));
-      // Parallel case is only for line-line, circle-circle and circle-line!!!
-      // But really for trimmed curves extremas can not exist!
-      Extrema_POnCurv dummypoint(0., gp_Pnt(0.,0.,0.));
-      if(type != type2) {
-       mySqDist.Append(AlgExt.SquareDistance(1));
-       if(type == GeomAbs_Circle) {
-         gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);
-         P1.SetValues(Ut11, PonC1);
-         Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-         if(ExtPLin.IsDone()) {
-           mynbext = 1;
-           P2 = ExtPLin.Point(1);
-           mypoints.Append(P1);
-           mypoints.Append(P2);
-         }
-         else {
-           myIsPar = Standard_False;
-           mynbext = 0;
-           mypoints.Append(dummypoint);
-           mypoints.Append(dummypoint);
-         }
-       }
-       else {
-         gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);
-         P2.SetValues(Ut21, PonC2);
-         Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
-         if(ExtPLin.IsDone()) {
-           mynbext = 1;
-           P1 = ExtPLin.Point(1);
-           mypoints.Append(P1);
-           mypoints.Append(P2);
-         }
-         else {
-           myIsPar = Standard_False;
-           mynbext = 0;
-           mypoints.Append(dummypoint);
-           mypoints.Append(dummypoint);
-         }
-       }
-       return;
-      }
-         
-      if(type == GeomAbs_Line) {
-       Standard_Boolean infinite = Precision::IsInfinite(Ut11) &&
-                                   Precision::IsInfinite(Ut12) &&
-                                   Precision::IsInfinite(Ut21) &&
-                                   Precision::IsInfinite(Ut22);
-
-       if(infinite) {
-         mynbext = 1;
-         mySqDist.Append(AlgExt.SquareDistance(1));
-         gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), 0.); 
-         P1.SetValues(0., PonC1);
-         Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-         if(ExtPLin.IsDone()) {
-           P2 = ExtPLin.Point(1);
-           mypoints.Append(P1);
-           mypoints.Append(P2);
-         }
-         else {
-           myIsPar = Standard_False;
-           mypoints.Append(dummypoint);
-           mypoints.Append(dummypoint);
-         }
-       }
-       else {
-         Standard_Boolean finish = Standard_False;
-         if(!Precision::IsInfinite(Ut11)) {
-           gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);  
-           Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-           if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
-             mynbext = 1;
-             mySqDist.Append(AlgExt.SquareDistance(1));
-             P1.SetValues(Ut11, PonC1);
-             P2 = ExtPLin.Point(1);
-             mypoints.Append(P1);
-             mypoints.Append(P2);
-             finish = Standard_True;
-           }
-         }
-         if(!finish) {
-           if(!Precision::IsInfinite(Ut12)) {
-             gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut12);  
-             Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-             if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
-               mynbext = 1;
-               mySqDist.Append(AlgExt.SquareDistance(1));
-               P1.SetValues(Ut12, PonC1);
-               P2 = ExtPLin.Point(1);
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-               finish = Standard_True;
-             }
-           }
-         }
-         if(!finish) {
-           if(!Precision::IsInfinite(Ut21)) {
-             gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);  
-             Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
-             if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
-               mynbext = 1;
-               mySqDist.Append(AlgExt.SquareDistance(1));
-               P2.SetValues(Ut21, PonC2);
-               P1 = ExtPLin.Point(1);
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-               finish = Standard_True;
-             }
-           }
-         }
-         if(!finish) {
-           if(!Precision::IsInfinite(Ut22)) {
-             gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut22);  
-             Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
-             if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
-               mynbext = 1;
-               mySqDist.Append(AlgExt.SquareDistance(1));
-               P2.SetValues(Ut22, PonC2);
-               P1 = ExtPLin.Point(1);
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-               finish = Standard_True;
-             }
-           }
-         }
-         if(!finish) {
-           mynbext = 0;
-           myIsPar = Standard_False;
-           mySqDist.Append(AlgExt.SquareDistance(1));
-           mypoints.Append(dummypoint);
-           mypoints.Append(dummypoint);
-         }
-       }
-         
-      }
-      else {
-       Standard_Boolean finish = Standard_False;
-       gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);  
-       P1.SetValues(Ut11, PonC1);
-       Extrema_ExtPElC ExtPCir(PonC1, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-       if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
-         for(i = 1; i <= ExtPCir.NbExt(); i++) {
-           mynbext++;
-           P2 = ExtPCir.Point(i);
-           mySqDist.Append(ExtPCir.SquareDistance(i));
-           mypoints.Append(P1);
-           mypoints.Append(P2);
-         }
-         if(mynbext == 2)  finish = Standard_True;
-       }
-       if(!finish) {
-         PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut12);  
-         ExtPCir.Perform(PonC1, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
-         P1.SetValues(Ut12, PonC1);
-         if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
-           if(mynbext == 0) {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               mynbext++;
-               P2 = ExtPCir.Point(i);
-               mySqDist.Append(ExtPCir.SquareDistance(i));
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-             }
-           }
-           else {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               Standard_Real dist = mySqDist(1);
-               if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
-                 mynbext++;
-                 P2 = ExtPCir.Point(i);
-                 mySqDist.Append(ExtPCir.SquareDistance(i));
-                 mypoints.Append(P1);
-                 mypoints.Append(P2);
-               }
-             }
-           }
-               
-           if(mynbext == 2)  finish = Standard_True;
-         }
-       }  
-       if(!finish) {
-         gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);  
-         ExtPCir.Perform(PonC2, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
-         P2.SetValues(Ut21, PonC2);
-         if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
-           if(mynbext == 0) {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               mynbext++;
-               P1 = ExtPCir.Point(i);
-               mySqDist.Append(ExtPCir.SquareDistance(i));
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-             }
-           }
-           else {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               Standard_Real dist = mySqDist(1);
-               if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
-                 mynbext++;
-                 P1 = ExtPCir.Point(i);
-                 mySqDist.Append(ExtPCir.SquareDistance(i));
-                 mypoints.Append(P1);
-                 mypoints.Append(P2);
-               }
-             }
-           }
-               
-           if(mynbext == 2)  finish = Standard_True;
-         }
-       }  
-       if(!finish) {
-         gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut22);  
-         ExtPCir.Perform(PonC2, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
-         P2.SetValues(Ut22, PonC2);
-         if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
-           if(mynbext == 0) {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               mynbext++;
-               P1 = ExtPCir.Point(i);
-               mySqDist.Append(ExtPCir.SquareDistance(i));
-               mypoints.Append(P1);
-               mypoints.Append(P2);
-             }
-           }
-           else {
-             for(i = 1; i <= ExtPCir.NbExt(); i++) {
-               Standard_Real dist = mySqDist(1);
-               if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
-                 mynbext++;
-                 P1 = ExtPCir.Point(i);
-                 mySqDist.Append(ExtPCir.SquareDistance(i));
-                 mypoints.Append(P1);
-                 mypoints.Append(P2);
-               }
-             }
-           }
-               
-           if(mynbext == 2)  finish = Standard_True;
-         }
-       }  
-       if(mynbext == 0) {
-         myIsPar = Standard_False;
-         mySqDist.Append(AlgExt.SquareDistance(1));
-         mypoints.Append(dummypoint);
-         mypoints.Append(dummypoint);
-         mySqDist.Append(AlgExt.SquareDistance(2));
-         mypoints.Append(dummypoint);
-         mypoints.Append(dummypoint);
-       }
-      }        
+      PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
     }
     else {
       NbExt = AlgExt.NbExt();
       for (i = 1; i <= NbExt; i++) {
        // Verification de la validite des parametres
        AlgExt.Points(i, P1, P2);
-       if (!inverse) {
+        if (!theIsInverse)
+        {
          U = P1.Parameter();
          U2 = P2.Parameter();
        }
@@ -649,10 +737,10 @@ void Extrema_ExtCC::Results(const Extrema_ExtElC&  AlgExt,
            (U  <= Ut12 + RealEpsilon())  &&
            (U2 >= Ut21 - RealEpsilon())  &&
            (U2 <= Ut22 + RealEpsilon())) {
-         mynbext++;
          Val = AlgExt.SquareDistance(i);
          mySqDist.Append(Val);
-         if (!inverse) {
+          if (!theIsInverse)
+          {
            P1.SetValues(U, P1.Value());
            P2.SetValues(U2, P2.Value());
            mypoints.Append(P1);
@@ -677,11 +765,11 @@ void Extrema_ExtCC::Results(const Extrema_ExtElC&  AlgExt,
 //purpose  : 
 //=======================================================================
 
-void Extrema_ExtCC::Results(const Extrema_ECC&   AlgExt,
-                            const Standard_Real  Ut11,
-                            const Standard_Real  Ut12,
-                            const Standard_Real  Ut21,
-                            const Standard_Real  Ut22)
+void Extrema_ExtCC::PrepareResults(const Extrema_ECC&   AlgExt,
+                                   const Standard_Real  Ut11,
+                                   const Standard_Real  Ut12,
+                                   const Standard_Real  Ut21,
+                                   const Standard_Real  Ut22)
 {
   Standard_Integer i, NbExt;
   Standard_Real Val, U, U2;
@@ -691,35 +779,41 @@ void Extrema_ExtCC::Results(const Extrema_ECC&   AlgExt,
   if (myDone)
   {
     myIsPar = AlgExt.IsParallel();
-    NbExt = AlgExt.NbExt();
-    for (i = 1; i <= NbExt; i++)
+    if (myIsPar)
     {
-      AlgExt.Points(i, P1, P2);
-      U = P1.Parameter();
-      U2 = P2.Parameter();
-
-      // Check points to be into param space.
-      if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[0])))
-      {
-        U = ElCLib::InPeriod(U, Ut11, Ut11+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[0])));
-      }
-      if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[1])))
-      {
-        U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[1])));
-      }
-
-      if ((U  >= Ut11 - RealEpsilon())  &&
-          (U  <= Ut12 + RealEpsilon())  &&
-          (U2 >= Ut21 - RealEpsilon())  &&
-          (U2 <= Ut22 + RealEpsilon())   )
+      PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
+    }
+    else
+    {
+      NbExt = AlgExt.NbExt();
+      for (i = 1; i <= NbExt; i++)
       {
-        mynbext++;
-        Val = AlgExt.SquareDistance(i);
-        mySqDist.Append(Val);
-        P1.SetValues(U, P1.Value());
-        P2.SetValues(U2, P2.Value());
-        mypoints.Append(P1);
-        mypoints.Append(P2);
+        AlgExt.Points(i, P1, P2);
+        U = P1.Parameter();
+        U2 = P2.Parameter();
+
+        // Check points to be into param space.
+        if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[0])))
+        {
+          U = ElCLib::InPeriod(U, Ut11, Ut11 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[0])));
+        }
+        if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[1])))
+        {
+          U2 = ElCLib::InPeriod(U2, Ut21, Ut21 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[1])));
+        }
+
+        if ((U >= Ut11 - RealEpsilon()) &&
+            (U <= Ut12 + RealEpsilon()) &&
+            (U2 >= Ut21 - RealEpsilon()) &&
+            (U2 <= Ut22 + RealEpsilon()))
+        {
+          Val = AlgExt.SquareDistance(i);
+          mySqDist.Append(Val);
+          P1.SetValues(U, P1.Value());
+          P2.SetValues(U2, P2.Value());
+          mypoints.Append(P1);
+          mypoints.Append(P2);
+        }
       }
     }
   }
index 57180fe..d8d17f1 100644 (file)
@@ -96,13 +96,35 @@ public:
 
 protected:
 
-  
-  Standard_EXPORT void Results (const Extrema_ExtElC& AlgExt, const Standard_Real Ut11, const Standard_Real Ut12, const Standard_Real Ut21, const Standard_Real Ut22);
-  
-  Standard_EXPORT void Results (const Extrema_ECC& AlgExt, const Standard_Real Ut11, const Standard_Real Ut12, const Standard_Real Ut21, const Standard_Real Ut22);
-
-
-
+  //! Prepares the extrema result(s) for analytical cases (line, circle, ellipsis etc.)
+  Standard_EXPORT void PrepareResults (const Extrema_ExtElC& AlgExt,
+                                       const Standard_Boolean theIsInverse,
+                                       const Standard_Real Ut11,
+                                       const Standard_Real Ut12,
+                                       const Standard_Real Ut21,
+                                       const Standard_Real Ut22);
+  
+  //! Prepares the extrema result(s) for general cases (e.g. with B-spline curves).
+  Standard_EXPORT void PrepareResults (const Extrema_ECC& AlgExt,
+                                       const Standard_Real Ut11,
+                                       const Standard_Real Ut12,
+                                       const Standard_Real Ut21,
+                                       const Standard_Real Ut22);
+
+  //! Prepares the extrema result(s) in case when the given curves are parallel.
+  Standard_EXPORT void PrepareParallelResult(const Standard_Real theUt11,
+                                             const Standard_Real theUt12,
+                                             const Standard_Real theUt21,
+                                             const Standard_Real theUt22,
+                                             const Standard_Real theSqDist);
+
+  // Clears all found extremas.
+  // This method does not change any flags (e.g. Done or IsParallel)
+  void ClearSolutions()
+  {
+    mySqDist.Clear();
+    mypoints.Clear();
+  }
 
 private:
 
@@ -113,8 +135,6 @@ private:
   Standard_Boolean myIsPar;
   Extrema_SequenceOfPOnCurv mypoints;
   TColStd_SequenceOfReal mySqDist;
-  Standard_Integer mynbext;
-  Standard_Boolean inverse;
   Standard_Address myC[2];
   Standard_Real myInf[2];
   Standard_Real mySup[2];
index 25cc8cd..05b65ea 100644 (file)
@@ -461,32 +461,52 @@ Standard_Boolean Extrema_ExtCS::IsDone() const
 
 Standard_Boolean Extrema_ExtCS::IsParallel() const
 {
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+
   return myIsPar;
 }
 
 
 Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if (myIsPar && N != 1) throw StdFail_InfiniteSolutions();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return mySqDist.Value(N);
 }
 
 
 Standard_Integer Extrema_ExtCS::NbExt() const
 {
-  if(!myDone) throw StdFail_NotDone();
-  return myPOnC.Length();
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+
+  return mySqDist.Length();
 }
 
 
 
 void Extrema_ExtCS::Points(const Standard_Integer N,
-  Extrema_POnCurv&       P1,
-  Extrema_POnSurf&       P2) const
+                           Extrema_POnCurv&       P1,
+                           Extrema_POnSurf&       P2) const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   P1 = myPOnC.Value(N);
   P2 = myPOnS.Value(N);
 }
index 18003ed..8c81128 100644 (file)
@@ -232,6 +232,13 @@ ExtremaExtElC_TrigonometricRoots::
 Extrema_ExtElC::Extrema_ExtElC () 
 {
   myDone = Standard_False; 
+  myIsPar = Standard_False;
+  myNbExt = 0;
+
+  for (Standard_Integer i = 0; i < 6; i++)
+  {
+    mySqDist[i] = RealLast();
+  }
 }
 //=======================================================================
 //function : Extrema_ExtElC
@@ -312,7 +319,8 @@ Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& theC1,
 
   if (myIsPar)
   {
-    mySqDist[0] = mySqDist[1] = theC2.SquareDistance(theC1.Location());
+    mySqDist[0] = theC2.SquareDistance(theC1.Location());
+    myNbExt = 1;
     myDone = Standard_True;
     return;
   }
@@ -558,6 +566,7 @@ Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1,
   if (Sol.InfiniteRoots()) { 
     myIsPar = Standard_True;
     mySqDist[0] = R*R;
+    myNbExt = 1;
     myDone = Standard_True;
     return; 
   }
@@ -901,128 +910,134 @@ Extrema_ExtElC::Extrema_ExtElC (const gp_Circ& C1,
   if (!bIsSamePlane) {
     return;
   }
+
+  // Here, both circles are in the same plane.
+
   //
   aDC2=aPc1.SquareDistance(aPc2);
   bIsSameAxe=aDC2<aTolD2;
   //
-  if(bIsSameAxe) {
+  if(bIsSameAxe)
+  {
     myIsPar = Standard_True;
-    Standard_Real dR = C1.Radius() - C2.Radius();
-    Standard_Real dC = C1.Location().Distance(C2.Location());
-    mySqDist[0] = dR*dR + dC*dC;
-    dR = C1.Radius() + C2.Radius();
-    mySqDist[1] = dR*dR + dC*dC;
-    myDone = Standard_True; 
+    myNbExt = 1;
+    myDone = Standard_True;
+    const Standard_Real aDR = C1.Radius() - C2.Radius();
+    mySqDist[0] = aDR*aDR;
+    return;
   }
-  else {
-    Standard_Boolean bIn, bOut;
-    Standard_Integer j1, j2;
-    Standard_Real aR1, aR2, aD12, aT11, aT12, aT21, aT22;
-    gp_Circ aC1, aC2;
-    gp_Pnt aP11, aP12, aP21, aP22;
-    //
-    myDone = Standard_True; 
-    //
-    aR1=C1.Radius();
-    aR2=C2.Radius();
+
+  Standard_Boolean bIn, bOut;
+  Standard_Integer j1, j2;
+  Standard_Real aR1, aR2, aD12, aT11, aT12, aT21, aT22;
+  gp_Circ aC1, aC2;
+  gp_Pnt aP11, aP12, aP21, aP22;
+  //
+  myDone = Standard_True;
+  //
+  aR1 = C1.Radius();
+  aR2 = C2.Radius();
+  //
+  j1 = 0;
+  j2 = 1;
+  aC1 = C1;
+  aC2 = C2;
+  if (aR2 > aR1)
+  {
+    j1 = 1;
+    j2 = 0;
+    aC1 = C2;
+    aC2 = C1;
+  }
+  //
+  aR1 = aC1.Radius(); // max radius
+  aR2 = aC2.Radius(); // min radius
+  //
+  aPc1 = aC1.Location();
+  aPc2 = aC2.Location();
+  //
+  aD12 = aPc1.Distance(aPc2);
+  gp_Vec aVec12(aPc1, aPc2);
+  gp_Dir aDir12(aVec12);
+  //
+  // 1. Four common solutions
+  myNbExt = 4;
+  //
+  aP11.SetXYZ(aPc1.XYZ() - aR1*aDir12.XYZ());
+  aP12.SetXYZ(aPc1.XYZ() + aR1*aDir12.XYZ());
+  aP21.SetXYZ(aPc2.XYZ() - aR2*aDir12.XYZ());
+  aP22.SetXYZ(aPc2.XYZ() + aR2*aDir12.XYZ());
+  //
+  aT11 = ElCLib::Parameter(aC1, aP11);
+  aT12 = ElCLib::Parameter(aC1, aP12);
+  aT21 = ElCLib::Parameter(aC2, aP21);
+  aT22 = ElCLib::Parameter(aC2, aP22);
+  //
+  // P11, P21
+  myPoint[0][j1].SetValues(aT11, aP11);
+  myPoint[0][j2].SetValues(aT21, aP21);
+  mySqDist[0] = aP11.SquareDistance(aP21);
+  // P11, P22
+  myPoint[1][j1].SetValues(aT11, aP11);
+  myPoint[1][j2].SetValues(aT22, aP22);
+  mySqDist[1] = aP11.SquareDistance(aP22);
+  //
+  // P12, P21
+  myPoint[2][j1].SetValues(aT12, aP12);
+  myPoint[2][j2].SetValues(aT21, aP21);
+  mySqDist[2] = aP12.SquareDistance(aP21);
+  //
+  // P12, P22
+  myPoint[3][j1].SetValues(aT12, aP12);
+  myPoint[3][j2].SetValues(aT22, aP22);
+  mySqDist[3] = aP12.SquareDistance(aP22);
+  //
+  // 2. Check for intersections
+  bOut = aD12 > (aR1 + aR2 + aTolD);
+  bIn = aD12 < (aR1 - aR2 - aTolD);
+  if (!bOut && !bIn)
+  {
+    Standard_Boolean bNbExt6;
+    Standard_Real aAlpha, aBeta, aT[2], aVal, aDist2;
+    gp_Pnt aPt, aPL1, aPL2;
+    gp_Dir aDLt;
     //
-    j1=0;
-    j2=1;
-    aC1=C1;
-    aC2=C2;
-    if (aR2>aR1) {
-      j1=1;
-      j2=0;
-      aC1=C2;
-      aC2=C1;
+    aAlpha = 0.5*(aR1*aR1 - aR2*aR2 + aD12*aD12) / aD12;
+    aVal = aR1*aR1 - aAlpha*aAlpha;
+    if (aVal < 0.)
+    {// see pkv/900/L4 for details
+      aVal = -aVal;
     }
+    aBeta = Sqrt(aVal);
+    //aBeta=Sqrt(aR1*aR1-aAlpha*aAlpha);
+    //--
+    aPt.SetXYZ(aPc1.XYZ() + aAlpha*aDir12.XYZ());
     //
-    aR1=aC1.Radius(); // max radius
-    aR2=aC2.Radius(); // min radius
-    //
-    aPc1=aC1.Location();
-    aPc2=aC2.Location();
-    //
-    aD12=aPc1.Distance(aPc2);
-    gp_Vec aVec12(aPc1, aPc2);
-    gp_Dir aDir12(aVec12);
-    //
-    // 1. Four common solutions
-    myNbExt=4;
-    //
-    aP11.SetXYZ(aPc1.XYZ()-aR1*aDir12.XYZ());
-    aP12.SetXYZ(aPc1.XYZ()+aR1*aDir12.XYZ());
-    aP21.SetXYZ(aPc2.XYZ()-aR2*aDir12.XYZ());
-    aP22.SetXYZ(aPc2.XYZ()+aR2*aDir12.XYZ());
-    //
-    aT11=ElCLib::Parameter(aC1, aP11);
-    aT12=ElCLib::Parameter(aC1, aP12);
-    aT21=ElCLib::Parameter(aC2, aP21);
-    aT22=ElCLib::Parameter(aC2, aP22);
+    aDLt = aDc1^aDir12;
+    aPL1.SetXYZ(aPt.XYZ() + aBeta*aDLt.XYZ());
+    aPL2.SetXYZ(aPt.XYZ() - aBeta*aDLt.XYZ());
     //
-    // P11, P21
-    myPoint[0][j1].SetValues(aT11, aP11);
-    myPoint[0][j2].SetValues(aT21, aP21);
-    mySqDist[0]=aP11.SquareDistance(aP21);
-    // P11, P22
-    myPoint[1][j1].SetValues(aT11, aP11);
-    myPoint[1][j2].SetValues(aT22, aP22);
-    mySqDist[1]=aP11.SquareDistance(aP22);
+    aDist2 = aPL1.SquareDistance(aPL2);
+    bNbExt6 = aDist2 > aTolD2;
     //
-    // P12, P21
-    myPoint[2][j1].SetValues(aT12, aP12);
-    myPoint[2][j2].SetValues(aT21, aP21);
-    mySqDist[2]=aP12.SquareDistance(aP21);
+    myNbExt = 5;// just in case. see pkv/900/L4 for details
+    aT[j1] = ElCLib::Parameter(aC1, aPL1);
+    aT[j2] = ElCLib::Parameter(aC2, aPL1);
+    myPoint[4][j1].SetValues(aT[j1], aPL1);
+    myPoint[4][j2].SetValues(aT[j2], aPL1);
+    mySqDist[4] = 0.;
     //
-    // P12, P22
-    myPoint[3][j1].SetValues(aT12, aP12);
-    myPoint[3][j2].SetValues(aT22, aP22);
-    mySqDist[3]=aP12.SquareDistance(aP22);
+    if (bNbExt6)
+    {
+      myNbExt = 6;
+      aT[j1] = ElCLib::Parameter(aC1, aPL2);
+      aT[j2] = ElCLib::Parameter(aC2, aPL2);
+      myPoint[5][j1].SetValues(aT[j1], aPL2);
+      myPoint[5][j2].SetValues(aT[j2], aPL2);
+      mySqDist[5] = 0.;
+    }
     //
-    // 2. Check for intersections
-    bOut=aD12>(aR1+aR2+aTolD);
-    bIn =aD12<(aR1-aR2-aTolD);
-    if (!bOut && !bIn) {
-      Standard_Boolean bNbExt6;
-      Standard_Real aAlpha, aBeta, aT[2], aVal, aDist2;
-      gp_Pnt aPt, aPL1, aPL2;
-      gp_Dir aDLt;
-      //
-      aAlpha=0.5*(aR1*aR1-aR2*aR2+aD12*aD12)/aD12;
-      aVal=aR1*aR1-aAlpha*aAlpha;
-      if (aVal<0.) {// see pkv/900/L4 for details
-       aVal=-aVal;
-      }
-      aBeta=Sqrt(aVal);
-      //aBeta=Sqrt(aR1*aR1-aAlpha*aAlpha);
-      //--
-      aPt.SetXYZ(aPc1.XYZ()+aAlpha*aDir12.XYZ());
-      //
-      aDLt=aDc1^aDir12;
-      aPL1.SetXYZ(aPt.XYZ()+aBeta*aDLt.XYZ());
-      aPL2.SetXYZ(aPt.XYZ()-aBeta*aDLt.XYZ());
-      //
-      aDist2=aPL1.SquareDistance(aPL2);
-      bNbExt6=aDist2>aTolD2;
-      //
-      myNbExt=5;// just in case. see pkv/900/L4 for details
-      aT[j1]=ElCLib::Parameter(aC1, aPL1);
-      aT[j2]=ElCLib::Parameter(aC2, aPL1);
-      myPoint[4][j1].SetValues(aT[j1], aPL1);
-      myPoint[4][j2].SetValues(aT[j2], aPL1);
-      mySqDist[4]=0.;
-      //
-      if (bNbExt6) {
-       myNbExt=6;
-       aT[j1]=ElCLib::Parameter(aC1, aPL2);
-       aT[j2]=ElCLib::Parameter(aC2, aPL2);
-       myPoint[5][j1].SetValues(aT[j1], aPL2);
-       myPoint[5][j2].SetValues(aT[j2], aPL2);
-       mySqDist[5]=0.;
-      }
-      //
-    }// if (!bOut || !bIn) {
-  }// else
+  }// if (!bOut || !bIn) {
 }
 
 //=======================================================================
@@ -1049,8 +1064,9 @@ Standard_Boolean Extrema_ExtElC::IsParallel () const
 //=======================================================================
 Standard_Integer Extrema_ExtElC::NbExt () const
 {
-  if (IsParallel()) {
-    throw StdFail_InfiniteSolutions();
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
   }
   return myNbExt;
 }
@@ -1060,20 +1076,12 @@ Standard_Integer Extrema_ExtElC::NbExt () const
 //=======================================================================
 Standard_Real Extrema_ExtElC::SquareDistance (const Standard_Integer N) const
 {
-  if (!myDone) { 
-    throw StdFail_NotDone();
-  }
-  if (myIsPar) {
-    if (N < 1 || N > 2) { 
-      throw Standard_OutOfRange();
-    }
-  }
-  else {  
-    if (N < 1 || N > NbExt()) { 
-      throw Standard_OutOfRange();
-    }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
   }
-  return mySqDist[N-1];
+
+  return mySqDist[N - 1];
 }
 //=======================================================================
 //function : Points
@@ -1083,9 +1091,16 @@ void Extrema_ExtElC::Points (const Standard_Integer N,
                             Extrema_POnCurv& P1, 
                             Extrema_POnCurv& P2) const
 {
-  if (N < 1 || N > NbExt()) { 
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
     throw Standard_OutOfRange();
   }
+
   P1 = myPoint[N-1][0];
   P2 = myPoint[N-1][1];
 }
index ac245de..99274b7 100644 (file)
 #include <StdFail_InfiniteSolutions.hxx>
 #include <StdFail_NotDone.hxx>
 
-//=============================================================================
-Extrema_ExtElC2d::Extrema_ExtElC2d () { myDone = Standard_False; }
-//=============================================================================
+//=======================================================================
+//function : Extrema_ExtElC2d
+//purpose  :
+//=======================================================================
+Extrema_ExtElC2d::Extrema_ExtElC2d()
+{
+  myDone = Standard_False;
+  myIsPar = Standard_False;
+  myNbExt = 0;
+
+  for (Standard_Integer i = 0; i < 8; i++)
+  {
+    mySqDist[i] = RealLast();
+  }
+}
 
 //=======================================================================
 //function : Extrema_ExtElC2d
@@ -67,6 +79,7 @@ Method:
   {
     myIsPar = Standard_True;
     mySqDist[0] = C2.SquareDistance(C1.Location());
+    myNbExt = 1;
   }
   else
   {
@@ -283,9 +296,14 @@ Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Circ2d& C2)
   gp_Pnt2d O2 = C2.Location();
 
   gp_Vec2d DO1O2 (O1, O2);
-  if (DO1O2.Magnitude() < Precision::Confusion()) { 
+  const Standard_Real aSqDCenters = DO1O2.SquareMagnitude();
+  if (aSqDCenters < Precision::SquareConfusion()) { 
     myIsPar = Standard_True;
-    return; 
+    myNbExt = 1;
+    myDone = Standard_True;
+    const Standard_Real aDR = C1.Radius() - C2.Radius();
+    mySqDist[0] = aDR*aDR;
+    return;
   }
 
   Standard_Integer NoSol, kk;
@@ -293,7 +311,7 @@ Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Circ2d& C2)
   Standard_Real r1 = C1.Radius(), r2 = C2.Radius();
   Standard_Real Usol2[2], Usol1[2];
   gp_Pnt2d P1[2], P2[2];
-  gp_Dir2d O1O2(DO1O2);
+  gp_Vec2d O1O2(DO1O2/Sqrt(aSqDCenters));
 
   P1[0] = O1.Translated(r1*O1O2);
   Usol1[0] = ElCLib::Parameter(C1, P1[0]);
@@ -417,17 +435,23 @@ Standard_Boolean Extrema_ExtElC2d::IsParallel () const
 
 Standard_Integer Extrema_ExtElC2d::NbExt () const
 {
-  if (IsParallel()) { throw StdFail_InfiniteSolutions(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+
   return myNbExt;
 }
 //============================================================================
 
 Standard_Real Extrema_ExtElC2d::SquareDistance (const Standard_Integer N) const
 {
-  if (!(N == 1 && myDone)) {
-    if (N < 1 || N > NbExt()) { throw Standard_OutOfRange(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
   }
-  return mySqDist[N-1];
+
+  return mySqDist[N - 1];
 }
 //============================================================================
 
@@ -435,6 +459,11 @@ void Extrema_ExtElC2d::Points (const Standard_Integer N,
                               Extrema_POnCurv2d& P1, 
                               Extrema_POnCurv2d& P2) const
 {
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
   if (N < 1 || N > NbExt()) { throw Standard_OutOfRange(); }
   P1 = myPoint[N-1][0];
   P2 = myPoint[N-1][1];
index 31e5f80..63d0a91 100644 (file)
@@ -45,6 +45,7 @@ Extrema_ExtElCS::Extrema_ExtElCS()
 {
   myDone = Standard_False;
   myIsPar = Standard_False;
+  myNbExt = 0;
 }
 
 
@@ -61,17 +62,16 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
 {
   myDone = Standard_True;
   myIsPar = Standard_False;
+  myNbExt = 0;
 
-  if (C.Direction().IsNormal(S.Axis().Direction(), 
-                            Precision::Angular())) {
+  if (C.Direction().IsNormal(S.Axis().Direction(),
+                            Precision::Angular()))
+  {
     mySqDist = new TColStd_HArray1OfReal(1, 1);
     mySqDist->SetValue(1, S.SquareDistance(C));
     myIsPar = Standard_True;
+    myNbExt = 1;
   }
-  else {
-    myNbExt = 0;
-  }
-  
 }
 
 
@@ -91,45 +91,17 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
   myIsPar = Standard_False;
 
   gp_Ax3 Pos = S.Position();
-  gp_Pnt Origin = Pos.Location();
-  gp_Pnt LineOrig = C.Location();
+
+  Standard_Boolean isParallel = Standard_False;
 
   Standard_Real radius = S.Radius();
   Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
-  if (Extrem.IsParallel()) {
-    // Line direction is similar to cylinder axis of rotation.
-    mySqDist = new TColStd_HArray1OfReal(1, 1);
-    myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
-    myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
-    Standard_Real aDist = sqrt(Extrem.SquareDistance(1)) - radius;
-    mySqDist->SetValue(1, aDist * aDist);
-    Standard_Real u, v, w;
-    gp_Vec aVec(LineOrig, Origin);
-    gp_Vec aDirVec(C.Direction());
-    w = aVec*aDirVec;
-    gp_Pnt LinPoint = LineOrig.Translated(w * aDirVec);
-    Extrema_POnCurv PonC(w, LinPoint);
-    myPoint1->SetValue(1, PonC);
-    gp_Pnt CylPoint;
-    gp_Vec OrigToLine(Origin, LinPoint);
-    if (OrigToLine.Magnitude() <= gp::Resolution())
-    {
-      u = 0.;
-      v = 0.;
-      CylPoint = ElSLib::Value(u, v, S);
-    }
-    else
-    {
-      OrigToLine.Normalize();
-      CylPoint = Origin.Translated(radius * OrigToLine);
-      ElSLib::CylinderParameters(Pos, radius, CylPoint, u, v);
-    }
-    Extrema_POnSurf PonS(u, v, CylPoint);
-    myPoint2->SetValue(1, PonS);
-    myDone = Standard_True;
-    myIsPar = Standard_True;
+  if (Extrem.IsParallel())
+  {
+    isParallel = Standard_True;
   }
-  else {
+  else
+  {
     Standard_Integer i, aStartIdx = 0;
 
     Extrema_POnCurv myPOnC1, myPOnC2;
@@ -142,7 +114,11 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
     {
       IntAna_Quadric theQuadric(S);
       IntAna_IntConicQuad Inters(C, theQuadric);
-      if (Inters.IsDone())
+      if (Inters.IsDone() && Inters.IsInQuadric())
+      {
+        isParallel = Standard_True;
+      }
+      else if (Inters.IsDone())
       {
         myNbExt = Inters.NbPoints();
         aStartIdx = myNbExt;
@@ -167,9 +143,10 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
         }
       }
     }
-
-    // line is tangent or outside of the cylinder
-    Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
+    else
+    {
+      // line is tangent or outside of the cylinder
+      Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
       if (ExPS.IsDone())
       {
         if (aStartIdx == 0)
@@ -182,15 +159,45 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
         else
           myNbExt += ExPS.NbExt();
 
-        for (i = aStartIdx + 1; i <= myNbExt; i++) {
+        for (i = aStartIdx + 1; i <= myNbExt; i++)
+        {
           myPoint1->SetValue(i, myPOnC2);
           myPoint2->SetValue(i, ExPS.Point(i - aStartIdx));
-          mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
+          mySqDist->SetValue(i, (myPOnC2.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
         }
       }
+    }
+    
     myDone = Standard_True;
   }
 
+  if (isParallel)
+  {
+    // Line direction is similar to cylinder axis of rotation.
+    // The case is possible when either extrema returned parallel status
+    // or Intersection tool returned infinite number of solutions.
+    // This is possible due to Intersection algorithm uses more precise
+    // characteristics to consider given geometries parallel.
+    // In the latter case there may be several extremas, thus we look for
+    // the one with the lowest distance and use it as a final solution.
+    mySqDist = new TColStd_HArray1OfReal(1, 1);
+    Standard_Real aDist = Extrem.SquareDistance(1);
+    const Standard_Integer aNbExt = Extrem.NbExt();
+    for (Standard_Integer i = 2; i <= aNbExt; i++)
+    {
+      const Standard_Real aD = Extrem.SquareDistance(i);
+      if (aD < aDist)
+      {
+        aDist = aD;
+      }
+    }
+      
+    aDist = sqrt(aDist) - radius;
+    mySqDist->SetValue(1, aDist * aDist);
+    myDone = Standard_True;
+    myIsPar = Standard_True;
+    myNbExt = 1;
+  }
 }
 
 
@@ -324,17 +331,16 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
 {
   myDone = Standard_True;
   myIsPar = Standard_False;
+  myNbExt = 0;
 
   gp_Ax2 Pos = C.Position();
   gp_Dir NCirc = Pos.Direction();
   gp_Dir NPln = S.Axis().Direction();
 
-  if (NCirc.IsParallel(NPln, Precision::Angular())) {
-
-    mySqDist = new TColStd_HArray1OfReal(1, 1);
-    mySqDist->SetValue(1, S.SquareDistance(C.Location()));
-    myIsPar = Standard_True;
+  Standard_Boolean isParallel = Standard_False;
 
+  if (NCirc.IsParallel(NPln, Precision::Angular())) {
+    isParallel = Standard_True;
   }
   else {
 
@@ -356,7 +362,12 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
     IntAna_IntConicQuad anInter(C, S,
                                 Precision::Angular(),
                                 Precision::Confusion());
-    if(anInter.IsDone())
+
+    if (anInter.IsDone() && anInter.IsInQuadric())
+    {
+      isParallel = Standard_True;
+    }
+    else if (anInter.IsDone())
     {
       if(anInter.NbPoints() > 1)
       {
@@ -364,49 +375,57 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
       }
     }
 
-    myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
-    mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
-    myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
-
-    Standard_Integer i;
-    gp_Pnt PC, PP;
-    Standard_Real U, V;
-    Extrema_POnCurv POnC;
-    Extrema_POnSurf POnS;
-    for(i = 0; i < 2; ++i)
+    if (!isParallel)
     {
-      PC = ElCLib::CircleValue(T[i], C.Position(), C.Radius());
-      POnC.SetValues(T[i], PC);
-      myPoint1->SetValue(i+1, POnC);
-      ElSLib::PlaneParameters(S.Position(), PC, U, V);
-      PP = ElSLib::PlaneValue(U, V, S.Position());
-      POnS.SetParameters(U, V, PP);
-      myPoint2->SetValue(i+1, POnS);
-      mySqDist->SetValue(i+1, PC.SquareDistance(PP));
-    }
-    //
-    if(myNbExt > 2)
-    {
-      //Add intersection points
-      for(i = 1; i <= anInter.NbPoints(); ++i)
+      myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
+      mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
+      myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
+
+      Standard_Integer i;
+      gp_Pnt PC, PP;
+      Standard_Real U, V;
+      Extrema_POnCurv POnC;
+      Extrema_POnSurf POnS;
+      for (i = 0; i < 2; ++i)
       {
-        Standard_Real t = anInter.ParamOnConic(i);
-        PC = ElCLib::CircleValue(t, C.Position(), C.Radius());
-        POnC.SetValues(t, PC);
-        myPoint1->SetValue(i+2, POnC);
+        PC = ElCLib::CircleValue(T[i], C.Position(), C.Radius());
+        POnC.SetValues(T[i], PC);
+        myPoint1->SetValue(i + 1, POnC);
         ElSLib::PlaneParameters(S.Position(), PC, U, V);
         PP = ElSLib::PlaneValue(U, V, S.Position());
         POnS.SetParameters(U, V, PP);
-        myPoint2->SetValue(i+2, POnS);
-        mySqDist->SetValue(i+2, PC.SquareDistance(PP));
+        myPoint2->SetValue(i + 1, POnS);
+        mySqDist->SetValue(i + 1, PC.SquareDistance(PP));
+      }
+      //
+      if (myNbExt > 2)
+      {
+        //Add intersection points
+        for (i = 1; i <= anInter.NbPoints(); ++i)
+        {
+          Standard_Real t = anInter.ParamOnConic(i);
+          PC = ElCLib::CircleValue(t, C.Position(), C.Radius());
+          POnC.SetValues(t, PC);
+          myPoint1->SetValue(i + 2, POnC);
+          ElSLib::PlaneParameters(S.Position(), PC, U, V);
+          PP = ElSLib::PlaneValue(U, V, S.Position());
+          POnS.SetParameters(U, V, PP);
+          myPoint2->SetValue(i + 2, POnS);
+          mySqDist->SetValue(i + 2, PC.SquareDistance(PP));
+        }
       }
     }
   }
-  //  
+  
+  if (isParallel)
+  {
+    mySqDist = new TColStd_HArray1OfReal(1, 1);
+    mySqDist->SetValue(1, S.SquareDistance(C.Location()));
+    myIsPar = Standard_True;
+    myNbExt = 1;
+  }
 }
 
-
-
 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
                                 const gp_Cylinder& S)
 {
@@ -430,29 +449,38 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
   // Compute extrema between the circle and the line.
   Extrema_ExtElC anExtC(anAxis, C, 0.);
 
-  if (anExtC.IsDone()) {
-    if (anExtC.IsParallel()) {
-      myIsPar =     Standard_True;
-      mySqDist = new TColStd_HArray1OfReal(1, 1);
-      Standard_Real aDist = sqrt (anExtC.SquareDistance(1)) - S.Radius();
-      mySqDist->SetValue(1, aDist * aDist);
-    } else {
-      Standard_Integer aNbExt   = anExtC.NbExt();
-      Standard_Integer i;
-      Standard_Integer aCurI    = 1;
-      Standard_Real    aTolConf = Precision::Confusion();
-      Standard_Real    aCylRad  = S.Radius();
+  if (!anExtC.IsDone())
+    return;
 
-      // Check whether two objects have intersection points
-      IntAna_Quadric aCylQuad(S);
-      IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
-      Standard_Integer aNbInter = 0;
-      if (aCircCylInter.IsDone())
-        aNbInter = aCircCylInter.NbPoints();
+  Standard_Boolean isParallel = Standard_False;
+
+  if (anExtC.IsParallel()) {
+    isParallel = Standard_True;
+  } else {
+    Standard_Integer aNbExt   = anExtC.NbExt();
+    Standard_Integer i;
+    Standard_Integer aCurI    = 1;
+    Standard_Real    aTolConf = Precision::Confusion();
+    Standard_Real    aCylRad  = S.Radius();
+
+    // Check whether two objects have intersection points
+    IntAna_Quadric aCylQuad(S);
+    IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
+    Standard_Integer aNbInter = 0;
+    if (aCircCylInter.IsDone() && aCircCylInter.IsInQuadric())
+    {
+      isParallel = Standard_True;
+    }
+    else if (aCircCylInter.IsDone())
+    {
+      aNbInter = aCircCylInter.NbPoints();
+    }
 
+    if (!isParallel)
+    {
       // Compute the extremas.
-      myNbExt  =     2*aNbExt + aNbInter;
-      mySqDist  = new TColStd_HArray1OfReal(1, myNbExt);
+      myNbExt = 2 * aNbExt + aNbInter;
+      mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
       myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
       myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
 
@@ -460,7 +488,7 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
         Extrema_POnCurv aPOnAxis;
         Extrema_POnCurv aPOnCirc;
         Standard_Real   aSqDist = anExtC.SquareDistance(i);
-        Standard_Real   aDist = sqrt (aSqDist);
+        Standard_Real   aDist = sqrt(aSqDist);
 
         anExtC.Points(i, aPOnAxis, aPOnCirc);
 
@@ -470,7 +498,7 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
         }
 
         gp_Dir aDir(aPOnAxis.Value().XYZ().Subtracted(aPOnCirc.Value().XYZ()));
-        Standard_Real aShift[2] = { aDist + aCylRad, aDist - aCylRad };
+        Standard_Real aShift[2] = {aDist + aCylRad, aDist - aCylRad};
         Standard_Integer j;
 
         for (j = 0; j < 2; j++) {
@@ -511,8 +539,36 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
         mySqDist->SetValue(aCurI++, 0.0);
       }
     }
+  }
 
-    myDone = Standard_True;
+  myDone = Standard_True;
+
+  if (isParallel)
+  {
+    // The case is possible when either extrema returned parallel status
+    // or Intersection tool returned infinite number of solutions.
+    // This is possible due to Intersection algorithm uses more precise
+    // characteristics to consider given geometries parallel.
+    // In the latter case there may be several extremas, thus we look for
+    // the one with the lowest distance and use it as a final solution.
+
+    myIsPar = Standard_True;
+    myNbExt = 1;
+    mySqDist = new TColStd_HArray1OfReal(1, 1);
+    Standard_Real aDist = anExtC.SquareDistance(1);
+
+    const Standard_Integer aNbExt = anExtC.NbExt();
+    for (Standard_Integer i = 2; i <= aNbExt; i++)
+    {
+      const Standard_Real aD = anExtC.SquareDistance(i);
+      if (aD < aDist)
+      {
+        aDist = aD;
+      }
+    }
+
+    aDist = sqrt(aDist) - S.Radius();
+    mySqDist->SetValue(1, aDist * aDist);
   }
 }
 //  Modified by skv - Thu Jul  7 14:37:05 2005 OCC9134 End
@@ -554,12 +610,15 @@ void Extrema_ExtElCS::Perform(const gp_Circ& C,
                               const gp_Sphere& S)
 {
   myDone = Standard_False;
+  myIsPar = Standard_False;
+  myNbExt = 0;
 
   if (gp_Lin(C.Axis()).SquareDistance(S.Location()) < Precision::SquareConfusion())
   {
     // Circle and sphere are parallel
     myIsPar = Standard_True;
     myDone = Standard_True;
+    myNbExt = 1;
 
     // Compute distance from circle to the sphere
     Standard_Real aSqDistLoc = C.Location().SquareDistance(S.Location());
@@ -697,6 +756,7 @@ void Extrema_ExtElCS::Perform(const gp_Hypr& C,
 {
   myDone = Standard_True;
   myIsPar = Standard_False;
+  myNbExt = 0;
 
   gp_Ax2 Pos = C.Position();
   gp_Dir NHypr = Pos.Direction();
@@ -707,7 +767,7 @@ void Extrema_ExtElCS::Perform(const gp_Hypr& C,
     mySqDist = new TColStd_HArray1OfReal(1, 1);
     mySqDist->SetValue(1, S.SquareDistance(C.Location()));
     myIsPar = Standard_True;
-
+    myNbExt = 1;
   }
   else {
 
@@ -736,12 +796,7 @@ void Extrema_ExtElCS::Perform(const gp_Hypr& C,
 
       myNbExt = 1;
     }
-    else {
-      myNbExt = 0;
-    }
-
   }
-  
 }
 
 
@@ -753,13 +808,17 @@ Standard_Boolean Extrema_ExtElCS::IsDone() const
 
 Standard_Integer Extrema_ExtElCS::NbExt() const
 {
-  if (myIsPar) throw StdFail_InfiniteSolutions();
+  if (!IsDone()) throw StdFail_NotDone();
   return myNbExt;
 }
 
 Standard_Real Extrema_ExtElCS::SquareDistance(const Standard_Integer N) const
 {
-  if (myIsPar && N != 1) throw StdFail_InfiniteSolutions();
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return mySqDist->Value(N);
 }
 
@@ -768,7 +827,16 @@ void Extrema_ExtElCS::Points(const Standard_Integer N,
                             Extrema_POnCurv& P1,
                             Extrema_POnSurf& P2) const
 {
-  if (myIsPar) throw StdFail_InfiniteSolutions();
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   P1 = myPoint1->Value(N);
   P2 = myPoint2->Value(N);
 }
@@ -776,5 +844,9 @@ void Extrema_ExtElCS::Points(const Standard_Integer N,
 
 Standard_Boolean Extrema_ExtElCS::IsParallel() const
 {
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return myIsPar;
 }
index 0c5dd2b..4aad73f 100644 (file)
@@ -31,6 +31,7 @@ Extrema_ExtElSS::Extrema_ExtElSS()
 {
   myDone = Standard_False;
   myIsPar = Standard_False;
+  myNbExt = 0;
 }
 
 
@@ -137,23 +138,25 @@ Standard_Boolean Extrema_ExtElSS::IsDone() const
 
 Standard_Boolean Extrema_ExtElSS::IsParallel() const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if (!IsDone()) throw StdFail_NotDone();
   return myIsPar;
 }
 
 
 Standard_Integer Extrema_ExtElSS::NbExt() const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if (myIsPar) throw StdFail_InfiniteSolutions();
+  if (!IsDone()) throw StdFail_NotDone();
   return myNbExt;
 }
 
 
 Standard_Real Extrema_ExtElSS::SquareDistance(const Standard_Integer N) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if (myIsPar && N != 1) throw StdFail_InfiniteSolutions();
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return mySqDist->Value(N);
 }
 
@@ -162,8 +165,16 @@ void Extrema_ExtElSS::Points(const Standard_Integer N,
                             Extrema_POnSurf&       P1,
                             Extrema_POnSurf&       P2) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if (myIsPar) throw StdFail_InfiniteSolutions();
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   P1 = myPOnS1->Value(N);
   P2 = myPOnS2->Value(N);
 }
index 6cccc46..53514f5 100644 (file)
 //function : Extrema_ExtPElC
 //purpose  : 
 //=======================================================================
-Extrema_ExtPElC::Extrema_ExtPElC () { myDone = Standard_False; }
+Extrema_ExtPElC::Extrema_ExtPElC()
+{
+  myDone = Standard_False;
+  myNbExt = 0;
+
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    mySqDist[i] = RealLast();
+    myIsMin[i] = Standard_False;
+  }
+}
 
 //=======================================================================
 //function : Extrema_ExtPElC
@@ -419,7 +429,7 @@ Method:
       Cu = ElCLib::Value(Us,C);
       DejaEnr = Standard_False;
       for (NoExt = 0; NoExt < myNbExt; NoExt++) {
-    if (TbExt[NoExt].SquareDistance(Cu) < Precision::SquareConfusion()) {
+        if (TbExt[NoExt].SquareDistance(Cu) < Precision::SquareConfusion()) {
          DejaEnr = Standard_True;
          break;
        }
index 8773309..460c595 100644 (file)
 #include <StdFail_NotDone.hxx>
 
 //=============================================================================
-Extrema_ExtPElC2d::Extrema_ExtPElC2d () { myDone = Standard_False; }
+Extrema_ExtPElC2d::Extrema_ExtPElC2d()
+{
+  myDone = Standard_False;
+  myNbExt = 0;
+
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    mySqDist[i] = RealLast();
+    myIsMin[i] = Standard_False;
+  }
+}
+
 //=============================================================================
 
 Extrema_ExtPElC2d::Extrema_ExtPElC2d 
@@ -162,6 +173,8 @@ void Extrema_ExtPElC2d::Perform (const gp_Pnt2d&     P,
   const Standard_Real Uinf, 
   const Standard_Real Usup)
 {
+  myDone = Standard_False;
+  myNbExt = 0;
   //  gp_Pnt2d OR, P1, P2;
   gp_Pnt2d OR;
   OR = E.Location();
@@ -173,7 +186,7 @@ void Extrema_ExtPElC2d::Perform (const gp_Pnt2d&     P,
 
   if (OR.IsEqual(P, Precision::Confusion()) &&
     (Abs(A-B) <= Tol)) {
-      myDone = Standard_False;
+      return;
   }
   else {
     Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
index 8257b55..d494bdd 100644 (file)
 static const Standard_Real ExtPElS_MyEps = Epsilon(2. * M_PI);
 //=============================================================================
 
-Extrema_ExtPElS::Extrema_ExtPElS () { myDone = Standard_False; }
+Extrema_ExtPElS::Extrema_ExtPElS()
+{
+  myDone = Standard_False;
+  myNbExt = 0;
+  for (Standard_Integer i = 0; i < 4; i++)
+  {
+    mySqDist[i] = RealLast();
+  }
+}
 //=============================================================================
 
 Extrema_ExtPElS::Extrema_ExtPElS (const gp_Pnt& P, 
@@ -416,16 +424,20 @@ Standard_Integer Extrema_ExtPElS::NbExt () const
 
 Standard_Real Extrema_ExtPElS::SquareDistance (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   return mySqDist[N-1];
 }
 //=============================================================================
 
 const Extrema_POnSurf& Extrema_ExtPElS::Point (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   return myPoint[N-1];
 }
 //=============================================================================
index 5329a15..969c8b6 100644 (file)
@@ -153,7 +153,7 @@ Extrema_ExtPExtS::Extrema_ExtPExtS()
   mytolv(0.0),
   myIsAnalyticallyComputable(Standard_False),
   myDone(Standard_False),
-  myNbExt(Standard_False)
+  myNbExt(0)
 {
 }
 
@@ -176,7 +176,7 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
   myS   (theS),
   myIsAnalyticallyComputable(Standard_False),
   myDone(Standard_False),
-  myNbExt(Standard_False)
+  myNbExt(0)
 {
   Initialize (theS,
               theUmin,
@@ -203,7 +203,7 @@ Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt&
   myS   (theS),
   myIsAnalyticallyComputable(Standard_False),
   myDone(Standard_False),
-  myNbExt(Standard_False)
+  myNbExt(0)
 {
   Initialize (theS,
               theS->FirstUParameter(),
@@ -237,6 +237,10 @@ void Extrema_ExtPExtS::Initialize (const Handle(GeomAdaptor_HSurfaceOfLinearExtr
   myvsup = theVsup;
   mytolv = theTolV;
   
+  myIsAnalyticallyComputable = Standard_False;
+  myDone = Standard_False;
+  myNbExt = 0;
+
   Handle(Adaptor3d_HCurve) anACurve = theS->BasisCurve();
 
   myF.Initialize (theS->ChangeSurface());
@@ -448,8 +452,10 @@ Standard_Integer Extrema_ExtPExtS::NbExt () const
 
 Standard_Real Extrema_ExtPExtS::SquareDistance (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   if (myIsAnalyticallyComputable)
     // modified by NIZHNY-MKK  Thu Sep 18 14:48:39 2003.BEGIN
     //     return myValue[N];
@@ -462,8 +468,10 @@ Standard_Real Extrema_ExtPExtS::SquareDistance (const Standard_Integer N) const
 
 const Extrema_POnSurf& Extrema_ExtPExtS::Point (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   if (myIsAnalyticallyComputable) {
     // modified by NIZHNY-MKK  Thu Sep 18 14:47:40 2003.BEGIN
     //     return myPoint[N];
index 1196c8a..c738841 100644 (file)
@@ -210,7 +210,16 @@ static Standard_Boolean IsExtremum (const Standard_Real U, const Standard_Real V
 
 Extrema_ExtPRevS::Extrema_ExtPRevS() 
 {
+  myvinf = myvsup = 0.0;
+  mytolv = Precision::Confusion();
   myDone = Standard_False;
+  myNbExt = 0;
+  myIsAnalyticallyComputable = Standard_False;
+
+  for (Standard_Integer i = 0; i < 8; i++)
+  {
+    mySqDist[i] = RealLast();
+  }
 }
 //=======================================================================
 //function : Extrema_ExtPRevS
@@ -273,6 +282,10 @@ void Extrema_ExtPRevS::Initialize (const Handle(GeomAdaptor_HSurfaceOfRevolution
   myvsup = theVsup;
   mytolv = theTolV;
 
+  myDone = Standard_False;
+  myNbExt = 0;
+  myIsAnalyticallyComputable = Standard_False;
+
   Handle(Adaptor3d_HCurve) anACurve = theS->BasisCurve();
   
   if (myS != theS)
@@ -535,8 +548,10 @@ Standard_Integer Extrema_ExtPRevS::NbExt() const
 
 Standard_Real Extrema_ExtPRevS::SquareDistance(const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   if (myIsAnalyticallyComputable)
     return mySqDist[N-1];
   else
@@ -549,8 +564,10 @@ Standard_Real Extrema_ExtPRevS::SquareDistance(const Standard_Integer N) const
 
 const Extrema_POnSurf& Extrema_ExtPRevS::Point(const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
-  if ((N < 1) || (N > myNbExt)) { throw Standard_OutOfRange(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
   if (myIsAnalyticallyComputable)
     return myPoint[N-1];
   else
index dd85af9..b4a03c8 100644 (file)
@@ -371,22 +371,21 @@ Standard_Boolean Extrema_ExtPS::IsDone() const
 
 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return mySqDist.Value(N);
 }
 
 
 Standard_Integer Extrema_ExtPS::NbExt() const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if (!IsDone()) throw StdFail_NotDone();
   return mySqDist.Length();
 }
 
 
 const Extrema_POnSurf& Extrema_ExtPS::Point(const Standard_Integer N) const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return myPoints.Value(N);
 }
 
index bf6451a..8675df6 100644 (file)
@@ -235,22 +235,25 @@ Standard_Boolean Extrema_ExtSS::IsDone() const
 
 Standard_Boolean Extrema_ExtSS::IsParallel() const
 {
+  if (!IsDone()) throw StdFail_NotDone();
   return myIsPar;
 }
 
 
 Standard_Real Extrema_ExtSS::SquareDistance(const Standard_Integer N) const
 {
-  if(!myDone) throw StdFail_NotDone();
-  if (myIsPar && N != 1) throw StdFail_InfiniteSolutions();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return mySqDist.Value(N);
 }
 
 
 Standard_Integer Extrema_ExtSS::NbExt() const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if (!IsDone()) throw StdFail_NotDone();
   return mySqDist.Length();
 }
 
@@ -260,7 +263,16 @@ void Extrema_ExtSS::Points(const Standard_Integer N,
                           Extrema_POnSurf&       P1,
                           Extrema_POnSurf&       P2) const
 {
-  if(!myDone) throw StdFail_NotDone();
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   P1 = myPOnS1.Value(N);
   P2 = myPOnS2.Value(N);
 }
index d69b046..b48055a 100644 (file)
@@ -530,8 +530,7 @@ Standard_Boolean Extrema_GExtPC::IsDone() const
 
 Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const 
 {
-  if(!mydone) throw StdFail_NotDone();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return mySqDist.Value(N);
 }
 
@@ -543,7 +542,7 @@ Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const
 
 Standard_Integer Extrema_GExtPC::NbExt() const
 {
-  if(!mydone) throw StdFail_NotDone();
+  if (!IsDone()) throw StdFail_NotDone();
   return mySqDist.Length();
 }
 
@@ -555,8 +554,7 @@ Standard_Integer Extrema_GExtPC::NbExt() const
 
 Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
 {
-  if(!mydone) throw StdFail_NotDone();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return myismin.Value(N);
 }
 
@@ -569,8 +567,7 @@ Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
 
 const ThePOnC & Extrema_GExtPC::Point(const Standard_Integer N) const
 {
-  if(!mydone) throw StdFail_NotDone();
-  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
+  if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
   return mypoint.Value(N);
 }
 
index dde9351..3f08ab5 100644 (file)
@@ -317,7 +317,10 @@ Standard_Boolean Extrema_GLocateExtPC::IsDone () const
 
 Standard_Real Extrema_GLocateExtPC::SquareDistance () const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   Standard_Real d=0;
   if ((type == GeomAbs_BezierCurve)) {
     d =  myLocExtPC.SquareDistance();
@@ -343,8 +346,11 @@ Standard_Real Extrema_GLocateExtPC::SquareDistance () const
 
 Standard_Boolean Extrema_GLocateExtPC::IsMin () const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
-  Standard_Boolean b=0;
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+  Standard_Boolean b = 0;
   if ((type == GeomAbs_BezierCurve)) {
     b = myLocExtPC.IsMin();
   }
@@ -369,8 +375,12 @@ Standard_Boolean Extrema_GLocateExtPC::IsMin () const
 
 const ThePOnC & Extrema_GLocateExtPC::Point () const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
-  if (type == GeomAbs_BezierCurve) {
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
+  if (type == GeomAbs_BezierCurve)
+  {
     return myLocExtPC.Point();
   }
   else if(type == GeomAbs_BSplineCurve ||
index fec566c..2c7767e 100644 (file)
@@ -622,7 +622,8 @@ Standard_Boolean Extrema_GenExtCC::IsDone() const
 //=======================================================================
 Standard_Boolean Extrema_GenExtCC::IsParallel() const 
 {
-  return myParallel; 
+  if (!IsDone()) throw StdFail_NotDone();
+  return myParallel;
 }
 
 //=======================================================================
@@ -631,8 +632,7 @@ Standard_Boolean Extrema_GenExtCC::IsParallel() const
 //=======================================================================
 Standard_Integer Extrema_GenExtCC::NbExt() const
 {
-  StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
-
+  if (!IsDone()) throw StdFail_NotDone();
   return myPoints1.Length();
 }
 
@@ -642,8 +642,10 @@ Standard_Integer Extrema_GenExtCC::NbExt() const
 //=======================================================================
 Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const
 {
-  StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()")
-  Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()")
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
 
   return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
 }
@@ -656,8 +658,15 @@ void Extrema_GenExtCC::Points(const Standard_Integer N,
                               POnC& P1,
                               POnC& P2) const
 {
-  StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()")
-  Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()")
+  if (IsParallel())
+  {
+    throw StdFail_InfiniteSolutions();
+  }
+
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
 
   P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)));
   P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
index 0e96f09..e83890b 100644 (file)
@@ -384,7 +384,11 @@ Standard_Integer Extrema_GenExtCS::NbExt() const
 //=======================================================================
 Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.SquareDistance(N);
 }
 
@@ -394,7 +398,11 @@ Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const
 //=======================================================================
 const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.PointOnCurve(N);
 }
 
@@ -404,7 +412,11 @@ const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N)
 //=======================================================================
 const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.PointOnSurface(N);
 }
 
index f3d26aa..bf63909 100644 (file)
@@ -205,9 +205,13 @@ Standard_Integer Extrema_GenExtPC::NbExt () const {
 //purpose  : 
 //=======================================================================
 
-Standard_Real Extrema_GenExtPC::SquareDistance (const Standard_Integer N) const {
+Standard_Real Extrema_GenExtPC::SquareDistance (const Standard_Integer N) const
+{
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
 
-  if (!IsDone()) { throw StdFail_NotDone(); }
   return myF.SquareDistance(N);
 }
 
@@ -219,7 +223,11 @@ Standard_Real Extrema_GenExtPC::SquareDistance (const Standard_Integer N) const
 
 Standard_Boolean Extrema_GenExtPC::IsMin (const Standard_Integer N) const {
 
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.IsMin(N);
 }
 
@@ -231,7 +239,11 @@ Standard_Boolean Extrema_GenExtPC::IsMin (const Standard_Integer N) const {
 
 const POnC & Extrema_GenExtPC::Point (const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.Point(N);
 }
 //=============================================================================
index 029e15c..dcd5a8f 100644 (file)
@@ -707,7 +707,7 @@ void Extrema_GenExtPS::BuildGrid(const gp_Pnt &thePoint)
   }
 }
 
-// Parameterisation of the sample
+// Parametrization of the sample
 void Extrema_GenExtPS::BuildTree()
 {
   // if tree already exists, assume it is already correctly filled
@@ -981,14 +981,22 @@ Standard_Integer Extrema_GenExtPS::NbExt () const
 
 Standard_Real Extrema_GenExtPS::SquareDistance (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.SquareDistance(N);
 }
 //=============================================================================
 
 const Extrema_POnSurf& Extrema_GenExtPS::Point (const Standard_Integer N) const
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if ((N < 1) || (N > NbExt()))
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.Point(N);
 }
 //=============================================================================
index ffb3489..7d691f3 100644 (file)
@@ -408,13 +408,17 @@ Standard_Integer Extrema_GenExtSS::NbExt() const
 }
 
 //=======================================================================
-//function : Value
+//function : SquareDistance
 //purpose  : 
 //=======================================================================
 
 Standard_Real Extrema_GenExtSS::SquareDistance(const Standard_Integer N) const 
-{  
-  if (!IsDone()) { throw StdFail_NotDone(); }
+{
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.SquareDistance(N);
 }
 
@@ -425,7 +429,11 @@ Standard_Real Extrema_GenExtSS::SquareDistance(const Standard_Integer N) const
 
 const Extrema_POnSurf& Extrema_GenExtSS::PointOnS1(const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.PointOnS1(N);
 }
 
@@ -436,7 +444,11 @@ const Extrema_POnSurf& Extrema_GenExtSS::PointOnS1(const Standard_Integer N) con
 
 const Extrema_POnSurf& Extrema_GenExtSS::PointOnS2(const Standard_Integer N) const 
 {
-  if (!IsDone()) { throw StdFail_NotDone(); }
+  if (N < 1 || N > NbExt())
+  {
+    throw Standard_OutOfRange();
+  }
+
   return myF.PointOnS2(N);
 }
 
index 7908247..dfc62eb 100644 (file)
@@ -139,7 +139,10 @@ Standard_Boolean Extrema_GenLocateExtPC::IsDone () const
 
 Standard_Real Extrema_GenLocateExtPC::SquareDistance() const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return myF.SquareDistance(1);
 }
 
@@ -151,7 +154,10 @@ Standard_Real Extrema_GenLocateExtPC::SquareDistance() const
 
 Standard_Boolean Extrema_GenLocateExtPC::IsMin () const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return myF.IsMin(1);
 }
 
@@ -163,7 +169,10 @@ Standard_Boolean Extrema_GenLocateExtPC::IsMin () const
 
 const POnC & Extrema_GenLocateExtPC::Point () const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return myF.Point(1);
 }
 
index ae45259..251899c 100644 (file)
@@ -54,13 +54,19 @@ Standard_Boolean Extrema_LocateExtCC::IsDone () const {
 
 Standard_Real Extrema_LocateExtCC::SquareDistance() const {
 
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return mySqDist;
 }
 
 void Extrema_LocateExtCC::Point (Extrema_POnCurv& P1, Extrema_POnCurv& P2) const {
 
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   P1 = myPoint1;
   P2 = myPoint2;
 }
index dae3d77..5bafa08 100644 (file)
@@ -77,7 +77,10 @@ Standard_Boolean Extrema_LocateExtCC2d::IsDone () const {
 
 Standard_Real Extrema_LocateExtCC2d::SquareDistance() const {
 
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   return mySqDist;
 }
 
@@ -91,7 +94,10 @@ Standard_Real Extrema_LocateExtCC2d::SquareDistance() const {
 void Extrema_LocateExtCC2d::Point (Extrema_POnCurv2d& P1, 
                                    Extrema_POnCurv2d& P2) const 
 {
-  if (!myDone) { throw StdFail_NotDone(); }
+  if (!IsDone())
+  {
+    throw StdFail_NotDone();
+  }
   P1 = myPoint1;
   P2 = myPoint2;
 }
index 6eb8d00..c52bbf3 100644 (file)
@@ -12,7 +12,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-Extrema_Point::Extrema_Point () { }
+Extrema_Point::Extrema_Point() :myU(0.0) {}
 
 
 Extrema_Point::Extrema_Point (const Standard_Real U, const Pnt& P)
index 64cc740..9a0918c 100644 (file)
@@ -347,13 +347,9 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
     return 1;
   }
 
-  Handle(Geom_Curve)   GC1, GC2;
+  Handle(Geom_Curve) GC1, GC2;
   Handle(Geom_Surface) GS1, GS2;
 
-  Standard_Boolean C1 = Standard_False;
-  Standard_Boolean C2 = Standard_False;
-  Standard_Boolean S1 = Standard_False;
-  Standard_Boolean S2 = Standard_False;
   Standard_Boolean isInfinitySolutions = Standard_False;
   Standard_Real aMinDist = RealLast();
 
@@ -364,11 +360,10 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
     GS1 = DrawTrSurf::GetSurface(a[1]);
     if ( GS1.IsNull())
       return 1;
-    S1 = Standard_True;
+
     GS1->Bounds(U1f,U1l,V1f,V1l);
   }
   else {
-    C1 = Standard_True;
     U1f = GC1->FirstParameter();
     U1l = GC1->LastParameter();
   }
@@ -378,23 +373,29 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
     GS2 = DrawTrSurf::GetSurface(a[2]);
     if ( GS2.IsNull())
       return 1;
-    S2 = Standard_True;
     GS2->Bounds(U2f,U2l,V2f,V2l);
   }
   else {
-    C2 = Standard_True;
     U2f = GC2->FirstParameter();
     U2l = GC2->LastParameter();
   }
 
   NCollection_Vector<gp_Pnt> aPnts1, aPnts2;
   NCollection_Vector<Standard_Real> aPrms[4];
-  if (C1 && C2)
+  if (!GC1.IsNull() && !GC2.IsNull())
   {
     GeomAPI_ExtremaCurveCurve Ex(GC1, GC2, U1f, U1l, U2f, U2l);
-
-    for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+    
+    // Since GeomAPI cannot provide access to flag directly.
+    isInfinitySolutions = Ex.Extrema().IsParallel();
+    if (isInfinitySolutions)
     {
+      aMinDist = Ex.LowerDistance();
+    }
+    else
+    {
+      for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+      {
         gp_Pnt aP1, aP2;
         Ex.Points(aJ, aP1, aP2);
         aPnts1.Append(aP1);
@@ -404,69 +405,86 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
         Ex.Parameters(aJ, aU1, aU2);
         aPrms[0].Append(aU1);
         aPrms[2].Append(aU2);
+      }
     }
-    // Since GeomAPI cannot provide access to flag directly.
-    isInfinitySolutions = Ex.Extrema().IsParallel();
-    if (isInfinitySolutions)
-      aMinDist = Ex.LowerDistance();
   }
-  else if (C1 && S2)
+  else if (!GC1.IsNull() && !GS2.IsNull())
   {
     GeomAPI_ExtremaCurveSurface Ex(GC1, GS2, U1f, U1l, U2f, U2l, V2f, V2l);
-    for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
-    {
-      gp_Pnt aP1, aP2;
-      Ex.Points(aJ, aP1, aP2);
-      aPnts1.Append(aP1);
-      aPnts2.Append(aP2);
-
-      Standard_Real aU1, aU2, aV2;
-      Ex.Parameters(aJ, aU1, aU2, aV2);
-      aPrms[0].Append(aU1);
-      aPrms[2].Append(aU2);
-      aPrms[3].Append(aV2);
-    }
+
     isInfinitySolutions = Ex.Extrema().IsParallel();
     if (isInfinitySolutions)
+    {
       aMinDist = Ex.LowerDistance();
+    }
+    else
+    {
+      for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+      {
+        gp_Pnt aP1, aP2;
+        Ex.Points(aJ, aP1, aP2);
+        aPnts1.Append(aP1);
+        aPnts2.Append(aP2);
+
+        Standard_Real aU1, aU2, aV2;
+        Ex.Parameters(aJ, aU1, aU2, aV2);
+        aPrms[0].Append(aU1);
+        aPrms[2].Append(aU2);
+        aPrms[3].Append(aV2);
+      }
+    }
   }
-  else if (S1 && C2)
+  else if (!GS1.IsNull() && !GC2.IsNull())
   {
     GeomAPI_ExtremaCurveSurface Ex(GC2, GS1, U2f, U2l, U1f, U1l, V1f, V1l);
-    for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
-    {
-      gp_Pnt aP2, aP1;
-      Ex.Points(aJ, aP2, aP1);
-      aPnts1.Append(aP1);
-      aPnts2.Append(aP2);
-
-      Standard_Real aU1, aV1, aU2;
-      Ex.Parameters(aJ, aU2, aU1, aV1);
-      aPrms[0].Append(aU1);
-      aPrms[1].Append(aV1);
-      aPrms[2].Append(aU2);
-    }
+
     isInfinitySolutions = Ex.Extrema().IsParallel();
     if (isInfinitySolutions)
+    {
       aMinDist = Ex.LowerDistance();
+    }
+    else
+    {
+      for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+      {
+        gp_Pnt aP2, aP1;
+        Ex.Points(aJ, aP2, aP1);
+        aPnts1.Append(aP1);
+        aPnts2.Append(aP2);
+
+        Standard_Real aU1, aV1, aU2;
+        Ex.Parameters(aJ, aU2, aU1, aV1);
+        aPrms[0].Append(aU1);
+        aPrms[1].Append(aV1);
+        aPrms[2].Append(aU2);
+      }
+    }
   }
-  else if (S1 && S2)
+  else if (!GS1.IsNull() && !GS2.IsNull())
   {
-    GeomAPI_ExtremaSurfaceSurface Ex(
-      GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
-    for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+    GeomAPI_ExtremaSurfaceSurface Ex(GS1, GS2, U1f, U1l, V1f, V1l, U2f, U2l, V2f, V2l);
+    // Since GeomAPI cannot provide access to flag directly.
+    isInfinitySolutions = Ex.Extrema().IsParallel();
+    if (isInfinitySolutions)
+    {
+      aMinDist = Ex.LowerDistance();
+    }
+    else
     {
-      gp_Pnt aP1, aP2;
-      Ex.Points(aJ, aP1, aP2);
-      aPnts1.Append(aP1);
-      aPnts2.Append(aP2);
-
-      Standard_Real aU1, aV1, aU2, aV2;
-      Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
-      aPrms[0].Append(aU1);
-      aPrms[1].Append(aV1);
-      aPrms[2].Append(aU2);
-      aPrms[3].Append(aV2);
+      for (Standard_Integer aJ = 1; aJ <= Ex.NbExtrema(); ++aJ)
+      {
+        gp_Pnt aP1, aP2;
+        Ex.Points(aJ, aP1, aP2);
+        aPnts1.Append(aP1);
+        aPnts2.Append(aP2);
+
+        Standard_Real aU1, aV1, aU2, aV2;
+        Ex.Parameters(aJ, aU1, aV1, aU2, aV2);
+        aPrms[0].Append(aU1);
+        aPrms[1].Append(aV1);
+        aPrms[2].Append(aU2);
+        aPrms[3].Append(aV2);
+      }
     }
   }
 
index c228e12..c8a38d8 100644 (file)
@@ -1898,7 +1898,7 @@ void FindSplitPoint(SplitDS &theSplitDS,
   anExtCC.SetRange(2, theMinParam, theMaxParam);
   anExtCC.Perform();
 
-  if (anExtCC.IsDone())
+  if (anExtCC.IsDone() && !anExtCC.IsParallel())
   {
     const Standard_Integer aNbExt = anExtCC.NbExt();
     for (Standard_Integer anIdx = 1; anIdx <= aNbExt; ++anIdx)
diff --git a/tests/bugs/modalg_7/bug29712_1 b/tests/bugs/modalg_7/bug29712_1
new file mode 100644 (file)
index 0000000..e3df14a
--- /dev/null
@@ -0,0 +1,14 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+restore [locate_data_file bug29712_edge.brep] ee
+restore [locate_data_file bug29712_face.brep] ff
+
+distmini dd ee ff
+
+checkreal Distance [dval dd_val] 0.0028427570965204128 1.0e-7 0.0
\ No newline at end of file
diff --git a/tests/lowalgos/extcc/bug29712_10 b/tests/lowalgos/extcc/bug29712_10
new file mode 100644 (file)
index 0000000..1d7d4f1
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other. So,
+# there exists single perpendicular only. 
+
+line c1 1 0 0 0 0 1 
+line c2 5 0 0 0 0 1
+trim c1 c1 -1.0e100 5
+trim c2 c2 5 20
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c1 c2
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c2 c1
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
\ No newline at end of file
diff --git a/tests/lowalgos/extcc/bug29712_11 b/tests/lowalgos/extcc/bug29712_11
new file mode 100644 (file)
index 0000000..0bd17d5
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other. So,
+# there exists single perpendicular only. 
+
+line c1 1 0 0 0 0 1 
+line c2 5 0 0 0 0 -1
+trim c1 c1 0 3
+trim c2 c2 -9.9e-8 1.0e100 
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c1 c2
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c2 c1
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
\ No newline at end of file
diff --git a/tests/lowalgos/extcc/bug29712_12 b/tests/lowalgos/extcc/bug29712_12
new file mode 100644 (file)
index 0000000..a869688
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other. So,
+# there exists single perpendicular only. 
+
+line c1 0 0 0 1 0 0
+line c2 0 4 0 -1 0 0
+trim c1 c1 0 1 
+trim c2 c2 -2 -1
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c1 c2
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c2 c1
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l 4.0 -eps 2.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_13 b/tests/lowalgos/extcc/bug29712_13
new file mode 100644 (file)
index 0000000..36dc300
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 4 6
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_14 b/tests/lowalgos/extcc/bug29712_14
new file mode 100644 (file)
index 0000000..ae82499
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -8.1 -6.1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_15 b/tests/lowalgos/extcc/bug29712_15
new file mode 100644 (file)
index 0000000..57043bd
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -1.9 0.1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_16 b/tests/lowalgos/extcc/bug29712_16
new file mode 100644 (file)
index 0000000..88324c0
--- /dev/null
@@ -0,0 +1,45 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+# So, there are two parallel arcs with distance 150
+# and one pair of points with distance 50. Extrema 
+# algorithm must return minimal distance (50) and
+# not infinite solution
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -2.0 0.0
+
+foreach a [ directory ext_* ] { unset $a }
+if { [regexp {Infinite} [extrema c1 c2]] } {
+  puts "Error: Extrema (c1 c2) returned infinite number of solution"
+}
+
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l $ExpDist
+
+foreach a [ directory ext_* ] { unset $a }
+if { [regexp {Infinite} [extrema c2 c1]] } {
+  puts "Error: Extrema (c2 c1) returned infinite number of solution"
+}
+
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c2 c1)"
+}
+
+checklength ext_1 -l $ExpDist
+
diff --git a/tests/lowalgos/extcc/bug29712_17 b/tests/lowalgos/extcc/bug29712_17
new file mode 100644 (file)
index 0000000..71f90ee
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.6 -1.6
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_18 b/tests/lowalgos/extcc/bug29712_18
new file mode 100644 (file)
index 0000000..61b29c9
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.5 -1.5
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_19 b/tests/lowalgos/extcc/bug29712_19
new file mode 100644 (file)
index 0000000..c03b7c2
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.4 -1.4
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_2 b/tests/lowalgos/extcc/bug29712_2
new file mode 100644 (file)
index 0000000..0ea43f9
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (B-spline) curves
+# and are shifted relatively to each other. So,
+# perpendicular between these curves does not exist but
+# extrema must be found as in case "Not-parallel". 
+
+bsplinecurve c1 1 2 0 2 1 2 0 0 0 1 1 0 0 1
+bsplinecurve c2 1 2 0 2 1 2 3 4 0 1 4 4 0 1
+
+extrema c1 c2
+checklength ext_1 -l [expr sqrt(20)] -eps 2.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_20 b/tests/lowalgos/extcc/bug29712_20
new file mode 100644 (file)
index 0000000..1107f9c
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.3 -1.3
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_21 b/tests/lowalgos/extcc/bug29712_21
new file mode 100644 (file)
index 0000000..f2a1b41
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.2 -1.2
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_22 b/tests/lowalgos/extcc/bug29712_22
new file mode 100644 (file)
index 0000000..9287c1f
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -3.1 -1.1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_23 b/tests/lowalgos/extcc/bug29712_23
new file mode 100644 (file)
index 0000000..db9e5b1
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -9.6 -7.6
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_24 b/tests/lowalgos/extcc/bug29712_24
new file mode 100644 (file)
index 0000000..280f73a
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -9.5 -7.5
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_25 b/tests/lowalgos/extcc/bug29712_25
new file mode 100644 (file)
index 0000000..c8bd097
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -8.3 -6.3
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_26 b/tests/lowalgos/extcc/bug29712_26
new file mode 100644 (file)
index 0000000..9f0cf23
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 -8.2 -6.2
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_27 b/tests/lowalgos/extcc/bug29712_27
new file mode 100644 (file)
index 0000000..30cb914
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 0 2
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_28 b/tests/lowalgos/extcc/bug29712_28
new file mode 100644 (file)
index 0000000..7246b9d
--- /dev/null
@@ -0,0 +1,40 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 3 5
+
+foreach a [ directory ext_* ] { unset $a }
+if { [regexp {Infinite} [extrema c1 c2]] } {
+  puts "Error: Extrema (c1 c2) returned infinite number of solution"
+}
+
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+checklength ext_1 -l $ExpDist
+
+foreach a [ directory ext_* ] { unset $a }
+if { [regexp {Infinite} [extrema c2 c1]] } {
+  puts "Error: Extrema (c2 c1) returned infinite number of solution"
+}
+
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c2 c1)"
+}
+
+checklength ext_1 -l $ExpDist
diff --git a/tests/lowalgos/extcc/bug29712_29 b/tests/lowalgos/extcc/bug29712_29
new file mode 100644 (file)
index 0000000..0339082
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 3.1 5.1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_3 b/tests/lowalgos/extcc/bug29712_3
new file mode 100644 (file)
index 0000000..e5424fa
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other. So,
+# perpendicular between these curves does not exist. 
+
+line c1 0 0 0 1 0 0 
+line c2 3 4 0 1 0 0 
+
+trim c1 c1 0 1
+trim c2 c2 0 1
+
+if { ![regexp {No solutions!} [extrema c1 c2] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
+
diff --git a/tests/lowalgos/extcc/bug29712_30 b/tests/lowalgos/extcc/bug29712_30
new file mode 100644 (file)
index 0000000..cb25e69
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 3
+trim c2 c2 4.3 6.3
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_31 b/tests/lowalgos/extcc/bug29712_31
new file mode 100644 (file)
index 0000000..aa03a20
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 pi
+trim c2 c2 -9.5 -7.5
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_32 b/tests/lowalgos/extcc/bug29712_32
new file mode 100644 (file)
index 0000000..bd554f5
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 pi
+trim c2 c2 -9.4 -7.4
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_33 b/tests/lowalgos/extcc/bug29712_33
new file mode 100644 (file)
index 0000000..eef4a02
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 pi
+trim c2 c2 0.0 2.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
\ No newline at end of file
diff --git a/tests/lowalgos/extcc/bug29712_34 b/tests/lowalgos/extcc/bug29712_34
new file mode 100644 (file)
index 0000000..f05a20f
--- /dev/null
@@ -0,0 +1,72 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+# Please pay attention to the fact that the extrema
+# algorithm works anti-symmetrically in this case.
+# It is connected with the following:
+# 1. In case Extrema "c1 c2" the last point of curve c2 
+# is projected to c1 one. As result, two 
+# extremas (point-circle) are found and they are returned.
+# 2. The parallel regions (with infinite number of solution) is
+# ignored because single pair is found with two nearest points.
+# 3. In case Extrema "c2 c1" the first point of curve c1
+# is projected to c2 one. As result, one extrema is found and it
+# is returned. At that the last point of c1 is not projected at all
+# because because it is included in parallel region (see item 2).
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 pi
+trim c2 c2 -2.0 0.0
+
+smallview
+
+# Case 1
+
+don c1 c2
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c1 c2
+if { [llength [ directory ext_* ] ] != 2 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+fit
+checkview -2d -screenshot -path ${imagedir}/${test_image}_1.png
+
+regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full l11
+regexp {The length ext_2 is +([-0-9.+eE]+)} [length ext_2] full l12
+
+if { $l11 > $l12} {
+  set tmp1 $l11
+  set l11 $l12
+  set l12 $tmp1
+}
+
+checkreal MinL1 $l11 50.0 1.0e-7 0.0
+checkreal MaxL1 $l12 150.0 1.0e-7 0.0
+
+# Case 2
+
+don c1 c2
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c2 c1
+if { [llength [ directory ext_* ] ] != 1 } {
+  puts "Error: Wrong number of solutions (c2 c1). See comment above."
+}
+
+fit
+checkview -2d -screenshot -path ${imagedir}/${test_image}_2.png
+
+regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full l21
+
+checkreal MinL2 $l21 50.0 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_35 b/tests/lowalgos/extcc/bug29712_35
new file mode 100644 (file)
index 0000000..9581cda
--- /dev/null
@@ -0,0 +1,68 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 pi
+trim c2 c2 pi 2*pi
+
+smallview
+
+# Case 1
+
+don c1 c2
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c1 c2
+if { [llength [ directory ext_* ] ] != 2 } {
+  puts "Error: Wrong number of solutions (c1 c2)"
+}
+
+fit
+checkview -2d -screenshot -path ${imagedir}/${test_image}_1.png
+
+regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full l11
+regexp {The length ext_2 is +([-0-9.+eE]+)} [length ext_2] full l12
+
+if { $l11 > $l12} {
+  set tmp1 $l11
+  set l11 $l12
+  set l12 $tmp1
+}
+
+checkreal MinL1 $l11 50.0 1.0e-7 0.0
+checkreal MaxL1 $l12 150.0 1.0e-7 0.0
+
+# Case 2
+
+don c1 c2
+
+foreach a [ directory ext_* ] { unset $a }
+extrema c2 c1
+if { [llength [ directory ext_* ] ] != 2 } {
+  puts "Error: Wrong number of solutions (c2 c1)"
+}
+
+fit
+checkview -2d -screenshot -path ${imagedir}/${test_image}_2.png
+
+regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full l21
+regexp {The length ext_2 is +([-0-9.+eE]+)} [length ext_2] full l22
+
+if { $l21 > $l22} {
+  set tmp2 $l11
+  set l21 $l22
+  set l22 $tmp2
+}
+
+checkreal MinL2 $l21 50.0 1.0e-7 0.0
+checkreal MaxL2 $l22 150.0 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_36 b/tests/lowalgos/extcc/bug29712_36
new file mode 100644 (file)
index 0000000..ab4291f
--- /dev/null
@@ -0,0 +1,24 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+circle c2 0 0 0 0 0 1 50
+trim c1 c1 0 2*pi
+trim c2 c2 -12.0 -10.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
\ No newline at end of file
diff --git a/tests/lowalgos/extcc/bug29712_37 b/tests/lowalgos/extcc/bug29712_37
new file mode 100644 (file)
index 0000000..ab06350
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 150.0
+
+circle c1 0 0 0 0 0 1 100
+lmirror c1 0 0 0 1 0 0 
+circle c2 0 0 0 0 0 1 50 
+trim c1 c1 3 6.5 
+trim c2 c2 4 6 
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_38 b/tests/lowalgos/extcc/bug29712_38
new file mode 100644 (file)
index 0000000..96d3b98
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 are concentric circles.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other.
+
+set ExpDist 50.0
+
+circle c1 0 0 0 0 0 1 100
+lmirror c1 0 0 0 1 0 0 
+circle c2 0 0 0 0 0 1 50 
+trim c1 c1 0 4 
+trim c2 c2 4 6 
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_39 b/tests/lowalgos/extcc/bug29712_39
new file mode 100644 (file)
index 0000000..9c3a6f2
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+set ExpDist 5
+
+circle c1 0 0 0 0 0 1 5
+line c2 0 0 0 0 0 1
+trim c2 c2 -1 1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_4 b/tests/lowalgos/extcc/bug29712_4
new file mode 100644 (file)
index 0000000..e446c58
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Extrema between parallel lines
+
+line c1 0 0 0 1 0 0 
+line c2 0 4 0 1 0 0 
+
+trim c1 c1 0 1
+trim c2 c2 0 1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 4.0 0.0 2.0e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 4.0 0.0 2.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_40 b/tests/lowalgos/extcc/bug29712_40
new file mode 100644 (file)
index 0000000..a648fb5
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+set ExpDist 5
+
+circle c1 0 0 0 0 0 1 5
+line c2 0 0 0 0 0 1
+trim c2 c2 -1 -5e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_41 b/tests/lowalgos/extcc/bug29712_41
new file mode 100644 (file)
index 0000000..9950478
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+set ExpDist 5
+
+circle c1 0 0 0 0 0 1 5
+line c2 0 0 0 0 0 1
+trim c2 c2 3e-8 1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0
diff --git a/tests/lowalgos/extcc/bug29712_42 b/tests/lowalgos/extcc/bug29712_42
new file mode 100644 (file)
index 0000000..478d2a8
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+set ExpDist 5
+
+circle c1 0 0 0 0 0 1 5
+line c2 0 0 0 0 0 1
+trim c2 c2 2e-7 1
+
+if { ![regexp {No solutions!} [extrema c1 c2] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
+
+if { ![regexp {No solutions!} [extrema c2 c1] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
diff --git a/tests/lowalgos/extcc/bug29712_43 b/tests/lowalgos/extcc/bug29712_43
new file mode 100644 (file)
index 0000000..4a9d7da
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+set ExpDist 5
+
+circle c1 0 0 0 0 0 1 5
+line c2 0 0 0 0 0 1
+trim c2 c2 -1.5e-7 -1
+
+if { ![regexp {No solutions!} [extrema c1 c2] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
+
+if { ![regexp {No solutions!} [extrema c2 c1] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
diff --git a/tests/lowalgos/extcc/bug29712_5 b/tests/lowalgos/extcc/bug29712_5
new file mode 100644 (file)
index 0000000..b5794fa
--- /dev/null
@@ -0,0 +1,29 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Curves c1 and c2 lie on parallel lines.
+# However, they are bounded (trimmed) curves
+# and are shifted relatively to each other. So,
+# perpendicular between these curves does not exist. 
+
+line c1 1 0 0 0 0 1 
+line c2 5 0 0 0 0 1
+trim c1 c1 -1.0e100 5
+trim c2 c2 10 20
+
+if { ![regexp {No solutions!} [extrema c1 c2] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
+
+if { ![regexp {No solutions!} [extrema c2 c1] ] } {
+  puts "Error in Extrema-algorithm"
+} else {
+  puts "Extrema-algorithm works properly"
+}
diff --git a/tests/lowalgos/extcc/bug29712_6 b/tests/lowalgos/extcc/bug29712_6
new file mode 100644 (file)
index 0000000..18d66b1
--- /dev/null
@@ -0,0 +1,18 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Extrema between parallel lines
+
+line c1 1 2 3 0 1 0 
+line c2 10 9 8 0 1 0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 [expr sqrt(106.0)] 0.0 1.0e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 [expr sqrt(106.0)] 0.0 1.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_7 b/tests/lowalgos/extcc/bug29712_7
new file mode 100644 (file)
index 0000000..505565c
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Extrema between parallel lines
+
+line c1 1 2 3 0 1 0 
+line c2 10 9 8 0 1 0
+trim c2 c2 -1 2
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 [expr sqrt(106.0)] 0.0 1.0e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 [expr sqrt(106.0)] 0.0 1.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_8 b/tests/lowalgos/extcc/bug29712_8
new file mode 100644 (file)
index 0000000..9f7f325
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Extrema between parallel lines
+
+line c1 1 2 3 0 1 0 
+line c2 10 9 8 0 1 0
+trim c1 c1 -100 200
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 [expr sqrt(106.0)] 0.0 1.0e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 [expr sqrt(106.0)] 0.0 1.0e-8
diff --git a/tests/lowalgos/extcc/bug29712_9 b/tests/lowalgos/extcc/bug29712_9
new file mode 100644 (file)
index 0000000..45fd11c
--- /dev/null
@@ -0,0 +1,20 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Extrema between parallel lines
+
+line c1 1 0 0 0 0 -1 
+line c2 5 0 0 0 0 1
+trim c1 c1 -5 2
+trim c2 c2 -1.0e100 9.9e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c1 c2] full aDist1
+checkreal Distance $aDist1 4.0 0.0 1.0e-8
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema c2 c1] full aDist2
+checkreal Distance $aDist2 4.0 0.0 1.0e-8
\ No newline at end of file
diff --git a/tests/lowalgos/extss/bug29712_44 b/tests/lowalgos/extss/bug29712_44
new file mode 100644 (file)
index 0000000..e12fea2
--- /dev/null
@@ -0,0 +1,20 @@
+puts "========"
+puts "OCC29712"
+puts "========"
+puts ""
+#################################################
+# Extrema algorithm raises exception
+#################################################
+
+# Planes s1 and s2 are parallel.
+
+set ExpDist 10.0
+
+plane s1 0 0 0 0 0 1
+plane s2 0 0 10 0 0 1
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema s1 s1] full aDist1
+checkreal Distance $aDist1 $ExpDist 1.0e-7 0.0
+
+regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} [extrema s2 s2] full aDist2
+checkreal Distance $aDist2 $ExpDist 1.0e-7 0.0