0023024: Update headers of OCCT files
[occt.git] / src / AppParCurves / AppParCurves_Projection.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 // lpa, le 11/09/91
20
21
22
23 #define No_Standard_RangeError
24 #define No_Standard_OutOfRange
25
26 #include <AppParCurves_Constraint.hxx>
27 #include <StdFail_NotDone.hxx>
28 #include <AppParCurves_MultiPoint.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <gp_Vec.hxx>
32 #include <gp_Vec2d.hxx>
33 #include <TColgp_Array1OfPnt.hxx>
34 #include <TColgp_Array1OfPnt2d.hxx>
35 #include <TColgp_Array1OfVec.hxx>
36 #include <TColgp_Array1OfVec2d.hxx>
37 #include <PLib.hxx>
38 #include <BSplCLib.hxx>
39
40
41
42
43
44 AppParCurves_Projection::
45    AppParCurves_Projection(const MultiLine& SSP,
46          const Standard_Integer FirstPoint,
47          const Standard_Integer LastPoint,
48          const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
49          math_Vector& Parameters,
50          const Standard_Integer Deg,
51          const Standard_Real Tol3d,
52          const Standard_Real Tol2d,
53          const Standard_Integer NbIterations):
54          ParError(FirstPoint, LastPoint,0.0) {
55
56   Standard_Boolean grad = Standard_True;
57   Standard_Integer i, j, k, i2, l;
58   Standard_Real UF, DU, Fval = 0.0, FU, DFU;
59   Standard_Real MErr3d=0.0, MErr2d=0.0, 
60                 Gain3d = Tol3d, Gain2d=Tol2d;
61   Standard_Real EC, ECmax = 1.e10, Errsov3d, Errsov2d;
62   Standard_Integer nbP3d = ToolLine::NbP3d(SSP);
63   Standard_Integer nbP2d = ToolLine::NbP2d(SSP);
64   Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
65   Standard_Integer nbP = nbP3d + nbP2d;
66   gp_Pnt Pt, P1, P2;
67   gp_Pnt2d Pt2d, P12d, P22d;
68   gp_Vec V1, V2, MyV;
69   gp_Vec2d V12d, V22d, MyV2d;
70   
71   if (nbP3d == 0) mynbP3d = 1;
72   if (nbP2d == 0) mynbP2d = 1;
73   TColgp_Array1OfPnt TabP(1, mynbP3d);
74   TColgp_Array1OfPnt2d TabP2d(1, mynbP2d);
75   TColgp_Array1OfVec TabV(1, mynbP3d);
76   TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
77
78   // Calcul de la fonction F= somme(||C(ui)-Ptli||2):
79   // Appel a une fonction heritant de MultipleVarFunctionWithGradient
80   // pour calculer F et grad_F.
81   // ================================================================
82
83   AppParCurves_ProFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg);
84
85
86   ECmax = 0.0;
87   // Projection:
88   // ===========
89   MyF.Value(Parameters, Fval);
90   SCU = MyF.CurveValue();
91   Standard_Integer deg = SCU.Degree();
92   TColgp_Array1OfPnt   TabPole(1, deg+1),   TabCoef(1, deg+1);
93   TColgp_Array1OfPnt2d TabPole2d(1, deg+1), TabCoef2d(1, deg+1);
94   TColgp_Array1OfPnt    TheCoef(1, (deg+1)*mynbP3d);
95   TColgp_Array1OfPnt2d  TheCoef2d(1, (deg+1)*mynbP2d);
96
97   
98   for (i = 1; i <= NbIterations; i++) {
99
100     // Stockage des Poles des courbes:
101     // ===============================
102     i2 = 0;
103     for (k = 1; k <= nbP3d; k++) {
104       SCU.Curve(k, TabPole);
105       BSplCLib::PolesCoefficients(TabPole, PLib::NoWeights(),
106                                   TabCoef, PLib::NoWeights());
107       for (j=1; j<=deg+1; j++) TheCoef(j+i2) = TabCoef(j);
108       i2 += deg+1;
109     }
110     i2 = 0;
111     for (k = 1; k <= nbP2d; k++) {
112       SCU.Curve(nbP3d+k, TabPole2d);
113       BSplCLib::PolesCoefficients(TabPole2d, PLib::NoWeights(), 
114                                   TabCoef2d, PLib::NoWeights());
115       for (j=1; j<=deg+1; j++) TheCoef2d(j+i2) = TabCoef2d(j);
116       i2 += deg+1;
117     }
118     for (j = FirstPoint+1; j <= LastPoint-1; j++) {
119       UF = Parameters(j);
120       if (nbP != 0 && nbP2d != 0) ToolLine::Value(SSP, j, TabP, TabP2d);
121       else if (nbP2d != 0)        ToolLine::Value(SSP, j, TabP2d);
122       else                        ToolLine::Value(SSP, j, TabP);
123       
124       FU = 0.0;
125       DFU = 0.0;
126       i2 = 0;
127       for (k = 1; k <= nbP3d; k++) {
128         for (l=1; l<=deg+1; l++) TabCoef(l) = TheCoef(l+i2);
129         i2 += deg+1;
130         BSplCLib::CoefsD2(UF, TabCoef, PLib::NoWeights(), Pt, V1, V2);
131         MyV = gp_Vec(Pt, TabP(k));
132         FU += MyV*V1;
133         DFU += V1.SquareMagnitude() + MyV*V2;
134       }
135       i2 = 0;
136       for (k = 1; k <= nbP2d; k++) {
137         for (l=1; l<=deg+1; l++) TabCoef2d(l) = TheCoef2d(l+i2);
138         i2 += deg+1;
139         BSplCLib::CoefsD2(UF, TabCoef2d, PLib::NoWeights(), Pt2d, V12d, V22d);
140         MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
141         FU += MyV2d*V12d;
142         DFU += V12d.SquareMagnitude() + MyV2d*V22d;
143       }
144
145       if (DFU <= RealEpsilon()) {
146         // Verification du parametrage:
147         EC = Abs(Parameters(j) - UF);
148         if (EC > ECmax) ECmax = EC;
149         break;
150       }
151
152       DU = -FU/DFU;
153       DU = Sign(Min(5.e-02, Abs(DU)), DU);
154       UF += DU;
155       Parameters(j) = UF;
156     }
157
158     // Test de progression:
159     // ====================
160     Errsov3d = MErr3d;
161     Errsov2d = MErr2d;
162
163     MyF.Value(Parameters, Fval);
164     SCU = MyF.CurveValue();
165     MErr3d = MyF.MaxError3d();
166     MErr2d = MyF.MaxError2d();
167
168     if (MErr3d< Tol3d && MErr2d < Tol2d) {
169       Done = Standard_True;
170       break;
171     }
172     if (MErr3d > 100.0*Tol3d || MErr2d > 100.0*Tol2d) {
173       Done = Standard_False;
174       grad = Standard_False;
175       break;
176     }
177     if (i >= 2) {
178       Gain3d = Abs(Errsov3d-MErr3d);
179       Gain2d = Abs(Errsov2d-MErr2d);
180       if ((MErr3d-Gain3d*(NbIterations-i)*0.5) > Tol3d ||
181           (MErr2d-Gain2d*(NbIterations-i)*0.5) > Tol2d) {
182         if (Gain3d < Tol3d/(2*NbIterations) &&
183             Gain2d < Tol2d/(2*NbIterations)) {
184           break;
185         }
186       }
187     }
188
189   }
190
191
192
193   AvError = 0.;
194   for (j = FirstPoint; j <= LastPoint; j++) {  
195     // Recherche des erreurs maxi et moyenne a un index donne:
196     for (k = 1; k <= nbP; k++) {
197       ParError(j) = Max(ParError(j), MyF.Error(j, k));
198     }
199     AvError += ParError(j);
200   }
201   AvError = AvError/(LastPoint-FirstPoint+1);
202
203
204   MError3d = MyF.MaxError3d();
205   MError2d = MyF.MaxError2d();
206   if (MError3d < Tol3d && MError2d < Tol2d) {
207     Done = Standard_True;
208   }
209
210 }
211
212
213
214 AppParCurves_MultiCurve AppParCurves_Projection::Value() const {
215   return SCU;
216 }
217
218
219 Standard_Boolean AppParCurves_Projection::IsDone() const {
220   return Done;
221 }
222
223
224 Standard_Real AppParCurves_Projection::Error(const Standard_Integer Index) const {
225   return ParError(Index);
226 }
227
228 Standard_Real AppParCurves_Projection::AverageError() const {
229   return AvError;
230 }
231
232 Standard_Real AppParCurves_Projection::MaxError3d() const {
233   return MError3d;
234 }
235
236 Standard_Real AppParCurves_Projection::MaxError2d() const {
237   return MError2d;
238 }
239
240