Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AppParCurves / AppParCurves_LinearCriteria.gxx
CommitLineData
7fd59977 1// File: AppParCurves_LinearCriteria.gxx
2// Created: Mon Nov 30 14:58:05 1998
3// Author: Igor FEOKTISTOV
4// <ifv@paradox.nnov.matra-dtv.fr>
5
6#include <PLib_Base.hxx>
7#include <PLib_JacobiPolynomial.hxx>
8#include <PLib_HermitJacobi.hxx>
9#include <GeomAbs_Shape.hxx>
10#include <TColStd_HArray2OfReal.hxx>
11#include <FEmTool_LinearTension.hxx>
12#include <FEmTool_LinearFlexion.hxx>
13#include <FEmTool_LinearJerk.hxx>
14#include <TColgp_Array1OfPnt.hxx>
15#include <TColgp_Array1OfPnt2d.hxx>
16#include <gp_Pnt2d.hxx>
17#include <gp_Pnt.hxx>
18#include <math_Matrix.hxx>
19#include <math_Gauss.hxx>
20
21static Standard_Integer order(const Handle(PLib_Base)& B)
22{
23 return (*( Handle(PLib_HermitJacobi)*)&B)->NivConstr();
24}
25
26
27//=======================================================================
28//function :
29//purpose :
30//=======================================================================
31AppParCurves_LinearCriteria::AppParCurves_LinearCriteria(const MultiLine& SSP,
32 const Standard_Integer FirstPoint,
33 const Standard_Integer LastPoint):
34 mySSP(SSP),
35 myPntWeight(FirstPoint, LastPoint),
36 myE(0)
37{
38 myPntWeight.Init(1.);
39}
40
41
42//=======================================================================
43//function :
44//purpose :
45//=======================================================================
46
47void AppParCurves_LinearCriteria::SetParameters(const Handle(TColStd_HArray1OfReal)& Parameters)
48{
49 myParameters = Parameters;
50 myE = 0; // Cache become invalid.
51}
52
53
54
55//=======================================================================
56//function : SetCurve
57//purpose :
58//=======================================================================
59
60void AppParCurves_LinearCriteria::SetCurve(const Handle(FEmTool_Curve)& C)
61{
62
63 if(myCurve.IsNull()) {
64 myCurve = C;
65
66 Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
67 NbDim = myCurve->Dimension(),
68 Order = order(myCurve->Base());
69
70 GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
71 switch (Order) {
72 case 0 : ConstraintOrder = GeomAbs_C0;
73 break;
74 case 1 : ConstraintOrder = GeomAbs_C1;
75 break;
76 case 2 : ConstraintOrder = GeomAbs_C2;
77 }
78
79 myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
80 myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
81 myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
82
83 Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
84
85 myCriteria[0]->Set(Coeff);
86 myCriteria[1]->Set(Coeff);
87 myCriteria[2]->Set(Coeff);
88 }
89 else if (myCurve != C) {
90
91 Standard_Integer OldMxDeg = myCurve->Base()->WorkDegree(),
92 OldNbDim = myCurve->Dimension(),
93 OldOrder = order(myCurve->Base());
94
95 myCurve = C;
96
97 Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
98 NbDim = myCurve->Dimension(),
99 Order = order(myCurve->Base());
100
101 if(MxDeg != OldMxDeg || Order != OldOrder) {
102
103 GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
104 switch (Order) {
105 case 0 : ConstraintOrder = GeomAbs_C0;
106 break;
107 case 1 : ConstraintOrder = GeomAbs_C1;
108 break;
109 case 2 : ConstraintOrder = GeomAbs_C2;
110 }
111
112 myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
113 myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
114 myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
115
116 Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
117
118 myCriteria[0]->Set(Coeff);
119 myCriteria[1]->Set(Coeff);
120 myCriteria[2]->Set(Coeff);
121 }
122 else if(NbDim != OldNbDim) {
123
124 Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
125
126 myCriteria[0]->Set(Coeff);
127 myCriteria[1]->Set(Coeff);
128 myCriteria[2]->Set(Coeff);
129 }
130 }
131}
132
133
134
135//=======================================================================
136//function : GetCurve
137//purpose :
138//=======================================================================
139void AppParCurves_LinearCriteria::GetCurve(Handle(FEmTool_Curve)& C) const
140{
141 C = myCurve;
142}
143
144
145//=======================================================================
146//function : SetEstimation
147//purpose :
148//=======================================================================
149void AppParCurves_LinearCriteria::SetEstimation(const Standard_Real E1,
150 const Standard_Real E2,
151 const Standard_Real E3)
152{
153 myEstimation[0] = E1;
154 myEstimation[1] = E2;
155 myEstimation[2] = E3;
156}
157
158Standard_Real& AppParCurves_LinearCriteria::EstLength()
159{
160 return myLength;
161}
162
163
164//=======================================================================
165//function : GetEstimation
166//purpose :
167//=======================================================================
168void AppParCurves_LinearCriteria::GetEstimation(Standard_Real& E1,
169 Standard_Real& E2,
170 Standard_Real& E3) const
171{
172 E1 = myEstimation[0];
173 E2 = myEstimation[1];
174 E3 = myEstimation[2];
175}
176
177
178
179//=======================================================================
180//function : AssemblyTable
181//purpose :
182//=======================================================================
183Handle(FEmTool_HAssemblyTable) AppParCurves_LinearCriteria::AssemblyTable() const
184{
185 if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::AssemblyTable");
186
187 Standard_Integer NbDim = myCurve->Dimension(),
188 NbElm = myCurve->NbElements(),
189 nc1 = order(myCurve->Base()) + 1;
190 Standard_Integer MxDeg = myCurve->Base()->WorkDegree() ;
191
192 Handle(FEmTool_HAssemblyTable) AssTable = new FEmTool_HAssemblyTable(1, NbDim, 1, NbElm);
193
194 Handle(TColStd_HArray1OfInteger) GlobIndex, Aux;
195
196 Standard_Integer i, el = 1, dim = 1, NbGlobVar = 0, gi0;
197
198 // For dim = 1
199 // For first element (el = 1)
200 GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
201
202 for(i = 0; i < nc1; i++) {
203 NbGlobVar++;
204 GlobIndex->SetValue(i, NbGlobVar);
205 }
206 gi0 = MxDeg - 2 * nc1 + 1;
207 for(i = nc1; i < 2*nc1; i++) {
208 NbGlobVar++;
209 GlobIndex->SetValue(i, NbGlobVar + gi0);
210 }
211 for(i = 2*nc1; i <= MxDeg; i++) {
212 NbGlobVar++;
213 GlobIndex->SetValue(i, NbGlobVar - nc1);
214 }
215 gi0 = NbGlobVar - nc1 + 1;
216 AssTable->SetValue(dim, el, GlobIndex);
217
218 // For rest elements
219 for(el = 2; el <= NbElm; el++) {
220 GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
221 for(i = 0; i < nc1; i++) GlobIndex->SetValue(i, gi0 + i);
222
223 gi0 = MxDeg - 2 * nc1 + 1;
224 for(i = nc1; i < 2*nc1; i++) {
225 NbGlobVar++;
226 GlobIndex->SetValue(i, NbGlobVar + gi0);
227 }
228 for(i = 2*nc1; i <= MxDeg; i++) {
229 NbGlobVar++;
230 GlobIndex->SetValue(i, NbGlobVar - nc1);
231 }
232 gi0 = NbGlobVar - nc1 + 1;
233 AssTable->SetValue(dim, el, GlobIndex);
234 }
235
236 // For other dimensions
237 gi0 = NbGlobVar;
238 for(dim = 2; dim <= NbDim; dim++) {
239 for(el = 1; el <= NbElm; el++) {
240 Aux = AssTable->Value(1, el);
241 GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
242 for(i = 0; i <= MxDeg; i++) GlobIndex->SetValue(i, Aux->Value(i) + NbGlobVar);
243 AssTable->SetValue(dim, el, GlobIndex);
244 }
245 NbGlobVar += gi0;
246 }
247
248 return AssTable;
249}
250
251
252
253
254//=======================================================================
255//function :
256//purpose :
257//=======================================================================
258Handle(TColStd_HArray2OfInteger) AppParCurves_LinearCriteria::DependenceTable() const
259{
260 if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::DependenceTable");
261
262 Standard_Integer Dim = myCurve->Dimension();
263
264 Handle(TColStd_HArray2OfInteger) DepTab =
265 new TColStd_HArray2OfInteger(1, Dim, 1, Dim, 0);
266 Standard_Integer i;
267 for(i=1; i <= Dim; i++) DepTab->SetValue(i,i,1);
268
269 return DepTab;
270}
271
272
273//=======================================================================
274//function : QualityValues
275//purpose :
276//=======================================================================
277
278Standard_Integer AppParCurves_LinearCriteria::QualityValues(const Standard_Real J1min,
279 const Standard_Real J2min,
280 const Standard_Real J3min,
281 Standard_Real& J1,
282 Standard_Real& J2,
283 Standard_Real& J3)
284{
285 if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::QualityValues");
286
287 Standard_Integer NbDim = myCurve->Dimension(),
288 NbElm = myCurve->NbElements();
289
290 TColStd_Array1OfReal& Knots = myCurve->Knots();
291 Handle(TColStd_HArray2OfReal) Coeff;
292
293 Standard_Integer el, deg = 0, curdeg, i;
294 Standard_Real UFirst, ULast;
295
296 J1 = J2 = J3 = 0.;
297 for(el = 1; el <= NbElm; el++) {
298
299 curdeg = myCurve->Degree(el);
300 if(deg != curdeg) {
301 deg = curdeg;
302 Coeff = new TColStd_HArray2OfReal(0, deg, 1, NbDim);
303 }
304
305 myCurve->GetElement(el, Coeff->ChangeArray2());
306
307 UFirst = Knots(el); ULast = Knots(el + 1);
308
309 myCriteria[0]->Set(Coeff);
310 myCriteria[0]->Set(UFirst, ULast);
311 J1 = J1 + myCriteria[0]->Value();
312
313 myCriteria[1]->Set(Coeff);
314 myCriteria[1]->Set(UFirst, ULast);
315 J2 = J2 + myCriteria[1]->Value();
316
317 myCriteria[2]->Set(Coeff);
318 myCriteria[2]->Set(UFirst, ULast);
319 J3 = J3 + myCriteria[2]->Value();
320
321 }
322
323// Calculation of ICDANA - see MOTEST.f
324// Standard_Real JEsMin[3] = {.01, .001, .001}; // from MOTLIS.f
325 Standard_Real JEsMin[3]; JEsMin[0] = J1min; JEsMin[1] = J2min; JEsMin[2] = J3min;
326 Standard_Real ValCri[3]; ValCri[0] = J1; ValCri[1] = J2; ValCri[2] = J3;
327
328 Standard_Integer ICDANA = 0;
329
330// (2) Test l'amelioration des estimations
331// (critere sureleve => Non minimisation )
332
333 for(i = 0; i <= 2; i++)
334 if((ValCri[i] < 0.8 * myEstimation[i]) && (myEstimation[i] > JEsMin[i])) {
335 if(ICDANA < 1) ICDANA = 1;
336 if(ValCri[i] < 0.1 * myEstimation[i]) ICDANA = 2;
337 myEstimation[i] = Max(1.05*ValCri[i], JEsMin[i]);
338 }
339
340
341// (3) Mise a jours des Estimation
342// (critere sous-estimer => mauvais conditionement)
343
344 if (ValCri[0] > myEstimation[0] * 2) {
345 myEstimation[0] += ValCri[0] * .1;
346 if (ICDANA == 0) {
347 if (ValCri[0] > myEstimation[0] * 10) {
348 ICDANA = 2;
349 }
350 else ICDANA = 1;
351 }
352 else {
353 ICDANA = 2;
354 }
355 }
356 if (ValCri[1] > myEstimation[1] * 20) {
357 myEstimation[1] += ValCri[1] * .1;
358 if (ICDANA == 0) {
359 if (ValCri[1] > myEstimation[1] * 100) {
360 ICDANA = 2;
361 }
362 else ICDANA = 1;
363 }
364 else {
365 ICDANA = 2;
366 }
367 }
368 if (ValCri[2] > myEstimation[2] * 20) {
369 myEstimation[2] += ValCri[2] * .05;
370 if (ICDANA == 0) {
371 if (ValCri[2] > myEstimation[2] * 100) {
372 ICDANA = 2;
373 }
374 else ICDANA = 1;
375 }
376 else {
377 ICDANA = 2;
378 }
379 }
380
381
382 return ICDANA;
383}
384
385
386//=======================================================================
387//function : ErrorValues
388//purpose :
389//=======================================================================
390
391void AppParCurves_LinearCriteria::ErrorValues(Standard_Real& MaxError,
392 Standard_Real& QuadraticError,
393 Standard_Real& AverageError)
394{
395 if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
396
397 Standard_Integer NbDim = myCurve->Dimension();
398
399 Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
400
401 if(NbDim != (2*myNbP2d + 3*myNbP3d)) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
402
403 TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
404 TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
405 TColStd_Array1OfReal BasePoint(1,NbDim);
406 gp_Pnt2d P2d;
407 gp_Pnt P3d;
408
409 Standard_Integer i, ipnt, c0 = 0;
410 Standard_Real SqrDist, Dist;
411
412 MaxError = QuadraticError = AverageError = 0.;
413
414 for(i = myParameters->Lower(); i <= myParameters->Upper(); i++) {
415
416 myCurve->D0(myParameters->Value(i), BasePoint);
417
418
419 c0 = 0;
420 ToolLine::Value(mySSP, i, TabP3d);
421 for(ipnt = 1; ipnt <= myNbP3d; ipnt++) {
422 P3d.SetCoord(BasePoint(c0+1), BasePoint(c0+2), BasePoint(c0+3));
423 SqrDist = P3d.SquareDistance(TabP3d(ipnt)); Dist = Sqrt(SqrDist);
424 MaxError = Max(MaxError, Dist);
425 QuadraticError += SqrDist;
426 AverageError += Dist;
427 c0 += 3;
428 }
429
430 if(myNbP3d == 0) ToolLine::Value(mySSP, i, TabP2d);
431 else ToolLine::Value(mySSP, i, TabP3d, TabP2d);
432 for(ipnt = 1; ipnt <= myNbP2d; ipnt++) {
433 P2d.SetCoord(BasePoint(c0+1), BasePoint(c0+2));
434 SqrDist = P2d.SquareDistance(TabP2d(ipnt)); Dist = Sqrt(SqrDist);
435 MaxError = Max(MaxError, Dist);
436 QuadraticError += SqrDist;
437 AverageError += Dist;
438 c0 += 2;
439 }
440 }
441}
442
443
444//=======================================================================
445//function : Hessian
446//purpose :
447//=======================================================================
448
449void AppParCurves_LinearCriteria::Hessian(const Standard_Integer Element,
450 const Standard_Integer Dimension1,
451 const Standard_Integer Dimension2,
452 math_Matrix& H)
453{
454 if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
455
456 if(DependenceTable()->Value(Dimension1, Dimension2) == 0)
457 Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
458
459 Standard_Integer //NbDim = myCurve->Dimension(),
460 MxDeg = myCurve->Base()->WorkDegree(),
461// Deg = myCurve->Degree(Element),
462 Order = order(myCurve->Base());
463
464
465 math_Matrix AuxH(0, H.RowNumber()-1, 0, H.ColNumber()-1, 0.);
466
467 TColStd_Array1OfReal& Knots = myCurve->Knots();
468 Standard_Real UFirst, ULast;
469
470 UFirst = Knots(Element); ULast = Knots(Element + 1);
471
472 Standard_Integer icrit;
473
474 // Quality criterion part of Hessian
475
476 H.Init(0);
477
478 for(icrit = 0; icrit <= 2; icrit++) {
479 myCriteria[icrit]->Set(UFirst, ULast);
480 myCriteria[icrit]->Hessian(Dimension1, Dimension2, AuxH);
481 H += (myQualityWeight*myPercent[icrit]/myEstimation[icrit]) * AuxH;
482 }
483
484 // Least square part of Hessian
485
486 AuxH.Init(0.);
487
488 Standard_Real coeff = (ULast - UFirst)/2., curcoeff, poid;
489 Standard_Integer ipnt, ii, degH = 2 * Order+1;
490
491
492 Handle(PLib_Base) myBase = myCurve->Base();
493 Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1,
494 di = myPntWeight.Lower() - myParameters->Lower();
495
496 //BuilCache
497 if (myE != Element) BuildCache(Element);
498
499 // Compute the least square Hessian
500 for(ii=1, ipnt = IF; ipnt <= IL; ipnt++, ii+=(MxDeg+1)) {
501 poid = myPntWeight(di + ipnt) * 2.;
502 const Standard_Real * BV = &myCache->Value(ii);
503
504 // Hermite*Hermite part of matrix
505 for(i = 0; i <= degH; i++) {
506 k1 = (i <= Order)? i : i - Order - 1;
507 curcoeff = Pow(coeff, k1) * poid * BV[i];
508
509 // Hermite*Hermite part of matrix
510 for(j = i; j <= degH; j++) {
511 k2 = (j <= Order)? j : j - Order - 1;
512 AuxH(i, j) += curcoeff * Pow(coeff, k2) * BV[j];
513 }
514 // Hermite*Jacobi part of matrix
515 for(j = degH + 1; j <= MxDeg; j++) {
516 AuxH(i, j) += curcoeff * BV[j];
517 }
518 }
519
520 // Jacoby*Jacobi part of matrix
521 for(i = degH+1; i <= MxDeg; i++) {
522 curcoeff = BV[i] * poid;
523 for(j = i; j <= MxDeg; j++) {
524 AuxH(i, j) += curcoeff * BV[j];
525 }
526 }
527 }
528
529 i1 = i0;
530 for(i = 0; i <= MxDeg; i++) {
531 j1 = j0 + i;
532 for(j = i; j <= MxDeg; j++) {
533 H(i1, j1) += myQuadraticWeight * AuxH(i, j);
534 H(j1, i1) = H(i1, j1);
535 j1++;
536 }
537 i1++;
538 }
539
540}
541
542//=======================================================================
543//function : Gradient
544//purpose :
545//=======================================================================
546void AppParCurves_LinearCriteria::Gradient(const Standard_Integer Element,
547 const Standard_Integer Dimension,
548 math_Vector& G)
549{
550 if(myCurve.IsNull())
551 Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
552
553 Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
554
555 if(Dimension > (2*myNbP2d + 3*myNbP3d))
556 Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
557
558 TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
559 TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
560
561 Standard_Boolean In3d;
562 Standard_Integer IndPnt, IndCrd;
563
564 if(Dimension <= 3*myNbP3d) {
565 In3d = Standard_True;
566 IndCrd = Dimension % 3;
567 IndPnt = Dimension / 3;
568 if(IndCrd == 0) IndCrd = 3;
569 else IndPnt++;
570 }
571 else {
572 In3d = Standard_False;
573 IndCrd = (Dimension - 3*myNbP3d) % 2;
574 IndPnt = (Dimension - 3*myNbP3d) / 2;
575 if(IndCrd == 0) IndCrd = 2;
576 else IndPnt++;
577 }
578
579 TColStd_Array1OfReal& Knots = myCurve->Knots();
580 Standard_Real UFirst, ULast, Pnt;
581 UFirst = Knots(Element); ULast = Knots(Element + 1);
582 Standard_Real coeff = (ULast-UFirst)/2;
583
584 Standard_Integer //Deg = myCurve->Degree(Element),
585 Order = order(myCurve->Base());
586
587 Handle(PLib_Base) myBase = myCurve->Base();
588 Standard_Integer MxDeg = myBase->WorkDegree();
589
590 Standard_Real curcoeff;
591 Standard_Integer degH = 2 * Order + 1;
592 Standard_Integer ipnt, k, i, ii, i0 = G.Lower(),
593 di = myPntWeight.Lower() - myParameters->Lower();
594
595 if (myE != Element) BuildCache(Element);
596 const Standard_Real * BV = &myCache->Value(1);
597 BV--;
598
599 G.Init(0.);
600
601 for(ii=1,ipnt = IF; ipnt <= IL; ipnt++) {
602 if(In3d) {
603 ToolLine::Value(mySSP, ipnt, TabP3d);
604 Pnt = TabP3d(IndPnt).Coord(IndCrd);
605 }
606 else {
607 if(myNbP3d == 0) ToolLine::Value(mySSP, ipnt, TabP2d);
608 else ToolLine::Value(mySSP, ipnt, TabP3d, TabP2d);
609 Pnt = TabP2d(IndPnt).Coord(IndCrd);
610 }
611
612 curcoeff = Pnt * myPntWeight(di + ipnt);
613 for(i = 0; i <= MxDeg; i++,ii++)
614 G(i0 + i) += BV[ii] * curcoeff;
615 }
616
617
618 G *= 2. * myQuadraticWeight;
619
620 for(i = 0; i <= degH; i++) {
621 k = (i <= Order)? i : i - Order - 1;
622 curcoeff = Pow(coeff, k);
623 G(i0 + i) *= curcoeff;
624 }
625}
626
627
628//=======================================================================
629//function : InputVector
630//purpose :
631//=======================================================================
632void AppParCurves_LinearCriteria::InputVector(const math_Vector& X,
633 const Handle(FEmTool_HAssemblyTable)& AssTable)
634{
635 Standard_Integer NbDim = myCurve->Dimension(),
636 NbElm = myCurve->NbElements() ;
637 Standard_Integer MxDeg = 0 ;
638 MxDeg = myCurve->Base()->WorkDegree();
639 TColStd_Array2OfReal CoeffEl(0, MxDeg, 1, NbDim);
640
641
642 Handle(TColStd_HArray1OfInteger) GlobIndex;
643
644 Standard_Integer el, dim, i, i0 = X.Lower() - 1;
645
646 for(el = 1; el <= NbElm; el++) {
647 for(dim = 1; dim <= NbDim; dim++) {
648 GlobIndex = AssTable->Value(dim, el);
649 for(i = 0; i <= MxDeg; i++) CoeffEl(i, dim) = X(i0 + GlobIndex->Value(i));
650 }
651 myCurve->SetDegree(el, MxDeg);
652 myCurve->SetElement(el, CoeffEl);
653 }
654}
655
656
657//=======================================================================
658//function : SetWeight
659//purpose :
660//=======================================================================
661void AppParCurves_LinearCriteria::SetWeight(const Standard_Real QuadraticWeight,
662 const Standard_Real QualityWeight,
663 const Standard_Real percentJ1,
664 const Standard_Real percentJ2,
665 const Standard_Real percentJ3)
666{
667 if (QuadraticWeight < 0. || QualityWeight < 0.)
668 Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
669 if (percentJ1 < 0. || percentJ2 < 0. || percentJ3 < 0.)
670 Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
671
672 myQuadraticWeight = QuadraticWeight; myQualityWeight = QualityWeight;
673
674 Standard_Real Total = percentJ1 + percentJ2 + percentJ3;
675 myPercent[0] = percentJ1 / Total;
676 myPercent[1] = percentJ2 / Total;
677 myPercent[2] = percentJ3 / Total;
678}
679
680
681//=======================================================================
682//function : GetWeight
683//purpose :
684//=======================================================================
685void AppParCurves_LinearCriteria::GetWeight(Standard_Real& QuadraticWeight,
686 Standard_Real& QualityWeight) const
687{
688
689 QuadraticWeight = myQuadraticWeight; QualityWeight = myQualityWeight;
690
691}
692
693//=======================================================================
694//function : SetWeight
695//purpose :
696//=======================================================================
697void AppParCurves_LinearCriteria::SetWeight(const TColStd_Array1OfReal& Weight)
698{
699 myPntWeight = Weight;
700}
701
702
703//=======================================================================
704//function : BuildCache
705//purpose :
706//=======================================================================
707void AppParCurves_LinearCriteria::BuildCache(const Standard_Integer Element)
708{
709 Standard_Real t;
710 Standard_Real UFirst, ULast;
711 Standard_Integer ipnt;
712
713 UFirst = myCurve->Knots()(Element);
714 ULast = myCurve->Knots()(Element + 1);
715
716 IF = 0;
717 for(ipnt = myParameters->Lower(); ipnt <= myParameters->Upper(); ipnt++) {
718 t = myParameters->Value(ipnt);
719 if((t > UFirst && t <= ULast) || (Element == 1 && t == UFirst)) {
720 if (IF == 0) IF=ipnt;
721 IL = ipnt;
722 }
723 else if (t>ULast) break;
724 }
725
726 if (IF != 0) {
727 Handle(PLib_Base) myBase = myCurve->Base();
728 Standard_Integer order = myBase->WorkDegree()+1, ii;
729 myCache = new TColStd_HArray1OfReal (1, (IL-IF+1)*(order));
730
731 ii =1;
732 for(ipnt = IF, ii=1; ipnt <= IL; ipnt++, ii+=order) {
733 Standard_Real * cache = &myCache->ChangeValue(ii);
734 TColStd_Array1OfReal BasicValue(cache[0], 0, order-1);
735 t = myParameters->Value(ipnt);
736 Standard_Real coeff = 2./(ULast - UFirst), c0 = -(ULast + UFirst)/2., s;
737 s = (t + c0) * coeff;
738 myBase->D0(s, BasicValue);
739 }
740 }
741 else { //pas de points dans l'interval.
742 IF = IL;
743 IL--;
744 }
745 myE = Element;
746}