0025418: Debug output to be limited to OCC development environment
[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 #include <Approx_CurvilinearParameter.ixx>
18
19 #include <Adaptor3d_Curve.hxx>
20 #include <GCPnts_AbscissaPoint.hxx>
21 #include <gp_Pnt.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec.hxx>
24 #include <gp_Vec2d.hxx>
25 #include <GeomAbs_Shape.hxx>
26 #include <AdvApprox_ApproxAFunction.hxx>
27 #include <Geom_BSplineCurve.hxx>
28 #include <TColStd_HArray1OfReal.hxx>
29 #include <TColStd_HArray1OfInteger.hxx>
30 #include <TColgp_Array1OfPnt.hxx>
31 #include <GeomAdaptor_HCurve.hxx>
32 #include <GeomAdaptor_HSurface.hxx>
33 #include <TColStd_Array1OfReal.hxx>
34 #include <AdvApprox_PrefAndRec.hxx>
35 #include <Adaptor3d_CurveOnSurface.hxx>
36 #include <Precision.hxx>
37 #include <Geom2d_BSplineCurve.hxx>
38 #include <TColgp_Array1OfPnt2d.hxx>
39 #include <math_Vector.hxx>
40 #include <CPnts_AbscissaPoint.hxx>
41 #include <Approx_CurvlinFunc.hxx>
42
43 #ifdef OCCT_DEBUG_CHRONO
44 #include <OSD_Timer.hxx>
45 static OSD_Chronometer chr_total, chr_init, chr_approx;
46
47 Standard_Real t_total, t_init, t_approx;
48 void InitChron(OSD_Chronometer& ch)
49
50     ch.Reset();
51     ch.Start();
52 }
53
54 void ResultChron( OSD_Chronometer & ch, Standard_Real & time) 
55 {
56     Standard_Real tch ;
57     ch.Stop();
58     ch.Show(tch);
59     time=time +tch;
60 }
61
62 Standard_IMPORT Standard_Integer uparam_count;
63 Standard_IMPORT Standard_Real t_uparam;
64 #endif
65
66 //=======================================================================
67 //class : Approx_CurvilinearParameter_EvalCurv
68 //purpose  : case of a free 3D curve
69 //=======================================================================
70
71 class Approx_CurvilinearParameter_EvalCurv : public AdvApprox_EvaluatorFunction
72 {
73  public:
74   Approx_CurvilinearParameter_EvalCurv (const Handle(Approx_CurvlinFunc)& theFunc, 
75                                         Standard_Real First, Standard_Real Last)
76     : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
77   
78   virtual void Evaluate (Standard_Integer *Dimension,
79                          Standard_Real     StartEnd[2],
80                          Standard_Real    *Parameter,
81                          Standard_Integer *DerivativeRequest,
82                          Standard_Real    *Result, // [Dimension]
83                          Standard_Integer *ErrorCode);
84   
85  private:
86   Handle(Approx_CurvlinFunc) fonct;
87   Standard_Real StartEndSav[2];
88 };
89
90 void Approx_CurvilinearParameter_EvalCurv::Evaluate (Standard_Integer * Dimension,
91                                                      Standard_Real    * StartEnd,
92                                                      Standard_Real    * Param,
93                                                      Standard_Integer * Order,
94                                                      Standard_Real    * Result,
95                                                      Standard_Integer * ErrorCode)
96 {
97   *ErrorCode = 0;
98   Standard_Real S = *Param;
99   TColStd_Array1OfReal Res(0, 2);
100   Standard_Integer i;
101   
102 // Dimension is incorrect
103   if (*Dimension != 3) {
104     *ErrorCode = 1;
105   }
106 // Parameter is incorrect
107   if ( S < StartEnd[0] || S > StartEnd[1] ) {
108     *ErrorCode = 2;
109   }
110
111   if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
112     {
113       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
114       StartEndSav[0]=StartEnd[0];
115       StartEndSav[1]=StartEnd[1];
116     }
117
118   if(!fonct->EvalCase1(S, *Order, Res)) {
119     *ErrorCode = 3;
120   }
121
122   for(i = 0; i <= 2; i++)
123     Result[i] = Res(i);  
124 }
125
126 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor3d_HCurve)& C3D,
127                                                          const Standard_Real Tol,
128                                                          const GeomAbs_Shape Order,
129                                                          const Standard_Integer MaxDegree,
130                                                          const Standard_Integer MaxSegments)
131 {
132 #ifdef OCCT_DEBUG_CHRONO
133   t_total = t_init = t_approx = t_uparam = 0;
134   uparam_count = 0;
135   InitChron(chr_total);
136 #endif
137   myCase = 1;
138 // Initialisation of input parameters of AdvApprox
139
140   Standard_Integer Num1DSS=0, Num2DSS=0, Num3DSS=1;
141   Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul; 
142   Handle(TColStd_HArray1OfReal) ThreeDTol  = new TColStd_HArray1OfReal(1,Num3DSS);
143   ThreeDTol->Init(Tol); 
144
145 #ifdef OCCT_DEBUG_CHRONO
146   InitChron(chr_init);
147 #endif
148   Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C3D, Tol/10);
149 #ifdef OCCT_DEBUG_CHRONO
150   ResultChron(chr_init, t_init);
151 #endif
152
153   Standard_Real FirstS = fonct->FirstParameter();
154   Standard_Real  LastS = fonct->LastParameter();
155
156   Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
157   TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
158   fonct->Intervals(CutPnts_C2,GeomAbs_C2);
159   Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
160   TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
161   fonct->Intervals(CutPnts_C3,GeomAbs_C3);
162   AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
163
164 #ifdef OCCT_DEBUG_CHRONO
165   InitChron(chr_approx);
166 #endif
167
168   Approx_CurvilinearParameter_EvalCurv evC (fonct, FirstS, LastS);
169   AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, 
170                                      OneDTolNul, TwoDTolNul, ThreeDTol,
171                                      FirstS, LastS, Order,
172                                      MaxDegree, MaxSegments,
173                                      evC, CutTool);
174
175 #ifdef OCCT_DEBUG_CHRONO
176   ResultChron(chr_approx, t_approx);
177 #endif
178
179   myDone      = aApprox.IsDone();
180   myHasResult = aApprox.HasResult();
181
182   if (myHasResult) {
183     TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
184     aApprox.Poles(1,Poles);
185     Handle(TColStd_HArray1OfReal)    Knots = aApprox.Knots();
186     Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
187     Standard_Integer Degree = aApprox.Degree();
188     myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
189   }
190   myMaxError3d = aApprox.MaxError(3,1);
191
192 #ifdef OCCT_DEBUG_CHRONO
193   ResultChron(chr_total, t_total);
194
195   cout<<" total reparametrization time = "<<t_total<<endl;
196   cout<<"initialization time = "<<t_init<<endl;
197   cout<<"approximation time = "<<t_approx<<endl;
198   cout<<"total time for uparam computation = "<<t_uparam<<endl;
199   cout<<"number uparam calles = "<<uparam_count<<endl;
200 #endif
201 }
202
203 //=======================================================================
204 //class : Approx_CurvilinearParameter_EvalCurvOnSurf
205 //purpose  : case of a curve on one surface
206 //=======================================================================
207
208 class Approx_CurvilinearParameter_EvalCurvOnSurf : public AdvApprox_EvaluatorFunction
209 {
210  public:
211   Approx_CurvilinearParameter_EvalCurvOnSurf (const Handle(Approx_CurvlinFunc)& theFunc, 
212                                               Standard_Real First, Standard_Real Last)
213     : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
214   
215   virtual void Evaluate (Standard_Integer *Dimension,
216                          Standard_Real     StartEnd[2],
217                          Standard_Real    *Parameter,
218                          Standard_Integer *DerivativeRequest,
219                          Standard_Real    *Result, // [Dimension]
220                          Standard_Integer *ErrorCode);
221   
222  private:
223   Handle(Approx_CurvlinFunc) fonct;
224   Standard_Real StartEndSav[2];
225 };
226
227 void Approx_CurvilinearParameter_EvalCurvOnSurf::Evaluate (Standard_Integer * Dimension,
228                                                            Standard_Real    * StartEnd,
229                                                            Standard_Real    * Param,
230                                                            Standard_Integer * Order,
231                                                            Standard_Real    * Result,
232                                                            Standard_Integer * ErrorCode)
233 {
234   *ErrorCode = 0;
235   Standard_Real S = *Param;
236   TColStd_Array1OfReal Res(0, 4);
237   Standard_Integer i;
238
239 // Dimension is incorrect
240   if (*Dimension != 5) {
241     *ErrorCode = 1;
242   }
243 // Parameter is incorrect
244   if ( S < StartEnd[0] || S > StartEnd[1] ) {
245     *ErrorCode = 2;
246   }
247
248   if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
249     {
250       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
251       StartEndSav[0]=StartEnd[0];
252       StartEndSav[1]=StartEnd[1];
253     }
254
255   if(!fonct->EvalCase2(S, *Order, Res)) {
256     *ErrorCode = 3;
257   }
258
259   for(i = 0; i <= 4; i++)
260     Result[i] = Res(i);  
261 }
262
263 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D,
264                                                          const Handle(Adaptor3d_HSurface)& Surf,
265                                                          const Standard_Real Tol,
266                                                          const GeomAbs_Shape Order,
267                                                          const Standard_Integer MaxDegree,
268                                                          const Standard_Integer MaxSegments)
269 {
270 #ifdef OCCT_DEBUG_CHRONO
271   t_total = t_init = t_approx = t_uparam = 0;
272   uparam_count = 0;
273   InitChron(chr_total);
274 #endif
275   myCase = 2;
276
277   // Initialisation of input parameters of AdvApprox
278
279   Standard_Integer Num1DSS=2, Num2DSS=0, Num3DSS=1, i;
280
281   Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
282   Standard_Real TolV,TolW;
283
284   ToleranceComputation(C2D,Surf,10,Tol,TolV,TolW);
285   OneDTol->SetValue(1,TolV);
286   OneDTol->SetValue(2,TolW);
287
288   OneDTol->SetValue(1,Tol);
289   OneDTol->SetValue(2,Tol);
290
291   Handle(TColStd_HArray1OfReal) TwoDTolNul; 
292   Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
293   ThreeDTol->Init(Tol/2.); 
294
295 #ifdef OCCT_DEBUG_CHRONO
296   InitChron(chr_init);
297 #endif
298   Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D, Surf, Tol/20);
299 #ifdef OCCT_DEBUG_CHRONO
300   ResultChron(chr_init, t_init);
301 #endif
302
303   Standard_Real FirstS = fonct->FirstParameter();
304   Standard_Real  LastS = fonct->LastParameter();
305
306   Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
307   TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
308   fonct->Intervals(CutPnts_C2,GeomAbs_C2);
309   Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
310   TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
311   fonct->Intervals(CutPnts_C3,GeomAbs_C3);
312   AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
313
314 #ifdef OCCT_DEBUG_CHRONO
315   InitChron(chr_approx);
316 #endif
317
318   Approx_CurvilinearParameter_EvalCurvOnSurf evCOnS (fonct, FirstS, LastS);
319   AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, 
320                                      OneDTol, TwoDTolNul, ThreeDTol,
321                                      FirstS, LastS, Order,
322                                      MaxDegree, MaxSegments,
323                                      evCOnS, CutTool);
324
325 #ifdef OCCT_DEBUG_CHRONO
326   ResultChron(chr_approx, t_approx);
327 #endif
328
329   myDone      = aApprox.IsDone();
330   myHasResult = aApprox.HasResult();
331
332   if (myHasResult) {
333     Standard_Integer NbPoles = aApprox.NbPoles();
334     TColgp_Array1OfPnt   Poles  (1,NbPoles);
335     TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
336     TColStd_Array1OfReal Poles1d(1,NbPoles);
337     aApprox.Poles(1,Poles);
338     aApprox.Poles1d(1,Poles1d);
339     for (i=1; i<=NbPoles; i++) 
340       Poles2d(i).SetX(Poles1d(i));
341     aApprox.Poles1d(2,Poles1d);
342     for (i=1; i<=NbPoles; i++) 
343       Poles2d(i).SetY(Poles1d(i));
344     Handle(TColStd_HArray1OfReal)    Knots = aApprox.Knots();
345     Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
346     Standard_Integer Degree = aApprox.Degree();
347     myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
348     myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
349   }
350   myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
351   myMaxError3d  = aApprox.MaxError(3,1);
352
353 #ifdef OCCT_DEBUG_CHRONO
354   ResultChron(chr_total, t_total);
355
356   cout<<" total reparametrization time = "<<t_total<<endl;
357   cout<<"initialization time = "<<t_init<<endl;
358   cout<<"approximation time = "<<t_approx<<endl;
359   cout<<"total time for uparam computation = "<<t_uparam<<endl;
360   cout<<"number uparam calles = "<<uparam_count<<endl;
361 #endif
362 }
363
364 //=======================================================================
365 //function : Approx_CurvilinearParameter_EvalCurvOn2Surf
366 //purpose  : case of a curve on two surfaces
367 //=======================================================================
368
369 class Approx_CurvilinearParameter_EvalCurvOn2Surf : public AdvApprox_EvaluatorFunction
370 {
371  public:
372   Approx_CurvilinearParameter_EvalCurvOn2Surf (const Handle(Approx_CurvlinFunc)& theFunc, 
373                                                Standard_Real First, Standard_Real Last)
374     : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
375   
376   virtual void Evaluate (Standard_Integer *Dimension,
377                          Standard_Real     StartEnd[2],
378                          Standard_Real    *Parameter,
379                          Standard_Integer *DerivativeRequest,
380                          Standard_Real    *Result, // [Dimension]
381                          Standard_Integer *ErrorCode);
382   
383  private:
384   Handle(Approx_CurvlinFunc) fonct;
385   Standard_Real StartEndSav[2];
386 };
387
388 void Approx_CurvilinearParameter_EvalCurvOn2Surf::Evaluate (Standard_Integer * Dimension,
389                                                             Standard_Real    * StartEnd,
390                                                             Standard_Real    * Param,
391                                                             Standard_Integer * Order,
392                                                             Standard_Real    * Result,
393                                                             Standard_Integer * ErrorCode)
394 {
395   *ErrorCode = 0;
396   Standard_Real S = *Param;
397   TColStd_Array1OfReal Res(0, 6);
398   Standard_Integer i;
399
400 // Dimension is incorrect
401   if (*Dimension != 7) {
402     *ErrorCode = 1;
403   }
404 // Parameter is incorrect
405   if ( S < StartEnd[0] || S > StartEnd[1] ) {
406     *ErrorCode = 2;
407   }
408
409 /*  if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) 
410     {
411       fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
412       StartEndSav[0]=StartEnd[0];
413       StartEndSav[1]=StartEnd[1];
414     }
415 */
416   if(!fonct->EvalCase3(S, *Order, Res)) {
417     *ErrorCode = 3;
418   }
419
420   for(i = 0; i <= 6; i++)
421     Result[i] = Res(i);  
422 }
423
424 Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D1,
425                                                          const Handle(Adaptor3d_HSurface)& Surf1,
426                                                          const Handle(Adaptor2d_HCurve2d)& C2D2,
427                                                          const Handle(Adaptor3d_HSurface)& Surf2,
428                                                          const Standard_Real Tol,
429                                                          const GeomAbs_Shape Order,
430                                                          const Standard_Integer MaxDegree,
431                                                          const Standard_Integer MaxSegments)
432 {
433   Standard_Integer i;
434
435 #ifdef OCCT_DEBUG_CHRONO
436   t_total = t_init = t_approx = t_uparam = 0;
437   uparam_count = 0;
438   InitChron(chr_total);
439 #endif
440   myCase = 3;
441
442   // Initialisation of input parameters of AdvApprox
443
444   Standard_Integer Num1DSS=4, Num2DSS=0, Num3DSS=1;
445   Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS); 
446
447   Standard_Real TolV,TolW;
448   ToleranceComputation(C2D1,Surf1,10,Tol,TolV,TolW);
449   OneDTol->SetValue(1,TolV); 
450   OneDTol->SetValue(2,TolW); 
451   
452   ToleranceComputation(C2D2,Surf2,10,Tol,TolV,TolW);
453   OneDTol->SetValue(3,TolV); 
454   OneDTol->SetValue(4,TolW); 
455
456   Handle(TColStd_HArray1OfReal) TwoDTolNul; 
457   Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
458   ThreeDTol->Init(Tol/2); 
459
460 #ifdef OCCT_DEBUG_CHRONO
461   InitChron(chr_init);
462 #endif
463   Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D1, C2D2, Surf1, Surf2, Tol/20);
464 #ifdef OCCT_DEBUG_CHRONO
465   ResultChron(chr_init, t_init);
466 #endif
467
468   Standard_Real FirstS = fonct->FirstParameter();
469   Standard_Real  LastS = fonct->LastParameter();
470
471   Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
472   TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
473   fonct->Intervals(CutPnts_C2,GeomAbs_C2);
474   Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
475   TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
476   fonct->Intervals(CutPnts_C3,GeomAbs_C3);
477   AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);  
478
479 #ifdef OCCT_DEBUG_CHRONO
480   InitChron(chr_approx);
481 #endif
482
483   Approx_CurvilinearParameter_EvalCurvOn2Surf evCOn2S (fonct, FirstS, LastS);
484   AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, 
485                                      OneDTol, TwoDTolNul, ThreeDTol,
486                                      FirstS, LastS, Order,
487                                      MaxDegree, MaxSegments,
488                                      evCOn2S, CutTool);
489
490 #ifdef OCCT_DEBUG_CHRONO
491   ResultChron(chr_approx, t_approx);
492 #endif
493
494   myDone      = aApprox.IsDone();
495   myHasResult = aApprox.HasResult();
496
497   if (myHasResult) {
498     Standard_Integer NbPoles = aApprox.NbPoles();
499     TColgp_Array1OfPnt   Poles  (1,NbPoles);
500     TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
501     TColStd_Array1OfReal Poles1d(1,NbPoles);
502     aApprox.Poles(1,Poles);
503     aApprox.Poles1d(1,Poles1d);
504     for (i=1; i<=NbPoles; i++) 
505       Poles2d(i).SetX(Poles1d(i));
506     aApprox.Poles1d(2,Poles1d);
507     for (i=1; i<=NbPoles; i++) 
508       Poles2d(i).SetY(Poles1d(i));
509     Handle(TColStd_HArray1OfReal)    Knots = aApprox.Knots();
510     Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
511     Standard_Integer Degree = aApprox.Degree();
512     myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
513     myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
514     aApprox.Poles1d(3,Poles1d);
515     for (i=1; i<=NbPoles; i++) 
516       Poles2d(i).SetX(Poles1d(i));
517     aApprox.Poles1d(4,Poles1d);
518     for (i=1; i<=NbPoles; i++) 
519       Poles2d(i).SetY(Poles1d(i));
520     myCurve2d2 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
521   }
522   myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
523   myMaxError2d2 = Max (aApprox.MaxError(1,3),aApprox.MaxError(1,4));
524   myMaxError3d  = aApprox.MaxError(3,1);
525
526 #ifdef OCCT_DEBUG_CHRONO
527   ResultChron(chr_total, t_total);
528
529   cout<<" total reparametrization time = "<<t_total<<endl;
530   cout<<"initialization time = "<<t_init<<endl;
531   cout<<"approximation time = "<<t_approx<<endl;
532   cout<<"total time for uparam computation = "<<t_uparam<<endl;
533   cout<<"number uparam calles = "<<uparam_count<<endl;
534 #endif
535 }
536
537 //=======================================================================
538 //function : IsDone
539 //purpose  : 
540 //=======================================================================
541
542  Standard_Boolean Approx_CurvilinearParameter::IsDone() const
543 {
544   return myDone;
545 }
546
547 //=======================================================================
548 //function : HasResult
549 //purpose  : 
550 //=======================================================================
551
552  Standard_Boolean Approx_CurvilinearParameter::HasResult() const
553 {
554   return myHasResult;
555 }
556
557 //=======================================================================
558 //function : Curve3d
559 //purpose  : returns the Bspline curve corresponding to the reparametrized 3D curve 
560 //=======================================================================
561
562  Handle(Geom_BSplineCurve) Approx_CurvilinearParameter::Curve3d() const
563 {
564   return myCurve3d;
565 }
566
567 //=======================================================================
568 //function : MaxError3d
569 //purpose  : returns the maximum error on the reparametrized 3D curve
570 //=======================================================================
571
572  Standard_Real Approx_CurvilinearParameter::MaxError3d() const
573 {
574   return myMaxError3d;
575 }
576
577 //=======================================================================
578 //function : Curve2d1
579 //purpose  : returns the BsplineCurve representing the reparametrized 2D curve on the
580 //           first surface (case of a curve on one or two surfaces)
581 //=======================================================================
582
583  Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d1() const
584 {
585   return myCurve2d1;
586 }
587
588 //=======================================================================
589 //function : MaxError2d1
590 //purpose  : returns the maximum error on the first reparametrized 2D curve
591 //=======================================================================
592
593  Standard_Real Approx_CurvilinearParameter::MaxError2d1() const
594 {
595   return myMaxError2d1;
596 }
597
598 //=======================================================================
599 //function : Curve2d2
600 //purpose  : returns the BsplineCurve representing the reparametrized 2D curve on the
601 //           second surface (case of a curve on two surfaces)
602 //=======================================================================
603
604  Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d2() const
605 {
606   return myCurve2d2;
607 }
608
609 //=======================================================================
610 //function : MaxError2d2
611 //purpose  : returns the maximum error on the second reparametrized 2D curve 
612 //=======================================================================
613
614  Standard_Real Approx_CurvilinearParameter::MaxError2d2() const
615 {
616   return myMaxError2d2;
617 }
618
619 //=======================================================================
620 //function : Dump
621 //purpose  : print the maximum errors(s)
622 //=======================================================================
623
624 void Approx_CurvilinearParameter::Dump(Standard_OStream& o) const
625 {
626   o << "Dump of Approx_CurvilinearParameter" << endl;
627   if (myCase==2 || myCase==3) 
628     o << "myMaxError2d1 = " << myMaxError2d1 << endl;
629   if (myCase==3) 
630     o << "myMaxError2d2 = " << myMaxError2d2 << endl;
631   o << "myMaxError3d = " << myMaxError3d << endl;
632 }
633
634 //=======================================================================
635 //function : ToleranceComputation
636 //purpose  : 
637 //=======================================================================
638
639 void Approx_CurvilinearParameter::ToleranceComputation(const Handle(Adaptor2d_HCurve2d) &C2D,
640                                                        const Handle(Adaptor3d_HSurface) &S, 
641                                                        const Standard_Integer MaxNumber, 
642                                                        const Standard_Real Tol,
643                                                        Standard_Real &TolV, Standard_Real &TolW)
644 {
645   Standard_Real FirstU = C2D->FirstParameter(),
646                 LastU  = C2D->LastParameter();
647 //  Standard_Real parU, Max_dS_dv=1.,Max_dS_dw=1.;
648   Standard_Real Max_dS_dv=1.,Max_dS_dw=1.;
649   gp_Pnt P;
650   gp_Pnt2d pntVW;
651   gp_Vec dS_dv,dS_dw;
652
653   for (Standard_Integer i=1; i<=MaxNumber; i++) {
654     pntVW = C2D->Value(FirstU + (i-1)*(LastU-FirstU)/(MaxNumber-1));
655     S->D1(pntVW.X(),pntVW.Y(),P,dS_dv,dS_dw);
656     Max_dS_dv = Max (Max_dS_dv, dS_dv.Magnitude());
657     Max_dS_dw = Max (Max_dS_dw, dS_dw.Magnitude());
658   }
659   TolV = Tol / (4.*Max_dS_dv);
660   TolW = Tol / (4.*Max_dS_dw);
661
662 #ifdef OCCT_DEBUG
663   cout << "TolV = " << TolV << endl;
664   cout << "TolW = " << TolW << endl;
665 #endif
666 }