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 |
38 | Geom2dAPI_PointsToBSpline::Geom2dAPI_PointsToBSpline() |
39 | { |
40 | myIsDone = Standard_False; |
41 | } |
42 | |
43 | |
44 | //======================================================================= |
45 | //function : Geom2dAPI_PointsToBSpline |
46 | //purpose : |
47 | //======================================================================= |
48 | |
49 | Geom2dAPI_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 | |
65 | Geom2dAPI_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 | |
82 | Geom2dAPI_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 | |
99 | Geom2dAPI_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 | |
117 | Geom2dAPI_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 | |
136 | void 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 | |
190 | void 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 | |
295 | void 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 | |
312 | void 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 | { |
320 | if (Params.Length() != Points.Length()) Standard_OutOfRange::Raise(""); |
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 | |
378 | void 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 | } |
440 | catch (Standard_Failure) { |
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 | |
468 | const Handle(Geom2d_BSplineCurve)& Geom2dAPI_PointsToBSpline::Curve() const |
469 | { |
470 | if ( !myIsDone) |
471 | StdFail_NotDone::Raise(" "); |
472 | return myCurve; |
473 | } |
474 | |
475 | |
476 | |
477 | //======================================================================= |
478 | //function : Geom2d_BSplineCurve |
479 | //purpose : |
480 | //======================================================================= |
481 | |
482 | Geom2dAPI_PointsToBSpline::operator Handle(Geom2d_BSplineCurve)() const |
483 | { |
484 | return myCurve; |
485 | } |
486 | |
487 | //======================================================================= |
488 | //function : Geom2d_BSplineCurve |
489 | //purpose : |
490 | //======================================================================= |
491 | |
492 | Standard_Boolean Geom2dAPI_PointsToBSpline::IsDone() const |
493 | { |
494 | return myIsDone; |
495 | } |
496 | |
497 | |