// Created on: 1997-09-17 // Created by: Philippe MANGIN // Copyright (c) 1997-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. //====================== Private Methodes =============================// //======================================================================= //function : Adjusting //purpose : Smoothing's adjusting like STRIM routine "MAJLIS" //======================================================================= void AppParCurves_Variational::Adjusting( Handle(AppParCurves_SmoothCriterion)& J, Standard_Real& WQuadratic, Standard_Real& WQuality, Handle(FEmTool_Curve)& TheCurve, TColStd_Array1OfReal& Ecarts) { // cout << "=========== Adjusting =============" << endl; /* Initialized data */ const Standard_Integer mxiter = 2; const Standard_Real eps1 = 1e-6; Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1; Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints; Standard_Real CurvTol = eps1 * J->EstLength() / NbrPnt; /* Local variables */ Standard_Integer iter, ipnt; Standard_Real ecart, emold, erold, tpara; Standard_Real vocri[4], j1cibl, vtest, vseuil; Standard_Integer i, numint, flag; TColStd_Array1OfReal tbpoid(myFirstPoint, myLastPoint); Standard_Boolean loptim, lrejet; Handle(AppParCurves_SmoothCriterion) JNew; Handle(FEmTool_Curve) CNew; Standard_Real E1, E2, E3; /* (0.b) Initialisations */ loptim = Standard_True; iter = 0; tbpoid.Init(1.); /* ============ boucle sur le moteur de lissage ============== */ vtest = WQuality * .9; j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint)); while(loptim) { ++iter; /* (1) Sauvegarde de l'etat precedents */ vocri[0] = myCriterium[0]; vocri[1] = myCriterium[1]; vocri[2] = myCriterium[2]; vocri[3] = myCriterium[3]; erold = myMaxError; emold = myAverageError; /* (2) Augmentation du poids des moindre carre */ if (j1cibl > vtest) { WQuadratic = j1cibl / vtest * WQuadratic; } /* (3) Augmentation du poid associe aux points a problemes */ vseuil = WQuality * .88; for (ipnt = myFirstPoint; ipnt <= myLastPoint; ++ipnt) { if (Ecarts(ipnt) > vtest) { ecart = (Ecarts(ipnt) - vseuil) / WQuality; tbpoid(ipnt) = (ecart * 3 + 1.) * tbpoid(ipnt); } } /* (4) Decoupe force */ if (TheCurve->NbElements() < myMaxSegment && myWithCutting) { numint = NearIndex(myParameters->Value(myMaxErrorIndex), TheCurve->Knots(), 0, flag); tpara = (TheCurve->Knots()(numint) + TheCurve->Knots()(numint + 1) + myParameters->Value(myMaxErrorIndex) * 2) / 4; CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements() + 1, TheCurve->Base(), CurvTol); for(i = 1; i <= numint; i++) CNew->Knots()(i) = TheCurve->Knots()(i); for(i = numint + 1; i <= TheCurve->Knots().Length(); i++) CNew->Knots()(i + 1) = TheCurve->Knots()(i); CNew->Knots()(numint + 1) = tpara; } else { CNew = new FEmTool_Curve(myDimension, TheCurve->NbElements(), TheCurve->Base(), CurvTol); CNew->Knots() = TheCurve->Knots(); } JNew = new AppParCurves_MyCriterion(mySSP, myFirstPoint, myLastPoint); JNew->EstLength() = J->EstLength(); J->GetEstimation(E1, E2, E3); JNew->SetEstimation(E1, E2, E3); JNew->SetParameters(myParameters); JNew->SetWeight(WQuadratic, WQuality, myPercent[0], myPercent[1], myPercent[2]); JNew->SetWeight(tbpoid); JNew->SetCurve(CNew); /* (5) Relissage */ TheMotor(JNew, WQuadratic, WQuality, CNew, Ecarts); /* (6) Tests de rejet */ j1cibl = Sqrt(myCriterium[0] / (NbrPnt - NbrConstraint)); vseuil = Sqrt(vocri[1]) + (erold - myMaxError) * 4; // if(CNew->NbElements() == TheCurve->NbElements()) lrejet = myMaxError > WQuality && myMaxError > erold * 1.01 || Sqrt(myCriterium[1]) > vseuil * 1.05; // else // lrejet = myMaxError > WQuality && myMaxError > erold * 1.05 // || Sqrt(myCriterium[1]) > vseuil * 1.01; if (lrejet) { myCriterium[0] = vocri[0]; myCriterium[1] = vocri[1]; myCriterium[2] = vocri[2]; myCriterium[3] = vocri[3]; myMaxError = erold; myAverageError = emold; loptim = Standard_False; } else { J = JNew; TheCurve = CNew; J->SetCurve(TheCurve); } /* (7) Test de convergence */ if (iter >= mxiter && myMaxSegment == CNew->NbElements() || myMaxError < WQuality) { loptim = Standard_False; } } }