0022627: Change OCCT memory management defaults
[occt.git] / src / AppParCurves / AppParCurves_Projection.gxx
CommitLineData
7fd59977 1// File AppParCurves_Projection.gxx
2// lpa, le 11/09/91
3
4
5
6#define No_Standard_RangeError
7#define No_Standard_OutOfRange
8
9#include <AppParCurves_Constraint.hxx>
10#include <StdFail_NotDone.hxx>
11#include <AppParCurves_MultiPoint.hxx>
12#include <gp_Pnt.hxx>
13#include <gp_Pnt2d.hxx>
14#include <gp_Vec.hxx>
15#include <gp_Vec2d.hxx>
16#include <TColgp_Array1OfPnt.hxx>
17#include <TColgp_Array1OfPnt2d.hxx>
18#include <TColgp_Array1OfVec.hxx>
19#include <TColgp_Array1OfVec2d.hxx>
20#include <PLib.hxx>
21#include <BSplCLib.hxx>
22
23
24
25
26
27AppParCurves_Projection::
28 AppParCurves_Projection(const MultiLine& SSP,
29 const Standard_Integer FirstPoint,
30 const Standard_Integer LastPoint,
31 const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
32 math_Vector& Parameters,
33 const Standard_Integer Deg,
34 const Standard_Real Tol3d,
35 const Standard_Real Tol2d,
36 const Standard_Integer NbIterations):
37 ParError(FirstPoint, LastPoint,0.0) {
38
39 Standard_Boolean grad = Standard_True;
40 Standard_Integer i, j, k, i2, l;
41 Standard_Real UF, DU, Fval = 0.0, FU, DFU;
42 Standard_Real MErr3d=0.0, MErr2d=0.0,
43 Gain3d = Tol3d, Gain2d=Tol2d;
44 Standard_Real EC, ECmax = 1.e10, Errsov3d, Errsov2d;
45 Standard_Integer nbP3d = ToolLine::NbP3d(SSP);
46 Standard_Integer nbP2d = ToolLine::NbP2d(SSP);
47 Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
48 Standard_Integer nbP = nbP3d + nbP2d;
49 gp_Pnt Pt, P1, P2;
50 gp_Pnt2d Pt2d, P12d, P22d;
51 gp_Vec V1, V2, MyV;
52 gp_Vec2d V12d, V22d, MyV2d;
53
54 if (nbP3d == 0) mynbP3d = 1;
55 if (nbP2d == 0) mynbP2d = 1;
56 TColgp_Array1OfPnt TabP(1, mynbP3d);
57 TColgp_Array1OfPnt2d TabP2d(1, mynbP2d);
58 TColgp_Array1OfVec TabV(1, mynbP3d);
59 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
60
61 // Calcul de la fonction F= somme(||C(ui)-Ptli||2):
62 // Appel a une fonction heritant de MultipleVarFunctionWithGradient
63 // pour calculer F et grad_F.
64 // ================================================================
65
66 AppParCurves_ProFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg);
67
68
69 ECmax = 0.0;
70 // Projection:
71 // ===========
72 MyF.Value(Parameters, Fval);
73 SCU = MyF.CurveValue();
74 Standard_Integer deg = SCU.Degree();
75 TColgp_Array1OfPnt TabPole(1, deg+1), TabCoef(1, deg+1);
76 TColgp_Array1OfPnt2d TabPole2d(1, deg+1), TabCoef2d(1, deg+1);
77 TColgp_Array1OfPnt TheCoef(1, (deg+1)*mynbP3d);
78 TColgp_Array1OfPnt2d TheCoef2d(1, (deg+1)*mynbP2d);
79
80
81 for (i = 1; i <= NbIterations; i++) {
82
83 // Stockage des Poles des courbes:
84 // ===============================
85 i2 = 0;
86 for (k = 1; k <= nbP3d; k++) {
87 SCU.Curve(k, TabPole);
88 BSplCLib::PolesCoefficients(TabPole, PLib::NoWeights(),
89 TabCoef, PLib::NoWeights());
90 for (j=1; j<=deg+1; j++) TheCoef(j+i2) = TabCoef(j);
91 i2 += deg+1;
92 }
93 i2 = 0;
94 for (k = 1; k <= nbP2d; k++) {
95 SCU.Curve(nbP3d+k, TabPole2d);
96 BSplCLib::PolesCoefficients(TabPole2d, PLib::NoWeights(),
97 TabCoef2d, PLib::NoWeights());
98 for (j=1; j<=deg+1; j++) TheCoef2d(j+i2) = TabCoef2d(j);
99 i2 += deg+1;
100 }
101 for (j = FirstPoint+1; j <= LastPoint-1; j++) {
102 UF = Parameters(j);
103 if (nbP != 0 && nbP2d != 0) ToolLine::Value(SSP, j, TabP, TabP2d);
104 else if (nbP2d != 0) ToolLine::Value(SSP, j, TabP2d);
105 else ToolLine::Value(SSP, j, TabP);
106
107 FU = 0.0;
108 DFU = 0.0;
109 i2 = 0;
110 for (k = 1; k <= nbP3d; k++) {
111 for (l=1; l<=deg+1; l++) TabCoef(l) = TheCoef(l+i2);
112 i2 += deg+1;
113 BSplCLib::CoefsD2(UF, TabCoef, PLib::NoWeights(), Pt, V1, V2);
114 MyV = gp_Vec(Pt, TabP(k));
115 FU += MyV*V1;
116 DFU += V1.SquareMagnitude() + MyV*V2;
117 }
118 i2 = 0;
119 for (k = 1; k <= nbP2d; k++) {
120 for (l=1; l<=deg+1; l++) TabCoef2d(l) = TheCoef2d(l+i2);
121 i2 += deg+1;
122 BSplCLib::CoefsD2(UF, TabCoef2d, PLib::NoWeights(), Pt2d, V12d, V22d);
123 MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
124 FU += MyV2d*V12d;
125 DFU += V12d.SquareMagnitude() + MyV2d*V22d;
126 }
127
128 if (DFU <= RealEpsilon()) {
129 // Verification du parametrage:
130 EC = Abs(Parameters(j) - UF);
131 if (EC > ECmax) ECmax = EC;
132 break;
133 }
134
135 DU = -FU/DFU;
136 DU = Sign(Min(5.e-02, Abs(DU)), DU);
137 UF += DU;
138 Parameters(j) = UF;
139 }
140
141 // Test de progression:
142 // ====================
143 Errsov3d = MErr3d;
144 Errsov2d = MErr2d;
145
146 MyF.Value(Parameters, Fval);
147 SCU = MyF.CurveValue();
148 MErr3d = MyF.MaxError3d();
149 MErr2d = MyF.MaxError2d();
150
151 if (MErr3d< Tol3d && MErr2d < Tol2d) {
152 Done = Standard_True;
153 break;
154 }
155 if (MErr3d > 100.0*Tol3d || MErr2d > 100.0*Tol2d) {
156 Done = Standard_False;
157 grad = Standard_False;
158 break;
159 }
160 if (i >= 2) {
161 Gain3d = Abs(Errsov3d-MErr3d);
162 Gain2d = Abs(Errsov2d-MErr2d);
163 if ((MErr3d-Gain3d*(NbIterations-i)*0.5) > Tol3d ||
164 (MErr2d-Gain2d*(NbIterations-i)*0.5) > Tol2d) {
165 if (Gain3d < Tol3d/(2*NbIterations) &&
166 Gain2d < Tol2d/(2*NbIterations)) {
167 break;
168 }
169 }
170 }
171
172 }
173
174
175
176 AvError = 0.;
177 for (j = FirstPoint; j <= LastPoint; j++) {
178 // Recherche des erreurs maxi et moyenne a un index donne:
179 for (k = 1; k <= nbP; k++) {
180 ParError(j) = Max(ParError(j), MyF.Error(j, k));
181 }
182 AvError += ParError(j);
183 }
184 AvError = AvError/(LastPoint-FirstPoint+1);
185
186
187 MError3d = MyF.MaxError3d();
188 MError2d = MyF.MaxError2d();
189 if (MError3d < Tol3d && MError2d < Tol2d) {
190 Done = Standard_True;
191 }
192
193}
194
195
196
197AppParCurves_MultiCurve AppParCurves_Projection::Value() const {
198 return SCU;
199}
200
201
202Standard_Boolean AppParCurves_Projection::IsDone() const {
203 return Done;
204}
205
206
207Standard_Real AppParCurves_Projection::Error(const Standard_Integer Index) const {
208 return ParError(Index);
209}
210
211Standard_Real AppParCurves_Projection::AverageError() const {
212 return AvError;
213}
214
215Standard_Real AppParCurves_Projection::MaxError3d() const {
216 return MError3d;
217}
218
219Standard_Real AppParCurves_Projection::MaxError2d() const {
220 return MError2d;
221}
222
223