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 | |
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()) 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 | |
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 | |
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 | |
467 | const 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 | |
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 | |