// File: Extrema_GExtCC.gxx // Created: Wed Jul 6 10:14:26 1994 // Author: Laurent PAINNOT // // Modified by MPS (june 96) : correction du trap dans le cas droite/Bezier // Modified by MPS (mai 97) : PRO 7598 // tri des solutions pour eviter de rendre plusieurs // fois la meme solution #include Extrema_ECC_hxx #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : Extrema_GExtCC //purpose : //======================================================================= Extrema_GExtCC::Extrema_GExtCC (const Standard_Real TolC1, const Standard_Real TolC2) : myDone (Standard_False) { myC[0] = 0; myC[1] = 0; myTol[0] = TolC1; myTol[1] = TolC2; } //======================================================================= //function : Extrema_GExtCC //purpose : //======================================================================= Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1, const Curve2& C2, const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2, const Standard_Real TolC1, const Standard_Real TolC2) : myDone (Standard_False) { SetCurve (1, C1, U1, U2); SetCurve (2, C2, V1, V2); SetTolerance (1, TolC1); SetTolerance (2, TolC2); Perform(); } //======================================================================= //function : Extrema_GExtCC //purpose : //======================================================================= Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1, const Curve2& C2, const Standard_Real TolC1, const Standard_Real TolC2) : myDone (Standard_False) { SetCurve (1, C1, C1.FirstParameter(), C1.LastParameter()); SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter()); SetTolerance (1, TolC1); SetTolerance (2, TolC2); Perform(); } //======================================================================= //function : SetCurve //purpose : //======================================================================= void Extrema_GExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetCurve()") Standard_Integer anInd = theRank - 1; myC[anInd] = (Standard_Address)&C; //clear the previous cache to rebuild it later in Perform() myCacheLists[anInd].Clear(); } //======================================================================= //function : SetCurve //purpose : //======================================================================= void Extrema_GExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C, const Standard_Real Uinf, const Standard_Real Usup) { SetCurve (theRank, C); SetRange (theRank, Uinf, Usup); } //======================================================================= //function : SetRange //purpose : //======================================================================= void Extrema_GExtCC::SetRange (const Standard_Integer theRank, const Standard_Real Uinf, const Standard_Real Usup) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetRange()") Standard_Integer anInd = theRank - 1; myInf[anInd] = Uinf; mySup[anInd] = Usup; } //======================================================================= //function : SetTolerance //purpose : //======================================================================= void Extrema_GExtCC::SetTolerance (const Standard_Integer theRank, const Standard_Real theTol) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetTolerance()") Standard_Integer anInd = theRank - 1; myTol[anInd] = theTol; } //======================================================================= //function : Perform //purpose : //======================================================================= void Extrema_GExtCC::Perform() { Standard_NullObject_Raise_if (!myC[0] || !myC[1], "Extrema_GExtCC::Perform()") myDone = Standard_False; mypoints.Clear(); mySqDist.Clear(); myIsPar = Standard_False; GeomAbs_CurveType type1 = (*((Curve1*)myC[0])).GetType(); GeomAbs_CurveType type2 = (*((Curve2*)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]; U21 = myInf[1]; U22 = mySup[1]; if (!Precision::IsInfinite(U11)) P1f = Tool1::Value(*((Curve1*)myC[0]), U11); if (!Precision::IsInfinite(U12)) P1l = Tool1::Value(*((Curve1*)myC[0]), U12); if (!Precision::IsInfinite(U21)) P2f = Tool2::Value(*((Curve2*)myC[1]), U21); if (!Precision::IsInfinite(U22)) P2l = Tool2::Value(*((Curve2*)myC[1]), U22); if (Precision::IsInfinite(U11) || Precision::IsInfinite(U21)) mydist11 = RealLast(); else mydist11 = P1f.SquareDistance(P2f); if (Precision::IsInfinite(U11) || Precision::IsInfinite(U22)) mydist12 = RealLast(); else mydist12 = P1f.SquareDistance(P2l); if (Precision::IsInfinite(U12) || Precision::IsInfinite(U21)) mydist21 = RealLast(); else mydist21 = P1l.SquareDistance(P2f); if (Precision::IsInfinite(U12) || Precision::IsInfinite(U22)) mydist22 = RealLast(); else mydist22 = P1l.SquareDistance(P2l); myECC.SetTolerance (Tol); //Depending on the types of curves, the algorithm is chosen: //- _ExtElC, when one of the curves is a line and the other is elementary, // or there are two circles; //- _GenExtCC, in all other cases if ( (type1 == GeomAbs_Line && type2 <= GeomAbs_Parabola) || (type2 == GeomAbs_Line && type1 <= GeomAbs_Parabola) ) { //analytical case - one curve is always a line Standard_Integer anInd1 = 0, anInd2 = 1; GeomAbs_CurveType aType2 = type2; if ((inverse = (type1 > type2)) == Standard_True ) { //algorithm uses inverse order of arguments anInd1 = 1; anInd2 = 0; aType2 = type1; } switch (aType2) { case GeomAbs_Line: { Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Line(), Tol); Results(Xtrem, U11, U12, U21, U22); break; } case GeomAbs_Circle: { Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Circle(), Tol); Results(Xtrem, U11, U12, U21, U22); break; } case GeomAbs_Ellipse: { Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Ellipse()); Results(Xtrem, U11, U12, U21, U22); break; } case GeomAbs_Hyperbola: { Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Hyperbola()); Results(Xtrem, U11, U12, U21, U22); break; } case GeomAbs_Parabola: { Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Parabola()); Results(Xtrem, U11, U12, U21, U22); break; } default: break; } } else if (type1 == GeomAbs_Circle && type2 == GeomAbs_Circle) { //analytical case - two circles Standard_Boolean bIsDone; Extrema_ExtElC CCXtrem ((*((Curve1*)myC[0])).Circle(), (*((Curve2*)myC[1])).Circle()); bIsDone = CCXtrem.IsDone(); //modified by NIZNHY-PKV Fri Nov 21 10:48:14 2008f if(bIsDone) { Results(CCXtrem, U11, U12, U21, U22); } //if(CCXtrem.IsParallel()) { //Results(CCXtrem, U11, U12, U21, U22); //} //modified by NIZNHY-PKV Fri Nov 21 10:48:23 2008t else { Standard_Integer i; Standard_Integer aNbS = 32; //default number of sample points per interval (why 32?) for (i = 0; i < 2; i++) { TColStd_ListOfTransient& aCacheList = myCacheLists[i]; if (aCacheList.IsEmpty()) { //no caches, build them Curve1& aC = *(Curve1*)myC[i]; //single interval from myInf[i] to mySup[i] Handle(Extrema_CCache) aCache = new Extrema_CCache (aC, myInf[i], mySup[i], aNbS, Standard_True); aCacheList.Append (aCache); } } Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (myCacheLists[0].First()); myECC.SetCurveCache (1, aCache1); Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (myCacheLists[1].First()); myECC.SetCurveCache (2, aCache2); myECC.Perform(); Results (myECC, U11, U12, U21, U22); } } else { //common case - use _GenExtCC //1. check and prepare caches Standard_Integer i, aNbS[2] = {32, 32}, aNbInter[2] = {1, 1}; Standard_Real rf = 0., rl = 0., LL[2] = {-1., -1.}; for (i = 0; i < 2; i++) { TColStd_ListOfTransient& aCacheList = myCacheLists[i]; if (aCacheList.IsEmpty()) { //no caches, build them Curve1& aC = *(Curve1*)myC[i]; Standard_Real du1 = 0., t = 0.; gp_Pnt P1, P2; GeomAbs_CurveType aType = aC.GetType(); switch (aType) { case GeomAbs_BezierCurve: aNbS[i] = aC.NbPoles() * 2; break; case GeomAbs_BSplineCurve: aNbS[i] = aC.NbPoles() * 2; rf = (Tool1::BSpline(*((Curve1*)myC[i])))->FirstParameter(); rl = (Tool1::BSpline(*((Curve1*)myC[i])))->LastParameter(); aNbS[i] = (Standard_Integer) ( aNbS[i] * ((mySup[i] - myInf[i]) / (rl - rf)) + 1 ); case GeomAbs_OtherCurve: //adjust number of sample points for B-Splines and Other curves aNbInter[i] = aC.NbIntervals (GeomAbs_C2); aNbS[i] = Max(aNbS[i] / aNbInter[i], 3); LL[i] = 0.; du1 = (mySup[i] - myInf[i]) / ((aNbS[i]-1)*aNbInter[i]); P1 = Tool1::Value(*((Curve1*)myC[i]), myInf[i]); for(t = myInf[i] + du1; t <= mySup[i]; t += du1) { P2 = Tool1::Value(*((Curve1*)myC[i]), t); LL[i] += P1.Distance(P2); P1 = P2; } LL[i] /= ((aNbS[i]-1)*aNbInter[i]); break; default: break; } } } if(LL[0] > 0. && LL[1] > 0.) { if(LL[0] > 4.*LL[1]) { aNbS[0] = (Standard_Integer) ( aNbS[0] * LL[0]/LL[1]/2. ); } else if(LL[1] > 4.*LL[0]) { aNbS[1] = (Standard_Integer) (aNbS[1] * LL[1]/LL[0]/2. ); } } for (i = 0; i < 2; i++) { TColStd_ListOfTransient& aCacheList = myCacheLists[i]; if (aCacheList.IsEmpty()) { //no caches, build them Curve1& aC = *(Curve1*)myC[i]; if (aC.GetType() >= GeomAbs_BSplineCurve) { //can be multiple intervals, one cache per one C2 interval TColStd_Array1OfReal anArr (1, aNbInter[i] + 1); aC.Intervals (anArr, GeomAbs_C2); for (Standard_Integer k = 1; k <= aNbInter[i]; k++) { Handle(Extrema_CCache) aCache = new Extrema_CCache (aC, anArr(k), anArr(k+1), aNbS[i], Standard_True); aCacheList.Append (aCache); } } else { //single interval from myInf[i] to mySup[i] Handle(Extrema_CCache) aCache = new Extrema_CCache (aC, myInf[i], mySup[i], aNbS[i], Standard_True); aCacheList.Append (aCache); } } } //2. process each cache from one list with each cache from the other TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[0]); for (; anIt1.More(); anIt1.Next()) { Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value()); myECC.SetCurveCache (1, aCache1); TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[1]); for (; anIt2.More(); anIt2.Next()) { Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value()); myECC.SetCurveCache (2, aCache2); myECC.Perform(); Results(myECC, U11, U12, U21, U22); } } } } //======================================================================= //function : IsDone //purpose : //======================================================================= Standard_Boolean Extrema_GExtCC::IsDone() const { return myDone; } //======================================================================= //function : IsParallel //purpose : //======================================================================= Standard_Boolean Extrema_GExtCC::IsParallel() const { return myIsPar; } //======================================================================= //function : Value //purpose : //======================================================================= Standard_Real Extrema_GExtCC::SquareDistance(const Standard_Integer N) const { if(!myDone) StdFail_NotDone::Raise(); if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise(); return mySqDist.Value(N); } //======================================================================= //function : NbExt //purpose : //======================================================================= Standard_Integer Extrema_GExtCC::NbExt() const { if(!myDone) StdFail_NotDone::Raise(); return mynbext; } //======================================================================= //function : Points //purpose : //======================================================================= void Extrema_GExtCC::Points(const Standard_Integer N, Extrema_POnCurv& P1, Extrema_POnCurv& P2) const { if(!myDone) StdFail_NotDone::Raise(); if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise(); P1 = mypoints.Value(2*N-1); P2 = mypoints.Value(2*N); } //======================================================================= //function : TrimmedDistances //purpose : //======================================================================= void Extrema_GExtCC::TrimmedSquareDistances(Standard_Real& dist11, Standard_Real& dist12, Standard_Real& dist21, Standard_Real& dist22, gp_Pnt& P11 , gp_Pnt& P12 , gp_Pnt& P21 , gp_Pnt& P22 ) const { dist11 = mydist11; dist12 = mydist12; dist21 = mydist21; dist22 = mydist22; P11 = P1f; P12 = P1l; P21 = P2f; P22 = P2l; } //======================================================================= //function : Results //purpose : //======================================================================= void Extrema_GExtCC::Results(const Extrema_ExtElC& 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; Extrema_POnCurv P1, P2; myDone = AlgExt.IsDone(); if (myDone) { myIsPar = AlgExt.IsParallel(); if (myIsPar) { GeomAbs_CurveType type = Tool1::GetType(*((Curve1*)myC[0])); GeomAbs_CurveType type2 = Tool2::GetType(*((Curve2*)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 = Tool1::Value(*((Curve1*)myC[0]), Ut11); P1.SetValues(Ut11, PonC1); Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)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 = Tool2::Value(*((Curve2*)myC[1]), Ut21); P2.SetValues(Ut21, PonC2); Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)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 = Tool1::Value(*((Curve1*)myC[0]), 0.); P1.SetValues(0., PonC1); Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)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 = Tool1::Value(*((Curve1*)myC[0]), Ut11); Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)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 = Tool1::Value(*((Curve1*)myC[0]), Ut12); Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)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 = Tool2::Value(*((Curve2*)myC[1]), Ut21); Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)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 = Tool2::Value(*((Curve2*)myC[1]), Ut22); Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)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 = Tool1::Value(*((Curve1*)myC[0]), Ut11); P1.SetValues(Ut11, PonC1); Extrema_ExtPElC ExtPCir(PonC1, Tool2::Circle(*((Curve2*)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 = Tool1::Value(*((Curve1*)myC[0]), Ut12); ExtPCir.Perform(PonC1, Tool2::Circle(*((Curve2*)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 = Tool2::Value(*((Curve2*)myC[1]), Ut21); ExtPCir.Perform(PonC2, Tool1::Circle(*((Curve1*)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 = Tool2::Value(*((Curve2*)myC[1]), Ut22); ExtPCir.Perform(PonC2, Tool1::Circle(*((Curve1*)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); } } } else { NbExt = AlgExt.NbExt(); for (i = 1; i <= NbExt; i++) { // Verification de la validite des parametres AlgExt.Points(i, P1, P2); if (!inverse) { U = P1.Parameter(); U2 = P2.Parameter(); } else { U2 = P1.Parameter(); U = P2.Parameter(); } if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) { U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0]))); } if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) { U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1]))); } if ((U >= Ut11 - RealEpsilon()) && (U <= Ut12 + RealEpsilon()) && (U2 >= Ut21 - RealEpsilon()) && (U2 <= Ut22 + RealEpsilon())) { mynbext++; Val = AlgExt.SquareDistance(i); mySqDist.Append(Val); if (!inverse) { P1.SetValues(U, P1.Value()); P2.SetValues(U2, P2.Value()); mypoints.Append(P1); mypoints.Append(P2); } else { P1.SetValues(U2, P1.Value()); P2.SetValues(U, P2.Value()); mypoints.Append(P2); mypoints.Append(P1); } } } } } } //======================================================================= //function : Results //purpose : //======================================================================= void Extrema_GExtCC::Results(const Extrema_ECC& AlgExt, const Standard_Real Ut11, const Standard_Real Ut12, const Standard_Real Ut21, const Standard_Real Ut22) { Standard_Integer i, j,NbExt; Standard_Real Val, U, U2,Uj,U2j; Extrema_POnCurv P1, P2,P1j,P2j; Standard_Boolean IsExtrema; myDone = AlgExt.IsDone(); if (myDone) { NbExt = AlgExt.NbExt(); for (i = 1; i <= NbExt; i++) { AlgExt.Points(i, P1, P2); U = P1.Parameter(); U2 = P2.Parameter(); IsExtrema=Standard_True; for (j=1;j<=mynbext;j++) { P1j=mypoints.Value(2*j-1); P2j=mypoints.Value(2*j); Uj=P1j.Parameter(); U2j=P2j.Parameter(); if ((Abs(Uj-U)<=myTol[0]) && (Abs(U2j-U2)<=myTol[1])) IsExtrema=Standard_False;} if (IsExtrema) { // Verification de la validite des parametres if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) { U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0]))); } if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) { U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1]))); } if ((U >= Ut11 - RealEpsilon()) && (U <= Ut12 + RealEpsilon()) && (U2 >= Ut21 - RealEpsilon()) && (U2 <= Ut22 + RealEpsilon())) { mynbext++; Val = AlgExt.SquareDistance(i); mySqDist.Append(Val); P1.SetValues(U, P1.Value()); P2.SetValues(U2, P2.Value()); mypoints.Append(P1); mypoints.Append(P2); } } } } }