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