Loading files
// Copyright (c) 1995-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// lpa, le 11/09/91
// Application of the corrected gradient method to minimize
// F = sum(||C(ui, Poles(ui)) - ptli||2.
// The conjugate gradient method is implemented in the mathematical
// library: math_BFGS.
// This algorithm must be called only when dealing with a set
// of constrained points (other than at extremities). Indeed, the call to the
// function F to minimize implies a call to ParLeastSquare and ResConstraint.
// If this is not the case, the call to ResConstraint is equivalent to a
// second least squares resolution, thus wasting a lot of time.
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#include <AppParCurves_Constraint.hxx>
#include <math_BFGS.hxx>
#include <StdFail_NotDone.hxx>
#include <AppParCurves_MultiPoint.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <NCollection_Array1.hxx>
#include <BSplCLib.hxx>
#include <PLib.hxx>
// #define AppParCurves_Gradient_BFGS BFGS_/**/AppParCurves_Gradient
AppParCurves_Gradient::AppParCurves_Gradient(
const MultiLine& SSP,
const int FirstPoint,
const int LastPoint,
const occ::handle<NCollection_HArray1<AppParCurves_ConstraintCouple>>& TheConstraints,
math_Vector& Parameters,
const int Deg,
const double Tol3d,
const double Tol2d,
const int NbIterations)
: ParError(FirstPoint, LastPoint, 0.0),
AvError(0.0),
MError3d(0.0),
MError2d(0.0)
{
// bool grad = true;
int j, k, i2, l;
double UF, DU, Fval = 0.0, FU, DFU;
int nbP3d = ToolLine::NbP3d(SSP);
int nbP2d = ToolLine::NbP2d(SSP);
int mynbP3d = nbP3d, mynbP2d = nbP2d;
int nbP = nbP3d + nbP2d;
// gp_Pnt Pt, P1, P2;
gp_Pnt Pt;
// gp_Pnt2d Pt2d, P12d, P22d;
gp_Pnt2d Pt2d;
// gp_Vec V1, V2, MyV;
gp_Vec V1, MyV;
// gp_Vec2d V12d, V22d, MyV2d;
gp_Vec2d V12d, MyV2d;
Done = false;
if (nbP3d == 0)
mynbP3d = 1;
if (nbP2d == 0)
mynbP2d = 1;
NCollection_Array1<gp_Pnt> TabP(1, mynbP3d);
NCollection_Array1<gp_Pnt2d> TabP2d(1, mynbP2d);
NCollection_Array1<gp_Vec> TabV(1, mynbP3d);
NCollection_Array1<gp_Vec2d> TabV2d(1, mynbP2d);
// Calculation of the function F= sum(||C(ui)-Ptli||2):
// Call to a function inheriting from MultipleVarFunctionWithGradient
// to compute F and grad_F.
// ================================================================
AppParCurves_ParFunction MyF(SSP, FirstPoint, LastPoint, TheConstraints, Parameters, Deg);
if (!MyF.Value(Parameters, Fval))
{
Done = false;
return;
}
SCU = MyF.CurveValue();
int deg = SCU.NbPoles() - 1;
NCollection_Array1<gp_Pnt> TabPole(1, deg + 1), TabCoef(1, deg + 1);
NCollection_Array1<gp_Pnt2d> TabPole2d(1, deg + 1), TabCoef2d(1, deg + 1);
NCollection_Array1<gp_Pnt> TheCoef(1, (deg + 1) * mynbP3d);
NCollection_Array1<gp_Pnt2d> TheCoef2d(1, (deg + 1) * mynbP2d);
// Storage of curve poles for projection:
// ============================================
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;
}
// Une iteration rapide de projection est faite par la methode de
// Rogers & Fog 89, methode equivalente a Hoschek 88 qui ne necessite pas
// le calcul de D2.
// Iteration de Projection:
// =======================
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::CoefsD1(UF, TabCoef, BSplCLib::NoWeights(), Pt, V1);
MyV = gp_Vec(Pt, TabP(k));
FU += MyV * V1;
DFU += V1.SquareMagnitude();
}
i2 = 0;
for (k = 1; k <= nbP2d; k++)
{
for (l = 1; l <= deg + 1; l++)
TabCoef2d(l) = TheCoef2d(l + i2);
i2 += deg + 1;
BSplCLib::CoefsD1(UF, TabCoef2d, BSplCLib::NoWeights(), Pt2d, V12d);
MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
FU += MyV2d * V12d;
DFU += V12d.SquareMagnitude();
}
if (DFU >= RealEpsilon())
{
DU = FU / DFU;
DU = std::copysign(std::min(5.e-02, std::abs(DU)), DU);
UF += DU;
Parameters(j) = UF;
}
}
if (!MyF.Value(Parameters, Fval))
{
SCU = AppParCurves_MultiCurve();
Done = false;
return;
}
MError3d = MyF.MaxError3d();
MError2d = MyF.MaxError2d();
if (MError3d <= Tol3d && MError2d <= Tol2d)
{
Done = true;
SCU = MyF.CurveValue();
}
else if (NbIterations != 0)
{
// NbIterations de gradient conjugue:
// =================================
double Eps = 1.e-07;
AppParCurves_Gradient_BFGS FResol(MyF, Parameters, Tol3d, Tol2d, Eps, NbIterations);
Parameters = MyF.NewParameters();
SCU = MyF.CurveValue();
}
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) = std::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 = true;
}
}
AppParCurves_MultiCurve AppParCurves_Gradient::Value() const
{
return SCU;
}
bool AppParCurves_Gradient::IsDone() const
{
return Done;
}
double AppParCurves_Gradient::Error(const int Index) const
{
return ParError(Index);
}
double AppParCurves_Gradient::AverageError() const
{
return AvError;
}
double AppParCurves_Gradient::MaxError3d() const
{
return MError3d;
}
double AppParCurves_Gradient::MaxError2d() const
{
return MError2d;
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.