0032832: Coding - get rid of unused headers [FairCurve to GeomAPI]
[occt.git] / src / Geom2dAPI / Geom2dAPI_PointsToBSpline.cxx
1 // Created on: 1994-03-23
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-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 <AppDef_BSplineCompute.hxx>
19 #include <AppDef_MultiPointConstraint.hxx>
20 #include <AppDef_Variational.hxx>
21 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
22 #include <AppParCurves_MultiBSpCurve.hxx>
23 #include <BSplCLib.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <Geom2dAPI_PointsToBSpline.hxx>
26 #include <math_Vector.hxx>
27 #include <Standard_OutOfRange.hxx>
28 #include <StdFail_NotDone.hxx>
29 #include <TColgp_Array1OfPnt2d.hxx>
30 #include <TColStd_Array1OfInteger.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32
33 //=======================================================================
34 //function : Geom2dAPI_PointsToBSpline
35 //purpose  : 
36 //=======================================================================
37 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline()
38 {
39   myIsDone = Standard_False;
40 }
41
42
43 //=======================================================================
44 //function : Geom2dAPI_PointsToBSpline
45 //purpose  : 
46 //=======================================================================
47
48 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
49   (const TColgp_Array1OfPnt2d& Points,
50    const Standard_Integer      DegMin, 
51    const Standard_Integer      DegMax,
52    const GeomAbs_Shape         Continuity,
53    const Standard_Real         Tol2D)
54 {
55   Init(Points,DegMin,DegMax,Continuity,Tol2D);
56 }
57
58
59 //=======================================================================
60 //function : Geom2dAPI_PointsToBSpline
61 //purpose  : 
62 //=======================================================================
63
64 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
65   (const TColStd_Array1OfReal& YValues,
66    const Standard_Real         X0,
67    const Standard_Real         DX,
68    const Standard_Integer      DegMin, 
69    const Standard_Integer      DegMax,
70    const GeomAbs_Shape         Continuity,
71    const Standard_Real         Tol2D)
72 {
73   Init(YValues,X0,DX,DegMin,DegMax,Continuity,Tol2D);
74 }
75
76 //=======================================================================
77 //function : Geom2dAPI_PointsToBSpline
78 //purpose  : 
79 //=======================================================================
80
81 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
82   (const TColgp_Array1OfPnt2d& Points,
83    const Approx_ParametrizationType ParType,
84    const Standard_Integer    DegMin, 
85    const Standard_Integer    DegMax,
86    const GeomAbs_Shape       Continuity,
87    const Standard_Real       Tol2D)
88 {
89   myIsDone = Standard_False;
90   Init(Points,ParType,DegMin,DegMax,Continuity,Tol2D);
91 }
92
93 //=======================================================================
94 //function : Geom2dAPI_PointsToBSpline
95 //purpose  : 
96 //=======================================================================
97
98 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
99   (const TColgp_Array1OfPnt2d&   Points,
100    const TColStd_Array1OfReal& Params,
101    const Standard_Integer      DegMin, 
102    const Standard_Integer      DegMax,
103    const GeomAbs_Shape         Continuity,
104    const Standard_Real         Tol2D)
105 {
106   myIsDone = Standard_False;
107   Init(Points,Params,DegMin,DegMax,Continuity,Tol2D);
108 }
109
110
111 //=======================================================================
112 //function : Geom2dAPI_PointsToBSpline
113 //purpose  : 
114 //=======================================================================
115
116 Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline
117   (const TColgp_Array1OfPnt2d&   Points,
118    const Standard_Real         W1,
119    const Standard_Real         W2,
120    const Standard_Real         W3,
121    const Standard_Integer      DegMax,
122    const GeomAbs_Shape         Continuity,
123    const Standard_Real         Tol2D)
124 {
125   myIsDone = Standard_False;
126   Init(Points,W1,W2,W3,DegMax,Continuity,Tol2D);
127 }
128
129
130 //=======================================================================
131 //function : Init
132 //purpose  : 
133 //=======================================================================
134
135 void Geom2dAPI_PointsToBSpline::Init
136   (const TColgp_Array1OfPnt2d& Points,
137    const Approx_ParametrizationType ParType,
138    const Standard_Integer      DegMin,
139    const Standard_Integer      DegMax,
140    const GeomAbs_Shape         Continuity,
141    const Standard_Real         Tol2D)
142 {
143   Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
144
145
146   Standard_Integer nbit = 2;
147   Standard_Boolean UseSquares = Standard_False;
148   if(Tol2D <= 1.e-3) UseSquares = Standard_True;
149
150   AppDef_BSplineCompute TheComputer
151     (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
152
153   switch( Continuity) {
154   case GeomAbs_C0:
155     TheComputer.SetContinuity(0); break;
156
157   case GeomAbs_G1: 
158   case GeomAbs_C1: 
159     TheComputer.SetContinuity(1); break;
160
161   case GeomAbs_G2:
162   case GeomAbs_C2:
163     TheComputer.SetContinuity(2); break;
164
165   default: 
166     TheComputer.SetContinuity(3);
167   }
168   
169   TheComputer.Perform(Points);
170
171   AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
172   
173   TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
174
175   TheCurve.Curve(1, Poles);
176   
177   myCurve = new Geom2d_BSplineCurve(Poles, 
178                                     TheCurve.Knots(),
179                                     TheCurve.Multiplicities(),
180                                     TheCurve.Degree());
181   myIsDone = Standard_True;
182 }
183
184 //=======================================================================
185 //function : Init
186 //purpose  : 
187 //=======================================================================
188
189 void Geom2dAPI_PointsToBSpline::Init
190   (const TColStd_Array1OfReal& YValues,
191    const Standard_Real         X0,
192    const Standard_Real         DX,
193    const Standard_Integer      DegMin, 
194    const Standard_Integer      DegMax,
195    const GeomAbs_Shape         Continuity,
196    const Standard_Real         Tol2D)
197 {
198   // first approximate the Y values (with dummy 0 as X values)
199
200   Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
201   TColgp_Array1OfPnt2d Points(YValues.Lower(),YValues.Upper());
202   math_Vector Param(YValues.Lower(),YValues.Upper());
203   Standard_Real length = DX * (YValues.Upper() - YValues.Lower());
204   Standard_Integer i;
205   
206   for (i = YValues.Lower(); i <= YValues.Upper(); i++) {
207     Param(i) = (X0+(i-1)*DX)/(X0+length);
208     Points(i).SetCoord(0.0, YValues(i));
209   }
210
211   AppDef_BSplineCompute TheComputer
212     (Param, DegMin,DegMax,Tol3D,Tol2D,0, Standard_True, Standard_True);
213
214   switch( Continuity) {
215   case GeomAbs_C0:
216     TheComputer.SetContinuity(0); break;
217
218   case GeomAbs_G1: 
219   case GeomAbs_C1: 
220     TheComputer.SetContinuity(1); break;
221
222   case GeomAbs_G2:
223   case GeomAbs_C2:
224     TheComputer.SetContinuity(2); break;
225
226   default: 
227     TheComputer.SetContinuity(3);
228   }
229   
230   TheComputer.Perform(Points);
231
232   const AppParCurves_MultiBSpCurve& TheCurve = TheComputer.Value();
233   
234   Standard_Integer Degree = TheCurve.Degree();
235   TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
236   Standard_Integer nk = TheCurve.Knots().Length();
237   TColStd_Array1OfReal Knots(1,nk);
238   TColStd_Array1OfInteger Mults(1,nk);
239
240   TheCurve.Curve(1, Poles);
241
242
243
244   // compute X values for the poles
245   TColStd_Array1OfReal XPoles(1,Poles.Upper());
246
247   // start with a line
248   TColStd_Array1OfReal    TempPoles(1,2);
249   TColStd_Array1OfReal    TempKnots(1,2);
250   TColStd_Array1OfInteger TempMults(1,2);
251   TempMults.Init(2);
252   TempPoles(1) = X0;
253   TempPoles(2) = X0 + length;
254   TempKnots(1) = 0.;
255   TempKnots(2) = 1.;
256
257   // increase the Degree
258   TColStd_Array1OfReal    NewTempPoles(1,Degree+1);
259   TColStd_Array1OfReal    NewTempKnots(1,2);
260   TColStd_Array1OfInteger NewTempMults(1,2);
261   BSplCLib::IncreaseDegree(1,Degree,Standard_False,1,
262                            TempPoles,TempKnots,TempMults,
263                            NewTempPoles,NewTempKnots,NewTempMults);
264
265
266   // insert the Knots
267   BSplCLib::InsertKnots(Degree,Standard_False,1,
268                         NewTempPoles,NewTempKnots,NewTempMults,
269                         TheCurve.Knots(),&TheCurve.Multiplicities(),
270                         XPoles,Knots,Mults,
271                         Epsilon(1));
272   
273   // scale the knots
274   for (i = 1; i <= nk; i++) {
275     Knots(i) = X0 + length * Knots(i);
276   }
277
278   // set the Poles
279   for (i = 1; i <= Poles.Upper(); i++) {
280     Poles(i).SetX(XPoles(i));
281   }
282
283
284
285   myCurve = new Geom2d_BSplineCurve(Poles, Knots, Mults, Degree);
286   myIsDone = Standard_True;
287 }
288
289 //=======================================================================
290 //function : Init
291 //purpose  : 
292 //=======================================================================
293
294 void Geom2dAPI_PointsToBSpline::Init
295   (const TColgp_Array1OfPnt2d& Points,
296    const Standard_Integer    DegMin,
297    const Standard_Integer    DegMax,
298    const GeomAbs_Shape       Continuity,
299    const Standard_Real       Tol2D)
300 {
301   myIsDone = Standard_False;
302   Init(Points,Approx_ChordLength,DegMin,DegMax,Continuity,Tol2D);
303 }
304
305
306 //=======================================================================
307 //function : Init
308 //purpose  : 
309 //=======================================================================
310
311 void Geom2dAPI_PointsToBSpline::Init
312   (const TColgp_Array1OfPnt2d&   Points,
313    const TColStd_Array1OfReal& Params,
314    const Standard_Integer      DegMin,
315    const Standard_Integer      DegMax,
316    const GeomAbs_Shape         Continuity,
317    const Standard_Real         Tol2D)
318 {
319   if (Params.Length() != Points.Length()) throw Standard_OutOfRange ("Geom2dAPI_PointsToBSpline::Init() - invalid input");
320
321   Standard_Real Tol3D = 0.; // dummy argument for BSplineCompute.
322   Standard_Integer Nbp = Params.Length();
323   math_Vector theParams(1,Nbp);
324   theParams(1) = 0.;
325   theParams(Nbp) = 1.;
326
327   Standard_Real Uf = Params(Params.Lower());
328   Standard_Real Ul = Params(Params.Upper()) - Uf;
329   for (Standard_Integer i=2; i<Nbp; i++) {
330     theParams(i) = (Params(i)-Uf)/Ul;
331   }
332   
333   AppDef_BSplineCompute TheComputer
334     (DegMin,DegMax,Tol3D,Tol2D,0,
335      Standard_True,Approx_IsoParametric,Standard_True);
336
337   TheComputer.SetParameters(theParams);
338
339   switch( Continuity) {
340   case GeomAbs_C0:
341     TheComputer.SetContinuity(0); break;
342
343   case GeomAbs_G1: 
344   case GeomAbs_C1: 
345     TheComputer.SetContinuity(1); break;
346
347   case GeomAbs_G2:
348   case GeomAbs_C2:
349     TheComputer.SetContinuity(2); break;
350
351   default: 
352     TheComputer.SetContinuity(3);
353   }
354
355   TheComputer.Perform(Points);
356
357   AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
358   
359   TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
360
361   TheCurve.Curve(1, Poles);
362   
363   myCurve = new Geom2d_BSplineCurve(Poles, 
364                                     TheCurve.Knots(),
365                                     TheCurve.Multiplicities(),
366                                     TheCurve.Degree());
367   myIsDone = Standard_True;  
368
369 }
370
371
372 //=======================================================================
373 //function : Init
374 //purpose  : 
375 //=======================================================================
376
377 void Geom2dAPI_PointsToBSpline::Init
378   (const TColgp_Array1OfPnt2d&   Points,
379    const Standard_Real         W1,
380    const Standard_Real         W2,
381    const Standard_Real         W3,
382    const Standard_Integer      DegMax,
383    const GeomAbs_Shape         Continuity,
384    const Standard_Real         Tol2D)
385 {
386   Standard_Integer NbPoint = Points.Length(), i;
387
388  
389   Standard_Integer nbit = 2;
390   if(Tol2D <= 1.e-3) nbit = 0;
391
392  //Variational algo
393
394   AppDef_MultiLine multL(NbPoint);
395   for(i = 1; i <= NbPoint; ++i) {
396     AppDef_MultiPointConstraint mpc(0, 1);
397     mpc.SetPoint2d(1, Points.Value(Points.Lower() + i - 1));
398     multL.SetValue(i, mpc);
399   }
400
401   Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC = 
402     new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
403   AppParCurves_Constraint  Constraint=AppParCurves_NoConstraint;
404   
405   for(i = 1; i <= NbPoint; ++i) {
406     AppParCurves_ConstraintCouple ACC(i,Constraint);
407     TABofCC->SetValue(i,ACC);
408   }
409   
410
411   AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
412
413 //===================================
414   Standard_Integer theMaxSegments = 1000;
415   Standard_Boolean theWithMinMax = Standard_False;
416 //===================================      
417
418   Variation.SetMaxDegree(DegMax);
419   Variation.SetContinuity(Continuity);
420   Variation.SetMaxSegment(theMaxSegments);
421
422   Variation.SetTolerance(Tol2D);
423   Variation.SetWithMinMax(theWithMinMax);
424   Variation.SetNbIterations(nbit);
425
426   Variation.SetCriteriumWeight(W1, W2, W3);
427
428   if(!Variation.IsCreated()) {
429     return;
430   }
431   
432   if(Variation.IsOverConstrained()) {
433     return;
434   }
435
436   try {
437     Variation.Approximate();
438   }
439   catch (Standard_Failure const&) {
440     return;
441   }
442
443   if(!Variation.IsDone()) {
444     return;
445   }
446
447   AppParCurves_MultiBSpCurve TheCurve = Variation.Value();
448
449   TColgp_Array1OfPnt2d Poles(1,TheCurve.NbPoles());
450
451   TheCurve.Curve(1, Poles);
452   
453   myCurve = new Geom2d_BSplineCurve(Poles, 
454                                     TheCurve.Knots(),
455                                     TheCurve.Multiplicities(),
456                                     TheCurve.Degree());
457
458   myIsDone = Standard_True;
459
460 }
461
462 //=======================================================================
463 //function : Handle(Geom2d_BSplineCurve)&
464 //purpose  : 
465 //=======================================================================
466
467 const Handle(Geom2d_BSplineCurve)& Geom2dAPI_PointsToBSpline::Curve() const 
468 {
469   if ( !myIsDone) 
470     throw StdFail_NotDone(" ");
471   return myCurve;
472 }
473
474
475
476 //=======================================================================
477 //function : Geom2d_BSplineCurve
478 //purpose  : 
479 //=======================================================================
480
481 Geom2dAPI_PointsToBSpline::operator Handle(Geom2d_BSplineCurve)() const
482 {
483   return myCurve;
484 }
485
486 //=======================================================================
487 //function : Geom2d_BSplineCurve
488 //purpose  : 
489 //=======================================================================
490
491 Standard_Boolean Geom2dAPI_PointsToBSpline::IsDone() const
492 {
493   return myIsDone;
494 }
495
496