1 // Created by: Bruno DUMORTIER
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
17 #include <AppCont_Function.hxx>
20 #include <BSplCLib.hxx>
22 #include <Standard_NoSuchObject.hxx>
23 #include <Geom_UndefinedDerivative.hxx>
24 #include <gp_Trsf.hxx>
25 #include <Precision.hxx>
26 #include <Approx_FitAndDivide2d.hxx>
28 #include <AppParCurves_MultiCurve.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom2d_BezierCurve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_Circle.hxx>
34 #include <Geom2d_Ellipse.hxx>
35 #include <Geom2d_Hyperbola.hxx>
36 #include <Geom2d_Parabola.hxx>
37 #include <Geom2d_TrimmedCurve.hxx>
38 #include <Geom_BSplineSurface.hxx>
39 #include <Geom_BezierSurface.hxx>
40 #include <Geom_BSplineCurve.hxx>
41 #include <Geom_BezierCurve.hxx>
42 #include <Geom_TrimmedCurve.hxx>
44 #include <TColgp_Array1OfPnt2d.hxx>
45 #include <TColgp_Array2OfPnt2d.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
47 #include <TColgp_SequenceOfPnt2d.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_Array1OfInteger.hxx>
50 #include <TColStd_SequenceOfReal.hxx>
51 #include <TColStd_ListOfTransient.hxx>
53 #include <GeomAbs_SurfaceType.hxx>
54 #include <GeomAbs_CurveType.hxx>
55 #include <Adaptor3d_Surface.hxx>
56 #include <Adaptor3d_Curve.hxx>
57 #include <Adaptor3d_HSurface.hxx>
58 #include <Adaptor3d_HCurve.hxx>
59 #include <Adaptor2d_HCurve2d.hxx>
60 #include <Geom2dAdaptor_Curve.hxx>
61 #include <Geom2dAdaptor_HCurve.hxx>
62 #include <GeomAdaptor_HCurve.hxx>
63 #include <GeomAdaptor.hxx>
64 #include <GeomAdaptor_Surface.hxx>
65 #include <TColgp_SequenceOfPnt.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <gp_Vec2d.hxx>
70 #include <Extrema_GenLocateExtPS.hxx>
71 #include <Extrema_ExtPS.hxx>
72 #include <GCPnts_QuasiUniformAbscissa.hxx>
73 #include <Standard_DomainError.hxx>
74 //#include <GeomLib_IsIso.hxx>
75 //#include <GeomLib_CheckSameParameter.hxx>
79 #include <DrawTrSurf.hxx>
80 #include <Geom2d_Curve.hxx>
82 //static Standard_Integer compteur = 0;
87 Handle(Adaptor3d_HSurface) mySurf; // Surface where to project.
88 Handle(Adaptor3d_HCurve) myCurve; // Curve to project.
89 Handle(Adaptor2d_HCurve2d) myInitCurve2d; // Initial 2dcurve projection.
90 Standard_Real mySqProjOrtTol; // Used to filter non-orthogonal projected point.
93 Standard_Real myPeriod[2]; // U and V period correspondingly.
96 //=======================================================================
97 //function : computePeriodicity
98 //purpose : Compute period information on adaptor.
99 //=======================================================================
100 static void computePeriodicity(const Handle(Adaptor3d_HSurface)& theSurf,
101 Standard_Real &theUPeriod,
102 Standard_Real &theVPeriod)
107 // Compute once information about periodicity.
108 // Param space may be reduced in case of rectangular trimmed surface,
109 // in this case really trimmed bounds should be set as unperiodic.
110 Standard_Real aTrimF, aTrimL, aBaseF, aBaseL, aDummyF, aDummyL;
111 Handle(Geom_Surface) aS = GeomAdaptor::MakeSurface(theSurf->Surface(), Standard_False); // Not trim.
113 if (theSurf->IsUPeriodic())
115 theUPeriod = theSurf->UPeriod();
117 else if(theSurf->IsUClosed())
119 theUPeriod = theSurf->LastUParameter() - theSurf->FirstUParameter();
121 if (theUPeriod != 0.0)
123 aTrimF = theSurf->FirstUParameter(); // Trimmed first
124 aTrimL = theSurf->LastUParameter(); // Trimmed last
125 aS->Bounds(aBaseF, aBaseL, aDummyF, aDummyL); // Non-trimmed values.
126 if (Abs (aBaseF - aTrimF) + Abs (aBaseL - aTrimL) > Precision::PConfusion())
128 // Param space reduced.
134 if (theSurf->IsVPeriodic())
136 theVPeriod = theSurf->VPeriod();
138 else if(theSurf->IsVClosed())
140 theVPeriod = theSurf->LastVParameter() - theSurf->FirstVParameter();
142 if (theVPeriod != 0.0)
144 aTrimF = theSurf->FirstVParameter(); // Trimmed first
145 aTrimL = theSurf->LastVParameter(); // Trimmed last
146 aS->Bounds(aDummyF, aDummyL, aBaseF, aBaseL); // Non-trimmed values.
147 if (Abs (aBaseF - aTrimF) + Abs (aBaseL - aTrimL) > Precision::PConfusion())
149 // Param space reduced.
155 //=======================================================================
156 //function : aFuncValue
157 //purpose : compute functional value in (theU,theV) point
158 //=======================================================================
159 static Standard_Real anOrthogSqValue(const gp_Pnt& aBasePnt,
160 const Handle(Adaptor3d_HSurface)& Surf,
161 const Standard_Real theU,
162 const Standard_Real theV)
164 // Since find projection, formula is:
165 // F1 = Dot(S_U, Vec(aBasePnt, aProjPnt))
166 // F2 = Dot(S_V, Vec(aBasePnt, aProjPnt))
171 Surf->D1(theU, theV, aProjPnt, aSu, aSv);
172 gp_Vec aBaseVec(aBasePnt, aProjPnt);
174 if (aSu.SquareMagnitude() > Precision::SquareConfusion())
177 if (aSv.SquareMagnitude() > Precision::SquareConfusion())
180 Standard_Real aFirstPart = aSu.Dot(aBaseVec);
181 Standard_Real aSecondPart = aSv.Dot(aBaseVec);
182 return (aFirstPart * aFirstPart + aSecondPart * aSecondPart);
185 //=======================================================================
187 //purpose : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
188 // <InitCurve2d> use for calculate start 2D point.
189 //=======================================================================
190 static gp_Pnt2d Function_Value(const Standard_Real theU,
191 const aFuncStruct& theData)
193 gp_Pnt2d p2d = theData.myInitCurve2d->Value(theU) ;
194 gp_Pnt p = theData.myCurve->Value(theU);
195 gp_Pnt aSurfPnt = theData.mySurf->Value(p2d.X(), p2d.Y());
196 Standard_Real aSurfPntDist = aSurfPnt.SquareDistance(p);
198 Standard_Real Uinf, Usup, Vinf, Vsup;
199 Uinf = theData.mySurf->Surface().FirstUParameter();
200 Usup = theData.mySurf->Surface().LastUParameter();
201 Vinf = theData.mySurf->Surface().FirstVParameter();
202 Vsup = theData.mySurf->Surface().LastVParameter();
204 // Check case when curve is close to co-parametrized isoline on surf.
205 if (Abs (p2d.X() - Uinf) < Precision::PConfusion() ||
206 Abs (p2d.X() - Usup) < Precision::PConfusion() )
210 theData.mySurf->D0(p2d.X(), theU, aPnt);
211 if (aPnt.SquareDistance(p) < aSurfPntDist)
215 if (Abs (p2d.Y() - Vinf) < Precision::PConfusion() ||
216 Abs (p2d.Y() - Vsup) < Precision::PConfusion() )
220 theData.mySurf->D0(theU, p2d.Y(), aPnt);
221 if (aPnt.SquareDistance(p) < aSurfPntDist)
225 Standard_Integer decalU = 0, decalV = 0;
226 Standard_Real U0 = p2d.X(), V0 = p2d.Y();
228 GeomAbs_SurfaceType Type = theData.mySurf->GetType();
229 if((Type != GeomAbs_BSplineSurface) &&
230 (Type != GeomAbs_BezierSurface) &&
231 (Type != GeomAbs_OffsetSurface) )
234 Standard_Real S = 0., T = 0.;
237 case GeomAbs_Cylinder:
239 gp_Cylinder Cylinder = theData.mySurf->Cylinder();
240 ElSLib::Parameters( Cylinder, p, S, T);
241 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
242 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
248 gp_Cone Cone = theData.mySurf->Cone();
249 ElSLib::Parameters( Cone, p, S, T);
250 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
251 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
257 gp_Sphere Sphere = theData.mySurf->Sphere();
258 ElSLib::Parameters( Sphere, p, S, T);
259 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
260 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
262 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
263 if(V0 > (Vsup+(Vsup-Vinf))) decalV = int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
265 if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI)
277 gp_Torus Torus = theData.mySurf->Torus();
278 ElSLib::Parameters( Torus, p, S, T);
279 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
280 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
281 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
282 if(V0 > Vsup) decalV = int((V0 - Vsup)/(2*M_PI))+1;
283 S += decalU*2*M_PI; T += decalV*2*M_PI;
287 throw Standard_NoSuchObject("ProjLib_ComputeApproxOnPolarSurface::Value");
289 return gp_Pnt2d(S, T);
292 // Non-analytical case.
293 Standard_Real Dist2Min = RealLast();
294 Standard_Real uperiod = theData.myPeriod[0],
295 vperiod = theData.myPeriod[1],
298 // U0 and V0 are the points within the initialized period.
305 decalU = int((Uinf - U0)/uperiod)+1;
306 U0 += decalU*uperiod;
315 decalU = -(int((U0 - Usup)/uperiod)+1);
316 U0 += decalU*uperiod;
325 decalV = int((Vinf - V0)/vperiod)+1;
326 V0 += decalV*vperiod;
335 decalV = -int((V0 - Vsup)/vperiod)-1;
336 V0 += decalV*vperiod;
340 // The surface around (U0,V0) is reduced.
341 Standard_Real uLittle = (Usup - Uinf)/10, vLittle = (Vsup - Vinf)/10;
342 Standard_Real uInfLi = 0, vInfLi = 0,uSupLi = 0, vSupLi = 0;
343 if((U0 - Uinf) > uLittle) uInfLi = U0 - uLittle; else uInfLi = Uinf;
344 if((V0 - Vinf) > vLittle) vInfLi = V0 - vLittle; else vInfLi = Vinf;
345 if((Usup - U0) > uLittle) uSupLi = U0 + uLittle; else uSupLi = Usup;
346 if((Vsup - V0) > vLittle) vSupLi = V0 + vLittle; else vSupLi = Vsup;
348 GeomAdaptor_Surface SurfLittle;
349 if (Type == GeomAbs_BSplineSurface)
351 Handle(Geom_Surface) GBSS(theData.mySurf->Surface().BSpline());
352 SurfLittle.Load(GBSS, uInfLi, uSupLi, vInfLi, vSupLi);
354 else if (Type == GeomAbs_BezierSurface)
356 Handle(Geom_Surface) GS(theData.mySurf->Surface().Bezier());
357 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
359 else if (Type == GeomAbs_OffsetSurface)
361 Handle(Geom_Surface) GS = GeomAdaptor::MakeSurface(theData.mySurf->Surface());
362 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
366 throw Standard_NoSuchObject ("ProjLib_ComputeApproxOnPolarSurface::ProjectUsingInitialCurve2d() - unknown surface type");
369 // Try to run simple search with initial point (U0, V0).
370 Extrema_GenLocateExtPS locext(SurfLittle, theData.myTolU, theData.myTolV);
371 locext.Perform(p, U0, V0);
374 locext.Point().Parameter(u, v);
375 Dist2Min = anOrthogSqValue(p, theData.mySurf, u, v);
376 if (Dist2Min < theData.mySqProjOrtTol && // Point is projection.
377 locext.SquareDistance() < aSurfPntDist + Precision::SquareConfusion()) // Point better than initial.
379 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
384 // Perform whole param space search.
385 Extrema_ExtPS ext(p, SurfLittle, theData.myTolU, theData.myTolV);
386 if (ext.IsDone() && ext.NbExt() >= 1)
388 Dist2Min = ext.SquareDistance(1);
389 Standard_Integer GoodValue = 1;
390 for (Standard_Integer i = 2 ; i <= ext.NbExt() ; i++ )
392 if( Dist2Min > ext.SquareDistance(i))
394 Dist2Min = ext.SquareDistance(i);
398 ext.Point(GoodValue).Parameter(u, v);
399 Dist2Min = anOrthogSqValue(p, theData.mySurf, u, v);
400 if (Dist2Min < theData.mySqProjOrtTol && // Point is projection.
401 ext.SquareDistance(GoodValue) < aSurfPntDist + Precision::SquareConfusion()) // Point better than initial.
403 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
408 // Both searches return bad values, use point from initial 2dcurve.
413 //=======================================================================
414 //function : ProjLib_PolarFunction
415 //purpose : (OCC217 - apo)- This class produce interface to call "gp_Pnt2d Function_Value(...)"
416 //=======================================================================
418 class ProjLib_PolarFunction : public AppCont_Function
420 aFuncStruct myStruct;
424 ProjLib_PolarFunction(const Handle(Adaptor3d_HCurve) & C,
425 const Handle(Adaptor3d_HSurface)& Surf,
426 const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
427 const Standard_Real Tol3d)
432 computePeriodicity(Surf, myStruct.myPeriod[0], myStruct.myPeriod[1]);
434 myStruct.myCurve = C;
435 myStruct.myInitCurve2d = InitialCurve2d;
436 myStruct.mySurf = Surf;
437 myStruct.mySqProjOrtTol = 10000.0 * Tol3d * Tol3d;
438 myStruct.myTolU = Surf->UResolution(Tol3d);
439 myStruct.myTolV = Surf->VResolution(Tol3d);
442 ~ProjLib_PolarFunction() {}
444 Standard_Real FirstParameter() const
446 return myStruct.myCurve->FirstParameter();
449 Standard_Real LastParameter() const
451 return myStruct.myCurve->LastParameter();
454 gp_Pnt2d Value(const Standard_Real t) const
456 return Function_Value(t, myStruct);
459 Standard_Boolean Value(const Standard_Real theT,
460 NCollection_Array1<gp_Pnt2d>& thePnt2d,
461 NCollection_Array1<gp_Pnt>& /*thePnt*/) const
463 thePnt2d(1) = Function_Value(theT, myStruct);
464 return Standard_True;
467 Standard_Boolean D1(const Standard_Real /*theT*/,
468 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
469 NCollection_Array1<gp_Vec>& /*theVec*/) const
470 {return Standard_False;}
473 //=======================================================================
474 //function : ProjLib_ComputeApproxOnPolarSurface
476 //=======================================================================
478 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface()
479 : myProjIsDone(Standard_False),
480 myTolerance(Precision::Approximation()),
482 myDegMin(-1), myDegMax(-1),
485 myBndPnt(AppParCurves_TangencyPoint)
489 //=======================================================================
490 //function : ProjLib_ComputeApproxOnPolarSurface
492 //=======================================================================
494 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
495 (const Handle(Adaptor2d_HCurve2d)& theInitialCurve2d,
496 const Handle(Adaptor3d_HCurve)& theCurve,
497 const Handle(Adaptor3d_HSurface)& theSurface,
498 const Standard_Real theTolerance3D)
499 : myProjIsDone(Standard_False),
500 myTolerance(theTolerance3D),
502 myDegMin(-1), myDegMax(-1),
505 myBndPnt(AppParCurves_TangencyPoint)
507 myBSpline = Perform(theInitialCurve2d, theCurve, theSurface);
510 //=======================================================================
511 //function : ProjLib_ComputeApproxOnPolarSurface
512 //purpose : case without curve of initialization
513 //=======================================================================
515 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
516 (const Handle(Adaptor3d_HCurve)& theCurve,
517 const Handle(Adaptor3d_HSurface)& theSurface,
518 const Standard_Real theTolerance3D)
519 : myProjIsDone(Standard_False),
520 myTolerance(theTolerance3D),
522 myDegMin(-1), myDegMax(-1),
525 myBndPnt(AppParCurves_TangencyPoint)
527 const Handle(Adaptor2d_HCurve2d) anInitCurve2d;
528 myBSpline = Perform(anInitCurve2d, theCurve, theSurface);
531 //=======================================================================
532 //function : ProjLib_ComputeApproxOnPolarSurface
533 //purpose : Process the case of sewing
534 //=======================================================================
536 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
537 (const Handle(Adaptor2d_HCurve2d)& theInitialCurve2d,
538 const Handle(Adaptor2d_HCurve2d)& theInitialCurve2dBis,
539 const Handle(Adaptor3d_HCurve)& theCurve,
540 const Handle(Adaptor3d_HSurface)& theSurface,
541 const Standard_Real theTolerance3D)
542 : myProjIsDone(Standard_False),
543 myTolerance(theTolerance3D),
545 myDegMin(-1), myDegMax(-1),
548 myBndPnt(AppParCurves_TangencyPoint)
550 // InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing
551 Handle(Geom2d_BSplineCurve) bsc =
552 Perform(theInitialCurve2d, theCurve, theSurface);
555 gp_Pnt2d P2dproj, P2d, P2dBis;
556 P2dproj = bsc->StartPoint();
557 P2d = theInitialCurve2d->Value(theInitialCurve2d->FirstParameter());
558 P2dBis = theInitialCurve2dBis->Value(theInitialCurve2dBis->FirstParameter());
560 Standard_Real Dist, DistBis;
561 Dist = P2dproj.Distance(P2d);
562 DistBis = P2dproj.Distance(P2dBis);
563 if( Dist < DistBis) {
564 // myBSpline2d is the pcurve that is found. It is translated to obtain myCurve2d
566 Handle(Geom2d_Geometry) GG = myBSpline->Translated(P2d, P2dBis);
567 my2ndCurve = Handle(Geom2d_Curve)::DownCast(GG);
571 Handle(Geom2d_Geometry) GG = my2ndCurve->Translated(P2dBis, P2d);
572 myBSpline = Handle(Geom2d_BSplineCurve)::DownCast(GG);
578 //=======================================================================
581 //=======================================================================
583 static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1,
584 Handle(Geom2d_BSplineCurve) C2,
585 Standard_Real theUJump,
586 Standard_Real theVJump)
588 Standard_Integer deg, deg1, deg2;
593 C1->IncreaseDegree(deg2);
596 else if ( deg2 < deg1) {
597 C2->IncreaseDegree(deg1);
602 Standard_Integer np1,np2,nk1,nk2,np,nk;
610 TColStd_Array1OfReal K1(1,nk1); C1->Knots(K1);
611 TColStd_Array1OfInteger M1(1,nk1); C1->Multiplicities(M1);
612 TColgp_Array1OfPnt2d P1(1,np1); C1->Poles(P1);
613 TColStd_Array1OfReal K2(1,nk2); C2->Knots(K2);
614 TColStd_Array1OfInteger M2(1,nk2); C2->Multiplicities(M2);
615 TColgp_Array1OfPnt2d P2(1,np2); C2->Poles(P2);
617 // Compute the new BSplineCurve
618 TColStd_Array1OfReal K(1,nk);
619 TColStd_Array1OfInteger M(1,nk);
620 TColgp_Array1OfPnt2d P(1,np);
622 Standard_Integer i, count = 0;
623 // Set Knots and Mults
624 for ( i = 1; i <= nk1; i++) {
630 for ( i = 2; i <= nk2; i++) {
637 for (i = 1; i <= np1; i++) {
641 for (i = 2; i <= np2; i++) {
643 P(count).SetX(P2(i).X() + theUJump);
644 P(count).SetY(P2(i).Y() + theVJump);
647 Handle(Geom2d_BSplineCurve) BS =
648 new Geom2d_BSplineCurve(P,K,M,deg);
652 //=======================================================================
655 //=======================================================================
657 void ProjLib_ComputeApproxOnPolarSurface::Perform
658 (const Handle(Adaptor3d_HCurve)& Curve, const Handle(Adaptor3d_HSurface)& S)
660 const Handle(Adaptor2d_HCurve2d) anInitCurve2d;
661 myBSpline = Perform(anInitCurve2d, Curve, S);
664 //=======================================================================
667 //=======================================================================
669 Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
670 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
671 const Handle(Adaptor3d_HCurve)& Curve,
672 const Handle(Adaptor3d_HSurface)& S)
675 Standard_Real Tol3d = myTolerance;
676 Standard_Real ParamTol = Precision::PApproximation();
678 Handle(Adaptor2d_HCurve2d) AHC2d = InitialCurve2d;
679 Handle(Adaptor3d_HCurve) AHC = Curve;
681 // if the curve 3d is a BSpline with degree C0, it is cut into sections with degree C1
683 GeomAbs_CurveType typeCurve = Curve->GetType();
684 if(typeCurve == GeomAbs_BSplineCurve) {
685 TColStd_ListOfTransient LOfBSpline2d;
686 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
687 Standard_Integer nbInter = Curve->NbIntervals(GeomAbs_C1);
689 Standard_Integer i, j;
690 Handle(Geom_TrimmedCurve) GTC;
691 Handle(Geom2d_TrimmedCurve) G2dTC;
692 TColStd_Array1OfReal Inter(1,nbInter+1);
693 Curve->Intervals(Inter,GeomAbs_C1);
694 Standard_Real firstinter = Inter.Value(1), secondinter = Inter.Value(2);
696 GTC = new Geom_TrimmedCurve(BSC, firstinter, secondinter);
697 AHC = new GeomAdaptor_HCurve(GTC);
699 // if there is an initialization curve:
700 // - either this is a BSpline C0, with discontinuity at the same parameters of nodes
701 // and the sections C1 are taken
702 // - or this is a curve C1 and the sections of intrest are taken otherwise the curve is created.
705 Standard_Integer nbInter2d;
706 Standard_Boolean C2dIsToCompute;
707 C2dIsToCompute = InitialCurve2d.IsNull();
708 Handle(Geom2d_BSplineCurve) BSC2d;
709 Handle(Geom2d_Curve) G2dC;
711 if(!C2dIsToCompute) {
712 nbInter2d = InitialCurve2d->NbIntervals(GeomAbs_C1);
713 TColStd_Array1OfReal Inter2d(1,nbInter2d+1);
714 InitialCurve2d->Intervals(Inter2d,GeomAbs_C1);
716 for(i = 1,j = 1;i <= nbInter;i++)
717 if(Abs(Inter.Value(i) - Inter2d.Value(j)) < ParamTol) { //OCC217
718 //if(Abs(Inter.Value(i) - Inter2d.Value(j)) < myTolerance) {
719 if (j > nbInter2d) break;
722 if(j != (nbInter2d+1)) {
723 C2dIsToCompute = Standard_True;
728 AHC2d = BuildInitialCurve2d(AHC, S);
731 typeCurve = InitialCurve2d->GetType();
734 G2dC = new Geom2d_Line(InitialCurve2d->Line());
737 case GeomAbs_Circle: {
738 G2dC = new Geom2d_Circle(InitialCurve2d->Circle());
741 case GeomAbs_Ellipse: {
742 G2dC = new Geom2d_Ellipse(InitialCurve2d->Ellipse());
745 case GeomAbs_Hyperbola: {
746 G2dC = new Geom2d_Hyperbola(InitialCurve2d->Hyperbola());
749 case GeomAbs_Parabola: {
750 G2dC = new Geom2d_Parabola(InitialCurve2d->Parabola());
753 case GeomAbs_BezierCurve: {
754 G2dC = InitialCurve2d->Bezier();
757 case GeomAbs_BSplineCurve: {
758 G2dC = InitialCurve2d->BSpline();
761 case GeomAbs_OtherCurve:
765 gp_Pnt2d fp2d = G2dC->Value(firstinter), lp2d = G2dC->Value(secondinter);
766 gp_Pnt fps, lps, fpc, lpc;
767 S->D0(fp2d.X(), fp2d.Y(), fps);
768 S->D0(lp2d.X(), lp2d.Y(), lps);
769 Curve->D0(firstinter, fpc);
770 Curve->D0(secondinter, lpc);
772 if((fps.IsEqual(fpc, Tol3d)) &&
773 (lps.IsEqual(lpc, Tol3d))) {
774 //if((fps.IsEqual(fpc, myTolerance)) &&
775 // (lps.IsEqual(lpc, myTolerance))) {
776 G2dTC = new Geom2d_TrimmedCurve(G2dC, firstinter, secondinter);
777 Geom2dAdaptor_Curve G2dAC(G2dTC);
778 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
779 myProjIsDone = Standard_True;
782 AHC2d = BuildInitialCurve2d(AHC, S);
783 C2dIsToCompute = Standard_True;
788 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
791 return Handle(Geom2d_BSplineCurve)();
793 LOfBSpline2d.Append(BSC2d);
796 return Handle(Geom2d_BSplineCurve)();
801 Standard_Real iinter, ip1inter;
802 Standard_Integer nbK2d, deg;
803 nbK2d = BSC2d->NbKnots(); deg = BSC2d->Degree();
805 for(i = 2;i <= nbInter;i++) {
806 iinter = Inter.Value(i);
807 ip1inter = Inter.Value(i+1);
809 GTC->SetTrim(iinter, ip1inter);
810 AHC = new GeomAdaptor_HCurve(GTC);
814 AHC2d = BuildInitialCurve2d(AHC, S);
817 gp_Pnt2d fp2d = G2dC->Value(iinter), lp2d = G2dC->Value(ip1inter);
818 gp_Pnt fps, lps, fpc, lpc;
819 S->D0(fp2d.X(), fp2d.Y(), fps);
820 S->D0(lp2d.X(), lp2d.Y(), lps);
821 Curve->D0(iinter, fpc);
822 Curve->D0(ip1inter, lpc);
824 if((fps.IsEqual(fpc, Tol3d)) &&
825 (lps.IsEqual(lpc, Tol3d))) {
826 //if((fps.IsEqual(fpc, myTolerance)) &&
827 // (lps.IsEqual(lpc, myTolerance))) {
828 G2dTC->SetTrim(iinter, ip1inter);
829 Geom2dAdaptor_Curve G2dAC(G2dTC);
830 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
831 myProjIsDone = Standard_True;
834 AHC2d = BuildInitialCurve2d(AHC, S);
838 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
840 return Handle(Geom2d_BSplineCurve)();
842 LOfBSpline2d.Append(BSC2d);
843 nbK2d += BSC2d->NbKnots() - 1;
844 deg = Max(deg, BSC2d->Degree());
847 return Handle(Geom2d_BSplineCurve)();
851 Standard_Real anUPeriod, anVPeriod;
852 computePeriodicity(S, anUPeriod, anVPeriod);
853 Standard_Integer NbC = LOfBSpline2d.Extent();
854 Handle(Geom2d_BSplineCurve) CurBS;
855 CurBS = Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
856 LOfBSpline2d.RemoveFirst();
857 for (Standard_Integer ii = 2; ii <= NbC; ii++)
859 Handle(Geom2d_BSplineCurve) BS =
860 Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
862 //Check for period jump in point of contact.
863 gp_Pnt2d aC1End = CurBS->Pole(CurBS->NbPoles()); // End of C1.
864 gp_Pnt2d aC2Beg = BS->Pole(1); // Beginning of C2.
865 Standard_Real anUJump = 0.0, anVJump = 0.0;
867 if (anUPeriod > 0.0 &&
868 Abs (aC1End.X() - aC2Beg.X()) > (anUPeriod ) / 2.01)
870 Standard_Real aMultCoeff = aC2Beg.X() < aC1End.X() ? 1.0 : -1.0;
871 anUJump = (anUPeriod) * aMultCoeff;
875 Abs (aC1End.Y() - aC2Beg.Y()) > (anVPeriod) / 2.01)
877 Standard_Real aMultCoeff = aC2Beg.Y() < aC1End.Y() ? 1.0 : -1.0;
878 anVJump = (anVPeriod) * aMultCoeff;
881 CurBS = Concat(CurBS,BS, anUJump, anVJump);
882 LOfBSpline2d.RemoveFirst();
888 if(InitialCurve2d.IsNull()) {
889 AHC2d = BuildInitialCurve2d(Curve, S);
891 return Handle(Geom2d_BSplineCurve)();
893 return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
897 //=======================================================================
898 //function : ProjLib_BuildInitialCurve2d
900 //=======================================================================
902 Handle(Adaptor2d_HCurve2d)
903 ProjLib_ComputeApproxOnPolarSurface::
904 BuildInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
905 const Handle(Adaptor3d_HSurface)& Surf)
907 // discretize the Curve with quasiuniform deflection
908 // density at least NbOfPnts points
909 myProjIsDone = Standard_False;
912 Standard_Real Tol3d = myTolerance;
913 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
914 Standard_Real DistTol3d = 100.0*Tol3d;
917 DistTol3d = myMaxDist;
919 Standard_Real DistTol3d2 = DistTol3d * DistTol3d;
920 Standard_Real uperiod = 0.0, vperiod = 0.0;
921 computePeriodicity(Surf, uperiod, vperiod);
923 // NO myTol is Tol2d !!!!
924 //Standard_Real TolU = myTolerance, TolV = myTolerance;
925 //Standard_Real Tol3d = 100*myTolerance; // At random Balthazar.
927 Standard_Integer NbOfPnts = 61;
928 GCPnts_QuasiUniformAbscissa QUA(Curve->GetCurve(),NbOfPnts);
929 NbOfPnts = QUA.NbPoints();
930 TColgp_Array1OfPnt Pts(1,NbOfPnts);
931 TColStd_Array1OfReal Param(1,NbOfPnts);
932 Standard_Integer i, j;
933 for( i = 1; i <= NbOfPnts ; i++ ) {
934 Param(i) = QUA.Parameter(i);
935 Pts(i) = Curve->Value(Param(i));
938 TColgp_Array1OfPnt2d Pts2d(1,NbOfPnts);
939 TColStd_Array1OfInteger Mult(1,NbOfPnts);
941 Mult(1) = Mult(NbOfPnts) = 2;
943 Standard_Real Uinf, Usup, Vinf, Vsup;
944 Uinf = Surf->Surface().FirstUParameter();
945 Usup = Surf->Surface().LastUParameter();
946 Vinf = Surf->Surface().FirstVParameter();
947 Vsup = Surf->Surface().LastVParameter();
948 GeomAbs_SurfaceType Type = Surf->GetType();
949 if((Type != GeomAbs_BSplineSurface) && (Type != GeomAbs_BezierSurface) &&
950 (Type != GeomAbs_OffsetSurface)) {
952 // Standard_Integer usens = 0, vsens = 0;
953 // to know the position relatively to the period
955 // case GeomAbs_Plane:
957 // gp_Pln Plane = Surf->Plane();
958 // for ( i = 1 ; i <= NbOfPnts ; i++) {
959 // ElSLib::Parameters( Plane, Pts(i), S, T);
960 // Pts2d(i).SetCoord(S,T);
962 // myProjIsDone = Standard_True;
965 case GeomAbs_Cylinder:
967 // Standard_Real Sloc, Tloc;
969 Standard_Integer usens = 0;
970 gp_Cylinder Cylinder = Surf->Cylinder();
971 ElSLib::Parameters( Cylinder, Pts(1), S, T);
972 Pts2d(1).SetCoord(S,T);
973 for ( i = 2 ; i <= NbOfPnts ; i++) {
975 ElSLib::Parameters( Cylinder, Pts(i), S, T);
976 if(Abs(Sloc - S) > M_PI) {
982 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
984 myProjIsDone = Standard_True;
989 // Standard_Real Sloc, Tloc;
991 Standard_Integer usens = 0;
992 gp_Cone Cone = Surf->Cone();
993 ElSLib::Parameters( Cone, Pts(1), S, T);
994 Pts2d(1).SetCoord(S,T);
995 for ( i = 2 ; i <= NbOfPnts ; i++) {
997 ElSLib::Parameters( Cone, Pts(i), S, T);
998 if(Abs(Sloc - S) > M_PI) {
1004 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
1006 myProjIsDone = Standard_True;
1009 case GeomAbs_Sphere:
1011 Standard_Real Sloc, Tloc;
1012 Standard_Integer usens = 0, vsens = 0; //usens steps by half-period
1013 Standard_Boolean vparit = Standard_False;
1014 gp_Sphere Sphere = Surf->Sphere();
1015 ElSLib::Parameters( Sphere, Pts(1), S, T);
1016 Pts2d(1).SetCoord(S,T);
1017 for ( i = 2 ; i <= NbOfPnts ; i++) {
1019 ElSLib::Parameters( Sphere, Pts(i), S, T);
1020 if(1.6*M_PI < Abs(Sloc - S)) {
1026 if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
1032 if(Abs(Tloc - Vsup) < (Vsup - Vinf)/5)
1038 Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
1041 Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
1045 myProjIsDone = Standard_True;
1050 Standard_Real Sloc, Tloc;
1051 Standard_Integer usens = 0, vsens = 0;
1052 gp_Torus Torus = Surf->Torus();
1053 ElSLib::Parameters( Torus, Pts(1), S, T);
1054 Pts2d(1).SetCoord(S,T);
1055 for ( i = 2 ; i <= NbOfPnts ; i++) {
1057 ElSLib::Parameters( Torus, Pts(i), S, T);
1058 if(Abs(Sloc - S) > M_PI) {
1064 if(Abs(Tloc - T) > M_PI) {
1070 Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
1072 myProjIsDone = Standard_True;
1076 throw Standard_NoSuchObject("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
1080 myProjIsDone = Standard_False;
1081 Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
1084 TColgp_SequenceOfPnt2d Sols;
1085 Standard_Boolean areManyZeros = Standard_False;
1087 Curve->D0(Param.Value(1), pntproj) ;
1088 Extrema_ExtPS aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
1089 Standard_Real aMinSqDist = RealLast();
1090 if (aExtPS.IsDone())
1092 for (i = 1; i <= aExtPS.NbExt(); i++)
1094 Standard_Real aSqDist = aExtPS.SquareDistance(i);
1095 if (aSqDist < aMinSqDist)
1096 aMinSqDist = aSqDist;
1099 if (aMinSqDist > DistTol3d2) //try to project with less tolerance
1101 TolU = Min(TolU, Precision::PConfusion());
1102 TolV = Min(TolV, Precision::PConfusion());
1103 aExtPS.Initialize(Surf->Surface(),
1104 Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(),
1105 Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
1107 aExtPS.Perform(pntproj);
1110 if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
1112 Standard_Integer GoodValue = 1;
1114 for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
1115 if( aExtPS.SquareDistance(i) < DistTol3d2 ) {
1116 if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
1117 aExtPS.Point(i).Parameter(u,v);
1119 Standard_Boolean isSame = Standard_False;
1120 for( j = 1; j <= Sols.Length(); j++ ) {
1121 if( p2d.SquareDistance( Sols.Value(j) ) <= 1.e-18 ) {
1122 isSame = Standard_True;
1126 if( !isSame ) Sols.Append( p2d );
1128 if( Dist2Min > aExtPS.SquareDistance(i) ) {
1129 Dist2Min = aExtPS.SquareDistance(i);
1135 if( Sols.Length() > 1 ) areManyZeros = Standard_True;
1137 if( Dist2Min <= DistTol3d2) {
1138 if( !areManyZeros ) {
1139 aExtPS.Point(GoodValue).Parameter(u,v);
1140 Pts2d(1).SetCoord(u,v);
1141 myProjIsDone = Standard_True;
1144 Standard_Integer nbSols = Sols.Length();
1145 Standard_Real Dist2Max = -1.e+200;
1146 for( i = 1; i <= nbSols; i++ ) {
1147 const gp_Pnt2d& aP1 = Sols.Value(i);
1148 for( j = i+1; j <= nbSols; j++ ) {
1149 const gp_Pnt2d& aP2 = Sols.Value(j);
1150 Standard_Real aDist2 = aP1.SquareDistance(aP2);
1151 if( aDist2 > Dist2Max ) Dist2Max = aDist2;
1154 Standard_Real aMaxT2 = Max(TolU,TolV);
1156 if( Dist2Max > aMaxT2 ) {
1157 Standard_Integer tPp = 0;
1158 for( i = 1; i <= 5; i++ ) {
1159 Standard_Integer nbExtOk = 0;
1160 Standard_Integer indExt = 0;
1161 Standard_Integer iT = 1 + (NbOfPnts - 1)/5*i;
1162 Curve->D0( Param.Value(iT), pntproj );
1163 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
1165 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
1166 for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
1167 if( aTPS.SquareDistance(j) < DistTol3d2 ) {
1169 if( aTPS.SquareDistance(j) < Dist2Min ) {
1170 Dist2Min = aTPS.SquareDistance(j);
1176 if( nbExtOk == 1 ) {
1178 aTPS.Point(indExt).Parameter(u,v);
1184 gp_Pnt2d aPp = gp_Pnt2d(u,v);
1187 Standard_Boolean isFound = Standard_False;
1189 Curve->D0( Param.Value(tPp+j), pntproj );
1190 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
1192 Standard_Integer indExt = 0;
1193 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
1194 for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
1195 if( aTPS.SquareDistance(i) < DistTol3d2 && aTPS.SquareDistance(i) < Dist2Min ) {
1196 Dist2Min = aTPS.SquareDistance(i);
1198 isFound = Standard_True;
1203 aTPS.Point(indExt).Parameter(u,v);
1204 aPn = gp_Pnt2d(u,v);
1208 if( (tPp+j) > NbOfPnts ) break;
1212 gp_Vec2d atV(aPp,aPn);
1213 Standard_Boolean isChosen = Standard_False;
1214 for( i = 1; i <= nbSols; i++ ) {
1215 const gp_Pnt2d& aP1 = Sols.Value(i);
1216 gp_Vec2d asV(aP1,aPp);
1217 if( asV.Dot(atV) > 0. ) {
1218 isChosen = Standard_True;
1219 Pts2d(1).SetCoord(aP1.X(),aP1.Y());
1220 myProjIsDone = Standard_True;
1225 aExtPS.Point(GoodValue).Parameter(u,v);
1226 Pts2d(1).SetCoord(u,v);
1227 myProjIsDone = Standard_True;
1231 aExtPS.Point(GoodValue).Parameter(u,v);
1232 Pts2d(1).SetCoord(u,v);
1233 myProjIsDone = Standard_True;
1237 aExtPS.Point(GoodValue).Parameter(u,v);
1238 Pts2d(1).SetCoord(u,v);
1239 myProjIsDone = Standard_True;
1243 aExtPS.Point(GoodValue).Parameter(u,v);
1244 Pts2d(1).SetCoord(u,v);
1245 myProjIsDone = Standard_True;
1250 // calculate the following points with GenLocate_ExtPS
1251 // (and store the result and each parameter in a sequence)
1252 Standard_Integer usens = 0, vsens = 0;
1253 // to know the position relatively to the period
1254 Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
1255 // U0 and V0 are the points in the initialized period
1256 // (period with u and v),
1257 // U1 and V1 are the points for construction of poles
1259 for ( i = 2 ; i <= NbOfPnts ; i++)
1261 myProjIsDone = Standard_False;
1262 Dist2Min = RealLast();
1263 Curve->D0(Param.Value(i), pntproj);
1264 Extrema_GenLocateExtPS aLocateExtPS(Surf->Surface(), TolU, TolV);
1265 aLocateExtPS.Perform(pntproj, U0, V0);
1267 if (aLocateExtPS.IsDone())
1269 if (aLocateExtPS.SquareDistance() < DistTol3d2)
1271 //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
1272 (aLocateExtPS.Point()).Parameter(U0,V0);
1273 U1 = U0 + usens*uperiod;
1274 V1 = V0 + vsens*vperiod;
1275 Pts2d(i).SetCoord(U1,V1);
1276 myProjIsDone = Standard_True;
1280 Extrema_ExtPS aGlobalExtr(pntproj, Surf->Surface(), TolU, TolV);
1281 if (aGlobalExtr.IsDone())
1283 Standard_Real LocalMinSqDist = RealLast();
1284 Standard_Integer imin = 0;
1285 for (Standard_Integer isol = 1; isol <= aGlobalExtr.NbExt(); isol++)
1287 Standard_Real aSqDist = aGlobalExtr.SquareDistance(isol);
1288 if (aSqDist < LocalMinSqDist)
1290 LocalMinSqDist = aSqDist;
1294 if (LocalMinSqDist < DistTol3d2)
1296 Standard_Real LocalU, LocalV;
1297 aGlobalExtr.Point(imin).Parameter(LocalU, LocalV);
1298 if (uperiod > 0. && Abs(U0 - LocalU) >= uperiod/2.)
1305 if (vperiod > 0. && Abs(V0 - LocalV) >= vperiod/2.)
1312 U0 = LocalU; V0 = LocalV;
1313 U1 = U0 + usens*uperiod;
1314 V1 = V0 + vsens*vperiod;
1315 Pts2d(i).SetCoord(U1,V1);
1316 myProjIsDone = Standard_True;
1318 if((i == 2) && (!IsEqual(uperiod, 0.0) || !IsEqual(vperiod, 0.0)))
1319 {//Make 1st point more precise for periodic surfaces
1320 const Standard_Integer aSize = 3;
1321 const gp_Pnt2d aP(Pts2d(2));
1322 Standard_Real aUpar[aSize], aVpar[aSize];
1323 Pts2d(1).Coord(aUpar[1], aVpar[1]);
1324 aUpar[0] = aUpar[1] - uperiod;
1325 aUpar[2] = aUpar[1] + uperiod;
1326 aVpar[0] = aVpar[1] - vperiod;
1327 aVpar[2] = aVpar[1] + vperiod;
1329 Standard_Real aSQdistMin = RealLast();
1330 Standard_Integer aBestUInd = 1, aBestVInd = 1;
1331 const Standard_Integer aSizeU = IsEqual(uperiod, 0.0) ? 1 : aSize,
1332 aSizeV = IsEqual(vperiod, 0.0) ? 1 : aSize;
1333 for(Standard_Integer uInd = 0; uInd < aSizeU; uInd++)
1335 for(Standard_Integer vInd = 0; vInd < aSizeV; vInd++)
1337 Standard_Real aSQdist = aP.SquareDistance(gp_Pnt2d(aUpar[uInd], aVpar[vInd]));
1338 if(aSQdist < aSQdistMin)
1340 aSQdistMin = aSQdist;
1347 Pts2d(1).SetCoord(aUpar[aBestUInd], aVpar[aBestVInd]);
1348 }//if(i == 2) condition
1353 if(!myProjIsDone && uperiod) {
1354 Standard_Real aUinf, aUsup, Uaux;
1355 aUinf = Surf->Surface().FirstUParameter();
1356 aUsup = Surf->Surface().LastUParameter();
1357 if((aUsup - U0) > (U0 - aUinf))
1358 Uaux = 2*aUinf - U0 + uperiod;
1360 Uaux = 2*aUsup - U0 - uperiod;
1362 Extrema_GenLocateExtPS locext(Surf->Surface(), TolU, TolV);
1363 locext.Perform(pntproj, Uaux, V0);
1365 if (locext.IsDone())
1366 if (locext.SquareDistance() < DistTol3d2) { //OCC217
1367 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1368 (locext.Point()).Parameter(u,v);
1369 if((aUsup - U0) > (U0 - aUinf))
1374 U1 = U0 + usens*uperiod;
1375 V1 = V0 + vsens*vperiod;
1376 Pts2d(i).SetCoord(U1,V1);
1377 myProjIsDone = Standard_True;
1380 if(!myProjIsDone && vperiod) {
1381 Standard_Real aVinf, aVsup, Vaux;
1382 aVinf = Surf->Surface().FirstVParameter();
1383 aVsup = Surf->Surface().LastVParameter();
1384 if((aVsup - V0) > (V0 - aVinf))
1385 Vaux = 2*aVinf - V0 + vperiod;
1387 Vaux = 2*aVsup - V0 - vperiod;
1389 Extrema_GenLocateExtPS locext(Surf->Surface(), TolU, TolV);
1390 locext.Perform(pntproj, U0, Vaux);
1392 if (locext.IsDone())
1393 if (locext.SquareDistance() < DistTol3d2) { //OCC217
1394 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1395 (locext.Point()).Parameter(u,v);
1396 if((aVsup - V0) > (V0 - aVinf))
1401 U1 = U0 + usens*uperiod;
1402 V1 = V0 + vsens*vperiod;
1403 Pts2d(i).SetCoord(U1,V1);
1404 myProjIsDone = Standard_True;
1407 if(!myProjIsDone && uperiod && vperiod) {
1408 Standard_Real Uaux, Vaux;
1409 if((Usup - U0) > (U0 - Uinf))
1410 Uaux = 2*Uinf - U0 + uperiod;
1412 Uaux = 2*Usup - U0 - uperiod;
1413 if((Vsup - V0) > (V0 - Vinf))
1414 Vaux = 2*Vinf - V0 + vperiod;
1416 Vaux = 2*Vsup - V0 - vperiod;
1418 Extrema_GenLocateExtPS locext(Surf->Surface(), TolU, TolV);
1419 locext.Perform(pntproj, Uaux, Vaux);
1421 if (locext.IsDone())
1422 if (locext.SquareDistance() < DistTol3d2) {
1423 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1424 (locext.Point()).Parameter(u,v);
1425 if((Usup - U0) > (U0 - Uinf))
1429 if((Vsup - V0) > (V0 - Vinf))
1434 U1 = U0 + usens*uperiod;
1435 V1 = V0 + vsens*vperiod;
1436 Pts2d(i).SetCoord(U1,V1);
1437 myProjIsDone = Standard_True;
1441 Extrema_ExtPS ext(pntproj, Surf->Surface(), TolU, TolV) ;
1443 Dist2Min = ext.SquareDistance(1);
1444 Standard_Integer aGoodValue = 1;
1445 for ( j = 2 ; j <= ext.NbExt() ; j++ )
1446 if( Dist2Min > ext.SquareDistance(j)) {
1447 Dist2Min = ext.SquareDistance(j);
1450 if (Dist2Min < DistTol3d2) {
1451 //if (Dist2Min < Tol3d * Tol3d) {
1452 (ext.Point(aGoodValue)).Parameter(u,v);
1454 if((U0 - u) > (2*uperiod/3)) {
1458 if((u - U0) > (2*uperiod/3)) {
1463 if((V0 - v) > (vperiod/2)) {
1467 if((v - V0) > (vperiod/2)) {
1472 U1 = U0 + usens*uperiod;
1473 V1 = V0 + vsens*vperiod;
1474 Pts2d(i).SetCoord(U1,V1);
1475 myProjIsDone = Standard_True;
1483 // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
1485 myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
1486 //jgv: put the curve into parametric range
1487 gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
1488 Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
1489 Standard_Real sense = 0.;
1492 if (TestU < Uinf - TolU)
1494 else if (TestU > Usup + TolU)
1496 while (TestU < Uinf - TolU || TestU > Usup + TolU)
1497 TestU += sense * uperiod;
1502 if (TestV < Vinf - TolV)
1504 else if (TestV > Vsup + TolV)
1506 while (TestV < Vinf - TolV || TestV > Vsup + TolV)
1507 TestV += sense * vperiod;
1509 gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
1510 if (Abs(Offset.X()) > gp::Resolution() ||
1511 Abs(Offset.Y()) > gp::Resolution())
1512 myBSpline->Translate(Offset);
1513 //////////////////////////////////////////
1514 Geom2dAdaptor_Curve GAC(myBSpline);
1515 Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
1518 // sprintf(name,"%s_%d","build",compteur++);
1519 // DrawTrSurf::Set(name,myBSpline);
1524 // Modified by Sergey KHROMOV - Thu Apr 18 10:57:50 2002 Begin
1525 // Standard_NoSuchObject_Raise_if(1,"ProjLib_Compu: build echec");
1526 // Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
1527 return Handle(Adaptor2d_HCurve2d)();
1529 // myProjIsDone = Standard_False;
1530 // Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
1531 // Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
1532 // Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
1535 //=======================================================================
1536 //function : ProjLib_ProjectUsingInitialCurve2d
1538 //=======================================================================
1539 Handle(Geom2d_BSplineCurve)
1540 ProjLib_ComputeApproxOnPolarSurface::
1541 ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
1542 const Handle(Adaptor3d_HSurface)& Surf,
1543 const Handle(Adaptor2d_HCurve2d)& InitCurve2d)
1546 Standard_Real Tol3d = myTolerance;
1547 Standard_Real DistTol3d = 100.0*Tol3d;
1550 DistTol3d = myMaxDist;
1552 Standard_Real DistTol3d2 = DistTol3d * DistTol3d;
1553 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
1554 Standard_Real Tol2d = Max(Sqrt(TolU*TolU + TolV*TolV), Precision::PConfusion());
1557 GeomAbs_SurfaceType TheTypeS = Surf->GetType();
1558 GeomAbs_CurveType TheTypeC = Curve->GetType();
1559 if(TheTypeS == GeomAbs_Plane) {
1561 gp_Pln Plane = Surf->Plane();
1562 if(TheTypeC == GeomAbs_BSplineCurve) {
1563 myTolReached = Precision::Confusion();
1564 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1565 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1566 for(i = 1;i <= Curve->NbPoles();i++) {
1567 ElSLib::Parameters( Plane, BSC->Pole(i), S, T);
1568 Poles2d(i).SetCoord(S,T);
1570 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1572 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1573 BSC->Multiplicities(Mults);
1574 if(BSC->IsRational()) {
1575 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1576 BSC->Weights(Weights);
1577 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1578 BSC->Degree(), BSC->IsPeriodic()) ;
1580 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1581 BSC->Degree(), BSC->IsPeriodic()) ;
1584 if(TheTypeC == GeomAbs_BezierCurve) {
1585 myTolReached = Precision::Confusion();
1586 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1587 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1588 for(i = 1;i <= Curve->NbPoles();i++) {
1589 ElSLib::Parameters( Plane, BC->Pole(i), S, T);
1590 Poles2d(i).SetCoord(S,T);
1592 TColStd_Array1OfReal Knots(1, 2);
1593 Knots.SetValue(1,0.0);
1594 Knots.SetValue(2,1.0);
1595 TColStd_Array1OfInteger Mults(1, 2);
1596 Mults.Init(BC->NbPoles());
1597 if(BC->IsRational()) {
1598 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1599 BC->Weights(Weights);
1600 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1601 BC->Degree(), BC->IsPeriodic()) ;
1603 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1604 BC->Degree(), BC->IsPeriodic()) ;
1607 if(TheTypeS == GeomAbs_BSplineSurface) {
1608 Handle(Geom_BSplineSurface) BSS = Surf->BSpline();
1609 if((BSS->MaxDegree() == 1) &&
1610 (BSS->NbUPoles() == 2) &&
1611 (BSS->NbVPoles() == 2)) {
1612 gp_Pnt p11 = BSS->Pole(1,1);
1613 gp_Pnt p12 = BSS->Pole(1,2);
1614 gp_Pnt p21 = BSS->Pole(2,1);
1615 gp_Pnt p22 = BSS->Pole(2,2);
1618 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){
1619 Standard_Integer Dist2Min = IntegerLast();
1621 if(TheTypeC == GeomAbs_BSplineCurve) {
1622 myTolReached = Tol3d;
1623 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1624 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1625 for(i = 1;i <= Curve->NbPoles();i++) {
1626 myProjIsDone = Standard_False;
1627 Dist2Min = IntegerLast();
1629 Extrema_GenLocateExtPS extrloc(Surf->Surface(), TolU, TolV);
1630 extrloc.Perform(BSC->Pole(i), (p11.X()+p22.X())/2, (p11.Y()+p22.Y())/2);
1632 if (extrloc.IsDone()) {
1633 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1634 if (Dist2Min < DistTol3d2) {
1635 (extrloc.Point()).Parameter(u,v);
1636 Poles2d(i).SetCoord(u,v);
1637 myProjIsDone = Standard_True;
1646 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1648 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1649 BSC->Multiplicities(Mults);
1650 if(BSC->IsRational()) {
1651 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1652 BSC->Weights(Weights);
1653 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1654 BSC->Degree(), BSC->IsPeriodic()) ;
1656 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1657 BSC->Degree(), BSC->IsPeriodic()) ;
1662 if(TheTypeC == GeomAbs_BezierCurve) {
1663 myTolReached = Tol3d;
1664 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1665 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1666 for(i = 1;i <= Curve->NbPoles();i++) {
1667 Dist2Min = IntegerLast();
1669 Extrema_GenLocateExtPS extrloc(Surf->Surface(), TolU, TolV);
1670 extrloc.Perform(BC->Pole(i), 0.5, 0.5);
1672 if (extrloc.IsDone()) {
1673 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1674 if (Dist2Min < DistTol3d2) {
1675 (extrloc.Point()).Parameter(u,v);
1676 Poles2d(i).SetCoord(u,v);
1677 myProjIsDone = Standard_True;
1683 myProjIsDone = Standard_False;
1687 TColStd_Array1OfReal Knots(1, 2);
1688 Knots.SetValue(1,0.0);
1689 Knots.SetValue(2,1.0);
1690 TColStd_Array1OfInteger Mults(1, 2);
1691 Mults.Init(BC->NbPoles());
1692 if(BC->IsRational()) {
1693 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1694 BC->Weights(Weights);
1695 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1696 BC->Degree(), BC->IsPeriodic()) ;
1698 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1699 BC->Degree(), BC->IsPeriodic()) ;
1705 else if(TheTypeS == GeomAbs_BezierSurface) {
1706 Handle(Geom_BezierSurface) BS = Surf->Bezier();
1707 if((BS->MaxDegree() == 1) &&
1708 (BS->NbUPoles() == 2) &&
1709 (BS->NbVPoles() == 2)) {
1710 gp_Pnt p11 = BS->Pole(1,1);
1711 gp_Pnt p12 = BS->Pole(1,2);
1712 gp_Pnt p21 = BS->Pole(2,1);
1713 gp_Pnt p22 = BS->Pole(2,2);
1716 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){
1717 Standard_Integer Dist2Min = IntegerLast();
1721 if(TheTypeC == GeomAbs_BSplineCurve) {
1722 myTolReached = Tol3d;
1723 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1724 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1725 for(i = 1;i <= Curve->NbPoles();i++) {
1726 myProjIsDone = Standard_False;
1727 Dist2Min = IntegerLast();
1729 Extrema_GenLocateExtPS extrloc(Surf->Surface(), TolU, TolV);
1730 extrloc.Perform(BSC->Pole(i), (p11.X()+p22.X())/2, (p11.Y()+p22.Y())/2);
1732 if (extrloc.IsDone()) {
1733 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1734 if (Dist2Min < DistTol3d2) {
1735 (extrloc.Point()).Parameter(u,v);
1736 Poles2d(i).SetCoord(u,v);
1737 myProjIsDone = Standard_True;
1746 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1748 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1749 BSC->Multiplicities(Mults);
1750 if(BSC->IsRational()) {
1751 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1752 BSC->Weights(Weights);
1753 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1754 BSC->Degree(), BSC->IsPeriodic()) ;
1756 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1757 BSC->Degree(), BSC->IsPeriodic()) ;
1762 if(TheTypeC == GeomAbs_BezierCurve) {
1763 myTolReached = Tol3d;
1764 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1765 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1766 for(i = 1;i <= Curve->NbPoles();i++) {
1767 Dist2Min = IntegerLast();
1769 Extrema_GenLocateExtPS extrloc(Surf->Surface(), TolU, TolV);
1770 extrloc.Perform(BC->Pole(i), 0.5, 0.5);
1772 if (extrloc.IsDone()) {
1773 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1774 if (Dist2Min < DistTol3d2) {
1775 (extrloc.Point()).Parameter(u,v);
1776 Poles2d(i).SetCoord(u,v);
1777 myProjIsDone = Standard_True;
1783 myProjIsDone = Standard_False;
1787 TColStd_Array1OfReal Knots(1, 2);
1788 Knots.SetValue(1,0.0);
1789 Knots.SetValue(2,1.0);
1790 TColStd_Array1OfInteger Mults(1, 2);
1791 Mults.Init(BC->NbPoles());
1792 if(BC->IsRational()) {
1793 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1794 BC->Weights(Weights);
1795 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1796 BC->Degree(), BC->IsPeriodic()) ;
1798 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1799 BC->Degree(), BC->IsPeriodic()) ;
1806 ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ;
1809 Standard_Integer Nb = 50;
1811 Standard_Real U, U1, U2;
1812 U1 = F.FirstParameter();
1813 U2 = F.LastParameter();
1815 TColgp_Array1OfPnt2d DummyPoles(1,Nb+1);
1816 TColStd_Array1OfReal DummyKnots(1,Nb+1);
1817 TColStd_Array1OfInteger DummyMults(1,Nb+1);
1820 DummyMults(Nb+1) = 2;
1821 for (Standard_Integer ij = 0; ij <= Nb; ij++) {
1822 U = (Nb-ij)*U1 + ij*U2;
1824 DummyPoles(ij+1) = F.Value(U);
1825 DummyKnots(ij+1) = ij;
1827 Handle(Geom2d_BSplineCurve) DummyC2d =
1828 new Geom2d_BSplineCurve(DummyPoles, DummyKnots, DummyMults, 1);
1830 Standard_CString Temp = "bs2d";
1831 DrawTrSurf::Set(Temp,DummyC2d);
1833 // DrawTrSurf::Set((Standard_CString ) "bs2d",DummyC2d);
1834 Handle(Geom2dAdaptor_HCurve) DDD =
1835 Handle(Geom2dAdaptor_HCurve)::DownCast(InitCurve2d);
1839 DrawTrSurf::Set(Temp,DDD->ChangeCurve2d().Curve());
1841 // DrawTrSurf::Set((Standard_CString ) "initc2d",DDD->ChangeCurve2d().Curve());
1844 Standard_Integer Deg1,Deg2;
1855 Standard_Integer aMaxSegments = 1000;
1856 if(myMaxSegments > 0)
1858 aMaxSegments = myMaxSegments;
1860 AppParCurves_Constraint aFistC = AppParCurves_TangencyPoint, aLastC = AppParCurves_TangencyPoint;
1861 if(myBndPnt != AppParCurves_TangencyPoint)
1867 Approx_FitAndDivide2d Fit(Deg1, Deg2, Tol3d, Tol2d, Standard_True, aFistC, aLastC);
1868 Fit.SetMaxSegments(aMaxSegments);
1871 Standard_Real anOldTol2d = Tol2d;
1872 Standard_Real aNewTol2d = 0;
1873 if(Fit.IsAllApproximated()) {
1875 Standard_Integer NbCurves = Fit.NbMultiCurves();
1876 Standard_Integer MaxDeg = 0;
1877 // To transform the MultiCurve into BSpline, it is required that all
1878 // Bezier constituing it have the same degree -> Calculation of MaxDeg
1879 Standard_Integer NbPoles = 1;
1880 for (j = 1; j <= NbCurves; j++) {
1881 Standard_Integer Deg = Fit.Value(j).Degree();
1882 MaxDeg = Max ( MaxDeg, Deg);
1883 Fit.Error(j,Tol3d, Tol2d);
1884 aNewTol2d = Max(aNewTol2d, Tol2d);
1887 myTolReached = Max(myTolReached, myTolerance * (aNewTol2d / anOldTol2d));
1889 NbPoles = MaxDeg * NbCurves + 1; //Tops on the BSpline
1890 TColgp_Array1OfPnt2d Poles( 1, NbPoles);
1892 TColgp_Array1OfPnt2d TempPoles( 1, MaxDeg + 1);//to augment the degree
1894 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Nodes of the BSpline
1896 Standard_Integer Compt = 1;
1897 for (i = 1; i <= NbCurves; i++) {
1898 Fit.Parameters(i, Knots(i), Knots(i+1));
1899 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
1900 TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Retrieve the tops
1901 MC.Curve(1, Poles2d);
1903 //Eventual augmentation of the degree
1904 Standard_Integer Inc = MaxDeg - MC.Degree();
1906 // BSplCLib::IncreaseDegree( Inc, Poles2d, PLib::NoWeights(),
1907 BSplCLib::IncreaseDegree( MaxDeg, Poles2d, BSplCLib::NoWeights(),
1908 TempPoles, BSplCLib::NoWeights());
1909 //update of tops of the PCurve
1910 for (Standard_Integer k = 1 ; k <= MaxDeg + 1; k++) {
1911 Poles.SetValue( Compt, TempPoles( k));
1916 //update of tops of the PCurve
1917 for (Standard_Integer k = 1 ; k <= MaxDeg + 1; k++) {
1918 Poles.SetValue( Compt, Poles2d( k));
1926 //update of fields of ProjLib_Approx
1927 Standard_Integer NbKnots = NbCurves + 1;
1929 TColStd_Array1OfInteger Mults( 1, NbKnots);
1931 Mults.SetValue( 1, MaxDeg + 1);
1932 Mults.SetValue(NbKnots, MaxDeg + 1);
1933 myProjIsDone = Standard_True;
1934 Handle(Geom2d_BSplineCurve) Dummy =
1935 new Geom2d_BSplineCurve(Poles,Knots,Mults,MaxDeg);
1937 // try to smoother the Curve GeomAbs_C1.
1939 Standard_Boolean OK = Standard_True;
1940 Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
1941 for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
1942 OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1, aSmoothTol);
1946 cout << "ProjLib_ComputeApproxOnPolarSurface : Smoothing echoue"<<endl;
1951 return Handle(Geom2d_BSplineCurve)();
1954 //=======================================================================
1955 //function : BSpline
1957 //=======================================================================
1959 Handle(Geom2d_BSplineCurve)
1960 ProjLib_ComputeApproxOnPolarSurface::BSpline() const
1966 //=======================================================================
1967 //function : Curve2d
1969 //=======================================================================
1971 Handle(Geom2d_Curve)
1972 ProjLib_ComputeApproxOnPolarSurface::Curve2d() const
1975 Standard_NoSuchObject_Raise_if
1977 "ProjLib_ComputeApproxOnPolarSurface:2ndCurve2d");
1982 //=======================================================================
1985 //=======================================================================
1987 Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const
1990 return myProjIsDone;
1992 //=======================================================================
1993 //function : SetTolerance
1995 //=======================================================================
1997 void ProjLib_ComputeApproxOnPolarSurface::SetTolerance(const Standard_Real theTol)
2000 myTolerance = theTol;
2002 //=======================================================================
2003 //function : SetDegree
2005 //=======================================================================
2006 void ProjLib_ComputeApproxOnPolarSurface::SetDegree(
2007 const Standard_Integer theDegMin,
2008 const Standard_Integer theDegMax)
2010 myDegMin = theDegMin;
2011 myDegMax = theDegMax;
2013 //=======================================================================
2014 //function : SetMaxSegments
2016 //=======================================================================
2017 void ProjLib_ComputeApproxOnPolarSurface::SetMaxSegments(
2018 const Standard_Integer theMaxSegments)
2020 myMaxSegments = theMaxSegments;
2023 //=======================================================================
2024 //function : SetBndPnt
2026 //=======================================================================
2027 void ProjLib_ComputeApproxOnPolarSurface::SetBndPnt(
2028 const AppParCurves_Constraint theBndPnt)
2030 myBndPnt = theBndPnt;
2033 //=======================================================================
2034 //function : SetMaxDist
2036 //=======================================================================
2037 void ProjLib_ComputeApproxOnPolarSurface::SetMaxDist(
2038 const Standard_Real theMaxDist)
2040 myMaxDist = theMaxDist;
2043 //=======================================================================
2044 //function : Tolerance
2046 //=======================================================================
2048 Standard_Real ProjLib_ComputeApproxOnPolarSurface::Tolerance() const
2051 return myTolReached;