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.
@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.
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)
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
{
myEP.Clear();
myVP.Clear();
+ myIsValid = Standard_True;
+ }
+
+ //! Returns TRUE if correct classification is possible
+ Standard_Boolean IsCorrect() const
+ {
+ return myIsValid;
}
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
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.
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
// fois la meme solution
#include <Adaptor3d_Curve.hxx>
+#include <Bnd_Range.hxx>
#include <ElCLib.hxx>
#include <Extrema_CurveTool.hxx>
#include <Extrema_ECC.hxx>
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();
}
//=======================================================================
SetCurve (2, C2, V1, V2);
SetTolerance (1, TolC1);
SetTolerance (2, TolC2);
+ mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
Perform();
}
SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter());
SetTolerance (1, TolC1);
SetTolerance (2, TolC2);
+ mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
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];
//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;
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;
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);
}
}
Standard_Boolean Extrema_ExtCC::IsParallel() const
{
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
+
return myIsPar;
}
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);
}
Standard_Integer Extrema_ExtCC::NbExt() const
{
if(!myDone) throw StdFail_NotDone();
- return mynbext;
+ return mySqDist.Length();
}
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);
}
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;
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();
}
(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);
//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;
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);
+ }
}
}
}
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:
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];
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);
}
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
if (myIsPar)
{
- mySqDist[0] = mySqDist[1] = theC2.SquareDistance(theC1.Location());
+ mySqDist[0] = theC2.SquareDistance(theC1.Location());
+ myNbExt = 1;
myDone = Standard_True;
return;
}
if (Sol.InfiniteRoots()) {
myIsPar = Standard_True;
mySqDist[0] = R*R;
+ myNbExt = 1;
myDone = Standard_True;
return;
}
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) {
}
//=======================================================================
//=======================================================================
Standard_Integer Extrema_ExtElC::NbExt () const
{
- if (IsParallel()) {
- throw StdFail_InfiniteSolutions();
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
}
return myNbExt;
}
//=======================================================================
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
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];
}
#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
{
myIsPar = Standard_True;
mySqDist[0] = C2.SquareDistance(C1.Location());
+ myNbExt = 1;
}
else
{
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;
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]);
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];
}
//============================================================================
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];
{
myDone = Standard_False;
myIsPar = Standard_False;
+ myNbExt = 0;
}
{
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;
- }
-
}
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;
{
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;
}
}
}
-
- // 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)
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;
+ }
}
{
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 {
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)
{
}
}
- 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)
{
// 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);
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);
}
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++) {
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
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());
{
myDone = Standard_True;
myIsPar = Standard_False;
+ myNbExt = 0;
gp_Ax2 Pos = C.Position();
gp_Dir NHypr = Pos.Direction();
mySqDist = new TColStd_HArray1OfReal(1, 1);
mySqDist->SetValue(1, S.SquareDistance(C.Location()));
myIsPar = Standard_True;
-
+ myNbExt = 1;
}
else {
myNbExt = 1;
}
- else {
- myNbExt = 0;
- }
-
}
-
}
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);
}
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);
}
Standard_Boolean Extrema_ExtElCS::IsParallel() const
{
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
return myIsPar;
}
{
myDone = Standard_False;
myIsPar = Standard_False;
+ myNbExt = 0;
}
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);
}
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);
}
//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
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;
}
#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
const Standard_Real Uinf,
const Standard_Real Usup)
{
+ myDone = Standard_False;
+ myNbExt = 0;
// gp_Pnt2d OR, P1, P2;
gp_Pnt2d OR;
OR = E.Location();
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()));
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,
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];
}
//=============================================================================
mytolv(0.0),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
- myNbExt(Standard_False)
+ myNbExt(0)
{
}
myS (theS),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
- myNbExt(Standard_False)
+ myNbExt(0)
{
Initialize (theS,
theUmin,
myS (theS),
myIsAnalyticallyComputable(Standard_False),
myDone(Standard_False),
- myNbExt(Standard_False)
+ myNbExt(0)
{
Initialize (theS,
theS->FirstUParameter(),
myvsup = theVsup;
mytolv = theTolV;
+ myIsAnalyticallyComputable = Standard_False;
+ myDone = Standard_False;
+ myNbExt = 0;
+
Handle(Adaptor3d_HCurve) anACurve = theS->BasisCurve();
myF.Initialize (theS->ChangeSurface());
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];
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];
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
myvsup = theVsup;
mytolv = theTolV;
+ myDone = Standard_False;
+ myNbExt = 0;
+ myIsAnalyticallyComputable = Standard_False;
+
Handle(Adaptor3d_HCurve) anACurve = theS->BasisCurve();
if (myS != theS)
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
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
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);
}
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();
}
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);
}
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);
}
Standard_Integer Extrema_GExtPC::NbExt() const
{
- if(!mydone) throw StdFail_NotDone();
+ if (!IsDone()) throw StdFail_NotDone();
return mySqDist.Length();
}
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);
}
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);
}
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();
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();
}
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 ||
//=======================================================================
Standard_Boolean Extrema_GenExtCC::IsParallel() const
{
- return myParallel;
+ if (!IsDone()) throw StdFail_NotDone();
+ return myParallel;
}
//=======================================================================
//=======================================================================
Standard_Integer Extrema_GenExtCC::NbExt() const
{
- StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
-
+ if (!IsDone()) throw StdFail_NotDone();
return myPoints1.Length();
}
//=======================================================================
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)));
}
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)));
//=======================================================================
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);
}
//=======================================================================
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);
}
//=======================================================================
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);
}
//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);
}
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);
}
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);
}
//=============================================================================
}
}
-// Parameterisation of the sample
+// Parametrization of the sample
void Extrema_GenExtPS::BuildTree()
{
// if tree already exists, assume it is already correctly filled
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);
}
//=============================================================================
}
//=======================================================================
-//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);
}
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);
}
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);
}
Standard_Real Extrema_GenLocateExtPC::SquareDistance() const
{
- if (!myDone) { throw StdFail_NotDone(); }
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
return myF.SquareDistance(1);
}
Standard_Boolean Extrema_GenLocateExtPC::IsMin () const
{
- if (!myDone) { throw StdFail_NotDone(); }
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
return myF.IsMin(1);
}
const POnC & Extrema_GenLocateExtPC::Point () const
{
- if (!myDone) { throw StdFail_NotDone(); }
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
return myF.Point(1);
}
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;
}
Standard_Real Extrema_LocateExtCC2d::SquareDistance() const {
- if (!myDone) { throw StdFail_NotDone(); }
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
return mySqDist;
}
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;
}
// 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)
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();
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();
}
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);
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);
+ }
}
}
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)
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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"
+}
+
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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"
+}
--- /dev/null
+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"
+}
--- /dev/null
+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"
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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