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