]> OCCT Git - occt-copy.git/commitdiff
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.

84 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/fclasses/bug26184_1 [deleted file]
tests/perf/fclasses/bug26184_2 [deleted file]
tests/perf/fclasses/bug27131 [deleted file]
tests/perf/fclasses/bug27371 [deleted file]
tests/perf/modalg/bug26184_1 [new file with mode: 0644]
tests/perf/modalg/bug26184_2 [new file with mode: 0644]
tests/perf/modalg/bug27131 [new file with mode: 0644]
tests/perf/modalg/bug27371 [new file with mode: 0644]

index f4c3e3602aeb26dc7bd27ba9b5127edba3d5380f..0ab9b28831eae9b31221bcada31343922b9325ca 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 a57322571e314b864525f76dbeaa22cec8920825..eb01f8f22f82c7ff5f87795d91e3d6f4c4d7c2aa 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 8f6174d36e31d6d11270c900ce9c9d793861a006..5050a748288f5ab49f351419156e108ab47f50c4 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 9db128ccb45f17b20da788fe0748d1e7150e5ff4..d342f1847b89d37cfb34aca618d8716d23ae4db0 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 88738245cb864c0931a94d565d0f1d15dd4d4fec..0c006d27d9ca771c26c7727098ed68b26e5a1c9f 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 211dd841022ec5b4521c53ffda1a9682bcb7bf00..da1d0007be79c5db0982f45295019b95a4c6974e 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 57180fe571f5bbe54c9cd864d262f607bc219dd9..d8d17f123cd6fb9296f9122ad2daeb8908bbf67e 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 25cc8cd62d6e2f1f41524f7a436c1149619e3c29..05b65eaa45b8d42daf8d399a02075f016c8a66ad 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 18003edb29daade0e3bad68b67cde57052cecd3f..8c81128afaeaeba5f6e489b71d439957996d6d50 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 ac245de393071b3687263943cec56619db41d2f9..99274b745bdc9c8c177a5bda2498c748f9b2ac93 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 31e5f80eacf895efd6c4dbb094a3fc6c8629d9eb..63d0a917a3bddde0435b3373ad40a2ec3de4cf12 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 0c5dd2bb947d4f7a2c14f33e240d138613340275..4aad73f56a5d47e74bdf19c2764f47f3282ddc1c 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 6cccc46605809b3450859434660540a664773ced..53514f594ba4df720bedfcc515985de612cf332a 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 877330983570adfc23ee5e7bf4e6b7cf76b770df..460c59569d230c77ed26e68cad1a68df5369a894 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 8257b554c0377826227728d5303d1a3eafc978dd..d494bddbac0500c4b8902e3bfe2e5de435a0a879 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 5329a15d4880a47c0cc5aca09c4521cf77df44a4..969c8b64ce6d5f52afcb948897169cc86d651199 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 1196c8a6bb93ba1b883830f1aa860c8ebe0ee419..c7388416fcc07e147b314474f829d9addb3449c1 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 dd85af977665b8312a2bddda3e9bb1a16c6c810c..b4a03c85f088965ef78072264c14f3fe835ace74 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 bf6451a64dc4f583a764a043a248fa00fef38a2b..8675df6cdcf193182305f2c1b290cddcaccd4524 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 d69b0464b297532c09351421693d588c84d21d3c..b48055a5bee1329f1dd5c35f4596ee99fdba7e46 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 dde9351d138810ba77b3e8ce1c44c1d393b53afd..3f08ab5291fc0a2012c451555c37d583d1d6a73a 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 fec566c2a91df94da730f1e714f773246a4fb476..2c7767eca26b01379d69e42e0c0dd73724e12601 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 0e96f09115b3869326f46bd057078cc5f37467c3..e83890b5252d0931bd1e7a23ec0ea2fa9796ee39 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 f3d26aaf7a5db6f22cd42bbdc40943a8cbd18cbd..bf6390935be631c98fe7f07c8b0547fc18b577b6 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 029e15c97f4fec60d0531e8715ffb276abf78945..dcd5a8f94f437e4bffd979e888b26168c1e2c119 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 ffb348929e876dfd7d90b5e52044b4d27e3cc299..7d691f3e4e8d264c4c9e76179424d9e8587c25f0 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 790824773d2bb6efd4e21660be390ba778bf7a54..dfc62eb05d392f0fdd5b82356a0a61abfcfb4827 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 ae45259ae8cdd3c64f525ddd49095b2a8ec317ee..251899c3f7de099fb60e97797dd8d870900b2868 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 dae3d77717eef9433faf7f58dbe5356eaaff0eac..5bafa089477158987e84eed068e7b16fe1f77a3a 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 6eb8d00d59ddfa33b0a52e18fde1db0d599b59de..c52bbf369d4d3dccda2793aae63952e5f2e3f913 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 64cc7402f846f4fc47242d845071318d51359721..9a0918ce87c5d14aeecd811c7507baba8b3e6923 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 c228e12adc0c33fadd3e0f78ce7e1019cc7df7b7..c8a38d8c2a49f89b15aab053765b038cf52221cf 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
diff --git a/tests/perf/fclasses/bug26184_1 b/tests/perf/fclasses/bug26184_1
deleted file mode 100644 (file)
index 6a2ad98..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-puts "============"
-puts "OCC26184"
-puts "============"
-puts ""
-#######################################################################
-# GeomAPI_ExtremaCurveCurve hangs on parallel b-spline curves
-#######################################################################
-
-restore [locate_data_file bug26184_Curve_Extrema_1_12971.brep] a1
-restore [locate_data_file bug26184_Curve_Extrema_2_12971.brep] a2
-
-mkcurve c1 a1
-mkcurve c2 a2
-
-cpulimit 20
-
-dchrono h restart
-extrema c1 c2
-dchrono h stop counter extrema
\ No newline at end of file
diff --git a/tests/perf/fclasses/bug26184_2 b/tests/perf/fclasses/bug26184_2
deleted file mode 100644 (file)
index 0c64d8c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-puts "============"
-puts "OCC26184"
-puts "============"
-puts ""
-#######################################################################
-# GeomAPI_ExtremaCurveCurve hangs on parallel b-spline curves
-#######################################################################
-
-restore [locate_data_file bug26184_Curve_Extrema_1_13767.brep] a1
-restore [locate_data_file bug26184_Curve_Extrema_2_13767.brep] a2
-
-mkcurve c1 a1
-mkcurve c2 a2
-
-cpulimit 20
-
-dchrono h restart
-extrema c1 c2
-dchrono h stop counter extrema
\ No newline at end of file
diff --git a/tests/perf/fclasses/bug27131 b/tests/perf/fclasses/bug27131
deleted file mode 100644 (file)
index 6200c0e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-puts "========"
-puts "OCC27131"
-puts "========"
-puts ""
-##############################################
-# DistShapeShape works slow on attached shapes
-##############################################
-restore [locate_data_file bug27131.brep] aShape
-explode aShape
-
-cpulimit 20
-
-# Check computation time
-dchrono h restart
-for { set i 1 } { $i <= 100 } { incr i } {
-  distmini d aShape_1 aShape_2
-}
-dchrono h stop counter distmini
-
-# Check result of distance distance
-set absTol 1.0e-10
-set relTol 0.001
-set aDist_Exp 0.0029087110153708622
-set aDist [dval d_val]
-checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol
\ No newline at end of file
diff --git a/tests/perf/fclasses/bug27371 b/tests/perf/fclasses/bug27371
deleted file mode 100644 (file)
index b04bd3c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-puts "========"
-puts "OCC27371"
-puts "========"
-puts ""
-##############################################
-# Regression: BRepExtrema works too much slower in 691 (from 670) 
-##############################################
-restore [locate_data_file bug27371.brep] aShape
-explode aShape
-
-cpulimit 20
-
-# Check computation time
-dchrono h restart
-for { set i 1 } { $i <= 100 } { incr i } {
-  distmini d aShape_1 aShape_2
-  distmini d aShape_2 aShape_1
-}
-dchrono h stop counter distmini
-
-# Check result of distance distance
-set absTol 1.0e-10
-set relTol 0.001
-set aDist_Exp 0.2
-set aDist [dval d_val]
-checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol
\ No newline at end of file
diff --git a/tests/perf/modalg/bug26184_1 b/tests/perf/modalg/bug26184_1
new file mode 100644 (file)
index 0000000..6a2ad98
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============"
+puts "OCC26184"
+puts "============"
+puts ""
+#######################################################################
+# GeomAPI_ExtremaCurveCurve hangs on parallel b-spline curves
+#######################################################################
+
+restore [locate_data_file bug26184_Curve_Extrema_1_12971.brep] a1
+restore [locate_data_file bug26184_Curve_Extrema_2_12971.brep] a2
+
+mkcurve c1 a1
+mkcurve c2 a2
+
+cpulimit 20
+
+dchrono h restart
+extrema c1 c2
+dchrono h stop counter extrema
\ No newline at end of file
diff --git a/tests/perf/modalg/bug26184_2 b/tests/perf/modalg/bug26184_2
new file mode 100644 (file)
index 0000000..0c64d8c
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============"
+puts "OCC26184"
+puts "============"
+puts ""
+#######################################################################
+# GeomAPI_ExtremaCurveCurve hangs on parallel b-spline curves
+#######################################################################
+
+restore [locate_data_file bug26184_Curve_Extrema_1_13767.brep] a1
+restore [locate_data_file bug26184_Curve_Extrema_2_13767.brep] a2
+
+mkcurve c1 a1
+mkcurve c2 a2
+
+cpulimit 20
+
+dchrono h restart
+extrema c1 c2
+dchrono h stop counter extrema
\ No newline at end of file
diff --git a/tests/perf/modalg/bug27131 b/tests/perf/modalg/bug27131
new file mode 100644 (file)
index 0000000..6200c0e
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC27131"
+puts "========"
+puts ""
+##############################################
+# DistShapeShape works slow on attached shapes
+##############################################
+restore [locate_data_file bug27131.brep] aShape
+explode aShape
+
+cpulimit 20
+
+# Check computation time
+dchrono h restart
+for { set i 1 } { $i <= 100 } { incr i } {
+  distmini d aShape_1 aShape_2
+}
+dchrono h stop counter distmini
+
+# Check result of distance distance
+set absTol 1.0e-10
+set relTol 0.001
+set aDist_Exp 0.0029087110153708622
+set aDist [dval d_val]
+checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol
\ No newline at end of file
diff --git a/tests/perf/modalg/bug27371 b/tests/perf/modalg/bug27371
new file mode 100644 (file)
index 0000000..b04bd3c
--- /dev/null
@@ -0,0 +1,26 @@
+puts "========"
+puts "OCC27371"
+puts "========"
+puts ""
+##############################################
+# Regression: BRepExtrema works too much slower in 691 (from 670) 
+##############################################
+restore [locate_data_file bug27371.brep] aShape
+explode aShape
+
+cpulimit 20
+
+# Check computation time
+dchrono h restart
+for { set i 1 } { $i <= 100 } { incr i } {
+  distmini d aShape_1 aShape_2
+  distmini d aShape_2 aShape_1
+}
+dchrono h stop counter distmini
+
+# Check result of distance distance
+set absTol 1.0e-10
+set relTol 0.001
+set aDist_Exp 0.2
+set aDist [dval d_val]
+checkreal "Distance value check" $aDist $aDist_Exp $absTol $relTol
\ No newline at end of file