// Created on: 1994-07-06 // Created by: Laurent PAINNOT // Copyright (c) 1994-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : Extrema_ExtCC //purpose : //======================================================================= Extrema_ExtCC::Extrema_ExtCC (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_ExtCC //purpose : //======================================================================= Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1, const Adaptor3d_Curve& 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_ExtCC //purpose : //======================================================================= Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1, const Adaptor3d_Curve& 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_ExtCC::SetCurve (const Standard_Integer theRank, const Adaptor3d_Curve& C) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::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_ExtCC::SetCurve (const Standard_Integer theRank, const Adaptor3d_Curve& C, const Standard_Real Uinf, const Standard_Real Usup) { SetCurve (theRank, C); SetRange (theRank, Uinf, Usup); } //======================================================================= //function : SetRange //purpose : //======================================================================= void Extrema_ExtCC::SetRange (const Standard_Integer theRank, const Standard_Real Uinf, const Standard_Real Usup) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::SetRange()") Standard_Integer anInd = theRank - 1; myInf[anInd] = Uinf; mySup[anInd] = Usup; } //======================================================================= //function : SetTolerance //purpose : //======================================================================= void Extrema_ExtCC::SetTolerance (const Standard_Integer theRank, const Standard_Real theTol) { Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::SetTolerance()") Standard_Integer anInd = theRank - 1; myTol[anInd] = theTol; } //======================================================================= //function : Perform //purpose : //======================================================================= void Extrema_ExtCC::Perform() { Standard_NullObject_Raise_if (!myC[0] || !myC[1], "Extrema_ExtCC::Perform()") myDone = Standard_False; mypoints.Clear(); mySqDist.Clear(); myIsPar = Standard_False; 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]; U21 = myInf[1]; U22 = mySup[1]; if (!Precision::IsInfinite(U11)) P1f = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), U11); if (!Precision::IsInfinite(U12)) P1l = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), U12); if (!Precision::IsInfinite(U21)) P2f = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), U21); if (!Precision::IsInfinite(U22)) P2l = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)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; inverse = (type1 > type2); if (inverse) { //algorithm uses inverse order of arguments anInd1 = 1; anInd2 = 0; aType2 = type1; } 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); break; } case GeomAbs_Circle: { Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Circle(), Tol); Results(Xtrem, 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); break; } case GeomAbs_Hyperbola: { Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Hyperbola()); Results(Xtrem, 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); break; } default: break; } } else if (type1 == GeomAbs_Circle && type2 == GeomAbs_Circle) { //analytical case - two circles Standard_Boolean bIsDone; Extrema_ExtElC CCXtrem ((*((Adaptor3d_Curve*)myC[0])).Circle(), (*((Adaptor3d_Curve*)myC[1])).Circle()); bIsDone = CCXtrem.IsDone(); if(bIsDone) { Results(CCXtrem, U11, U12, U21, U22); } 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 Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)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; Standard_Integer aNbS[2] = {32, 32}, aNbInter[2] = {1, 1}; Standard_Real Coeff[2] = {1., 1.}; Standard_Real rf = 0., rl = 0., LL[2] = {-1., -1.}; Standard_Boolean KnotSampling[2] = {Standard_False, Standard_False}; for (i = 0; i < 2; i++) { TColStd_ListOfTransient& aCacheList = myCacheLists[i]; if (aCacheList.IsEmpty()) { //no caches, build them Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)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: if (aC.Degree() <= 3 && aC.NbKnots() > 2) KnotSampling[i] = Standard_True; aNbS[i] = aC.NbPoles() * 2; rf = (Extrema_CurveTool::BSpline(*((Adaptor3d_Curve*)myC[i])))->FirstParameter(); rl = (Extrema_CurveTool::BSpline(*((Adaptor3d_Curve*)myC[i])))->LastParameter(); aNbS[i] = (Standard_Integer) ( aNbS[i] * ((mySup[i] - myInf[i]) / (rl - rf)) + 1 ); case GeomAbs_OtherCurve: case GeomAbs_Line: //adjust number of sample points for Lines, 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 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[i]), myInf[i]); for(t = myInf[i] + du1; t <= mySup[i]; t += du1) { P2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)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]) { Coeff[0] = LL[0]/LL[1]/2.; if (aNbS[0] * Coeff[0] <= 10000.0) aNbS[0] = (Standard_Integer) ( aNbS[0] * Coeff[0] ); } else if(LL[1] > 4.*LL[0]) { Coeff[1] = LL[1]/LL[0]/2.; if (aNbS[1] * Coeff[1] <= 10000.0) aNbS[1] = (Standard_Integer) (aNbS[1] * Coeff[1] ); } } //modified by NIZNHY-PKV Tue Apr 17 10:01:32 2012f Standard_Integer aNbSTresh; // aNbSTresh=10000; // for (i = 0; i < 2; ++i) { if (aNbS[i]>aNbSTresh) { aNbS[i]=aNbSTresh; } } //modified by NIZNHY-PKV Tue Apr 17 10:01:34 2012t for (i = 0; i < 2; i++) { TColStd_ListOfTransient& aCacheList = myCacheLists[i]; if (aCacheList.IsEmpty()) { //no caches, build them Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)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); if (KnotSampling[i]) { Standard_Integer NbIntervCN = aC.NbIntervals(GeomAbs_CN); TColStd_Array1OfReal IntervalsCN(1, NbIntervCN + 1); aC.Intervals(IntervalsCN, GeomAbs_CN); Standard_Integer j = 1, start_j = 1, k; Standard_Real NextKnot; for (k = 1; k <= aNbInter[i]; k++) { do { NextKnot = IntervalsCN(j+1); j++; } while (NextKnot != anArr(k+1)); Handle(Extrema_CCache) aCache = new Extrema_CCache(aC, anArr(k), anArr(k+1), IntervalsCN, start_j, j, Coeff[i]); aCacheList.Append (aCache); start_j = j; } } else { 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_ExtCC::IsDone() const { return myDone; } //======================================================================= //function : IsParallel //purpose : //======================================================================= Standard_Boolean Extrema_ExtCC::IsParallel() const { return myIsPar; } //======================================================================= //function : Value //purpose : //======================================================================= Standard_Real Extrema_ExtCC::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_ExtCC::NbExt() const { if(!myDone) StdFail_NotDone::Raise(); return mynbext; } //======================================================================= //function : Points //purpose : //======================================================================= void Extrema_ExtCC::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_ExtCC::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_ExtCC::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 = 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); } } } 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 (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())) { 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_ExtCC::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 (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())) { mynbext++; Val = AlgExt.SquareDistance(i); mySqDist.Append(Val); P1.SetValues(U, P1.Value()); P2.SetValues(U2, P2.Value()); mypoints.Append(P1); mypoints.Append(P2); } } } } }