Warnings on vc14 were eliminated
[occt.git] / src / Approx / Approx_BSplComputeLine.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15#include <stdio.h>
16
17#include <Approx_ParametrizationType.hxx>
18#include <TColStd_Array1OfReal.hxx>
19#include <TColgp_Array1OfPnt.hxx>
20#include <TColgp_Array1OfPnt2d.hxx>
21#include <gp_Pnt.hxx>
22#include <gp_Pnt2d.hxx>
23#include <gp_Vec.hxx>
24#include <gp_Vec2d.hxx>
25#include <TColgp_Array1OfVec.hxx>
26#include <TColgp_Array1OfVec2d.hxx>
27#include <AppParCurves_Constraint.hxx>
28#include <AppParCurves_HArray1OfConstraintCouple.hxx>
29#include <AppParCurves_MultiPoint.hxx>
30#include <Precision.hxx>
31#include <math_IntegerVector.hxx>
32#include <math_Gauss.hxx>
33#include <math_Uzawa.hxx>
34#include <AppParCurves_ConstraintCouple.hxx>
35#include Approx_BSpParLeastSquareOfMyBSplGradient_hxx
36
0797d9d3 37#if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
7fd59977 38
39static Standard_Boolean mydebug = Standard_False;
40
41#include <Draw.hxx>
42#include <Draw_Appli.hxx>
43#include <DrawTrSurf.hxx>
44#include <Draw_Text2D.hxx>
45#include <Draw_Text3D.hxx>
46#include <TColStd_Array1OfInteger.hxx>
47#include <Geom_BSplineCurve.hxx>
48#include <Geom2d_BSplineCurve.hxx>
49#include <Geom_Line.hxx>
50#include <Geom2d_Line.hxx>
51#include <Geom_TrimmedCurve.hxx>
52#include <Geom2d_TrimmedCurve.hxx>
53
54
55static void DUMP(const MultiLine& Line)
56{
57 Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
58 firstP = LineTool::FirstPoint(Line);
59 lastP = LineTool::LastPoint(Line);
60
61 nbP3d = LineTool::NbP3d(Line);
62 nbP2d = LineTool::NbP2d(Line);
63 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
64 if (nbP3d == 0) mynbP3d = 1;
65 if (nbP2d == 0) mynbP2d = 1;
66
67 TColgp_Array1OfPnt tabP(1, mynbP3d);
68 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
69 TColgp_Array1OfVec TabV(1, mynbP3d);
70 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
71 Standard_Boolean Ok;
72 Handle(Geom_Line) L3d;
73 Handle(Geom2d_Line) L2d;
74 Handle(Geom_TrimmedCurve) L3dt;
75 Handle(Geom2d_TrimmedCurve) L2dt;
76 Handle(Draw_Text2D) T2D;
77 Handle(Draw_Text3D) T3D;
78
79 char solname[100];
80 char mytext[10];
81
82 for (i = firstP; i <= lastP; i++) {
83 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
84 else if (nbP2d != 0) LineTool::Value(Line, i, tabP2d);
85 else if (nbP3d != 0) LineTool::Value(Line, i, tabP);
86
87 for (j = 1; j <= nbP3d; j++) {
88 sprintf(solname, "%s%i%s_%i", "p", j, "3d", i);
89 char* Temp = solname ;
90 DrawTrSurf::Set(Temp, tabP(j));
91// DrawTrSurf::Set(solname, tabP(j));
92 if (i == firstP || i == lastP) {
93 sprintf(mytext, "%s%i", " ", i);
94 T3D = new Draw_Text3D(tabP(j), mytext, Draw_vert);
95 dout << T3D;
96 }
97 }
98 for (j = 1; j <= nbP2d; j++) {
99 sprintf(solname, "%s%i%s_%i", "p", j, "2d", i);
100 char* Temp = solname ;
101 DrawTrSurf::Set(Temp, tabP2d(j));
102// DrawTrSurf::Set(solname, tabP2d(j));
103 if (i == firstP || i == lastP) {
104 sprintf(mytext, "%s%i", " ", i);
105 T2D = new Draw_Text2D(tabP2d(j), mytext, Draw_vert);
106 dout << T2D;
107 }
108 }
109
110 // le cas des tangentes aux extremites:
111 if (i == firstP || i == lastP) {
112 if (nbP3d != 0 && nbP2d != 0)
113 Ok = LineTool::Tangency(Line, i, TabV, TabV2d);
114 else if (nbP2d != 0)
115 Ok = LineTool::Tangency(Line, i, TabV2d);
116 else if (nbP3d != 0)
117 Ok = LineTool::Tangency(Line, i, TabV);
118
119 if (Ok) {
120 for (j = 1; j <= nbP3d; j++) {
121 sprintf(solname, "%s%i%s_%i", "t", j, "3d", i);
122 L3d = new Geom_Line (tabP(j), gp_Dir(TabV(j)));
123 L3dt = new Geom_TrimmedCurve(L3d, 0.0, 0.3);
124 char* Temp = solname ;
125 DrawTrSurf::Set(Temp, L3dt);
126// DrawTrSurf::Set(solname, L3dt);
127 }
128 for (j = 1; j <= nbP2d; j++) {
129 sprintf(solname, "%s%i%s_%i", "t", j, "2d", i);
130 L2d = new Geom2d_Line (tabP2d(j), gp_Dir2d(TabV2d(j)));
131 L2dt = new Geom2d_TrimmedCurve(L2d, 0.0, 0.3);
132 char* Temp = solname ;
133 DrawTrSurf::Set(Temp, L2dt);
134// DrawTrSurf::Set(solname, L2dt);
135 }
136 }
137 }
138 }
139 dout.Flush();
140}
141
142
143static void DUMP(const AppParCurves_MultiBSpCurve& C)
144{
145 static Standard_Integer nbappel = 0;
146 Standard_Integer i, j, nbP2d, nbP3d;
147 Standard_Integer nbpoles = C.NbPoles();
148 Standard_Integer deg = C.Degree();
149 const TColStd_Array1OfReal& Knots = C.Knots();
150 const TColStd_Array1OfInteger& Mults = C.Multiplicities();
151
152 Handle(Geom_BSplineCurve) BSp;
153 Handle(Geom2d_BSplineCurve) BSp2d;
154
155 TColgp_Array1OfPnt tabPoles(1, nbpoles);
156 TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles);
157 char solname[100];
158
159 nbappel++;
160 for (i = 1; i <= C.NbCurves(); i++) {
161 if (C.Dimension(i) == 3) {
162 C.Curve(i, tabPoles);
163 BSp = new Geom_BSplineCurve(tabPoles, Knots, Mults, deg);
164 sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
165 char* Temp = solname ;
166 DrawTrSurf::Set(Temp, BSp);
167// DrawTrSurf::Set(solname, BSp);
168 }
169 else {
170 C.Curve(i, tabPoles2d);
171 BSp2d = new Geom2d_BSplineCurve(tabPoles2d, Knots, Mults, deg);
172 sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
173 char* Temp = solname ;
174 DrawTrSurf::Set(Temp, BSp2d);
175// DrawTrSurf::Set(solname, BSp2d);
176 }
177 }
178 dout.Flush();
179}
180
181
182#endif
183
184
185
186
187//=======================================================================
188//function : FirstTangencyVector
189//purpose :
190//=======================================================================
191void Approx_BSplComputeLine::FirstTangencyVector(const MultiLine& Line,
192 const Standard_Integer index,
193 math_Vector& V)
194const {
195
196 Standard_Integer i, j, nbP2d, nbP3d;
197 nbP3d = LineTool::NbP3d(Line);
198 nbP2d = LineTool::NbP2d(Line);
199 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
200 if (nbP3d == 0) mynbP3d = 1;
201 if (nbP2d == 0) mynbP2d = 1;
202 Standard_Boolean Ok=Standard_False;
203 TColgp_Array1OfVec TabV(1, mynbP3d);
204 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
205
206 if (nbP3d != 0 && nbP2d != 0)
207 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
208 else if (nbP2d != 0)
209 Ok = LineTool::Tangency(Line, index, TabV2d);
210 else if (nbP3d != 0)
211 Ok = LineTool::Tangency(Line, index, TabV);
212
213 if (Ok) {
214 if (nbP3d != 0) {
215 j = 1;
216 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
217 V(j) = TabV(i).X();
218 V(j+1) = TabV(i).Y();
219 V(j+2) = TabV(i).Z();
220 j += 3;
221 }
222 }
223 if (nbP2d != 0) {
224 j = nbP3d*3+1;
225 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
226 V(j) = TabV2d(i).X();
227 V(j+1) = TabV2d(i).Y();
228 j += 2;
229 }
230 }
231 }
232 else {
233
234 // recherche d un vecteur tangent par construction d une parabole:
235 AppParCurves_Constraint firstC, lastC;
236 firstC = lastC = AppParCurves_PassPoint;
237 Standard_Integer nbpoles = 3;
238 math_Vector mypar(index, index+2);
239 Parameters(Line, index, index+2, mypar);
240 Approx_BSpParLeastSquareOfMyBSplGradient
241 LSQ(Line, index, index+2, firstC, lastC, mypar, nbpoles);
242 AppParCurves_MultiCurve C = LSQ.BezierValue();
243
244 gp_Pnt myP;
245 gp_Vec myV;
246 gp_Pnt2d myP2d;
247 gp_Vec2d myV2d;
248 j = 1;
249 for (i = 1; i <= nbP3d; i++) {
250 C.D1(i, 0.0, myP, myV);
251 V(j) = myV.X();
252 V(j+1) = myV.Y();
253 V(j+2) = myV.Z();
254 j += 3;
255 }
256 j = nbP3d*3+1;
257 for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
258 C.D1(i, 0.0, myP2d, myV2d);
259 V(j) = myV2d.X();
260 V(j+1) = myV2d.Y();
261 j += 2;
262 }
263 }
264
265}
266
267
268//=======================================================================
269//function : LastTangencyVector
270//purpose :
271//=======================================================================
272void Approx_BSplComputeLine::LastTangencyVector(const MultiLine& Line,
273 const Standard_Integer index,
274 math_Vector& V)
275const {
276 Standard_Integer i, j, nbP2d, nbP3d;
277 nbP3d = LineTool::NbP3d(Line);
278 nbP2d = LineTool::NbP2d(Line);
279 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
280 if (nbP3d == 0) mynbP3d = 1;
281 if (nbP2d == 0) mynbP2d = 1;
282 Standard_Boolean Ok=Standard_False;
283 TColgp_Array1OfVec TabV(1, mynbP3d);
284 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
285
286
287 if (nbP3d != 0 && nbP2d != 0)
288 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
289 else if (nbP2d != 0)
290 Ok = LineTool::Tangency(Line, index, TabV2d);
291 else if (nbP3d != 0)
292 Ok = LineTool::Tangency(Line, index, TabV);
293
294 if (Ok) {
295 if (nbP3d != 0) {
296 j = 1;
297 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
298 V(j) = TabV(i).X();
299 V(j+1) = TabV(i).Y();
300 V(j+2) = TabV(i).Z();
301 j += 3;
302 }
303 }
304 if (nbP2d != 0) {
305 j = nbP3d*3+1;
306 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
307 V(j) = TabV2d(i).X();
308 V(j+1) = TabV2d(i).Y();
309 j += 2;
310 }
311 }
312 }
313 else {
314
315 // recherche d un vecteur tangent par construction d une parabole:
316 AppParCurves_Constraint firstC, lastC;
317 firstC = lastC = AppParCurves_PassPoint;
318 Standard_Integer nbpoles = 3;
319 math_Vector mypar(index-2, index);
320 Parameters(Line, index-2, index, mypar);
321 Approx_BSpParLeastSquareOfMyBSplGradient
322 LSQ(Line, index-2, index, firstC, lastC, mypar, nbpoles);
323 AppParCurves_MultiCurve C = LSQ.BezierValue();
324
325 gp_Pnt myP;
326 gp_Vec myV;
327 gp_Pnt2d myP2d;
328 gp_Vec2d myV2d;
329 j = 1;
330 for (i = 1; i <= nbP3d; i++) {
331 C.D1(i, 1.0, myP, myV);
332 V(j) = myV.X();
333 V(j+1) = myV.Y();
334 V(j+2) = myV.Z();
335 j += 3;
336 }
337 j = nbP3d*3+1;
338 for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
339 C.D1(i, 1.0, myP2d, myV2d);
340 V(j) = myV2d.X();
341 V(j+1) = myV2d.Y();
342 j += 2;
343 }
344 }
345
346}
347
348
349
350//=======================================================================
351//function : SearchFirstLambda
352//purpose :
353//=======================================================================
354Standard_Real Approx_BSplComputeLine::
355 SearchFirstLambda(const MultiLine& Line,
356 const math_Vector& aPar,
357 const TColStd_Array1OfReal& Theknots,
358 const math_Vector& V,
359 const Standard_Integer index) const {
360
361 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
362
363 Standard_Integer nbP2d, nbP3d;
364 gp_Pnt P1, P2;
365 gp_Pnt2d P12d, P22d;
366 nbP3d = LineTool::NbP3d(Line);
367 nbP2d = LineTool::NbP2d(Line);
368 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
369 if (nbP3d == 0) mynbP3d = 1;
370 if (nbP2d == 0) mynbP2d = 1;
371 TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
372 TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
373
374
375 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
376 else if (nbP2d != 0) LineTool::Value(Line, index, tabP12d);
377 else if (nbP3d != 0) LineTool::Value(Line, index, tabP1);
378
379 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index+1, tabP2, tabP22d);
380 else if (nbP2d != 0) LineTool::Value(Line, index+1, tabP22d);
381 else if (nbP3d != 0) LineTool::Value(Line, index+1, tabP2);
382
383
384 Standard_Real U1 = aPar(index), U2 = aPar(index+1);
385 Standard_Real lambda, S;
386 Standard_Integer low = V.Lower();
387 Standard_Integer nbknots = Theknots.Length();
388
389 if (nbP3d != 0) {
390 P1 = tabP1(1);
391 P2 = tabP2(1);
392 gp_Vec P1P2(P1, P2), myV;
393 myV.SetCoord(V(low), V(low+1), V(low+2));
394 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
395 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
396 }
397 else {
398 P12d = tabP12d(1);
399 P22d = tabP22d(1);
400 gp_Vec2d P1P2(P12d, P22d), myV;
401 myV.SetCoord(V(low), V(low+1));
402 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
403 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
404 }
405 return ((S*lambda)*(Theknots(2)-Theknots(1))/(Theknots(nbknots)-Theknots(1)));
406
407}
408
409
410//=======================================================================
411//function : SearchLastLambda
412//purpose :
413//=======================================================================
414Standard_Real Approx_BSplComputeLine::
415 SearchLastLambda(const MultiLine& Line,
416 const math_Vector& aPar,
417 const TColStd_Array1OfReal& Theknots,
418 const math_Vector& V,
419 const Standard_Integer index) const
420
421{
422 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
423
424 Standard_Integer nbP2d, nbP3d;
425 gp_Pnt P1, P2;
426 gp_Pnt2d P12d, P22d;
427 nbP3d = LineTool::NbP3d(Line);
428 nbP2d = LineTool::NbP2d(Line);
429 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
430 if (nbP3d == 0) mynbP3d = 1;
431 if (nbP2d == 0) mynbP2d = 1;
432 TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
433 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
434
435 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index-1, tabP, tabP2d);
436 else if (nbP2d != 0) LineTool::Value(Line, index-1, tabP2d);
437 else if (nbP3d != 0) LineTool::Value(Line, index-1, tabP);
438
439 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
440 else if (nbP2d != 0) LineTool::Value(Line, index, tabP22d);
441 else if (nbP3d != 0) LineTool::Value(Line, index, tabP2);
442
443
444 Standard_Real U1 = aPar(index-1), U2 = aPar(index);
445 Standard_Real lambda, S;
446 Standard_Integer low = V.Lower();
447 Standard_Integer nbknots = Theknots.Length();
448 if (nbP3d != 0) {
449 P1 = tabP(1);
450 P2 = tabP2(1);
451 gp_Vec P1P2(P1, P2), myV;
452 myV.SetCoord(V(low), V(low+1), V(low+2));
453 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
454 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
455 }
456 else {
457 P12d = tabP2d(1);
458 P22d = tabP22d(1);
459 gp_Vec2d P1P2(P12d, P22d), myV;
460 myV.SetCoord(V(low), V(low+1));
461 lambda = (P1P2.Magnitude())/(myV.Magnitude()*(U2-U1));
462 S = (P1P2.Dot(myV)> 0.0) ? 1.0 : -1.0;
463 }
464
465 return ((S*lambda)*(Theknots(nbknots)-Theknots(nbknots-1))
466 /(Theknots(nbknots)-Theknots(1)));
467}
468
469
470
471//=======================================================================
472//function : Approx_BSplComputeLine
473//purpose :
474//=======================================================================
475Approx_BSplComputeLine::Approx_BSplComputeLine
476 (const MultiLine& Line,
477 const math_Vector& Parameters,
478 const Standard_Integer degreemin,
479 const Standard_Integer degreemax,
480 const Standard_Real Tolerance3d,
481 const Standard_Real Tolerance2d,
482 const Standard_Integer NbIterations,
483 const Standard_Boolean cutting,
484 const Standard_Boolean Squares)
485{
486 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
487 Parameters.Upper());
488 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
489 myfirstParam->SetValue(i, Parameters(i));
490 }
491 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
492 Par = Approx_IsoParametric;
493 mydegremin = degreemin;
494 mydegremax = degreemax;
495 mytol3d = Tolerance3d;
496 mytol2d = Tolerance2d;
497 mysquares = Squares;
498 mycut = cutting;
499 myitermax = NbIterations;
500 alldone = Standard_False;
501 mycont = -1;
502 myfirstC = AppParCurves_TangencyPoint;
503 mylastC = AppParCurves_TangencyPoint;
504 myhasknots = Standard_False;
505 myhasmults = Standard_False;
506 currenttol3d = currenttol2d = RealLast();
507 tolreached = Standard_False;
508 Perform(Line);
509}
510
511
512//=======================================================================
513//function : Approx_BSplComputeLine
514//purpose :
515//=======================================================================
516Approx_BSplComputeLine::Approx_BSplComputeLine
517 (const math_Vector& Parameters,
518 const Standard_Integer degreemin,
519 const Standard_Integer degreemax,
520 const Standard_Real Tolerance3d,
521 const Standard_Real Tolerance2d,
522 const Standard_Integer NbIterations,
523 const Standard_Boolean cutting,
524 const Standard_Boolean Squares)
525{
526 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
527 Parameters.Upper());
528 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
529 myfirstParam->SetValue(i, Parameters(i));
530 }
531 myfirstC = AppParCurves_TangencyPoint;
532 mylastC = AppParCurves_TangencyPoint;
533 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
534 Par = Approx_IsoParametric;
535 mydegremin = degreemin;
536 mydegremax = degreemax;
537 mytol3d = Tolerance3d;
538 mytol2d = Tolerance2d;
539 mysquares = Squares;
540 mycut = cutting;
541 myitermax = NbIterations;
542 alldone = Standard_False;
543 myhasknots = Standard_False;
544 myhasmults = Standard_False;
545 mycont = -1;
546 currenttol3d = currenttol2d = RealLast();
547 tolreached = Standard_False;
548}
549
550//=======================================================================
551//function : Approx_BSplComputeLine
552//purpose :
553//=======================================================================
554Approx_BSplComputeLine::Approx_BSplComputeLine
555 (const Standard_Integer degreemin,
556 const Standard_Integer degreemax,
557 const Standard_Real Tolerance3d,
558 const Standard_Real Tolerance2d,
559 const Standard_Integer NbIterations,
560 const Standard_Boolean cutting,
561 const Approx_ParametrizationType parametrization,
562 const Standard_Boolean Squares)
563{
564 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
565 Par = parametrization;
566 mydegremin = degreemin;
567 mydegremax = degreemax;
568 mytol3d = Tolerance3d;
569 mytol2d = Tolerance2d;
570 mysquares = Squares;
571 mycut = cutting;
572 myitermax = NbIterations;
573 myfirstC = AppParCurves_TangencyPoint;
574 mylastC = AppParCurves_TangencyPoint;
575 alldone = Standard_False;
576 myhasknots = Standard_False;
577 myhasmults = Standard_False;
578 mycont = -1;
579 currenttol3d = currenttol2d = RealLast();
580 tolreached = Standard_False;
581}
582
583
584//=======================================================================
585//function : Approx_BSplComputeLine
586//purpose :
587//=======================================================================
588Approx_BSplComputeLine::Approx_BSplComputeLine
589 (const MultiLine& Line,
590 const Standard_Integer degreemin,
591 const Standard_Integer degreemax,
592 const Standard_Real Tolerance3d,
593 const Standard_Real Tolerance2d,
594 const Standard_Integer NbIterations,
595 const Standard_Boolean cutting,
596 const Approx_ParametrizationType parametrization,
597 const Standard_Boolean Squares)
598{
599 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
600 alldone = Standard_False;
601 mydegremin = degreemin;
602 mydegremax = degreemax;
603 mytol3d = Tolerance3d;
604 mytol2d = Tolerance2d;
605 mysquares = Squares;
606 mycut = cutting;
607 myitermax = NbIterations;
608 Par = parametrization;
609 myfirstC = AppParCurves_TangencyPoint;
610 mylastC = AppParCurves_TangencyPoint;
611 myhasknots = Standard_False;
612 myhasmults = Standard_False;
613 mycont = -1;
614 currenttol3d = currenttol2d = RealLast();
615 tolreached = Standard_False;
616 Perform(Line);
617}
618
619
620
621//=======================================================================
622//function : Perform
623//purpose :
624//=======================================================================
625void Approx_BSplComputeLine::Perform(const MultiLine& Line)
626{
627
0797d9d3 628#if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
7fd59977 629 if (mydebug) DUMP(Line);
630#endif
631
632 Standard_Integer i, Thefirstpt, Thelastpt;
633 Standard_Boolean Finish = Standard_False, begin = Standard_True;
634
635 // recherche des vraies contraintes donnees par la Line:
636 FindRealConstraints(Line);
637
638 Thefirstpt = LineTool::FirstPoint(Line);
639 Thelastpt = LineTool::LastPoint(Line);
640 Standard_Integer myfirstpt = Thefirstpt;
641 Standard_Integer mylastpt = Thelastpt;
642
643 AppParCurves_ConstraintCouple myCouple1(myfirstpt, realfirstC);
644 AppParCurves_ConstraintCouple myCouple2(mylastpt, reallastC);
645 myConstraints->SetValue(1, myCouple1);
646 myConstraints->SetValue(2, myCouple2);
647
648 math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
649 if(myfirstParam.IsNull()) {
650 Parameters(Line, Thefirstpt, Thelastpt, TheParam);
651 }
652 else {
653 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
654 TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
655 }
656 }
657
658 myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
659 for ( i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
660 myParameters->SetValue(i, TheParam(i));
661 }
662 Standard_Integer nbknots = 2;
663 Standard_Real l;
664 alldone = Standard_False;
665
666 if (!mycut) {
667
668 // cas ou on ne desire pas de noeuds supplementaires.
669 // ==================================================
670
671 if (!myhasknots) {
672 TColStd_Array1OfReal theknots(1, 2);
673 TColStd_Array1OfInteger themults(1, 2);
674 theknots(1) = 0.0;
675 theknots(2) = 1.0;
676 alldone = Compute(Line, myfirstpt, mylastpt, TheParam, theknots, themults);
677 }
678 else {
679 if (!myhasmults) {
680 TColStd_Array1OfInteger themults(1, myknots->Length());
681 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
682 myknots->Array1(), themults);
683 }
684 else {
685 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
686 myknots->Array1(), mymults->ChangeArray1());
687 }
688 }
689 }
690 else {
691
692 // cas ou on va iterer a partir de noeuds donnes par l''utilisateur
693 // ou a partir d''une bezier.
694 // ================================================================
695
696 while (!Finish) {
697
698 currenttol3d = currenttol2d = RealLast();
699
700 if (myhasknots && begin) {
701
702 if (!myhasmults) {
703
704 // 1er cas: l''utilisateur donne des noeuds de depart mais
705 // a nous de fixer les multiplicites en fonction de la
706 // continuite desiree.
707 // ========================================================
708
709 TColStd_Array1OfInteger TheMults(1, myknots->Length());
710 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
711 myknots->Array1(), TheMults);
712 }
713 else {
714
715 // 2eme cas: l''utilisateur donne des noeuds de depart
716 // avec leurs multiplicites.
717 // ===================================================
718
719 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
720 myknots->Array1(), mymults->ChangeArray1());
721 }
722 begin = Standard_False;
723 }
724
725 else {
726
727 // 3eme cas: l''utilisateur ne donne aucun noeuds de depart
728 // ========================================================
729
730 TColStd_Array1OfReal Theknots(1, nbknots);
731 TColStd_Array1OfInteger TheMults(1, nbknots);
732 Theknots(1) = 0.0;
733 Theknots(nbknots) = 1.0;
734 for (i = 2; i <= nbknots-1; i++) {
735
736 l = (mylastpt-myfirstpt)*Standard_Real(i-1)
737 /Standard_Real(nbknots-1);
738 Standard_Integer ll = (Standard_Integer)(l);
739 Standard_Real a = l - ll;
740 Standard_Real p1 = TheParam(ll + myfirstpt);
741 Standard_Real p2 = TheParam(ll + 1 + myfirstpt);
742 Theknots(i) = (1.-a)*p1 + a*p2;
743 }
744
745 alldone = Compute(Line, myfirstpt, mylastpt, TheParam, Theknots, TheMults);
746
747 }
748
749 if (!alldone) nbknots++;
750 else Finish = Standard_True;
751 }
752 }
753
0797d9d3 754#if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
7fd59977 755 if (mydebug) DUMP(TheMultiBSpCurve);
756#endif
757
758}
759
760
761
762
763//=======================================================================
764//function : Parameters
765//purpose :
766//=======================================================================
767const TColStd_Array1OfReal& Approx_BSplComputeLine::Parameters() const
768{
769 return myParameters->Array1();
770}
771
772
773
774//=======================================================================
775//function : Value
776//purpose :
777//=======================================================================
778const AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::Value() const
779{
780 return TheMultiBSpCurve;
781}
782
783//=======================================================================
784//function : ChangeValue
785//purpose :
786//=======================================================================
787AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::ChangeValue()
788{
789 return TheMultiBSpCurve;
790}
791
792//=======================================================================
793//function : Parameters
794//purpose :
795//=======================================================================
796
797void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
798 const Standard_Integer firstP,
799 const Standard_Integer lastP,
800 math_Vector& TheParameters) const
801{
802 Standard_Integer i, j, Nbp, nbP2d, nbP3d;
803 Standard_Real dist;
804 gp_Pnt P1, P2;
805 gp_Pnt2d P12d, P22d;
806 Nbp = lastP-firstP+1;
807
808
809 if (Nbp == 2) {
810 TheParameters(firstP) = 0.0;
811 TheParameters(lastP) = 1.0;
812 }
813 else if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
814 nbP3d = LineTool::NbP3d(Line);
815 nbP2d = LineTool::NbP2d(Line);
816 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
817 if (nbP3d == 0) mynbP3d = 1;
818 if (nbP2d == 0) mynbP2d = 1;
819
820 TheParameters(firstP) = 0.0;
821 dist = 0.0;
822 TColgp_Array1OfPnt tabP(1, mynbP3d);
823 TColgp_Array1OfPnt tabPP(1, mynbP3d);
824 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
825 TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
826
827 for (i = firstP+1; i <= lastP; i++) {
828 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i-1, tabP, tabP2d);
829 else if (nbP2d != 0) LineTool::Value(Line, i-1, tabP2d);
830 else if (nbP3d != 0) LineTool::Value(Line, i-1, tabP);
831
832 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
833 else if (nbP2d != 0) LineTool::Value(Line, i, tabPP2d);
834 else if (nbP3d != 0) LineTool::Value(Line, i, tabPP);
835 dist = 0;
836 for (j = 1; j <= nbP3d; j++) {
837 P1 = tabP(j);
838 P2 = tabPP(j);
839 dist += P2.Distance(P1);
840 }
841 for (j = 1; j <= nbP2d; j++) {
842 P12d = tabP2d(j);
843 P22d = tabPP2d(j);
844 dist += P22d.Distance(P12d);
845 }
846
847 dist = dist/(nbP3d+nbP2d);
848
849 if(Par == Approx_ChordLength)
850 TheParameters(i) = TheParameters(i-1) + dist;
851 else {// Par == Approx_Centripetal
852 TheParameters(i) = TheParameters(i-1) + Sqrt(dist);
853 }
854 }
855 for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
856 }
857 else {
858 for (i = firstP; i <= lastP; i++) {
859 TheParameters(i) = (Standard_Real(i)-firstP)/
860 (Standard_Real(lastP)-Standard_Real(firstP));
861 }
862 }
863}
864
865
866//=======================================================================
867//function : Compute
868//purpose :
869//=======================================================================
870Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
871 const Standard_Integer fpt,
872 const Standard_Integer lpt,
873 math_Vector& Para,
874 const TColStd_Array1OfReal& Knots,
875 TColStd_Array1OfInteger& Mults)
876{
877 Standard_Integer i, deg, nbpoles, multinter;
878 Standard_Boolean mydone;
879 Standard_Real Fv, TheTol3d, TheTol2d, l1, l2;
880 Standard_Integer nbp = lpt-fpt+1;
881 mylambda1 = 0.0;
882 mylambda2 = 0.0;
883
884 math_Vector aParams(Para.Lower(), Para.Upper());
885
886 for (deg = mydegremin; deg <= mydegremax; deg++) {
887
888 aParams = Para;
889
890 if (!myhasmults) {
891 Mults(Mults.Lower()) = deg+1;
892 Mults(Mults.Upper()) = deg+1;
893 nbpoles = deg+1;
894 if (mycont == -1) multinter = 1;
895 else multinter = Max(1, deg-mycont);
896 for (i = Mults.Lower()+1; i <= Mults.Upper()-1; i++) {
897 Mults(i) = multinter;
898 nbpoles += multinter;
899 }
900 }
901 else {
902 nbpoles = -deg-1;
903 for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
904 nbpoles += Mults.Value(i);
905 }
906 }
907
908 Standard_Integer nbpolestocompare = nbpoles;
909 if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
910 if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
911 if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
912 if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
913 if (nbpolestocompare > nbp) {
914 Interpol(Line);
915 tolreached = Standard_True;
916 return Standard_True;
917 }
918
919 AppParCurves_MultiBSpCurve mySCU(nbpoles);
920
921 if (mysquares) {
922 Approx_BSpParLeastSquareOfMyBSplGradient SQ(Line,Knots,Mults,fpt,lpt,
923 realfirstC, reallastC, aParams, nbpoles);
924 mydone = SQ.IsDone();
925 if(mydone) {
926 mySCU = SQ.BSplineValue();
927 SQ.Error(Fv, TheTol3d, TheTol2d);
928 }
929 else continue;
930 }
931 else {
932 if (nbpoles != deg+1) {
933
934 if (deg == mydegremin && (realfirstC >= AppParCurves_TangencyPoint ||
935 reallastC >= AppParCurves_TangencyPoint)) {
936 Approx_BSpParLeastSquareOfMyBSplGradient
937 thefitt(Line,Knots,Mults, fpt,lpt,realfirstC,reallastC, aParams, nbpoles);
938 mylambda1 = thefitt.FirstLambda()*deg;
939 mylambda2 = thefitt.LastLambda()*deg;
940
941 }
942 l1 = mylambda1/deg;
943 l2 = mylambda2/deg;
944
945 Approx_MyBSplGradient GRAD(Line, fpt, lpt, myConstraints,
946 aParams, Knots, Mults, deg, mytol3d,
947 mytol2d, myitermax, l1, l2);
948
949 mydone = GRAD.IsDone();
950 if(mydone) {
951 mySCU = GRAD.Value();
952 TheTol3d = GRAD.MaxError3d();
953 TheTol2d = GRAD.MaxError2d();
954 }
955 else continue;
956 }
957 else {
958 Approx_MyGradientbis GRAD2(Line, fpt, lpt, myConstraints,
959 aParams, deg, mytol3d,
960 mytol2d, myitermax);
961 mydone = GRAD2.IsDone();
962 if(mydone) {
963 if (GRAD2.Value().NbCurves() == 0)
964 continue;
965 mySCU = AppParCurves_MultiBSpCurve (GRAD2.Value(), Knots, Mults);
966 TheTol3d = GRAD2.MaxError3d();
967 TheTol2d = GRAD2.MaxError2d();
968 }
969 else continue;
970 }
971 }
972 Standard_Boolean save = Standard_True;
973
974 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
975 if (aParams(i) <= -0.000001 || aParams(i) >= 1.000001) {
976 save = Standard_False;
977 break;
978 }
979 }
980
981 if (mydone) {
982 if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
983 // Stockage de la multicurve approximee.
984 tolreached = Standard_True;
985 TheMultiBSpCurve = mySCU;
986 currenttol3d = TheTol3d;
987 currenttol2d = TheTol2d;
988 if (save) {
989 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
990 myParameters->SetValue(i, aParams(i));
991 }
992 }
993 return Standard_True;
994 }
995 }
996
997 if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
998 TheMultiBSpCurve = mySCU;
999 currenttol3d = TheTol3d;
1000 currenttol2d = TheTol2d;
1001 if (save) {
1002 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
1003 myParameters->SetValue(i, aParams(i));
1004 }
1005 }
1006 }
1007
1008 }
1009
1010 return Standard_False;
1011}
1012
1013
1014
1015//=======================================================================
1016//function : SetParameters
1017//purpose :
1018//=======================================================================
1019void Approx_BSplComputeLine::SetParameters(const math_Vector& ThePar)
1020{
1021 myfirstParam = new TColStd_HArray1OfReal(ThePar.Lower(),
1022 ThePar.Upper());
1023 for (Standard_Integer i = ThePar.Lower(); i <= ThePar.Upper(); i++) {
1024 myfirstParam->SetValue(i, ThePar(i));
1025 }
1026}
1027
1028
1029//=======================================================================
1030//function : SetKnots
1031//purpose :
1032//=======================================================================
1033void Approx_BSplComputeLine::SetKnots(const TColStd_Array1OfReal& Knots)
1034{
1035 myhasknots = Standard_True;
1036 myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1037 for (Standard_Integer i = Knots.Lower(); i <= Knots.Upper(); i++) {
1038 myknots->SetValue(i, Knots(i));
1039 }
1040}
1041
1042
1043//=======================================================================
1044//function : SetKnotsAndMultiplicities
1045//purpose :
1046//=======================================================================
1047void Approx_BSplComputeLine::SetKnotsAndMultiplicities
1048 (const TColStd_Array1OfReal& Knots,
1049 const TColStd_Array1OfInteger& Mults)
1050{
1051 myhasknots = Standard_True;
1052 myhasmults = Standard_True;
1053 Standard_Integer i;
1054 myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1055 for (i = Knots.Lower(); i <= Knots.Upper(); i++) {
1056 myknots->SetValue(i, Knots(i));
1057 }
1058 mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
1059 for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
1060 mymults->SetValue(i, Mults(i));
1061 }
1062}
1063
1064//=======================================================================
1065//function : Init
1066//purpose :
1067//=======================================================================
1068void Approx_BSplComputeLine::Init(const Standard_Integer degreemin,
1069 const Standard_Integer degreemax,
1070 const Standard_Real Tolerance3d,
1071 const Standard_Real Tolerance2d,
1072 const Standard_Integer NbIterations,
1073 const Standard_Boolean cutting,
1074 const Approx_ParametrizationType parametrization,
1075 const Standard_Boolean Squares)
1076{
1077 mydegremin = degreemin;
1078 mydegremax = degreemax;
1079 mytol3d = Tolerance3d;
1080 mytol2d = Tolerance2d;
1081 Par = parametrization;
1082 mysquares = Squares;
1083 mycut = cutting;
1084 myitermax = NbIterations;
1085}
1086
1087
1088
1089//=======================================================================
1090//function : SetDegrees
1091//purpose :
1092//=======================================================================
1093void Approx_BSplComputeLine::SetDegrees(const Standard_Integer degreemin,
1094 const Standard_Integer degreemax)
1095{
1096 mydegremin = degreemin;
1097 mydegremax = degreemax;
1098}
1099
1100
1101//=======================================================================
1102//function : SetTolerances
1103//purpose :
1104//=======================================================================
1105void Approx_BSplComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1106 const Standard_Real Tolerance2d)
1107{
1108 mytol3d = Tolerance3d;
1109 mytol2d = Tolerance2d;
1110}
1111
1112
1113//=======================================================================
1114//function : SetConstraints
1115//purpose :
1116//=======================================================================
1117void Approx_BSplComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1118 const AppParCurves_Constraint LastC)
1119{
1120 myfirstC = FirstC;
1121 mylastC = LastC;
1122}
1123
1124
1125
1126//=======================================================================
1127//function : IsAllApproximated
1128//purpose :
1129//=======================================================================
1130Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const
1131{
1132 return alldone;
1133}
1134
1135//=======================================================================
1136//function : IsToleranceReached
1137//purpose :
1138//=======================================================================
1139Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const
1140{
1141 return tolreached;
1142}
1143
1144//=======================================================================
1145//function : Error
1146//purpose :
1147//=======================================================================
1148void Approx_BSplComputeLine::Error(Standard_Real& tol3d,
1149 Standard_Real& tol2d) const
1150{
1151 tol3d = currenttol3d;
1152 tol2d = currenttol2d;
1153}
1154
1155
1156
1157//=======================================================================
1158//function : SetContinuity
1159//purpose :
1160//=======================================================================
1161void Approx_BSplComputeLine::SetContinuity(const Standard_Integer C)
1162{
1163 mycont = C;
1164}
1165
1166
1167
1168//=======================================================================
1169//function : FindRealConstraints
1170//purpose :
1171//=======================================================================
1172void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
1173{
1174 realfirstC = myfirstC;
1175 reallastC = mylastC;
1176 Standard_Integer nbP2d, nbP3d;
1177 nbP3d = LineTool::NbP3d(Line);
1178 nbP2d = LineTool::NbP2d(Line);
1179 Standard_Boolean Ok=Standard_False;
1180 TColgp_Array1OfVec TabV(1, Max(1, nbP3d));
1181 TColgp_Array1OfVec2d TabV2d(1, Max(1, nbP2d));
1182 Standard_Integer Thefirstpt = LineTool::FirstPoint(Line);
1183 Standard_Integer Thelastpt = LineTool::LastPoint(Line);
1184
1185 if (myfirstC >= AppParCurves_TangencyPoint) {
1186
1187 if (nbP3d != 0 && nbP2d != 0)
1188 Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1189 else if (nbP2d != 0)
1190 Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1191 else if (nbP3d != 0)
1192 Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1193
1194 realfirstC = AppParCurves_PassPoint;
1195 if (Ok) {
1196 realfirstC = AppParCurves_TangencyPoint;
1197 if (myfirstC == AppParCurves_CurvaturePoint) {
1198 if (nbP3d != 0 && nbP2d != 0)
1199 Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1200 else if (nbP2d != 0)
1201 Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1202 else if (nbP3d != 0)
1203 Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1204 if (Ok) {
1205 realfirstC = AppParCurves_CurvaturePoint;
1206 }
1207 }
1208 }
1209 }
1210
1211
1212 if (mylastC >= AppParCurves_TangencyPoint) {
1213
1214 if (nbP3d != 0 && nbP2d != 0)
1215 Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1216 else if (nbP2d != 0)
1217 Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1218 else if (nbP3d != 0)
1219 Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1220
1221 reallastC = AppParCurves_PassPoint;
1222 if (Ok) {
1223 reallastC = AppParCurves_TangencyPoint;
1224 if (mylastC == AppParCurves_CurvaturePoint) {
1225 if (nbP3d != 0 && nbP2d != 0)
1226 Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1227 else if (nbP2d != 0)
1228 Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1229 else if (nbP3d != 0)
1230 Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1231 if (Ok) {
1232 reallastC = AppParCurves_CurvaturePoint;
1233 }
1234 }
1235 }
1236 }
1237
1238}
1239
1240
1241
1242
1243//=======================================================================
1244//function : Interpol
1245//purpose :
1246//=======================================================================
1247void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
1248{
1249 Standard_Integer i, Thefirstpt, Thelastpt, deg = 3;
1250 mycont = 2;
1251 Thefirstpt = LineTool::FirstPoint(Line);
1252 Thelastpt = LineTool::LastPoint(Line);
1253 math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
1254 //Par = Approx_ChordLength;
1255 if(myfirstParam.IsNull()) {
1256 Parameters(Line, Thefirstpt, Thelastpt, TheParam);
1257 }
1258 else {
1259 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
1260 TheParam(i+Thefirstpt-1) = myfirstParam->Value(i);
1261 }
1262 }
1263 AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1264 Standard_Real lambda1, lambda2;
1265 Standard_Real Fv;
1266
1267 // Recherche du nombre de noeuds.
1268 Standard_Integer nbknots, nbpoles, nbpoints;
1269 nbpoints = Thelastpt - Thefirstpt + 1;
1270
1271 if (nbpoints == 2) {
1272 Cons = AppParCurves_NoConstraint;
1273 Standard_Integer mydeg = 1;
1274 Approx_BSpParLeastSquareOfMyBSplGradient
1275 LSQ(Line, Thefirstpt, Thelastpt, Cons, Cons, TheParam, mydeg+1);
1276 alldone = LSQ.IsDone();
1277 TColStd_Array1OfReal TheKnots(1, 2);
1278 TColStd_Array1OfInteger TheMults(1, 2);
1279 TheKnots(1) = TheParam(Thefirstpt); TheKnots(2) = TheParam(Thelastpt);
1280 TheMults(1) = TheMults(2) = mydeg+1;
1281 TheMultiBSpCurve =
1282 AppParCurves_MultiBSpCurve (LSQ.BezierValue(),TheKnots,TheMults);
1283 LSQ.Error(Fv, currenttol3d, currenttol2d);
1284
1285 }
1286 else {
1287 nbpoles = nbpoints + 2;
1288 nbknots = nbpoints;
1289
1290 // Resolution:
1291 TColStd_Array1OfReal Theknots(1, nbknots);
1292 Theknots(1) = TheParam(Thefirstpt);
1293 Theknots(nbknots) = TheParam(Thelastpt);
1294 TColStd_Array1OfInteger TheMults(1, nbknots);
1295 TheMults(1) = deg+1;
1296 TheMults(nbknots) = deg+1;
1297
1298 Standard_Integer low = TheParam.Lower();
1299 for (i = 2; i <= nbknots-1; i++) {
1300 Theknots(i) = TheParam(i+low-1);
1301 TheMults(i) = 1;
1302 }
1303
1304
1305 Standard_Integer nbP = 3*LineTool::NbP3d(Line)+ 2*LineTool::NbP2d(Line);
1306 math_Vector V1(1, nbP), V2(1, nbP);
1307
1308 if (nbpoints == 3 || nbpoints == 4) {
1309 FirstTangencyVector(Line, Thefirstpt, V1);
1310 lambda1 = SearchFirstLambda(Line, TheParam, Theknots, V1, Thefirstpt);
1311
1312 LastTangencyVector(Line, Thelastpt, V2);
1313 lambda2 = SearchLastLambda(Line, TheParam, Theknots, V2, Thelastpt);
1314 }
1315
1316 else {
1317 Standard_Integer nnpol, nnp = Min(nbpoints, 9);
1318 nnpol = nnp;
1319 Standard_Integer lastp = Min(Thelastpt, Thefirstpt + nnp-1);
1320 Standard_Real U;
1321 Approx_BSpParLeastSquareOfMyBSplGradient
1322 SQ1(Line, Thefirstpt, lastp, Cons, Cons, nnpol);
1323
1324 math_Vector P1(Thefirstpt, lastp);
1325 for (i=Thefirstpt; i <=lastp; i++) P1(i) = TheParam(i);
1326 SQ1.Perform(P1);
1327 const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
1328 U = 0.0;
1329 TangencyVector(Line, C1, U, V1);
1330
1331 Standard_Integer firstp = Max(Thefirstpt, Thelastpt - nnp+1);
1332
1333
1334 if (firstp == Thefirstpt && lastp == Thelastpt) {
1335 U = 1.0;
1336 TangencyVector (Line, C1, U, V2);
1337 }
1338 else {
1339 Approx_BSpParLeastSquareOfMyBSplGradient
1340 SQ2(Line, firstp, Thelastpt, Cons, Cons, nnpol);
1341
1342 math_Vector P2(firstp, Thelastpt);
1343 for (i=firstp; i <=Thelastpt; i++) P2(i) = TheParam(i);
1344 SQ2.Perform(P2);
1345 const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
1346 U = 1.0;
1347 TangencyVector(Line, C2, U, V2);
1348 }
1349
1350
1351 lambda1 = 1./deg;
1352 lambda1 = lambda1*(Theknots(2)-Theknots(1))
1353 /(Theknots(nbknots)-Theknots(1));
1354 lambda2 = 1./deg;
1355 lambda2 = lambda2*(Theknots(nbknots)-Theknots(nbknots-1))
1356 /(Theknots(nbknots)-Theknots(1));
1357
1358 }
1359
1360 Approx_BSpParLeastSquareOfMyBSplGradient
1361 SQ(Line, Theknots,TheMults,Thefirstpt, Thelastpt,
1362 Cons, Cons, nbpoles);
1363
1364 lambda1 = lambda1/deg;
1365 lambda2 = lambda2/deg;
1366 SQ.Perform(TheParam, V1, V2, lambda1, lambda2);
1367 alldone = SQ.IsDone();
1368 TheMultiBSpCurve = SQ.BSplineValue();
1369 SQ.Error(Fv, currenttol3d, currenttol2d);
1370 tolreached = Standard_True;
1371 }
1372 myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
1373 for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
1374 myParameters->SetValue(i, TheParam(i));
1375 }
1376}
1377
1378
1379//=======================================================================
1380//function : TangencyVector
1381//purpose :
1382//=======================================================================
1383void Approx_BSplComputeLine::TangencyVector(
1384 const MultiLine& Line,
1385 const AppParCurves_MultiCurve& C,
1386 const Standard_Real U,
1387 math_Vector& V) const
1388{
1389
1390 Standard_Integer i, j, nbP2d, nbP3d;
1391 nbP3d = LineTool::NbP3d(Line);
1392 nbP2d = LineTool::NbP2d(Line);
1393
1394 gp_Pnt myP;
1395 gp_Vec myV;
1396 gp_Pnt2d myP2d;
1397 gp_Vec2d myV2d;
1398 j = 1;
1399 for (i = 1; i <= nbP3d; i++) {
1400 C.D1(i, U, myP, myV);
1401 V(j) = myV.X();
1402 V(j+1) = myV.Y();
1403 V(j+2) = myV.Z();
1404 j += 3;
1405 }
1406 j = nbP3d*3+1;
1407 for (i = nbP3d+1; i <= nbP3d+nbP2d; i++) {
1408 C.D1(i, U, myP2d, myV2d);
1409 V(j) = myV2d.X();
1410 V(j+1) = myV2d.Y();
1411 j += 2;
1412 }
1413
1414}
1415