567278b43cd14f74ad54d1ce65ba12899effc85f
[occt.git] / src / GeomAPI / GeomAPI_PointsToBSpline.cxx
1 // Created on: 1994-03-21
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 #include <GeomAPI_PointsToBSpline.ixx>
18
19 #include <AppDef_BSplineCompute.hxx>
20 #include <AppDef_MultiLine.hxx>
21 #include <AppParCurves_MultiBSpCurve.hxx>
22 #include <math_Vector.hxx>
23 #include <BSplCLib.hxx>
24 #include <AppDef_MultiLine.hxx>
25 #include <AppDef_MultiPointConstraint.hxx>
26 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
27 #include <AppParCurves_Constraint.hxx>
28 #include <AppDef_TheVariational.hxx>
29
30
31 //=======================================================================
32 //function : GeomAPI_PointsToBSpline
33 //purpose  : 
34 //=======================================================================
35
36 GeomAPI_PointsToBSpline::GeomAPI_PointsToBSpline()
37 {
38   myIsDone = Standard_False;
39 }
40
41
42 //=======================================================================
43 //function : GeomAPI_PointsToBSpline
44 //purpose  : 
45 //=======================================================================
46
47 GeomAPI_PointsToBSpline::GeomAPI_PointsToBSpline
48   (const TColgp_Array1OfPnt& Points,
49    const Standard_Integer    DegMin, 
50    const Standard_Integer    DegMax,
51    const GeomAbs_Shape       Continuity,
52    const Standard_Real       Tol3D)
53 {
54   myIsDone = Standard_False;
55   Init(Points,DegMin,DegMax,Continuity,Tol3D);
56 }
57
58 //=======================================================================
59 //function : GeomAPI_PointsToBSpline
60 //purpose  : 
61 //=======================================================================
62
63 GeomAPI_PointsToBSpline::GeomAPI_PointsToBSpline
64   (const TColgp_Array1OfPnt& Points,
65    const Approx_ParametrizationType ParType,
66    const Standard_Integer    DegMin, 
67    const Standard_Integer    DegMax,
68    const GeomAbs_Shape       Continuity,
69    const Standard_Real       Tol3D)
70 {
71   myIsDone = Standard_False;
72   Init(Points,ParType,DegMin,DegMax,Continuity,Tol3D);
73 }
74
75
76 //=======================================================================
77 //function : GeomAPI_PointsToBSpline
78 //purpose  : 
79 //=======================================================================
80
81 GeomAPI_PointsToBSpline::GeomAPI_PointsToBSpline
82   (const TColgp_Array1OfPnt&   Points,
83    const TColStd_Array1OfReal& Params,
84    const Standard_Integer      DegMin, 
85    const Standard_Integer      DegMax,
86    const GeomAbs_Shape         Continuity,
87    const Standard_Real         Tol3D)
88 {
89   myIsDone = Standard_False;
90   Init(Points,Params,DegMin,DegMax,Continuity,Tol3D);
91 }
92
93 //=======================================================================
94 //function : GeomAPI_PointsToBSpline
95 //purpose  : 
96 //=======================================================================
97
98 GeomAPI_PointsToBSpline::GeomAPI_PointsToBSpline
99   (const TColgp_Array1OfPnt&   Points,
100    const Standard_Real         W1,
101    const Standard_Real         W2,
102    const Standard_Real         W3,
103    const Standard_Integer      DegMax,
104    const GeomAbs_Shape         Continuity,
105    const Standard_Real         Tol3D)
106 {
107   myIsDone = Standard_False;
108   Init(Points,W1,W2,W3,DegMax,Continuity,Tol3D);
109 }
110
111 //=======================================================================
112 //function : Init
113 //purpose  : 
114 //=======================================================================
115
116 void GeomAPI_PointsToBSpline::Init
117   (const TColgp_Array1OfPnt& Points,
118    const Standard_Integer    DegMin,
119    const Standard_Integer    DegMax,
120    const GeomAbs_Shape       Continuity,
121    const Standard_Real       Tol3D)
122 {
123   myIsDone = Standard_False;
124   Init(Points,Approx_ChordLength,DegMin,DegMax,Continuity,Tol3D);
125 }
126 //=======================================================================
127 //function : Init
128 //purpose  : 
129 //=======================================================================
130
131 void GeomAPI_PointsToBSpline::Init
132   (const TColgp_Array1OfPnt& Points,
133    const Approx_ParametrizationType ParType,
134    const Standard_Integer    DegMin,
135    const Standard_Integer    DegMax,
136    const GeomAbs_Shape       Continuity,
137    const Standard_Real       Tol3D)
138 {
139   Standard_Real Tol2D = 0.; // dummy argument for BSplineCompute.
140
141   Standard_Integer nbit = 2;
142   Standard_Boolean UseSquares = Standard_False;
143   if(Tol3D <= 1.e-3) UseSquares = Standard_True;
144
145
146   AppDef_BSplineCompute TheComputer
147     (DegMin,DegMax,Tol3D,Tol2D,nbit,Standard_True,ParType,UseSquares);
148
149   switch( Continuity) {
150   case GeomAbs_C0:
151     TheComputer.SetContinuity(0); break;
152
153   case GeomAbs_G1: 
154   case GeomAbs_C1: 
155     TheComputer.SetContinuity(1); break;
156
157   case GeomAbs_G2:
158   case GeomAbs_C2:
159     TheComputer.SetContinuity(2); break;
160
161   default: 
162     TheComputer.SetContinuity(3);
163   }
164   
165   TheComputer.Perform(Points);
166
167   AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
168
169   TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
170
171   TheCurve.Curve(1, Poles);
172   
173   myCurve = new Geom_BSplineCurve(Poles, 
174                                   TheCurve.Knots(),
175                                   TheCurve.Multiplicities(),
176                                   TheCurve.Degree());
177   myIsDone = Standard_True;
178 }
179
180
181 //=======================================================================
182 //function : Init
183 //purpose  : 
184 //=======================================================================
185
186 void GeomAPI_PointsToBSpline::Init
187   (const TColgp_Array1OfPnt&   Points,
188    const TColStd_Array1OfReal& Params,
189    const Standard_Integer      DegMin,
190    const Standard_Integer      DegMax,
191    const GeomAbs_Shape         Continuity,
192    const Standard_Real         Tol3D)
193 {
194   if (Params.Length() != Points.Length()) Standard_OutOfRange::Raise("");
195
196   Standard_Real Tol2D = 0.; // dummy argument for BSplineCompute.
197   Standard_Integer Nbp = Params.Length();
198   math_Vector theParams(1,Nbp);
199   theParams(1) = 0.;
200   theParams(Nbp) = 1.;
201
202   Standard_Real Uf = Params(Params.Lower());
203   Standard_Real Ul = Params(Params.Upper()) - Uf;
204   for (Standard_Integer i=2; i<Nbp; i++) {
205     theParams(i) = (Params(i)-Uf)/Ul;
206   }
207   
208   AppDef_BSplineCompute TheComputer
209     (DegMin,DegMax,Tol3D,Tol2D,0,
210      Standard_True,Approx_IsoParametric,Standard_True);
211
212   TheComputer.SetParameters(theParams);
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   AppParCurves_MultiBSpCurve TheCurve = TheComputer.Value();
233   
234   TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
235   TColStd_Array1OfReal Knots(TheCurve.Knots().Lower(), 
236                              TheCurve.Knots().Upper());
237
238   TheCurve.Curve(1, Poles);
239   Knots = TheCurve.Knots();
240   BSplCLib::Reparametrize(Params(Params.Lower()),
241                           Params(Params.Upper()),
242                           Knots);
243
244   myCurve = new Geom_BSplineCurve(Poles, 
245                                   Knots,
246                                   TheCurve.Multiplicities(),
247                                   TheCurve.Degree());
248   myIsDone = Standard_True;
249 }
250
251 //=======================================================================
252 //function : Init
253 //purpose  : 
254 //=======================================================================
255
256 void GeomAPI_PointsToBSpline::Init
257   (const TColgp_Array1OfPnt&   Points,
258    const Standard_Real         W1,
259    const Standard_Real         W2,
260    const Standard_Real         W3,
261    const Standard_Integer      DegMax,
262    const GeomAbs_Shape         Continuity,
263    const Standard_Real         Tol3D)
264 {
265   Standard_Integer NbPoint = Points.Length(), i;
266
267  
268   Standard_Integer nbit = 2;
269   if(Tol3D <= 1.e-3) nbit = 0;
270
271  //Variational algo
272
273   AppDef_MultiLine multL(NbPoint);
274   for(i = 1; i <= NbPoint; ++i) {
275     AppDef_MultiPointConstraint mpc(1, 0);
276     mpc.SetPoint(1, Points.Value(Points.Lower() + i - 1));
277     multL.SetValue(i, mpc);
278   }
279
280   Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC = 
281     new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
282   AppParCurves_Constraint  Constraint=AppParCurves_NoConstraint;
283   
284   for(i = 1; i <= NbPoint; ++i) {
285     AppParCurves_ConstraintCouple ACC(i,Constraint);
286     TABofCC->SetValue(i,ACC);
287   }
288   
289
290   AppDef_TheVariational Variation(multL, 1, NbPoint, TABofCC);
291
292 //===================================
293   Standard_Integer theMaxSegments = 1000;
294   Standard_Boolean theWithMinMax = Standard_False;
295 //===================================      
296
297   Variation.SetMaxDegree(DegMax);
298   Variation.SetContinuity(Continuity);
299   Variation.SetMaxSegment(theMaxSegments);
300
301   Variation.SetTolerance(Tol3D);
302   Variation.SetWithMinMax(theWithMinMax);
303   Variation.SetNbIterations(nbit);
304
305   Variation.SetCriteriumWeight(W1, W2, W3);
306
307   if(!Variation.IsCreated()) {
308     return;
309   }
310   
311   if(Variation.IsOverConstrained()) {
312     return;
313   }
314
315   try {
316     Variation.Approximate();
317   }
318   catch (Standard_Failure) {
319     return;
320   }
321
322   if(!Variation.IsDone()) {
323     return;
324   }
325
326   AppParCurves_MultiBSpCurve TheCurve = Variation.Value();
327
328   TColgp_Array1OfPnt Poles(1,TheCurve.NbPoles());
329
330   TheCurve.Curve(1, Poles);
331   
332   myCurve = new Geom_BSplineCurve(Poles, 
333                                   TheCurve.Knots(),
334                                   TheCurve.Multiplicities(),
335                                   TheCurve.Degree());
336   myIsDone = Standard_True;
337
338 }
339
340
341 //=======================================================================
342 //function : Handle_Geom_BSplineCurve&
343 //purpose  : 
344 //=======================================================================
345
346 const Handle(Geom_BSplineCurve)& GeomAPI_PointsToBSpline::Curve() const 
347 {
348   if ( !myIsDone) 
349     StdFail_NotDone::Raise("GeomAPI_PointsToBSpline::Curve ");
350   return myCurve;
351 }
352
353
354
355 //=======================================================================
356 //function : Geom_BSplineCurve
357 //purpose  : 
358 //=======================================================================
359
360 GeomAPI_PointsToBSpline::operator Handle(Geom_BSplineCurve)() const
361 {
362   return myCurve;
363 }
364
365
366 //=======================================================================
367 //function : IsDone
368 //purpose  : 
369 //=======================================================================
370
371 Standard_Boolean GeomAPI_PointsToBSpline::IsDone() const 
372 {
373   return myIsDone; 
374 }