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