0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / Geom2dAPI / Geom2dAPI_PointsToBSpline.cxx
CommitLineData
b311480e 1// Created on: 1994-03-23
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <Geom2dAPI_PointsToBSpline.ixx>
18
19#include <AppDef_BSplineCompute.hxx>
20#include <AppDef_MultiLine.hxx>
21#include <AppParCurves_MultiBSpCurve.hxx>
22#include <BSplCLib.hxx>
23#include <TColStd_Array1OfInteger.hxx>
24#include <TColStd_Array1OfReal.hxx>
25#include <TColgp_Array1OfPnt2d.hxx>
26#include <math_Vector.hxx>
27#include <AppDef_MultiPointConstraint.hxx>
28#include <AppParCurves_HArray1OfConstraintCouple.hxx>
f62de372 29#include <AppDef_Variational.hxx>
7fd59977 30
31
32//=======================================================================
33//function : Geom2dAPI_PointsToBSpline
34//purpose :
35//=======================================================================
36
37Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline()
38{
39 myIsDone = Standard_False;
40}
41
42
43//=======================================================================
44//function : Geom2dAPI_PointsToBSpline
45//purpose :
46//=======================================================================
47
48Geom2dAPI_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
64Geom2dAPI_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
81Geom2dAPI_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
98Geom2dAPI_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
116Geom2dAPI_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
135void 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
189void 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
294void 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
311void 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()) Standard_OutOfRange::Raise("");
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
377void 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
f62de372 411 AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
7fd59977 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) {
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//=======================================================================
857ffd5e 463//function : Handle(Geom2d_BSplineCurve)&
7fd59977 464//purpose :
465//=======================================================================
466
467const Handle(Geom2d_BSplineCurve)& Geom2dAPI_PointsToBSpline::Curve() const
468{
469 if ( !myIsDone)
470 StdFail_NotDone::Raise(" ");
471 return myCurve;
472}
473
474
475
476//=======================================================================
477//function : Geom2d_BSplineCurve
478//purpose :
479//=======================================================================
480
481Geom2dAPI_PointsToBSpline::operator Handle(Geom2d_BSplineCurve)() const
482{
483 return myCurve;
484}
485
486//=======================================================================
487//function : Geom2d_BSplineCurve
488//purpose :
489//=======================================================================
490
491Standard_Boolean Geom2dAPI_PointsToBSpline::IsDone() const
492{
493 return myIsDone;
494}
495
496