1 // File AppParCurves_Projection.gxx
6 #define No_Standard_RangeError
7 #define No_Standard_OutOfRange
9 #include <AppParCurves_Constraint.hxx>
10 #include <StdFail_NotDone.hxx>
11 #include <AppParCurves_MultiPoint.hxx>
13 #include <gp_Pnt2d.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>
21 #include <BSplCLib.hxx>
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) {
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;
50 gp_Pnt2d Pt2d, P12d, P22d;
52 gp_Vec2d V12d, V22d, MyV2d;
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);
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 // ================================================================
66 AppParCurves_ProFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg);
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);
81 for (i = 1; i <= NbIterations; i++) {
83 // Stockage des Poles des courbes:
84 // ===============================
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);
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);
101 for (j = FirstPoint+1; j <= LastPoint-1; 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);
110 for (k = 1; k <= nbP3d; k++) {
111 for (l=1; l<=deg+1; l++) TabCoef(l) = TheCoef(l+i2);
113 BSplCLib::CoefsD2(UF, TabCoef, PLib::NoWeights(), Pt, V1, V2);
114 MyV = gp_Vec(Pt, TabP(k));
116 DFU += V1.SquareMagnitude() + MyV*V2;
119 for (k = 1; k <= nbP2d; k++) {
120 for (l=1; l<=deg+1; l++) TabCoef2d(l) = TheCoef2d(l+i2);
122 BSplCLib::CoefsD2(UF, TabCoef2d, PLib::NoWeights(), Pt2d, V12d, V22d);
123 MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
125 DFU += V12d.SquareMagnitude() + MyV2d*V22d;
128 if (DFU <= RealEpsilon()) {
129 // Verification du parametrage:
130 EC = Abs(Parameters(j) - UF);
131 if (EC > ECmax) ECmax = EC;
136 DU = Sign(Min(5.e-02, Abs(DU)), DU);
141 // Test de progression:
142 // ====================
146 MyF.Value(Parameters, Fval);
147 SCU = MyF.CurveValue();
148 MErr3d = MyF.MaxError3d();
149 MErr2d = MyF.MaxError2d();
151 if (MErr3d< Tol3d && MErr2d < Tol2d) {
152 Done = Standard_True;
155 if (MErr3d > 100.0*Tol3d || MErr2d > 100.0*Tol2d) {
156 Done = Standard_False;
157 grad = Standard_False;
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)) {
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));
182 AvError += ParError(j);
184 AvError = AvError/(LastPoint-FirstPoint+1);
187 MError3d = MyF.MaxError3d();
188 MError2d = MyF.MaxError2d();
189 if (MError3d < Tol3d && MError2d < Tol2d) {
190 Done = Standard_True;
197 AppParCurves_MultiCurve AppParCurves_Projection::Value() const {
202 Standard_Boolean AppParCurves_Projection::IsDone() const {
207 Standard_Real AppParCurves_Projection::Error(const Standard_Integer Index) const {
208 return ParError(Index);
211 Standard_Real AppParCurves_Projection::AverageError() const {
215 Standard_Real AppParCurves_Projection::MaxError3d() const {
219 Standard_Real AppParCurves_Projection::MaxError2d() const {