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 | |
27 | AppParCurves_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 | |
197 | AppParCurves_MultiCurve AppParCurves_Projection::Value() const { |
198 | return SCU; |
199 | } |
200 | |
201 | |
202 | Standard_Boolean AppParCurves_Projection::IsDone() const { |
203 | return Done; |
204 | } |
205 | |
206 | |
207 | Standard_Real AppParCurves_Projection::Error(const Standard_Integer Index) const { |
208 | return ParError(Index); |
209 | } |
210 | |
211 | Standard_Real AppParCurves_Projection::AverageError() const { |
212 | return AvError; |
213 | } |
214 | |
215 | Standard_Real AppParCurves_Projection::MaxError3d() const { |
216 | return MError3d; |
217 | } |
218 | |
219 | Standard_Real AppParCurves_Projection::MaxError2d() const { |
220 | return MError2d; |
221 | } |
222 | |
223 | |