0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / Approx / Approx_CurvilinearParameter.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
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>
34 #include <gp_Pnt.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <gp_Vec.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>
47
48 #ifdef OCCT_DEBUG_CHRONO
49 #include <OSD_Timer.hxx>
50 static OSD_Chronometer chr_total, chr_init, chr_approx;
51
52 Standard_Real t_total, t_init, t_approx;
53 void InitChron(OSD_Chronometer& ch)
54
55     ch.Reset();
56     ch.Start();
57 }
58
59 void ResultChron( OSD_Chronometer & ch, Standard_Real & time) 
60 {
61     Standard_Real tch ;
62     ch.Stop();
63     ch.Show(tch);
64     time=time +tch;
65 }
66
67 Standard_IMPORT Standard_Integer uparam_count;
68 Standard_IMPORT Standard_Real t_uparam;
69 #endif
70
71 //=======================================================================
72 //class : Approx_CurvilinearParameter_EvalCurv
73 //purpose  : case of a free 3D curve
74 //=======================================================================
75
76 class Approx_CurvilinearParameter_EvalCurv : public AdvApprox_EvaluatorFunction
77 {
78  public:
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; }
82   
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);
89   
90  private:
91   Handle(Approx_CurvlinFunc) fonct;
92   Standard_Real StartEndSav[2];
93 };
94
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)
101 {
102   *ErrorCode = 0;
103   Standard_Real S = *Param;
104   TColStd_Array1OfReal Res(0, 2);
105   Standard_Integer i;
106   
107 // Dimension is incorrect
108   if (*Dimension != 3) {
109     *ErrorCode = 1;
110   }
111 // Parameter is incorrect
112   if ( S < StartEnd[0] || S > StartEnd[1] ) {
113     *ErrorCode = 2;
114   }
115
116   if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
117     {
118       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
119       StartEndSav[0]=StartEnd[0];
120       StartEndSav[1]=StartEnd[1];
121     }
122
123   if(!fonct->EvalCase1(S, *Order, Res)) {
124     *ErrorCode = 3;
125   }
126
127   for(i = 0; i <= 2; i++)
128     Result[i] = Res(i);  
129 }
130
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)
136 {
137 #ifdef OCCT_DEBUG_CHRONO
138   t_total = t_init = t_approx = t_uparam = 0;
139   uparam_count = 0;
140   InitChron(chr_total);
141 #endif
142   myCase = 1;
143 // Initialisation of input parameters of AdvApprox
144
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); 
149
150 #ifdef OCCT_DEBUG_CHRONO
151   InitChron(chr_init);
152 #endif
153   Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C3D, Tol/10);
154 #ifdef OCCT_DEBUG_CHRONO
155   ResultChron(chr_init, t_init);
156 #endif
157
158   Standard_Real FirstS = fonct->FirstParameter();
159   Standard_Real  LastS = fonct->LastParameter();
160
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);
168
169 #ifdef OCCT_DEBUG_CHRONO
170   InitChron(chr_approx);
171 #endif
172
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,
178                                      evC, CutTool);
179
180 #ifdef OCCT_DEBUG_CHRONO
181   ResultChron(chr_approx, t_approx);
182 #endif
183
184   myDone      = aApprox.IsDone();
185   myHasResult = aApprox.HasResult();
186
187   if (myHasResult) {
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);
194   }
195   myMaxError3d = aApprox.MaxError(3,1);
196
197 #ifdef OCCT_DEBUG_CHRONO
198   ResultChron(chr_total, t_total);
199
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;
205 #endif
206 }
207
208 //=======================================================================
209 //class : Approx_CurvilinearParameter_EvalCurvOnSurf
210 //purpose  : case of a curve on one surface
211 //=======================================================================
212
213 class Approx_CurvilinearParameter_EvalCurvOnSurf : public AdvApprox_EvaluatorFunction
214 {
215  public:
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; }
219   
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);
226   
227  private:
228   Handle(Approx_CurvlinFunc) fonct;
229   Standard_Real StartEndSav[2];
230 };
231
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)
238 {
239   *ErrorCode = 0;
240   Standard_Real S = *Param;
241   TColStd_Array1OfReal Res(0, 4);
242   Standard_Integer i;
243
244 // Dimension is incorrect
245   if (*Dimension != 5) {
246     *ErrorCode = 1;
247   }
248 // Parameter is incorrect
249   if ( S < StartEnd[0] || S > StartEnd[1] ) {
250     *ErrorCode = 2;
251   }
252
253   if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
254     {
255       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
256       StartEndSav[0]=StartEnd[0];
257       StartEndSav[1]=StartEnd[1];
258     }
259
260   if(!fonct->EvalCase2(S, *Order, Res)) {
261     *ErrorCode = 3;
262   }
263
264   for(i = 0; i <= 4; i++)
265     Result[i] = Res(i);  
266 }
267
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)
274 {
275 #ifdef OCCT_DEBUG_CHRONO
276   t_total = t_init = t_approx = t_uparam = 0;
277   uparam_count = 0;
278   InitChron(chr_total);
279 #endif
280   myCase = 2;
281
282   // Initialisation of input parameters of AdvApprox
283
284   Standard_Integer Num1DSS=2, Num2DSS=0, Num3DSS=1, i;
285
286   Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
287   Standard_Real TolV,TolW;
288
289   ToleranceComputation(C2D,Surf,10,Tol,TolV,TolW);
290   OneDTol->SetValue(1,TolV);
291   OneDTol->SetValue(2,TolW);
292
293   OneDTol->SetValue(1,Tol);
294   OneDTol->SetValue(2,Tol);
295
296   Handle(TColStd_HArray1OfReal) TwoDTolNul; 
297   Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
298   ThreeDTol->Init(Tol/2.); 
299
300 #ifdef OCCT_DEBUG_CHRONO
301   InitChron(chr_init);
302 #endif
303   Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D, Surf, Tol/20);
304 #ifdef OCCT_DEBUG_CHRONO
305   ResultChron(chr_init, t_init);
306 #endif
307
308   Standard_Real FirstS = fonct->FirstParameter();
309   Standard_Real  LastS = fonct->LastParameter();
310
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);
318
319 #ifdef OCCT_DEBUG_CHRONO
320   InitChron(chr_approx);
321 #endif
322
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,
328                                      evCOnS, CutTool);
329
330 #ifdef OCCT_DEBUG_CHRONO
331   ResultChron(chr_approx, t_approx);
332 #endif
333
334   myDone      = aApprox.IsDone();
335   myHasResult = aApprox.HasResult();
336
337   if (myHasResult) {
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);
354   }
355   myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
356   myMaxError3d  = aApprox.MaxError(3,1);
357
358 #ifdef OCCT_DEBUG_CHRONO
359   ResultChron(chr_total, t_total);
360
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;
366 #endif
367 }
368
369 //=======================================================================
370 //function : Approx_CurvilinearParameter_EvalCurvOn2Surf
371 //purpose  : case of a curve on two surfaces
372 //=======================================================================
373
374 class Approx_CurvilinearParameter_EvalCurvOn2Surf : public AdvApprox_EvaluatorFunction
375 {
376  public:
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; }
380   
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);
387   
388  private:
389   Handle(Approx_CurvlinFunc) fonct;
390   Standard_Real StartEndSav[2];
391 };
392
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)
399 {
400   *ErrorCode = 0;
401   Standard_Real S = *Param;
402   TColStd_Array1OfReal Res(0, 6);
403   Standard_Integer i;
404
405 // Dimension is incorrect
406   if (*Dimension != 7) {
407     *ErrorCode = 1;
408   }
409 // Parameter is incorrect
410   if ( S < StartEnd[0] || S > StartEnd[1] ) {
411     *ErrorCode = 2;
412   }
413
414 /*  if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
415     {
416       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
417       StartEndSav[0]=StartEnd[0];
418       StartEndSav[1]=StartEnd[1];
419     }
420 */
421   if(!fonct->EvalCase3(S, *Order, Res)) {
422     *ErrorCode = 3;
423   }
424
425   for(i = 0; i <= 6; i++)
426     Result[i] = Res(i);  
427 }
428
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)
437 {
438   Standard_Integer i;
439
440 #ifdef OCCT_DEBUG_CHRONO
441   t_total = t_init = t_approx = t_uparam = 0;
442   uparam_count = 0;
443   InitChron(chr_total);
444 #endif
445   myCase = 3;
446
447   // Initialisation of input parameters of AdvApprox
448
449   Standard_Integer Num1DSS=4, Num2DSS=0, Num3DSS=1;
450   Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS); 
451
452   Standard_Real TolV,TolW;
453   ToleranceComputation(C2D1,Surf1,10,Tol,TolV,TolW);
454   OneDTol->SetValue(1,TolV); 
455   OneDTol->SetValue(2,TolW); 
456   
457   ToleranceComputation(C2D2,Surf2,10,Tol,TolV,TolW);
458   OneDTol->SetValue(3,TolV); 
459   OneDTol->SetValue(4,TolW); 
460
461   Handle(TColStd_HArray1OfReal) TwoDTolNul; 
462   Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
463   ThreeDTol->Init(Tol/2); 
464
465 #ifdef OCCT_DEBUG_CHRONO
466   InitChron(chr_init);
467 #endif
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);
471 #endif
472
473   Standard_Real FirstS = fonct->FirstParameter();
474   Standard_Real  LastS = fonct->LastParameter();
475
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);  
483
484 #ifdef OCCT_DEBUG_CHRONO
485   InitChron(chr_approx);
486 #endif
487
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,
493                                      evCOn2S, CutTool);
494
495 #ifdef OCCT_DEBUG_CHRONO
496   ResultChron(chr_approx, t_approx);
497 #endif
498
499   myDone      = aApprox.IsDone();
500   myHasResult = aApprox.HasResult();
501
502   if (myHasResult) {
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);
526   }
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);
530
531 #ifdef OCCT_DEBUG_CHRONO
532   ResultChron(chr_total, t_total);
533
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;
539 #endif
540 }
541
542 //=======================================================================
543 //function : IsDone
544 //purpose  : 
545 //=======================================================================
546
547  Standard_Boolean Approx_CurvilinearParameter::IsDone() const
548 {
549   return myDone;
550 }
551
552 //=======================================================================
553 //function : HasResult
554 //purpose  : 
555 //=======================================================================
556
557  Standard_Boolean Approx_CurvilinearParameter::HasResult() const
558 {
559   return myHasResult;
560 }
561
562 //=======================================================================
563 //function : Curve3d
564 //purpose  : returns the Bspline curve corresponding to the reparametrized 3D curve 
565 //=======================================================================
566
567  Handle(Geom_BSplineCurve) Approx_CurvilinearParameter::Curve3d() const
568 {
569   return myCurve3d;
570 }
571
572 //=======================================================================
573 //function : MaxError3d
574 //purpose  : returns the maximum error on the reparametrized 3D curve
575 //=======================================================================
576
577  Standard_Real Approx_CurvilinearParameter::MaxError3d() const
578 {
579   return myMaxError3d;
580 }
581
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 //=======================================================================
587
588  Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d1() const
589 {
590   return myCurve2d1;
591 }
592
593 //=======================================================================
594 //function : MaxError2d1
595 //purpose  : returns the maximum error on the first reparametrized 2D curve
596 //=======================================================================
597
598  Standard_Real Approx_CurvilinearParameter::MaxError2d1() const
599 {
600   return myMaxError2d1;
601 }
602
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 //=======================================================================
608
609  Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d2() const
610 {
611   return myCurve2d2;
612 }
613
614 //=======================================================================
615 //function : MaxError2d2
616 //purpose  : returns the maximum error on the second reparametrized 2D curve 
617 //=======================================================================
618
619  Standard_Real Approx_CurvilinearParameter::MaxError2d2() const
620 {
621   return myMaxError2d2;
622 }
623
624 //=======================================================================
625 //function : Dump
626 //purpose  : print the maximum errors(s)
627 //=======================================================================
628
629 void Approx_CurvilinearParameter::Dump(Standard_OStream& o) const
630 {
631   o << "Dump of Approx_CurvilinearParameter" << endl;
632   if (myCase==2 || myCase==3) 
633     o << "myMaxError2d1 = " << myMaxError2d1 << endl;
634   if (myCase==3) 
635     o << "myMaxError2d2 = " << myMaxError2d2 << endl;
636   o << "myMaxError3d = " << myMaxError3d << endl;
637 }
638
639 //=======================================================================
640 //function : ToleranceComputation
641 //purpose  : 
642 //=======================================================================
643
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)
649 {
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.;
654   gp_Pnt P;
655   gp_Pnt2d pntVW;
656   gp_Vec dS_dv,dS_dw;
657
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());
663   }
664   TolV = Tol / (4.*Max_dS_dv);
665   TolW = Tol / (4.*Max_dS_dw);
666
667 #ifdef OCCT_DEBUG
668   cout << "TolV = " << TolV << endl;
669   cout << "TolW = " << TolW << endl;
670 #endif
671 }