a7870c6ae38eacabeefcd870538f4764972d4a24
[occt.git] / src / AppParCurves / AppParCurves_Variational_7.gxx
1 // Created on: 1997-09-17
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //====================== Private Methodes =============================//
18 //=======================================================================
19 //function : Adjusting
20 //purpose  : Smoothing's  adjusting like STRIM routine "MAJLIS"
21 //=======================================================================
22 void AppParCurves_Variational::Adjusting(
23                          Handle(AppParCurves_SmoothCriterion)& J,
24                          Standard_Real& WQuadratic,
25                          Standard_Real& WQuality,
26                          Handle(FEmTool_Curve)& TheCurve,
27                          TColStd_Array1OfReal& Ecarts) 
28 {
29
30 //  cout << "=========== Adjusting =============" << endl;
31
32     /* Initialized data */
33
34   const Standard_Integer mxiter = 2;
35   const Standard_Real eps1 = 1e-6;
36   Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
37   Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
38   Standard_Real CurvTol = eps1 * J->EstLength() / NbrPnt;
39
40
41     /* Local variables */
42   Standard_Integer iter, ipnt;
43   Standard_Real ecart, emold, erold, tpara;
44   Standard_Real vocri[4], j1cibl, vtest, vseuil;
45   Standard_Integer i, numint, flag;
46   TColStd_Array1OfReal tbpoid(myFirstPoint, myLastPoint);
47   Standard_Boolean loptim, lrejet;
48   Handle(AppParCurves_SmoothCriterion) JNew;
49   Handle(FEmTool_Curve) CNew;
50   Standard_Real E1, E2, E3;
51   
52
53 /* (0.b) Initialisations */
54
55   loptim = Standard_True;
56   iter = 0;
57   tbpoid.Init(1.);
58
59
60 /* ============   boucle sur le moteur de lissage  ============== */
61
62   vtest = WQuality * .9;
63   j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
64   
65   while(loptim) {
66     
67     ++iter;
68     
69 /*     (1) Sauvegarde de l'etat precedents */
70
71     vocri[0] = myCriterium[0];
72     vocri[1] = myCriterium[1];
73     vocri[2] = myCriterium[2];
74     vocri[3] = myCriterium[3];
75     erold = myMaxError; 
76     emold = myAverageError; 
77
78 /*     (2) Augmentation du poids des moindre carre */
79
80     if (j1cibl > vtest) {
81       WQuadratic = j1cibl / vtest * WQuadratic;
82     }
83
84 /*     (3) Augmentation du poid associe aux points a problemes */
85
86     vseuil = WQuality * .88;
87     
88     for (ipnt = myFirstPoint; ipnt <= myLastPoint; ++ipnt) {
89       if (Ecarts(ipnt) > vtest) {
90         ecart = (Ecarts(ipnt) - vseuil) / WQuality;
91         tbpoid(ipnt) = (ecart * 3 + 1.) * tbpoid(ipnt);
92       }
93     }
94
95 /*     (4) Decoupe force */
96
97     if (TheCurve->NbElements() < myMaxSegment && myWithCutting) {
98
99       numint = NearIndex(myParameters->Value(myMaxErrorIndex), TheCurve->Knots(), 0, flag);
100
101       tpara = (TheCurve->Knots()(numint) + TheCurve->Knots()(numint + 1) + 
102                myParameters->Value(myMaxErrorIndex) * 2) / 4;
103       
104       CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements() + 1, 
105                                TheCurve->Base(), CurvTol);
106
107       for(i = 1; i <= numint; i++) CNew->Knots()(i) = TheCurve->Knots()(i);
108       for(i = numint + 1; i <= TheCurve->Knots().Length(); i++) 
109         CNew->Knots()(i + 1) = TheCurve->Knots()(i);
110
111       CNew->Knots()(numint + 1) = tpara;
112
113     } else {
114
115       CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements(), TheCurve->Base(), CurvTol);
116
117       CNew->Knots() = TheCurve->Knots();
118     }
119
120
121     JNew = new AppParCurves_MyCriterion(mySSP, myFirstPoint, myLastPoint);
122
123     JNew->EstLength() = J->EstLength();
124
125     J->GetEstimation(E1, E2, E3);
126
127     JNew->SetEstimation(E1, E2, E3);
128
129     JNew->SetParameters(myParameters);
130
131     JNew->SetWeight(WQuadratic, WQuality, myPercent[0], myPercent[1], myPercent[2]);
132
133     JNew->SetWeight(tbpoid);
134
135     JNew->SetCurve(CNew);
136
137 /*     (5) Relissage */
138
139     TheMotor(JNew, WQuadratic, WQuality, CNew, Ecarts);
140
141 /*     (6) Tests de rejet */
142
143     j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint));
144     vseuil = Sqrt(vocri[1]) + (erold - myMaxError) * 4;
145     
146     lrejet = ((myMaxError > WQuality) && (myMaxError > erold * 1.01)) || (Sqrt(myCriterium[1]) > vseuil * 1.05);
147
148     if (lrejet) {
149       myCriterium[0] = vocri[0];
150       myCriterium[1] = vocri[1];
151       myCriterium[2] = vocri[2];
152       myCriterium[3] = vocri[3];
153       myMaxError = erold;
154       myAverageError = emold;
155       
156       loptim = Standard_False;
157     }
158     else {
159       J = JNew;
160       TheCurve = CNew;
161       J->SetCurve(TheCurve);
162     }
163
164 /*     (7) Test de convergence */
165
166     if (((iter >= mxiter) && (myMaxSegment == CNew->NbElements())) || myMaxError < WQuality) {
167       loptim = Standard_False;
168     }
169     
170   }
171   
172   
173 }
174
175
176
177
178