// Copyright (c) 1995-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. // lpa, le 11/09/91 #define No_Standard_RangeError #define No_Standard_OutOfRange #include #include #include #include #include #include #include #include #include #include #include #include #include AppParCurves_Projection:: AppParCurves_Projection(const MultiLine& SSP, const Standard_Integer FirstPoint, const Standard_Integer LastPoint, const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints, math_Vector& Parameters, const Standard_Integer Deg, const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Integer NbIterations): ParError(FirstPoint, LastPoint,0.0) { Standard_Boolean grad = Standard_True; Standard_Integer i, j, k, i2, l; Standard_Real UF, DU, Fval = 0.0, FU, DFU; Standard_Real MErr3d=0.0, MErr2d=0.0, Gain3d = Tol3d, Gain2d=Tol2d; Standard_Real EC, ECmax = 1.e10, Errsov3d, Errsov2d; Standard_Integer nbP3d = ToolLine::NbP3d(SSP); Standard_Integer nbP2d = ToolLine::NbP2d(SSP); Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d; Standard_Integer nbP = nbP3d + nbP2d; gp_Pnt Pt, P1, P2; gp_Pnt2d Pt2d, P12d, P22d; gp_Vec V1, V2, MyV; gp_Vec2d V12d, V22d, MyV2d; if (nbP3d == 0) mynbP3d = 1; if (nbP2d == 0) mynbP2d = 1; TColgp_Array1OfPnt TabP(1, mynbP3d); TColgp_Array1OfPnt2d TabP2d(1, mynbP2d); TColgp_Array1OfVec TabV(1, mynbP3d); TColgp_Array1OfVec2d TabV2d(1, mynbP2d); // Calcul de la fonction F= somme(||C(ui)-Ptli||2): // Appel a une fonction heritant de MultipleVarFunctionWithGradient // pour calculer F et grad_F. // ================================================================ AppParCurves_ProFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg); ECmax = 0.0; // Projection: // =========== MyF.Value(Parameters, Fval); SCU = MyF.CurveValue(); Standard_Integer deg = SCU.Degree(); TColgp_Array1OfPnt TabPole(1, deg+1), TabCoef(1, deg+1); TColgp_Array1OfPnt2d TabPole2d(1, deg+1), TabCoef2d(1, deg+1); TColgp_Array1OfPnt TheCoef(1, (deg+1)*mynbP3d); TColgp_Array1OfPnt2d TheCoef2d(1, (deg+1)*mynbP2d); for (i = 1; i <= NbIterations; i++) { // Stockage des Poles des courbes: // =============================== i2 = 0; for (k = 1; k <= nbP3d; k++) { SCU.Curve(k, TabPole); BSplCLib::PolesCoefficients(TabPole, PLib::NoWeights(), TabCoef, PLib::NoWeights()); for (j=1; j<=deg+1; j++) TheCoef(j+i2) = TabCoef(j); i2 += deg+1; } i2 = 0; for (k = 1; k <= nbP2d; k++) { SCU.Curve(nbP3d+k, TabPole2d); BSplCLib::PolesCoefficients(TabPole2d, PLib::NoWeights(), TabCoef2d, PLib::NoWeights()); for (j=1; j<=deg+1; j++) TheCoef2d(j+i2) = TabCoef2d(j); i2 += deg+1; } for (j = FirstPoint+1; j <= LastPoint-1; j++) { UF = Parameters(j); if (nbP != 0 && nbP2d != 0) ToolLine::Value(SSP, j, TabP, TabP2d); else if (nbP2d != 0) ToolLine::Value(SSP, j, TabP2d); else ToolLine::Value(SSP, j, TabP); FU = 0.0; DFU = 0.0; i2 = 0; for (k = 1; k <= nbP3d; k++) { for (l=1; l<=deg+1; l++) TabCoef(l) = TheCoef(l+i2); i2 += deg+1; BSplCLib::CoefsD2(UF, TabCoef, PLib::NoWeights(), Pt, V1, V2); MyV = gp_Vec(Pt, TabP(k)); FU += MyV*V1; DFU += V1.SquareMagnitude() + MyV*V2; } i2 = 0; for (k = 1; k <= nbP2d; k++) { for (l=1; l<=deg+1; l++) TabCoef2d(l) = TheCoef2d(l+i2); i2 += deg+1; BSplCLib::CoefsD2(UF, TabCoef2d, PLib::NoWeights(), Pt2d, V12d, V22d); MyV2d = gp_Vec2d(Pt2d, TabP2d(k)); FU += MyV2d*V12d; DFU += V12d.SquareMagnitude() + MyV2d*V22d; } if (DFU <= RealEpsilon()) { // Verification du parametrage: EC = Abs(Parameters(j) - UF); if (EC > ECmax) ECmax = EC; break; } DU = -FU/DFU; DU = Sign(Min(5.e-02, Abs(DU)), DU); UF += DU; Parameters(j) = UF; } // Test de progression: // ==================== Errsov3d = MErr3d; Errsov2d = MErr2d; MyF.Value(Parameters, Fval); SCU = MyF.CurveValue(); MErr3d = MyF.MaxError3d(); MErr2d = MyF.MaxError2d(); if (MErr3d< Tol3d && MErr2d < Tol2d) { Done = Standard_True; break; } if (MErr3d > 100.0*Tol3d || MErr2d > 100.0*Tol2d) { Done = Standard_False; grad = Standard_False; break; } if (i >= 2) { Gain3d = Abs(Errsov3d-MErr3d); Gain2d = Abs(Errsov2d-MErr2d); if ((MErr3d-Gain3d*(NbIterations-i)*0.5) > Tol3d || (MErr2d-Gain2d*(NbIterations-i)*0.5) > Tol2d) { if (Gain3d < Tol3d/(2*NbIterations) && Gain2d < Tol2d/(2*NbIterations)) { break; } } } } AvError = 0.; for (j = FirstPoint; j <= LastPoint; j++) { // Recherche des erreurs maxi et moyenne a un index donne: for (k = 1; k <= nbP; k++) { ParError(j) = Max(ParError(j), MyF.Error(j, k)); } AvError += ParError(j); } AvError = AvError/(LastPoint-FirstPoint+1); MError3d = MyF.MaxError3d(); MError2d = MyF.MaxError2d(); if (MError3d < Tol3d && MError2d < Tol2d) { Done = Standard_True; } } AppParCurves_MultiCurve AppParCurves_Projection::Value() const { return SCU; } Standard_Boolean AppParCurves_Projection::IsDone() const { return Done; } Standard_Real AppParCurves_Projection::Error(const Standard_Integer Index) const { return ParError(Index); } Standard_Real AppParCurves_Projection::AverageError() const { return AvError; } Standard_Real AppParCurves_Projection::MaxError3d() const { return MError3d; } Standard_Real AppParCurves_Projection::MaxError2d() const { return MError2d; }