1 // Created on: 1997-08-22
2 // Created by: Sergey SOKOLOV
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_Curve.hxx>
20 #include <Adaptor3d_CurveOnSurface.hxx>
21 #include <Adaptor3d_HCurve.hxx>
22 #include <Adaptor3d_HSurface.hxx>
23 #include <AdvApprox_ApproxAFunction.hxx>
24 #include <AdvApprox_PrefAndRec.hxx>
25 #include <Approx_CurvilinearParameter.hxx>
26 #include <Approx_CurvlinFunc.hxx>
27 #include <CPnts_AbscissaPoint.hxx>
28 #include <GCPnts_AbscissaPoint.hxx>
29 #include <Geom2d_BSplineCurve.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <GeomAbs_Shape.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
35 #include <gp_Pnt2d.hxx>
37 #include <gp_Vec2d.hxx>
38 #include <math_Vector.hxx>
39 #include <Precision.hxx>
40 #include <Standard_ConstructionError.hxx>
41 #include <Standard_OutOfRange.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_Array1OfPnt2d.hxx>
44 #include <TColStd_Array1OfReal.hxx>
45 #include <TColStd_HArray1OfInteger.hxx>
46 #include <TColStd_HArray1OfReal.hxx>
48 #ifdef OCCT_DEBUG_CHRONO
49 #include <OSD_Timer.hxx>
50 static OSD_Chronometer chr_total, chr_init, chr_approx;
52 Standard_Real t_total, t_init, t_approx;
53 void InitChron(OSD_Chronometer& ch)
59 void ResultChron( OSD_Chronometer & ch, Standard_Real & time)
67 Standard_IMPORT Standard_Integer uparam_count;
68 Standard_IMPORT Standard_Real t_uparam;
71 //=======================================================================
72 //class : Approx_CurvilinearParameter_EvalCurv
73 //purpose : case of a free 3D curve
74 //=======================================================================
76 class Approx_CurvilinearParameter_EvalCurv : public AdvApprox_EvaluatorFunction
79 Approx_CurvilinearParameter_EvalCurv (const Handle(Approx_CurvlinFunc)& theFunc,
80 Standard_Real First, Standard_Real Last)
81 : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
83 virtual void Evaluate (Standard_Integer *Dimension,
84 Standard_Real StartEnd[2],
85 Standard_Real *Parameter,
86 Standard_Integer *DerivativeRequest,
87 Standard_Real *Result, // [Dimension]
88 Standard_Integer *ErrorCode);
91 Handle(Approx_CurvlinFunc) fonct;
92 Standard_Real StartEndSav[2];
95 void Approx_CurvilinearParameter_EvalCurv::Evaluate (Standard_Integer * Dimension,
96 Standard_Real * StartEnd,
97 Standard_Real * Param,
98 Standard_Integer * Order,
99 Standard_Real * Result,
100 Standard_Integer * ErrorCode)
103 Standard_Real S = *Param;
104 TColStd_Array1OfReal Res(0, 2);
107 // Dimension is incorrect
108 if (*Dimension != 3) {
111 // Parameter is incorrect
112 if ( S < StartEnd[0] || S > StartEnd[1] ) {
116 if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
118 fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
119 StartEndSav[0]=StartEnd[0];
120 StartEndSav[1]=StartEnd[1];
123 if(!fonct->EvalCase1(S, *Order, Res)) {
127 for(i = 0; i <= 2; i++)
131 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor3d_HCurve)& C3D,
132 const Standard_Real Tol,
133 const GeomAbs_Shape Order,
134 const Standard_Integer MaxDegree,
135 const Standard_Integer MaxSegments)
137 #ifdef OCCT_DEBUG_CHRONO
138 t_total = t_init = t_approx = t_uparam = 0;
140 InitChron(chr_total);
143 // Initialisation of input parameters of AdvApprox
145 Standard_Integer Num1DSS=0, Num2DSS=0, Num3DSS=1;
146 Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul;
147 Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
148 ThreeDTol->Init(Tol);
150 #ifdef OCCT_DEBUG_CHRONO
153 Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C3D, Tol/10);
154 #ifdef OCCT_DEBUG_CHRONO
155 ResultChron(chr_init, t_init);
158 Standard_Real FirstS = fonct->FirstParameter();
159 Standard_Real LastS = fonct->LastParameter();
161 Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
162 TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
163 fonct->Intervals(CutPnts_C2,GeomAbs_C2);
164 Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
165 TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
166 fonct->Intervals(CutPnts_C3,GeomAbs_C3);
167 AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
169 #ifdef OCCT_DEBUG_CHRONO
170 InitChron(chr_approx);
173 Approx_CurvilinearParameter_EvalCurv evC (fonct, FirstS, LastS);
174 AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
175 OneDTolNul, TwoDTolNul, ThreeDTol,
176 FirstS, LastS, Order,
177 MaxDegree, MaxSegments,
180 #ifdef OCCT_DEBUG_CHRONO
181 ResultChron(chr_approx, t_approx);
184 myDone = aApprox.IsDone();
185 myHasResult = aApprox.HasResult();
188 TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
189 aApprox.Poles(1,Poles);
190 Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
191 Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
192 Standard_Integer Degree = aApprox.Degree();
193 myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
195 myMaxError3d = aApprox.MaxError(3,1);
197 #ifdef OCCT_DEBUG_CHRONO
198 ResultChron(chr_total, t_total);
200 cout<<" total reparametrization time = "<<t_total<<endl;
201 cout<<"initialization time = "<<t_init<<endl;
202 cout<<"approximation time = "<<t_approx<<endl;
203 cout<<"total time for uparam computation = "<<t_uparam<<endl;
204 cout<<"number uparam calles = "<<uparam_count<<endl;
208 //=======================================================================
209 //class : Approx_CurvilinearParameter_EvalCurvOnSurf
210 //purpose : case of a curve on one surface
211 //=======================================================================
213 class Approx_CurvilinearParameter_EvalCurvOnSurf : public AdvApprox_EvaluatorFunction
216 Approx_CurvilinearParameter_EvalCurvOnSurf (const Handle(Approx_CurvlinFunc)& theFunc,
217 Standard_Real First, Standard_Real Last)
218 : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
220 virtual void Evaluate (Standard_Integer *Dimension,
221 Standard_Real StartEnd[2],
222 Standard_Real *Parameter,
223 Standard_Integer *DerivativeRequest,
224 Standard_Real *Result, // [Dimension]
225 Standard_Integer *ErrorCode);
228 Handle(Approx_CurvlinFunc) fonct;
229 Standard_Real StartEndSav[2];
232 void Approx_CurvilinearParameter_EvalCurvOnSurf::Evaluate (Standard_Integer * Dimension,
233 Standard_Real * StartEnd,
234 Standard_Real * Param,
235 Standard_Integer * Order,
236 Standard_Real * Result,
237 Standard_Integer * ErrorCode)
240 Standard_Real S = *Param;
241 TColStd_Array1OfReal Res(0, 4);
244 // Dimension is incorrect
245 if (*Dimension != 5) {
248 // Parameter is incorrect
249 if ( S < StartEnd[0] || S > StartEnd[1] ) {
253 if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
255 fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
256 StartEndSav[0]=StartEnd[0];
257 StartEndSav[1]=StartEnd[1];
260 if(!fonct->EvalCase2(S, *Order, Res)) {
264 for(i = 0; i <= 4; i++)
268 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D,
269 const Handle(Adaptor3d_HSurface)& Surf,
270 const Standard_Real Tol,
271 const GeomAbs_Shape Order,
272 const Standard_Integer MaxDegree,
273 const Standard_Integer MaxSegments)
275 #ifdef OCCT_DEBUG_CHRONO
276 t_total = t_init = t_approx = t_uparam = 0;
278 InitChron(chr_total);
282 // Initialisation of input parameters of AdvApprox
284 Standard_Integer Num1DSS=2, Num2DSS=0, Num3DSS=1, i;
286 Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
287 Standard_Real TolV,TolW;
289 ToleranceComputation(C2D,Surf,10,Tol,TolV,TolW);
290 OneDTol->SetValue(1,TolV);
291 OneDTol->SetValue(2,TolW);
293 OneDTol->SetValue(1,Tol);
294 OneDTol->SetValue(2,Tol);
296 Handle(TColStd_HArray1OfReal) TwoDTolNul;
297 Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
298 ThreeDTol->Init(Tol/2.);
300 #ifdef OCCT_DEBUG_CHRONO
303 Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D, Surf, Tol/20);
304 #ifdef OCCT_DEBUG_CHRONO
305 ResultChron(chr_init, t_init);
308 Standard_Real FirstS = fonct->FirstParameter();
309 Standard_Real LastS = fonct->LastParameter();
311 Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
312 TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
313 fonct->Intervals(CutPnts_C2,GeomAbs_C2);
314 Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
315 TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
316 fonct->Intervals(CutPnts_C3,GeomAbs_C3);
317 AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
319 #ifdef OCCT_DEBUG_CHRONO
320 InitChron(chr_approx);
323 Approx_CurvilinearParameter_EvalCurvOnSurf evCOnS (fonct, FirstS, LastS);
324 AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
325 OneDTol, TwoDTolNul, ThreeDTol,
326 FirstS, LastS, Order,
327 MaxDegree, MaxSegments,
330 #ifdef OCCT_DEBUG_CHRONO
331 ResultChron(chr_approx, t_approx);
334 myDone = aApprox.IsDone();
335 myHasResult = aApprox.HasResult();
338 Standard_Integer NbPoles = aApprox.NbPoles();
339 TColgp_Array1OfPnt Poles (1,NbPoles);
340 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
341 TColStd_Array1OfReal Poles1d(1,NbPoles);
342 aApprox.Poles(1,Poles);
343 aApprox.Poles1d(1,Poles1d);
344 for (i=1; i<=NbPoles; i++)
345 Poles2d(i).SetX(Poles1d(i));
346 aApprox.Poles1d(2,Poles1d);
347 for (i=1; i<=NbPoles; i++)
348 Poles2d(i).SetY(Poles1d(i));
349 Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
350 Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
351 Standard_Integer Degree = aApprox.Degree();
352 myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
353 myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
355 myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
356 myMaxError3d = aApprox.MaxError(3,1);
358 #ifdef OCCT_DEBUG_CHRONO
359 ResultChron(chr_total, t_total);
361 cout<<" total reparametrization time = "<<t_total<<endl;
362 cout<<"initialization time = "<<t_init<<endl;
363 cout<<"approximation time = "<<t_approx<<endl;
364 cout<<"total time for uparam computation = "<<t_uparam<<endl;
365 cout<<"number uparam calles = "<<uparam_count<<endl;
369 //=======================================================================
370 //function : Approx_CurvilinearParameter_EvalCurvOn2Surf
371 //purpose : case of a curve on two surfaces
372 //=======================================================================
374 class Approx_CurvilinearParameter_EvalCurvOn2Surf : public AdvApprox_EvaluatorFunction
377 Approx_CurvilinearParameter_EvalCurvOn2Surf (const Handle(Approx_CurvlinFunc)& theFunc,
378 Standard_Real First, Standard_Real Last)
379 : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
381 virtual void Evaluate (Standard_Integer *Dimension,
382 Standard_Real StartEnd[2],
383 Standard_Real *Parameter,
384 Standard_Integer *DerivativeRequest,
385 Standard_Real *Result, // [Dimension]
386 Standard_Integer *ErrorCode);
389 Handle(Approx_CurvlinFunc) fonct;
390 Standard_Real StartEndSav[2];
393 void Approx_CurvilinearParameter_EvalCurvOn2Surf::Evaluate (Standard_Integer * Dimension,
394 Standard_Real * StartEnd,
395 Standard_Real * Param,
396 Standard_Integer * Order,
397 Standard_Real * Result,
398 Standard_Integer * ErrorCode)
401 Standard_Real S = *Param;
402 TColStd_Array1OfReal Res(0, 6);
405 // Dimension is incorrect
406 if (*Dimension != 7) {
409 // Parameter is incorrect
410 if ( S < StartEnd[0] || S > StartEnd[1] ) {
414 /* if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
416 fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
417 StartEndSav[0]=StartEnd[0];
418 StartEndSav[1]=StartEnd[1];
421 if(!fonct->EvalCase3(S, *Order, Res)) {
425 for(i = 0; i <= 6; i++)
429 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D1,
430 const Handle(Adaptor3d_HSurface)& Surf1,
431 const Handle(Adaptor2d_HCurve2d)& C2D2,
432 const Handle(Adaptor3d_HSurface)& Surf2,
433 const Standard_Real Tol,
434 const GeomAbs_Shape Order,
435 const Standard_Integer MaxDegree,
436 const Standard_Integer MaxSegments)
440 #ifdef OCCT_DEBUG_CHRONO
441 t_total = t_init = t_approx = t_uparam = 0;
443 InitChron(chr_total);
447 // Initialisation of input parameters of AdvApprox
449 Standard_Integer Num1DSS=4, Num2DSS=0, Num3DSS=1;
450 Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
452 Standard_Real TolV,TolW;
453 ToleranceComputation(C2D1,Surf1,10,Tol,TolV,TolW);
454 OneDTol->SetValue(1,TolV);
455 OneDTol->SetValue(2,TolW);
457 ToleranceComputation(C2D2,Surf2,10,Tol,TolV,TolW);
458 OneDTol->SetValue(3,TolV);
459 OneDTol->SetValue(4,TolW);
461 Handle(TColStd_HArray1OfReal) TwoDTolNul;
462 Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
463 ThreeDTol->Init(Tol/2);
465 #ifdef OCCT_DEBUG_CHRONO
468 Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D1, C2D2, Surf1, Surf2, Tol/20);
469 #ifdef OCCT_DEBUG_CHRONO
470 ResultChron(chr_init, t_init);
473 Standard_Real FirstS = fonct->FirstParameter();
474 Standard_Real LastS = fonct->LastParameter();
476 Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
477 TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
478 fonct->Intervals(CutPnts_C2,GeomAbs_C2);
479 Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
480 TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
481 fonct->Intervals(CutPnts_C3,GeomAbs_C3);
482 AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
484 #ifdef OCCT_DEBUG_CHRONO
485 InitChron(chr_approx);
488 Approx_CurvilinearParameter_EvalCurvOn2Surf evCOn2S (fonct, FirstS, LastS);
489 AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
490 OneDTol, TwoDTolNul, ThreeDTol,
491 FirstS, LastS, Order,
492 MaxDegree, MaxSegments,
495 #ifdef OCCT_DEBUG_CHRONO
496 ResultChron(chr_approx, t_approx);
499 myDone = aApprox.IsDone();
500 myHasResult = aApprox.HasResult();
503 Standard_Integer NbPoles = aApprox.NbPoles();
504 TColgp_Array1OfPnt Poles (1,NbPoles);
505 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
506 TColStd_Array1OfReal Poles1d(1,NbPoles);
507 aApprox.Poles(1,Poles);
508 aApprox.Poles1d(1,Poles1d);
509 for (i=1; i<=NbPoles; i++)
510 Poles2d(i).SetX(Poles1d(i));
511 aApprox.Poles1d(2,Poles1d);
512 for (i=1; i<=NbPoles; i++)
513 Poles2d(i).SetY(Poles1d(i));
514 Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
515 Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
516 Standard_Integer Degree = aApprox.Degree();
517 myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
518 myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
519 aApprox.Poles1d(3,Poles1d);
520 for (i=1; i<=NbPoles; i++)
521 Poles2d(i).SetX(Poles1d(i));
522 aApprox.Poles1d(4,Poles1d);
523 for (i=1; i<=NbPoles; i++)
524 Poles2d(i).SetY(Poles1d(i));
525 myCurve2d2 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
527 myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
528 myMaxError2d2 = Max (aApprox.MaxError(1,3),aApprox.MaxError(1,4));
529 myMaxError3d = aApprox.MaxError(3,1);
531 #ifdef OCCT_DEBUG_CHRONO
532 ResultChron(chr_total, t_total);
534 cout<<" total reparametrization time = "<<t_total<<endl;
535 cout<<"initialization time = "<<t_init<<endl;
536 cout<<"approximation time = "<<t_approx<<endl;
537 cout<<"total time for uparam computation = "<<t_uparam<<endl;
538 cout<<"number uparam calles = "<<uparam_count<<endl;
542 //=======================================================================
545 //=======================================================================
547 Standard_Boolean Approx_CurvilinearParameter::IsDone() const
552 //=======================================================================
553 //function : HasResult
555 //=======================================================================
557 Standard_Boolean Approx_CurvilinearParameter::HasResult() const
562 //=======================================================================
564 //purpose : returns the Bspline curve corresponding to the reparametrized 3D curve
565 //=======================================================================
567 Handle(Geom_BSplineCurve) Approx_CurvilinearParameter::Curve3d() const
572 //=======================================================================
573 //function : MaxError3d
574 //purpose : returns the maximum error on the reparametrized 3D curve
575 //=======================================================================
577 Standard_Real Approx_CurvilinearParameter::MaxError3d() const
582 //=======================================================================
583 //function : Curve2d1
584 //purpose : returns the BsplineCurve representing the reparametrized 2D curve on the
585 // first surface (case of a curve on one or two surfaces)
586 //=======================================================================
588 Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d1() const
593 //=======================================================================
594 //function : MaxError2d1
595 //purpose : returns the maximum error on the first reparametrized 2D curve
596 //=======================================================================
598 Standard_Real Approx_CurvilinearParameter::MaxError2d1() const
600 return myMaxError2d1;
603 //=======================================================================
604 //function : Curve2d2
605 //purpose : returns the BsplineCurve representing the reparametrized 2D curve on the
606 // second surface (case of a curve on two surfaces)
607 //=======================================================================
609 Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d2() const
614 //=======================================================================
615 //function : MaxError2d2
616 //purpose : returns the maximum error on the second reparametrized 2D curve
617 //=======================================================================
619 Standard_Real Approx_CurvilinearParameter::MaxError2d2() const
621 return myMaxError2d2;
624 //=======================================================================
626 //purpose : print the maximum errors(s)
627 //=======================================================================
629 void Approx_CurvilinearParameter::Dump(Standard_OStream& o) const
631 o << "Dump of Approx_CurvilinearParameter" << endl;
632 if (myCase==2 || myCase==3)
633 o << "myMaxError2d1 = " << myMaxError2d1 << endl;
635 o << "myMaxError2d2 = " << myMaxError2d2 << endl;
636 o << "myMaxError3d = " << myMaxError3d << endl;
639 //=======================================================================
640 //function : ToleranceComputation
642 //=======================================================================
644 void Approx_CurvilinearParameter::ToleranceComputation(const Handle(Adaptor2d_HCurve2d) &C2D,
645 const Handle(Adaptor3d_HSurface) &S,
646 const Standard_Integer MaxNumber,
647 const Standard_Real Tol,
648 Standard_Real &TolV, Standard_Real &TolW)
650 Standard_Real FirstU = C2D->FirstParameter(),
651 LastU = C2D->LastParameter();
652 // Standard_Real parU, Max_dS_dv=1.,Max_dS_dw=1.;
653 Standard_Real Max_dS_dv=1.,Max_dS_dw=1.;
658 for (Standard_Integer i=1; i<=MaxNumber; i++) {
659 pntVW = C2D->Value(FirstU + (i-1)*(LastU-FirstU)/(MaxNumber-1));
660 S->D1(pntVW.X(),pntVW.Y(),P,dS_dv,dS_dw);
661 Max_dS_dv = Max (Max_dS_dv, dS_dv.Magnitude());
662 Max_dS_dw = Max (Max_dS_dw, dS_dw.Magnitude());
664 TolV = Tol / (4.*Max_dS_dv);
665 TolW = Tol / (4.*Max_dS_dw);
668 cout << "TolV = " << TolV << endl;
669 cout << "TolW = " << TolW << endl;