mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
160
src/AppParCurves/AppParCurves.cdl
Executable file
160
src/AppParCurves/AppParCurves.cdl
Executable file
@@ -0,0 +1,160 @@
|
||||
-- File: AppParCurves.cdl
|
||||
-- Created: Thu Apr 11 11:42:01 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
package AppParCurves
|
||||
|
||||
---Purpose: Parallel Approximation in n curves.
|
||||
-- This package gives all the algorithms used to approximate a MultiLine
|
||||
-- described by the tool MLineTool.
|
||||
-- The result of the approximation will be a MultiCurve.
|
||||
|
||||
uses math, FEmTool, gp, TColgp, StdFail, TColStd, TCollection, Standard, MMgt, GeomAbs,
|
||||
PLib
|
||||
|
||||
is
|
||||
|
||||
enumeration Constraint is
|
||||
NoConstraint,
|
||||
PassPoint,
|
||||
TangencyPoint,
|
||||
CurvaturePoint
|
||||
end Constraint;
|
||||
---Purpose:
|
||||
-- - NoConstraint: this point has no constraints.
|
||||
-- - PassPoint: the approximation curve passes through this point.
|
||||
-- - TangencyPoint: this point has a tangency constraint.
|
||||
-- - CurvaturePoint: this point has a curvature constraint.
|
||||
|
||||
|
||||
|
||||
|
||||
deferred generic class MLineTool; --- Template
|
||||
|
||||
|
||||
class MultiPoint;
|
||||
|
||||
class MultiCurve;
|
||||
|
||||
class MultiBSpCurve;
|
||||
|
||||
class ConstraintCouple;
|
||||
|
||||
|
||||
-- Algorithms:
|
||||
|
||||
|
||||
generic class LeastSquare;
|
||||
---Purpose: computes in parallel the least square resolution of a
|
||||
-- set of points (MultiLine). The result is a
|
||||
-- set of Bezier curves (MultiCurve).
|
||||
|
||||
generic class ResolConstraint;
|
||||
---Purpose: computes the approximating resolution with constraints
|
||||
-- starting from a guess solution issued, for example,
|
||||
-- from the least squares.
|
||||
-- It uses the Uzawa method from the mathematical package.
|
||||
|
||||
|
||||
generic class Function;
|
||||
|
||||
|
||||
generic class BSpFunction;
|
||||
|
||||
|
||||
generic class Gradient, Gradient_BFGS, ParLeastSquare, ResConstraint, ParFunction;
|
||||
---Purpose: computes the approximation of a MultiLine by the
|
||||
-- search for a new parameters to minimize the
|
||||
-- sum||C(ui)-Qi||2 with a gradient method.
|
||||
|
||||
|
||||
|
||||
generic class BSpGradient, BSpGradient_BFGS, BSpParLeastSquare, BSpParFunction;
|
||||
---Purpose: computes the approximation of a MultiLine by the
|
||||
-- search for a new parameters to minimize the
|
||||
-- sum||C(ui)-Qi||2 with a gradient method.
|
||||
-- The Result is a Bspline set.
|
||||
|
||||
|
||||
generic class Projection, ProLeastSquare, ProConstraint, ProFunction;
|
||||
---Purpose: computes the approximation of a Multiline by
|
||||
-- searching for a new parameter with a projection
|
||||
-- method.
|
||||
|
||||
deferred class SmoothCriterion;
|
||||
generic class LinearCriteria;
|
||||
|
||||
class MyCriterion;
|
||||
---Level: Internal
|
||||
|
||||
generic class Variational;
|
||||
---Purpose: computes the approximation of a Multiline by
|
||||
-- Variational optimization.
|
||||
|
||||
|
||||
|
||||
--- instantiate classes:
|
||||
--
|
||||
|
||||
class Array1OfConstraintCouple instantiates Array1 from TCollection
|
||||
(ConstraintCouple);
|
||||
|
||||
class HArray1OfConstraintCouple instantiates HArray1 from TCollection
|
||||
(ConstraintCouple,Array1OfConstraintCouple);
|
||||
|
||||
|
||||
|
||||
class Array1OfMultiPoint instantiates Array1 from TCollection
|
||||
(MultiPoint);
|
||||
|
||||
class HArray1OfMultiPoint instantiates HArray1 from TCollection
|
||||
(MultiPoint,Array1OfMultiPoint);
|
||||
|
||||
|
||||
class Array1OfMultiCurve instantiates Array1 from TCollection
|
||||
(MultiCurve);
|
||||
|
||||
class HArray1OfMultiCurve instantiates HArray1 from TCollection
|
||||
(MultiCurve, Array1OfMultiCurve);
|
||||
|
||||
class SequenceOfMultiCurve instantiates Sequence from TCollection
|
||||
(MultiCurve);
|
||||
|
||||
|
||||
class Array1OfMultiBSpCurve instantiates Array1 from TCollection
|
||||
(MultiBSpCurve);
|
||||
|
||||
class HArray1OfMultiBSpCurve instantiates HArray1 from TCollection
|
||||
(MultiBSpCurve, Array1OfMultiBSpCurve);
|
||||
|
||||
class SequenceOfMultiBSpCurve instantiates Sequence from TCollection
|
||||
(MultiBSpCurve);
|
||||
|
||||
|
||||
BernsteinMatrix(NbPoles: in Integer from Standard;
|
||||
U : in Vector from math;
|
||||
A : in out Matrix from math);
|
||||
|
||||
|
||||
Bernstein(NbPoles: in Integer from Standard;
|
||||
U : in Vector from math;
|
||||
A : in out Matrix from math;
|
||||
DA : in out Matrix from math);
|
||||
|
||||
|
||||
SecondDerivativeBernstein(U: Real; DDA: in out Vector from math);
|
||||
|
||||
|
||||
SplineFunction(NbPoles : in Integer from Standard;
|
||||
Degree : in Integer from Standard;
|
||||
Parameters : in Vector from math;
|
||||
FlatKnots : in Vector from math;
|
||||
A : in out Matrix from math;
|
||||
DA : in out Matrix from math;
|
||||
Index : in out IntegerVector from math);
|
||||
|
||||
end AppParCurves;
|
231
src/AppParCurves/AppParCurves.cxx
Executable file
231
src/AppParCurves/AppParCurves.cxx
Executable file
@@ -0,0 +1,231 @@
|
||||
// File AppParCurves.cxx
|
||||
|
||||
#define No_Standard_RangeError
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <AppParCurves.ixx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
|
||||
|
||||
void AppParCurves::BernsteinMatrix(const Standard_Integer NbPoles,
|
||||
const math_Vector& U,
|
||||
math_Matrix& A) {
|
||||
|
||||
Standard_Integer i, j, id;
|
||||
Standard_Real u0, u1, y0, y1, xs;
|
||||
Standard_Integer first = U.Lower(), last = U.Upper();
|
||||
math_Vector B(1, NbPoles-1);
|
||||
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
B(1) = 1;
|
||||
u0 = U(i);
|
||||
u1 = 1.-u0;
|
||||
|
||||
for (id = 2; id <= NbPoles-1; id++) {
|
||||
y0 = B(1);
|
||||
y1 = u0*y0;
|
||||
B(1) = y0-y1;
|
||||
for (j = 2; j <= id-1; j++) {
|
||||
xs = y1;
|
||||
y0 = B(j);
|
||||
y1 = u0*y0;
|
||||
B(j) = y0-y1+xs;
|
||||
}
|
||||
B(id) = y1;
|
||||
}
|
||||
A(i, 1) = u1*B(1);
|
||||
A(i, NbPoles) = u0*B(NbPoles-1);
|
||||
for (j = 2; j <= NbPoles-1; j++) {
|
||||
A(i, j) = u1*B(j)+u0*B(j-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves::Bernstein(const Standard_Integer NbPoles,
|
||||
const math_Vector& U,
|
||||
math_Matrix& A,
|
||||
math_Matrix& DA) {
|
||||
|
||||
Standard_Integer i, j, id, Ndeg = NbPoles-1;
|
||||
Standard_Real u0, u1, y0, y1, xs, bj, bj1;;
|
||||
Standard_Integer first = U.Lower(), last = U.Upper();
|
||||
math_Vector B(1, NbPoles-1);
|
||||
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
B(1) = 1;
|
||||
u0 = U(i);
|
||||
u1 = 1.-u0;
|
||||
|
||||
for (id = 2; id <= NbPoles-1; id++) {
|
||||
y0 = B(1);
|
||||
y1 = u0*y0;
|
||||
B(1) = y0-y1;
|
||||
for (j = 2; j <= id-1; j++) {
|
||||
xs = y1;
|
||||
y0 = B(j);
|
||||
y1 = u0*y0;
|
||||
B(j) = y0-y1+xs;
|
||||
}
|
||||
B(id) = y1;
|
||||
}
|
||||
DA(i, 1) = -Ndeg*B(1);
|
||||
DA(i, NbPoles) = Ndeg*B(NbPoles-1);
|
||||
A(i, 1) = u1*B(1);
|
||||
A(i, NbPoles) = u0*B(NbPoles-1);
|
||||
for (j = 2; j <= NbPoles-1; j++) {
|
||||
bj = B(j); bj1 = B(j-1);
|
||||
DA(i,j) = Ndeg*(bj1-bj);
|
||||
A(i, j) = u1*bj+u0*bj1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves::SecondDerivativeBernstein(const Standard_Real U,
|
||||
math_Vector& DDA) {
|
||||
// Standard_Real U1 = 1-U, Y0, Y1, Xs;
|
||||
Standard_Real Y0, Y1, Xs;
|
||||
Standard_Integer NbPoles = DDA.Length();
|
||||
Standard_Integer id, j, N2, N3, N4, deg = NbPoles-1;
|
||||
N2 = deg-1; N3 = deg-2, N4 = deg*(deg-1);
|
||||
math_Vector B(1, deg-1);
|
||||
B(1) = 1.;
|
||||
|
||||
// Cas particulier si degre = 1:
|
||||
if (deg == 1) {
|
||||
DDA(1) = 0.0;
|
||||
DDA(2) = 0.0;
|
||||
}
|
||||
else if (deg == 2) {
|
||||
DDA(1) = 2.0;
|
||||
DDA(2) = -4.0;
|
||||
DDA(3) = 2.0;
|
||||
}
|
||||
else {
|
||||
|
||||
for (id = 2; id <= deg-1; id++) {
|
||||
Y0 = B(1);
|
||||
Y1 = U*Y0;
|
||||
B(1) = Y0-Y1;
|
||||
for (j = 2; j <= id-1; j++) {
|
||||
Xs = Y1;
|
||||
Y0 = B(j);
|
||||
Y1 = U*Y0;
|
||||
B(j) = Y0 - Y1 +Xs;
|
||||
}
|
||||
B(id) = Y1;
|
||||
}
|
||||
|
||||
DDA(1) = N4*B(1);
|
||||
DDA(2) = N4*(-2*B(1) + B(2));
|
||||
DDA(deg) = N4*(B(deg-2) - 2*B(deg-1));
|
||||
DDA(deg+1) = N4*B(deg-1);
|
||||
|
||||
for(j = 2; j <= deg-2; j++) {
|
||||
DDA(j+1) = N4*(B(j-1)-2*B(j)+B(j+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AppParCurves::SplineFunction(const Standard_Integer nbpoles,
|
||||
const Standard_Integer deg,
|
||||
const math_Vector& Parameters,
|
||||
const math_Vector& flatknots,
|
||||
math_Matrix& A,
|
||||
math_Matrix& DA,
|
||||
math_IntegerVector& index)
|
||||
{
|
||||
// Standard_Real U, NewU, co, diff, t1, t2;
|
||||
Standard_Real U, NewU;
|
||||
// gp_Pnt2d Pt, P0;
|
||||
// gp_Vec2d V1;
|
||||
// Standard_Integer i, j, k, iter, in, ik, deg1 = deg+1;
|
||||
Standard_Integer i, j, deg1 = deg+1;
|
||||
// Standard_Integer oldkindex, kindex, theindex, ttindex;
|
||||
Standard_Integer oldkindex, kindex, theindex;
|
||||
math_Vector locpoles(1 , deg1);
|
||||
math_Vector locdpoles(1 , deg1);
|
||||
Standard_Integer firstp = Parameters.Lower(), lastp = Parameters.Upper();
|
||||
|
||||
TColStd_Array1OfReal Aflatknots(flatknots.Lower(), flatknots.Upper());
|
||||
for (i = flatknots.Lower(); i <= flatknots.Upper(); i++) {
|
||||
Aflatknots(i) = flatknots(i);
|
||||
}
|
||||
|
||||
|
||||
oldkindex = 1;
|
||||
|
||||
Standard_Integer pp, qq;
|
||||
Standard_Real Saved, Inverse, LocalInverse, locqq, locdqq, val;
|
||||
|
||||
for (i = firstp; i <= lastp; i++) {
|
||||
U = Parameters(i);
|
||||
NewU = U;
|
||||
kindex = oldkindex;
|
||||
BSplCLib::LocateParameter(deg, Aflatknots, U, Standard_False,
|
||||
deg1, nbpoles+1, kindex, NewU);
|
||||
|
||||
oldkindex = kindex;
|
||||
|
||||
// On stocke les index:
|
||||
index(i) = kindex - deg-1;
|
||||
|
||||
locpoles(1) = 1.0;
|
||||
|
||||
for (qq = 2; qq <= deg; qq++) {
|
||||
locpoles(qq) = 0.0;
|
||||
for (pp = 1; pp <= qq-1; pp++) {
|
||||
Inverse = 1.0 / (flatknots(kindex + pp) - flatknots(kindex - qq + pp + 1)) ;
|
||||
Saved = (U - flatknots(kindex - qq + pp + 1)) * Inverse * locpoles(pp);
|
||||
locpoles(pp) *= (flatknots(kindex + pp) - U) * Inverse ;
|
||||
locpoles(pp) += locpoles(qq) ;
|
||||
locpoles(qq) = Saved ;
|
||||
}
|
||||
}
|
||||
|
||||
qq = deg+1;
|
||||
for (pp = 1; pp <= deg; pp++) {
|
||||
locdpoles(pp)= locpoles(pp);
|
||||
}
|
||||
|
||||
locqq = 0.0;
|
||||
locdqq = 0.0;
|
||||
for (pp = 1; pp <= deg; pp++) {
|
||||
Inverse = 1.0 / (flatknots(kindex + pp) - flatknots(kindex - qq + pp + 1));
|
||||
Saved = (U - flatknots(kindex - qq + pp + 1)) * Inverse * locpoles(pp);
|
||||
locpoles(pp) *= (flatknots(kindex + pp) - U) * Inverse;
|
||||
locpoles(pp) += locqq;
|
||||
locqq = Saved ;
|
||||
LocalInverse = (Standard_Real) (deg) * Inverse;
|
||||
Saved = LocalInverse * locdpoles(pp);
|
||||
locdpoles(pp) *= - LocalInverse ;
|
||||
locdpoles(pp) += locdqq;
|
||||
locdqq = Saved ;
|
||||
}
|
||||
|
||||
locpoles(qq) = locqq;
|
||||
locdpoles(qq) = locdqq;
|
||||
|
||||
for (j = 1; j <= deg1; j++) {
|
||||
val = locpoles(j);
|
||||
theindex = j+oldkindex-deg1;
|
||||
A(i, theindex) = val;
|
||||
DA(i, theindex) = locdpoles(j);
|
||||
}
|
||||
|
||||
for (j = 1; j < oldkindex-deg; j++)
|
||||
A(i, j) = DA(i, j) = 0.0;
|
||||
for (j = oldkindex+1; j <= nbpoles; j++)
|
||||
A(i, j) = DA(i, j) = 0.0;
|
||||
|
||||
}
|
||||
|
||||
}
|
214
src/AppParCurves/AppParCurves_BSpFunction.cdl
Executable file
214
src/AppParCurves/AppParCurves_BSpFunction.cdl
Executable file
@@ -0,0 +1,214 @@
|
||||
-- File: AppParCurves_BSpFunction.cdl
|
||||
-- Created: Tue Sep 21 18:02:28 1993
|
||||
-- Author: Modelistation
|
||||
-- <model@zerox>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
|
||||
|
||||
generic class BSpFunction from AppParCurves (
|
||||
MultiLine as any;
|
||||
ToolLine as any; -- as ToolLine(MultiLine)
|
||||
Squares as any)
|
||||
|
||||
inherits MultipleVarFunctionWithGradient from math
|
||||
|
||||
---Purpose: This function inherits MultipleVarFunctionWithGradient to be
|
||||
-- used in the mathematical algorithm BFGS.
|
||||
-- It computes the value of the function
|
||||
-- F=sum(||Qui - B*Pi||)2 where Pi are Poles of the BSpline
|
||||
-- curves approximating the given MultiLine SSP and ui the
|
||||
-- parameters associated to the points Qi of SSP.
|
||||
-- It also computes the gradient for values ui of the parameter.
|
||||
|
||||
|
||||
uses MultiBSpCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves,
|
||||
Constraint from AppParCurves,
|
||||
Vector from math,
|
||||
IntegerVector from math,
|
||||
Matrix from math,
|
||||
HArray1OfInteger from TColStd,
|
||||
Array1OfReal from TColStd,
|
||||
Array1OfInteger from TColStd
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: Vector; Knots: Array1OfReal;
|
||||
Mults: Array1OfInteger; NbPol: Integer)
|
||||
---Purpose: initializes the fields of the function. The approximating
|
||||
-- curve has <NbPol> control points.
|
||||
|
||||
returns BSpFunction from AppParCurves;
|
||||
|
||||
|
||||
NbVariables(me)
|
||||
---Purpose: returns the number of variables of the function. It
|
||||
-- corresponds to the number of MultiPoints.
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
Perform(me: in out; X: Vector)
|
||||
---Purpose: this method is used each time Value or Gradient is
|
||||
-- needed.
|
||||
|
||||
is static protected;
|
||||
|
||||
|
||||
Value(me: in out; X: Vector; F: out Real)
|
||||
---Purpose: this method computes the new approximation of the
|
||||
-- MultiLine
|
||||
-- SSP and calculates F = sum (||Pui - Bi*Pi||2) for each
|
||||
-- point of the MultiLine.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Gradient(me: in out; X: Vector; G: out Vector)
|
||||
---Purpose: returns the gradient G of the sum above for the
|
||||
-- parameters Xi.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Values(me: in out; X: Vector; F: out Real; G: out Vector)
|
||||
---Purpose: returns the value F=sum(||Pui - Bi*Pi||)2.
|
||||
-- returns the value G = grad(F) for the parameters Xi.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
NewParameters(me)
|
||||
---Purpose: returns the new parameters of the MultiLine.
|
||||
---C++: return const&
|
||||
returns Vector
|
||||
is static;
|
||||
|
||||
|
||||
CurveValue(me: in out)
|
||||
---Purpose: returns the MultiBSpCurve approximating the set after
|
||||
-- computing the value F or Grad(F).
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
Error(me: in out; IPoint, CurveIndex: Integer)
|
||||
---Purpose: returns the distance between the MultiPoint of range
|
||||
-- IPoint and the curve CurveIndex.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
MaxError3d(me)
|
||||
---Purpose: returns the maximum distance between the points
|
||||
-- and the MultiBSpCurve.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
MaxError2d(me)
|
||||
---Purpose: returns the maximum distance between the points
|
||||
-- and the MultiBSpCurve.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
FunctionMatrix(me)
|
||||
---Purpose: returns the function matrix used to approximate the
|
||||
-- multiline.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix from math
|
||||
is static;
|
||||
|
||||
|
||||
DerivativeFunctionMatrix(me)
|
||||
---Purpose: returns the derivative function matrix used to approximate the
|
||||
-- multiline.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix from math
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
Index(me)
|
||||
---Purpose: Returns the indexes of the first non null values of
|
||||
-- A and DA.
|
||||
-- The values are non null from Index(ieme point) +1
|
||||
-- to Index(ieme point) + degree +1.
|
||||
---C++: return const&
|
||||
|
||||
returns IntegerVector
|
||||
is static;
|
||||
|
||||
|
||||
FirstConstraint(me; TheConstraints: HArray1OfConstraintCouple;
|
||||
FirstPoint: Integer)
|
||||
---Purpose:
|
||||
|
||||
returns Constraint from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
LastConstraint(me; TheConstraints: HArray1OfConstraintCouple;
|
||||
LastPoint: Integer)
|
||||
---Purpose:
|
||||
|
||||
returns Constraint from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
SetFirstLambda(me: in out; l1: Real)
|
||||
is static;
|
||||
|
||||
|
||||
SetLastLambda(me: in out; l2: Real)
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
Done: Boolean;
|
||||
MyMultiLine : MultiLine;
|
||||
MyMultiBSpCurve: MultiBSpCurve from AppParCurves;
|
||||
nbpoles: Integer;
|
||||
myParameters: Vector;
|
||||
FVal: Real;
|
||||
ValGrad_F: Vector from math;
|
||||
MyF: Matrix from math;
|
||||
PTLX : Matrix from math;
|
||||
PTLY : Matrix from math;
|
||||
PTLZ : Matrix from math;
|
||||
A: Matrix from math;
|
||||
DA: Matrix from math;
|
||||
MyLeastSquare : Squares;
|
||||
Contraintes: Boolean;
|
||||
NbP: Integer;
|
||||
NbCu: Integer;
|
||||
Adeb: Integer;
|
||||
Afin: Integer;
|
||||
tabdim: HArray1OfInteger from TColStd;
|
||||
ERR3d: Real;
|
||||
ERR2d: Real;
|
||||
FirstP: Integer;
|
||||
LastP: Integer;
|
||||
myConstraints: HArray1OfConstraintCouple from AppParCurves;
|
||||
mylambda1: Real;
|
||||
mylambda2: Real;
|
||||
|
||||
end BSpFunction;
|
311
src/AppParCurves/AppParCurves_BSpFunction.gxx
Executable file
311
src/AppParCurves/AppParCurves_BSpFunction.gxx
Executable file
@@ -0,0 +1,311 @@
|
||||
#include <AppParCurves_MultiBSpCurve.hxx>
|
||||
#include <AppParCurves_MultiPoint.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColStd_HArray1OfInteger.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
#include <AppParCurves_ConstraintCouple.hxx>
|
||||
#include <AppParCurves_HArray1OfConstraintCouple.hxx>
|
||||
|
||||
|
||||
AppParCurves_BSpFunction::
|
||||
AppParCurves_BSpFunction(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const math_Vector& Parameters,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults,
|
||||
const Standard_Integer NbPol) :
|
||||
MyMultiLine(SSP),
|
||||
MyMultiBSpCurve(NbPol),
|
||||
myParameters(Parameters.Lower(), Parameters.Upper()),
|
||||
ValGrad_F(FirstPoint, LastPoint),
|
||||
MyF(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLX(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLY(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLZ(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
A(FirstPoint, LastPoint, 1, NbPol),
|
||||
DA(FirstPoint, LastPoint, 1, NbPol),
|
||||
MyLeastSquare(SSP, Knots, Mults, FirstPoint, LastPoint,
|
||||
FirstConstraint(TheConstraints, FirstPoint),
|
||||
LastConstraint(TheConstraints, LastPoint), NbPol)
|
||||
{
|
||||
Standard_Integer i;
|
||||
for (i = Parameters.Lower(); i <= Parameters.Upper(); i++)
|
||||
myParameters(i) = Parameters(i);
|
||||
FirstP = FirstPoint;
|
||||
LastP = LastPoint;
|
||||
myConstraints = TheConstraints;
|
||||
NbP = LastP-FirstP+1;
|
||||
Adeb = FirstP;
|
||||
Afin = LastP;
|
||||
nbpoles = NbPol;
|
||||
MyMultiBSpCurve.SetKnots(Knots);
|
||||
MyMultiBSpCurve.SetMultiplicities(Mults);
|
||||
Contraintes = Standard_False;
|
||||
Standard_Integer myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == FirstP) {
|
||||
if (Cons >= 1) Adeb = Adeb+1;
|
||||
}
|
||||
else if (myindex == LastP) {
|
||||
if (Cons >= 1) Afin = Afin-1;
|
||||
}
|
||||
else {
|
||||
if (Cons >= 1) Contraintes = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer nb3d = ToolLine::NbP3d(SSP);
|
||||
Standard_Integer nb2d = ToolLine::NbP2d(SSP);
|
||||
Standard_Integer mynb3d= nb3d, mynb2d=nb2d;
|
||||
if (nb3d == 0) mynb3d = 1;
|
||||
if (nb2d == 0) mynb2d = 1;
|
||||
|
||||
NbCu = nb3d+nb2d;
|
||||
tabdim = new TColStd_HArray1OfInteger(0, NbCu-1);
|
||||
|
||||
if (Contraintes) {
|
||||
for (i = 1; i <= NbCu; i++) {
|
||||
if (i <= nb3d) tabdim->SetValue(i-1, 3);
|
||||
else tabdim->SetValue(i-1, 2);
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabP(1, mynb3d);
|
||||
TColgp_Array1OfPnt2d TabP2d(1, mynb2d);
|
||||
|
||||
for ( i = FirstP; i <= LastP; i++) {
|
||||
if (nb3d != 0 && nb2d != 0) ToolLine::Value(SSP, i, TabP, TabP2d);
|
||||
else if (nb3d != 0) ToolLine::Value(SSP, i, TabP);
|
||||
else ToolLine::Value(SSP, i, TabP2d);
|
||||
for (Standard_Integer j = 1; j <= NbCu; j++) {
|
||||
if (tabdim->Value(j-1) == 3) {
|
||||
TabP(j).Coord(PTLX(i, j), PTLY(i, j),PTLZ(i, j));
|
||||
}
|
||||
else {
|
||||
TabP2d(j).Coord(PTLX(i, j), PTLY(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_Constraint AppParCurves_BSpFunction::FirstConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer FirstPoint) const
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == FirstPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_Constraint AppParCurves_BSpFunction::LastConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer LastPoint) const
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == LastPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_BSpFunction::Value (const math_Vector& X,
|
||||
Standard_Real& F) {
|
||||
|
||||
myParameters = X;
|
||||
|
||||
// Resolution moindres carres:
|
||||
// ===========================
|
||||
MyLeastSquare.Perform(myParameters, mylambda1, mylambda2);
|
||||
if (!(MyLeastSquare.IsDone())) {
|
||||
Done = Standard_False;
|
||||
return Standard_False;
|
||||
}
|
||||
if (!Contraintes) {
|
||||
MyLeastSquare.Error(FVal, ERR3d, ERR2d);
|
||||
F = FVal;
|
||||
}
|
||||
|
||||
// Resolution avec contraintes:
|
||||
// ============================
|
||||
else {
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AppParCurves_BSpFunction::Perform(const math_Vector& X) {
|
||||
Standard_Integer j;
|
||||
|
||||
myParameters = X;
|
||||
// Resolution moindres carres:
|
||||
// ===========================
|
||||
MyLeastSquare.Perform(myParameters, mylambda1, mylambda2);
|
||||
|
||||
if (!(MyLeastSquare.IsDone())) {
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
for(j = myParameters.Lower(); j <= myParameters.Upper(); j++) {
|
||||
ValGrad_F(j) = 0.0;
|
||||
}
|
||||
|
||||
if (!Contraintes) {
|
||||
MyLeastSquare.ErrorGradient(ValGrad_F, FVal, ERR3d, ERR2d);
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AppParCurves_BSpFunction::SetFirstLambda(const Standard_Real l1)
|
||||
{
|
||||
mylambda1 = l1;
|
||||
}
|
||||
|
||||
void AppParCurves_BSpFunction::SetLastLambda(const Standard_Real l2)
|
||||
{
|
||||
mylambda2 = l2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_BSpFunction::NbVariables() const{
|
||||
return NbP;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_BSpFunction::Gradient (const math_Vector& X,
|
||||
math_Vector& G) {
|
||||
|
||||
Perform(X);
|
||||
G = ValGrad_F;
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_BSpFunction::Values (const math_Vector& X,
|
||||
Standard_Real& F,
|
||||
math_Vector& G) {
|
||||
|
||||
|
||||
Perform(X);
|
||||
F = FVal;
|
||||
G = ValGrad_F;
|
||||
|
||||
/*
|
||||
math_Vector mygradient = G;
|
||||
math_Vector myx = X;
|
||||
Standard_Real myf = FVal;
|
||||
Standard_Real F2 = FVal;
|
||||
math_Vector G2 = ValGrad_F;
|
||||
for (Standard_Integer i = 1; i <= X.Length(); i++) {
|
||||
myx = X;
|
||||
myx(i) = X(i) + 1.0e-10;
|
||||
Value(myx, F2);
|
||||
mygradient(i) = (F2 - myf)/(1.0e-10);
|
||||
}
|
||||
|
||||
cout << " Gradient calcule : " << G2 << endl;
|
||||
cout << " Gradient interpole : " << mygradient << endl;
|
||||
*/
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_MultiBSpCurve AppParCurves_BSpFunction::CurveValue() {
|
||||
if (!Contraintes) MyMultiBSpCurve = MyLeastSquare.BSplineValue();
|
||||
return MyMultiBSpCurve;
|
||||
}
|
||||
|
||||
|
||||
Standard_Real AppParCurves_BSpFunction::Error(const Standard_Integer IPoint,
|
||||
const Standard_Integer CurveIndex) {
|
||||
const math_Matrix& DD = MyLeastSquare.Distance();
|
||||
Standard_Real d = DD.Value(IPoint, CurveIndex);
|
||||
if (!Contraintes) return d;
|
||||
else return Sqrt(MyF(IPoint, CurveIndex));
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_BSpFunction::MaxError3d() const
|
||||
{
|
||||
return ERR3d;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_BSpFunction::MaxError2d() const
|
||||
{
|
||||
return ERR2d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const math_Vector& AppParCurves_BSpFunction::NewParameters() const
|
||||
{
|
||||
return myParameters;
|
||||
}
|
||||
|
||||
|
||||
const math_Matrix& AppParCurves_BSpFunction::FunctionMatrix() const
|
||||
{
|
||||
return MyLeastSquare.FunctionMatrix();
|
||||
}
|
||||
|
||||
const math_Matrix& AppParCurves_BSpFunction::DerivativeFunctionMatrix() const
|
||||
{
|
||||
return MyLeastSquare.DerivativeFunctionMatrix();
|
||||
}
|
||||
|
||||
|
||||
const math_IntegerVector& AppParCurves_BSpFunction::Index() const
|
||||
{
|
||||
return MyLeastSquare.KIndex();
|
||||
}
|
176
src/AppParCurves/AppParCurves_BSpGradient.cdl
Executable file
176
src/AppParCurves/AppParCurves_BSpGradient.cdl
Executable file
@@ -0,0 +1,176 @@
|
||||
-- File: AppParCurves_BSpGradient.cdl
|
||||
-- Created: Wed Sep 22 10:23:14 1993
|
||||
-- Author: Modelistation
|
||||
-- <model@zerox>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
|
||||
generic class BSpGradient from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This algorithm uses the algorithms LeastSquare,
|
||||
-- ResConstraint and a gradient method to approximate a set
|
||||
-- of points (AppDef_MultiLine) with a minimization of the
|
||||
-- sum(square(|F(i)-Qi|)) by changing the parameter.
|
||||
-- The algorithm used is from of the mathematical
|
||||
-- package: math_BFGS, a gradient method.
|
||||
|
||||
|
||||
|
||||
uses Vector from math,
|
||||
MultipleVarFunctionWithGradient from math,
|
||||
MultiBSpCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves,
|
||||
Array1OfReal from TColStd,
|
||||
Array1OfInteger from TColStd
|
||||
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
NotDone from StdFail
|
||||
|
||||
|
||||
private class BSpParLeastSquare instantiates LeastSquare from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
private class BSpParFunction instantiates BSpFunction from AppParCurves
|
||||
(MultiLine, ToolLine, BSpParLeastSquare);
|
||||
|
||||
|
||||
class BSpGradient_BFGS from AppParCurves
|
||||
inherits BFGS from math
|
||||
uses MultipleVarFunctionWithGradient from math,
|
||||
Vector from math
|
||||
|
||||
is
|
||||
|
||||
Create ( F : in out MultipleVarFunctionWithGradient from math ;
|
||||
StartingPoint : Vector from math ;
|
||||
Tolerance3d : Real from Standard ;
|
||||
Tolerance2d : Real from Standard ;
|
||||
Eps : Real from Standard ;
|
||||
NbIterations : Integer from Standard = 200 );
|
||||
|
||||
IsSolutionReached ( me ;
|
||||
F : in out MultipleVarFunctionWithGradient from math )
|
||||
returns Boolean from Standard is redefined ;
|
||||
|
||||
fields
|
||||
|
||||
myTol3d : Real from Standard ;
|
||||
myTol2d : Real from Standard ;
|
||||
|
||||
end BSpGradient_BFGS from AppParCurves ;
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: in out Vector;
|
||||
Knots: Array1OfReal; Mults: Array1OfInteger;
|
||||
Deg: Integer;
|
||||
Tol3d, Tol2d: Real; NbIterations: Integer = 1)
|
||||
---Purpose: Tries to minimize the sum (square(||Qui - Bi*Pi||))
|
||||
-- where Pui describe the approximating BSpline curves'Poles
|
||||
-- and Qi the MultiLine points with a parameter ui.
|
||||
-- In this algorithm, the parameters ui are the unknowns.
|
||||
-- The tolerance required on this sum is given by Tol.
|
||||
-- The desired degree of the resulting curve is Deg.
|
||||
|
||||
returns BSpGradient from AppParCurves;
|
||||
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: in out Vector;
|
||||
Knots: Array1OfReal; Mults: Array1OfInteger;
|
||||
Deg: Integer;
|
||||
Tol3d, Tol2d: Real; NbIterations: Integer;
|
||||
lambda1, lambda2: Real)
|
||||
---Purpose: Tries to minimize the sum (square(||Qui - Bi*Pi||))
|
||||
-- where Pui describe the approximating BSpline curves'Poles
|
||||
-- and Qi the MultiLine points with a parameter ui.
|
||||
-- In this algorithm, the parameters ui are the unknowns.
|
||||
-- The tolerance required on this sum is given by Tol.
|
||||
-- The desired degree of the resulting curve is Deg.
|
||||
|
||||
returns BSpGradient from AppParCurves;
|
||||
|
||||
|
||||
Perform(me: in out; SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: in out Vector;
|
||||
Knots: Array1OfReal; Mults: Array1OfInteger;
|
||||
Deg: Integer;
|
||||
Tol3d, Tol2d: Real; NbIterations: Integer = 200)
|
||||
is static protected;
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if all has been correctly done.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Value(me)
|
||||
---Purpose: returns all the BSpline curves approximating the
|
||||
-- MultiLine SSP after minimization of the parameter.
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
Error(me; Index: Integer)
|
||||
---Purpose: returns the difference between the old and the new
|
||||
-- approximation.
|
||||
-- An exception is raised if NotDone.
|
||||
-- An exception is raised if Index<1 or Index>NbParameters.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail,
|
||||
OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
MaxError3d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
MaxError2d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
AverageError(me)
|
||||
---Purpose: returns the average error between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
SCU: MultiBSpCurve from AppParCurves;
|
||||
ParError: Vector from math;
|
||||
AvError: Real;
|
||||
MError3d: Real;
|
||||
MError2d: Real;
|
||||
mylambda1: Real;
|
||||
mylambda2: Real;
|
||||
Done: Boolean;
|
||||
|
||||
end BSpGradient from AppParCurves;
|
376
src/AppParCurves/AppParCurves_BSpGradient.gxx
Executable file
376
src/AppParCurves/AppParCurves_BSpGradient.gxx
Executable file
@@ -0,0 +1,376 @@
|
||||
// File AppParCurves_BSpGradient.gxx
|
||||
// lpa, le 11/09/91
|
||||
|
||||
|
||||
// Application de la methode du gradient corrige pour minimiser
|
||||
// F = somme(||C(ui, Poles(ui)) - ptli||2.
|
||||
// La methode de gradient conjugue est programmee dans la bibliotheque
|
||||
// mathematique: math_BFGS.
|
||||
|
||||
|
||||
#define No_Standard_RangeError
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <AppParCurves_Constraint.hxx>
|
||||
#include <AppParCurves_ConstraintCouple.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 <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_Array1OfVec.hxx>
|
||||
#include <TColgp_Array1OfVec2d.hxx>
|
||||
|
||||
#include <OSD_Chronometer.hxx>
|
||||
|
||||
static OSD_Chronometer chr1;
|
||||
|
||||
|
||||
static Standard_Boolean islambdadefined = Standard_False;
|
||||
|
||||
|
||||
|
||||
static AppParCurves_Constraint FirstConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer FirstPoint)
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == FirstPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
static AppParCurves_Constraint LastConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer LastPoint)
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == LastPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AppParCurves_BSpGradient::
|
||||
AppParCurves_BSpGradient(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
math_Vector& Parameters,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults,
|
||||
const Standard_Integer Deg,
|
||||
const Standard_Real Tol3d,
|
||||
const Standard_Real Tol2d,
|
||||
const Standard_Integer NbIterations):
|
||||
ParError(FirstPoint, LastPoint,0.0)
|
||||
{
|
||||
Perform(SSP, FirstPoint, LastPoint, TheConstraints, Parameters,
|
||||
Knots, Mults, Deg, Tol3d, Tol2d, NbIterations);
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_BSpGradient::
|
||||
AppParCurves_BSpGradient(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
math_Vector& Parameters,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults,
|
||||
const Standard_Integer Deg,
|
||||
const Standard_Real Tol3d,
|
||||
const Standard_Real Tol2d,
|
||||
const Standard_Integer NbIterations,
|
||||
const Standard_Real lambda1,
|
||||
const Standard_Real lambda2):
|
||||
ParError(FirstPoint, LastPoint,0.0)
|
||||
{
|
||||
mylambda1 = lambda1;
|
||||
mylambda2 = lambda2;
|
||||
islambdadefined = Standard_True;
|
||||
Perform(SSP, FirstPoint, LastPoint, TheConstraints, Parameters,
|
||||
Knots, Mults, Deg, Tol3d, Tol2d, NbIterations);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AppParCurves_BSpGradient::
|
||||
Perform(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
math_Vector& Parameters,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults,
|
||||
const Standard_Integer Deg,
|
||||
const Standard_Real Tol3d,
|
||||
const Standard_Real Tol2d,
|
||||
const Standard_Integer NbIterations)
|
||||
{
|
||||
|
||||
// Standard_Boolean grad = Standard_True;
|
||||
Standard_Integer i, j, k, i2, l;
|
||||
Standard_Real UF, DU, Fval = 0.0, FU, DFU;
|
||||
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_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 = Standard_False;
|
||||
|
||||
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.
|
||||
// ================================================================
|
||||
|
||||
Standard_Integer nbpoles = -Deg -1;
|
||||
for (i = Mults.Lower() ;i <= Mults.Upper(); i++) {
|
||||
nbpoles += Mults(i);
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPole(1, nbpoles);
|
||||
TColgp_Array1OfPnt2d TabPole2d(1, nbpoles);
|
||||
TColgp_Array1OfPnt ThePoles(1, (nbpoles)*mynbP3d);
|
||||
TColgp_Array1OfPnt2d ThePoles2d(1, (nbpoles)*mynbP2d);
|
||||
|
||||
|
||||
AppParCurves_Constraint
|
||||
FirstCons = FirstConstraint(TheConstraints, FirstPoint),
|
||||
LastCons = LastConstraint(TheConstraints, LastPoint);
|
||||
|
||||
|
||||
AppParCurves_BSpParFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints,
|
||||
Parameters, Knots, Mults, nbpoles);
|
||||
|
||||
|
||||
|
||||
if (FirstCons >= AppParCurves_TangencyPoint ||
|
||||
LastCons >= AppParCurves_TangencyPoint) {
|
||||
|
||||
if (!islambdadefined) {
|
||||
AppParCurves_BSpParLeastSquare thefitt(SSP, Knots, Mults, FirstPoint,
|
||||
LastPoint, FirstCons, LastCons,
|
||||
Parameters, nbpoles);
|
||||
if (FirstCons >= AppParCurves_TangencyPoint) {
|
||||
mylambda1 = thefitt.FirstLambda();
|
||||
MyF.SetFirstLambda(mylambda1);
|
||||
}
|
||||
if (LastCons >= AppParCurves_TangencyPoint) {
|
||||
mylambda2 = thefitt.LastLambda();
|
||||
MyF.SetLastLambda(mylambda2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MyF.SetFirstLambda(mylambda1);
|
||||
MyF.SetLastLambda(mylambda2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MyF.Value(Parameters, Fval);
|
||||
MError3d = MyF.MaxError3d();
|
||||
MError2d = MyF.MaxError2d();
|
||||
SCU = MyF.CurveValue();
|
||||
|
||||
if (MError3d > Tol3d || MError2d > Tol2d) {
|
||||
|
||||
// Stockage des Poles des courbes pour projeter:
|
||||
// ============================================
|
||||
i2 = 0;
|
||||
for (k = 1; k <= nbP3d; k++) {
|
||||
SCU.Curve(k, TabPole);
|
||||
for (j=1; j<=nbpoles; j++) ThePoles(j+i2) = TabPole(j);
|
||||
i2 += nbpoles;
|
||||
}
|
||||
i2 = 0;
|
||||
for (k = 1; k <= nbP2d; k++) {
|
||||
SCU.Curve(nbP3d+k, TabPole2d);
|
||||
for (j=1; j<=nbpoles; j++) ThePoles2d(j+i2) = TabPole2d(j);
|
||||
i2 += nbpoles;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
const math_Matrix& A = MyF.FunctionMatrix();
|
||||
const math_Matrix& DA = MyF.DerivativeFunctionMatrix();
|
||||
const math_IntegerVector& Index = MyF.Index();
|
||||
Standard_Real aa, da, a, b, c, d , e , f, px, py, pz;
|
||||
Standard_Integer indexdeb, indexfin;
|
||||
|
||||
for (j = FirstPoint+1; j <= LastPoint-1; j++) {
|
||||
|
||||
UF = Parameters(j);
|
||||
if (nbP3d != 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;
|
||||
|
||||
indexdeb = Index(j) + 1;
|
||||
indexfin = indexdeb + Deg;
|
||||
|
||||
for (k = 1; k <= nbP3d; k++) {
|
||||
a = b = c = d = e = f = 0.0;
|
||||
for (l = indexdeb; l <= indexfin; l++) {
|
||||
Pt = ThePoles(l+i2);
|
||||
px = Pt.X(); py = Pt.Y(); pz = Pt.Z();
|
||||
aa = A(j, l); da = DA(j, l);
|
||||
a += aa* px; d += da* px;
|
||||
b += aa* py; e += da* py;
|
||||
c += aa* pz; f += da* pz;
|
||||
}
|
||||
Pt.SetCoord(a, b, c);
|
||||
V1.SetCoord(d, e, f);
|
||||
i2 += nbpoles;
|
||||
|
||||
MyV = gp_Vec(Pt, TabP(k));
|
||||
FU += MyV*V1;
|
||||
DFU += V1.SquareMagnitude();
|
||||
}
|
||||
i2 = 0;
|
||||
for (k = 1; k <= nbP2d; k++) {
|
||||
a = b = d = e = 0.0;
|
||||
for (l = indexdeb; l <= indexfin; l++) {
|
||||
Pt2d = ThePoles2d(l+i2);
|
||||
px = Pt2d.X(); py = Pt2d.Y();
|
||||
aa = A(j, l); da = DA(j, l);
|
||||
a += aa* px; d += da* px;
|
||||
b += aa* py; e += da* py;
|
||||
}
|
||||
Pt2d.SetCoord(a, b);
|
||||
V12d.SetCoord(d, e);
|
||||
i2 += nbpoles;
|
||||
|
||||
MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
|
||||
FU += MyV2d*V12d;
|
||||
DFU += V12d.SquareMagnitude();
|
||||
}
|
||||
|
||||
if (DFU >= RealEpsilon()) {
|
||||
DU = FU/DFU;
|
||||
DU = Sign(Min(5.e-02, Abs(DU)), DU);
|
||||
UF += DU;
|
||||
Parameters(j) = UF;
|
||||
}
|
||||
}
|
||||
|
||||
MyF.Value(Parameters, Fval);
|
||||
MError3d = MyF.MaxError3d();
|
||||
MError2d = MyF.MaxError2d();
|
||||
}
|
||||
|
||||
|
||||
if (MError3d<= Tol3d && MError2d <= Tol2d) {
|
||||
Done = Standard_True;
|
||||
}
|
||||
else if (NbIterations != 0) {
|
||||
// NbIterations de gradient conjugue:
|
||||
// =================================
|
||||
Standard_Real Eps = 1.e-07;
|
||||
AppParCurves_BSpGradient_BFGS FResol(MyF, Parameters, Tol3d,
|
||||
Tol2d, Eps, NbIterations);
|
||||
}
|
||||
|
||||
SCU = MyF.CurveValue();
|
||||
|
||||
|
||||
AvError = 0.;
|
||||
for (j = FirstPoint; j <= LastPoint; j++) {
|
||||
Parameters(j) = MyF.NewParameters()(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_MultiBSpCurve AppParCurves_BSpGradient::Value() const {
|
||||
return SCU;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_BSpGradient::IsDone() const {
|
||||
return Done;
|
||||
}
|
||||
|
||||
|
||||
Standard_Real AppParCurves_BSpGradient::Error(const Standard_Integer Index) const {
|
||||
return ParError(Index);
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_BSpGradient::AverageError() const {
|
||||
return AvError;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_BSpGradient::MaxError3d() const {
|
||||
return MError3d;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_BSpGradient::MaxError2d() const {
|
||||
return MError2d;
|
||||
}
|
||||
|
||||
|
39
src/AppParCurves/AppParCurves_BSpGradient_BFGS.gxx
Executable file
39
src/AppParCurves/AppParCurves_BSpGradient_BFGS.gxx
Executable file
@@ -0,0 +1,39 @@
|
||||
// File: AppParCurves_BSpGradient_BFGS.gxx
|
||||
// Created: Thu Dec 16 13:02:58 1999
|
||||
// Author: Atelier CAS2000
|
||||
// <cas@cageox.paris1.matra-dtv.fr>
|
||||
|
||||
|
||||
|
||||
// Redefinition de math_BFGS:
|
||||
// ==========================
|
||||
|
||||
AppParCurves_BSpGradient_BFGS::AppParCurves_BSpGradient_BFGS(math_MultipleVarFunctionWithGradient& F,
|
||||
const math_Vector& StartingPoint,
|
||||
const Standard_Real Tolerance3d,
|
||||
const Standard_Real Tolerance2d,
|
||||
const Standard_Real Eps,
|
||||
const Standard_Integer NbIterations):
|
||||
math_BFGS(F, Eps, NbIterations, Eps),
|
||||
myTol3d(Tolerance3d),
|
||||
myTol2d(Tolerance2d)
|
||||
{
|
||||
|
||||
Perform(F, StartingPoint);
|
||||
}
|
||||
|
||||
Standard_Boolean AppParCurves_BSpGradient_BFGS::IsSolutionReached(math_MultipleVarFunctionWithGradient& F) const {
|
||||
Standard_Boolean Result, Result2;
|
||||
AppParCurves_BSpParFunction *F1 = (AppParCurves_BSpParFunction*) &F;
|
||||
|
||||
Result = (2.0 * fabs(TheMinimum - PreviousMinimum) <=
|
||||
1.e-10 * (fabs(TheMinimum) + fabs(PreviousMinimum))+1.e-12) ;
|
||||
Standard_Real MErr3d = F1->MaxError3d();
|
||||
Standard_Real MErr2d = F1->MaxError2d();
|
||||
Result2 = ((MErr3d <= myTol3d) && (MErr2d <= myTol2d));
|
||||
|
||||
return (Result || Result2);
|
||||
}
|
||||
|
||||
|
||||
|
56
src/AppParCurves/AppParCurves_ConstraintCouple.cdl
Executable file
56
src/AppParCurves/AppParCurves_ConstraintCouple.cdl
Executable file
@@ -0,0 +1,56 @@
|
||||
-- File: AppParCurves_ConstraintCouple.cdl
|
||||
-- Created: Wed Feb 24 16:50:46 1993
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@phobox>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
class ConstraintCouple from AppParCurves
|
||||
---Purpose: associates an index and a constraint for an object.
|
||||
-- This couple is used by AppDef_TheVariational when performing approximations.
|
||||
uses Constraint from AppParCurves
|
||||
|
||||
is
|
||||
|
||||
Create returns ConstraintCouple;
|
||||
---Purpose: returns an indefinite ConstraintCouple.
|
||||
|
||||
Create(TheIndex: Integer; Cons: Constraint)
|
||||
---Purpose: Create a couple the object <Index> will have the
|
||||
-- constraint <Cons>.
|
||||
|
||||
returns ConstraintCouple;
|
||||
|
||||
|
||||
Index(me)
|
||||
---Purpose: returns the index of the constraint object.
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
Constraint(me)
|
||||
---Purpose: returns the constraint of the object.
|
||||
|
||||
returns Constraint
|
||||
is static;
|
||||
|
||||
|
||||
SetIndex(me: in out; TheIndex: Integer)
|
||||
---Purpose: Changes the index of the constraint object.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
SetConstraint(me: in out; Cons: Constraint)
|
||||
---Purpose: Changes the constraint of the object.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myIndex: Integer;
|
||||
myConstraint: Constraint from AppParCurves;
|
||||
|
||||
end ConstraintCouple;
|
41
src/AppParCurves/AppParCurves_ConstraintCouple.cxx
Executable file
41
src/AppParCurves/AppParCurves_ConstraintCouple.cxx
Executable file
@@ -0,0 +1,41 @@
|
||||
// File AppParCurves_ConstraintCouple.cxx
|
||||
|
||||
#include <AppParCurves_ConstraintCouple.ixx>
|
||||
|
||||
|
||||
|
||||
AppParCurves_ConstraintCouple::
|
||||
AppParCurves_ConstraintCouple() {}
|
||||
|
||||
|
||||
AppParCurves_ConstraintCouple::
|
||||
AppParCurves_ConstraintCouple(const Standard_Integer TheIndex,
|
||||
const AppParCurves_Constraint Cons)
|
||||
{
|
||||
myIndex = TheIndex;
|
||||
myConstraint = Cons;
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_ConstraintCouple::Index() const
|
||||
{
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
AppParCurves_Constraint AppParCurves_ConstraintCouple::Constraint() const
|
||||
{
|
||||
return myConstraint;
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_ConstraintCouple::SetIndex(const Standard_Integer TheIndex)
|
||||
{
|
||||
myIndex = TheIndex;
|
||||
}
|
||||
|
||||
void AppParCurves_ConstraintCouple::
|
||||
SetConstraint(const AppParCurves_Constraint Cons)
|
||||
{
|
||||
myConstraint = Cons;
|
||||
}
|
||||
|
168
src/AppParCurves/AppParCurves_Function.cdl
Executable file
168
src/AppParCurves/AppParCurves_Function.cdl
Executable file
@@ -0,0 +1,168 @@
|
||||
-- File: Function.cdl
|
||||
-- Created: Fri Sep 20 15:07:26 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991
|
||||
|
||||
|
||||
generic class Function from AppParCurves (
|
||||
MultiLine as any;
|
||||
ToolLine as any; -- as ToolLine(MultiLine)
|
||||
Squares as any;
|
||||
ResolCons as any)
|
||||
|
||||
inherits MultipleVarFunctionWithGradient from math
|
||||
|
||||
---Purpose: This function inherits MultipleVarFunctionWithGradient to be
|
||||
-- used in the mathematical algorithm BFGS.
|
||||
-- It computes the value of the function
|
||||
-- F=sum(||Qui - B*Pi||)2 where Pi are Poles of the Bezier curves
|
||||
-- approximating the given MultiLine SSP and ui the parameters
|
||||
-- associated to the points Qi of SSP.
|
||||
-- It also computes the gradient for values ui of the parameter.
|
||||
|
||||
|
||||
uses MultiCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves,
|
||||
Constraint from AppParCurves,
|
||||
Vector from math,
|
||||
Matrix from math,
|
||||
HArray1OfInteger from TColStd
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: Vector; Deg: Integer)
|
||||
---Purpose: initializes the fields of the function. The approximating
|
||||
-- curve has the desired degree Deg.
|
||||
|
||||
returns Function from AppParCurves;
|
||||
|
||||
|
||||
NbVariables(me)
|
||||
---Purpose: returns the number of variables of the function. It
|
||||
-- corresponds to the number of MultiPoints.
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
Perform(me: in out; X: Vector)
|
||||
---Purpose: this method is used each time Value or Gradient is
|
||||
-- needed.
|
||||
|
||||
is static protected;
|
||||
|
||||
|
||||
Value(me: in out; X: Vector; F: out Real)
|
||||
---Purpose: this method computes the new approximation of the
|
||||
-- MultiLine
|
||||
-- SSP and calculates F = sum (||Pui - Bi*Pi||2) for each
|
||||
-- point of the MultiLine.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Gradient(me: in out; X: Vector; G: out Vector)
|
||||
---Purpose: returns the gradient G of the sum above for the
|
||||
-- parameters Xi.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Values(me: in out; X: Vector; F: out Real; G: out Vector)
|
||||
---Purpose: returns the value F=sum(||Pui - Bi*Pi||)2.
|
||||
-- returns the value G = grad(F) for the parameters Xi.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
NewParameters(me)
|
||||
---Purpose: returns the new parameters of the MultiLine.
|
||||
---C++: return const&
|
||||
returns Vector
|
||||
is static;
|
||||
|
||||
|
||||
CurveValue(me: in out)
|
||||
---Purpose: returns the MultiCurve approximating the set after
|
||||
-- computing the value F or Grad(F).
|
||||
---C++: return const&
|
||||
returns MultiCurve from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
Error(me; IPoint, CurveIndex: Integer)
|
||||
---Purpose: returns the distance between the MultiPoint of range
|
||||
-- IPoint and the curve CurveIndex.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
MaxError3d(me)
|
||||
---Purpose: returns the maximum distance between the points
|
||||
-- and the MultiCurve.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
MaxError2d(me)
|
||||
---Purpose: returns the maximum distance between the points
|
||||
-- and the MultiCurve.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
FirstConstraint(me; TheConstraints: HArray1OfConstraintCouple;
|
||||
FirstPoint: Integer)
|
||||
---Purpose:
|
||||
|
||||
returns Constraint from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
LastConstraint(me; TheConstraints: HArray1OfConstraintCouple;
|
||||
LastPoint: Integer)
|
||||
---Purpose:
|
||||
|
||||
returns Constraint from AppParCurves
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
Done: Boolean;
|
||||
MyMultiLine : MultiLine;
|
||||
MyMultiCurve: MultiCurve from AppParCurves;
|
||||
Degre: Integer;
|
||||
myParameters: Vector;
|
||||
FVal: Real;
|
||||
ValGrad_F: Vector from math;
|
||||
MyF: Matrix from math;
|
||||
PTLX : Matrix from math;
|
||||
PTLY : Matrix from math;
|
||||
PTLZ : Matrix from math;
|
||||
A: Matrix from math;
|
||||
DA: Matrix from math;
|
||||
MyLeastSquare : Squares;
|
||||
Contraintes: Boolean;
|
||||
NbP: Integer;
|
||||
NbCu: Integer;
|
||||
Adeb: Integer;
|
||||
Afin: Integer;
|
||||
tabdim: HArray1OfInteger from TColStd;
|
||||
ERR3d: Real;
|
||||
ERR2d: Real;
|
||||
FirstP: Integer;
|
||||
LastP: Integer;
|
||||
myConstraints: HArray1OfConstraintCouple from AppParCurves;
|
||||
|
||||
end Function;
|
609
src/AppParCurves/AppParCurves_Function.gxx
Executable file
609
src/AppParCurves/AppParCurves_Function.gxx
Executable file
@@ -0,0 +1,609 @@
|
||||
// File AppParCurves_Function.gxx
|
||||
// Lpa, le 20/09/91
|
||||
|
||||
|
||||
// Calcul de la valeur de F et grad_F, connaissant le parametrage.
|
||||
// Cette fonction, appelee par le gradient conjugue, calcul F et
|
||||
// DF(ui, Poles(ui)) ce qui implique un calcul des nouveaux poles
|
||||
// a chaque appel.
|
||||
|
||||
#define No_Standard_RangeError
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
|
||||
|
||||
#include <AppParCurves_MultiCurve.hxx>
|
||||
#include <AppParCurves_MultiPoint.hxx>
|
||||
#include <TColStd_HArray1OfInteger.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <AppParCurves_ConstraintCouple.hxx>
|
||||
|
||||
AppParCurves_Function::
|
||||
AppParCurves_Function(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const math_Vector& Parameters,
|
||||
const Standard_Integer Deg) :
|
||||
MyMultiLine(SSP),
|
||||
MyMultiCurve(Deg+1),
|
||||
myParameters(Parameters.Lower(), Parameters.Upper()),
|
||||
ValGrad_F(FirstPoint, LastPoint),
|
||||
MyF(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLX(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLY(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
PTLZ(FirstPoint, LastPoint,
|
||||
1, ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP), 0.0),
|
||||
A(FirstPoint, LastPoint, 1, Deg+1),
|
||||
DA(FirstPoint, LastPoint, 1, Deg+1),
|
||||
MyLeastSquare(SSP, FirstPoint, LastPoint,
|
||||
FirstConstraint(TheConstraints, FirstPoint),
|
||||
LastConstraint(TheConstraints, LastPoint), Deg+1)
|
||||
{
|
||||
Standard_Integer i;
|
||||
for (i=Parameters.Lower(); i<=Parameters.Upper();i++)
|
||||
myParameters(i)=Parameters(i);
|
||||
FirstP = FirstPoint;
|
||||
LastP = LastPoint;
|
||||
myConstraints = TheConstraints;
|
||||
NbP = LastP-FirstP+1;
|
||||
Adeb = FirstP;
|
||||
Afin = LastP;
|
||||
Degre = Deg;
|
||||
Contraintes = Standard_False;
|
||||
Standard_Integer myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == FirstP) {
|
||||
if (Cons >= 1) Adeb = Adeb+1;
|
||||
}
|
||||
else if (myindex == LastP) {
|
||||
if (Cons >= 1) Afin = Afin-1;
|
||||
}
|
||||
else {
|
||||
if (Cons >= 1) Contraintes = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer nb3d = ToolLine::NbP3d(SSP);
|
||||
Standard_Integer nb2d = ToolLine::NbP2d(SSP);
|
||||
Standard_Integer mynb3d= nb3d, mynb2d=nb2d;
|
||||
if (nb3d == 0) mynb3d = 1;
|
||||
if (nb2d == 0) mynb2d = 1;
|
||||
|
||||
NbCu = nb3d+nb2d;
|
||||
tabdim = new TColStd_HArray1OfInteger(0, NbCu-1);
|
||||
|
||||
if (Contraintes) {
|
||||
for (i = 1; i <= NbCu; i++) {
|
||||
if (i <= nb3d) tabdim->SetValue(i-1, 3);
|
||||
else tabdim->SetValue(i-1, 2);
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabP(1, mynb3d);
|
||||
TColgp_Array1OfPnt2d TabP2d(1, mynb2d);
|
||||
|
||||
for ( i = FirstP; i <= LastP; i++) {
|
||||
if (nb3d != 0 && nb2d != 0) ToolLine::Value(SSP, i, TabP, TabP2d);
|
||||
else if (nb3d != 0) ToolLine::Value(SSP, i, TabP);
|
||||
else ToolLine::Value(SSP, i, TabP2d);
|
||||
for (Standard_Integer j = 1; j <= NbCu; j++) {
|
||||
if (tabdim->Value(j-1) == 3) {
|
||||
TabP(j).Coord(PTLX(i, j), PTLY(i, j),PTLZ(i, j));
|
||||
}
|
||||
else {
|
||||
TabP2d(j).Coord(PTLX(i, j), PTLY(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_Constraint AppParCurves_Function::FirstConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer FirstPoint) const
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == FirstPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_Constraint AppParCurves_Function::LastConstraint
|
||||
(const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const Standard_Integer LastPoint) const
|
||||
{
|
||||
Standard_Integer i, myindex;
|
||||
Standard_Integer low = TheConstraints->Lower(), upp= TheConstraints->Upper();
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint Cons = AppParCurves_NoConstraint;
|
||||
|
||||
for (i = low; i <= upp; i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
Cons = mycouple.Constraint();
|
||||
myindex = mycouple.Index();
|
||||
if (myindex == LastPoint) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Cons;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_Function::Value (const math_Vector& X,
|
||||
Standard_Real& F) {
|
||||
|
||||
myParameters = X;
|
||||
|
||||
// Resolution moindres carres:
|
||||
// ===========================
|
||||
MyLeastSquare.Perform(myParameters);
|
||||
if (!(MyLeastSquare.IsDone())) {
|
||||
Done = Standard_False;
|
||||
return Standard_False;
|
||||
}
|
||||
if (!Contraintes) {
|
||||
MyLeastSquare.Error(FVal, ERR3d, ERR2d);
|
||||
F = FVal;
|
||||
}
|
||||
|
||||
// Resolution avec contraintes:
|
||||
// ============================
|
||||
else {
|
||||
Standard_Integer Npol = Degre+1;
|
||||
// Standard_Boolean Ext = Standard_True;
|
||||
Standard_Integer Ci, i, j, dimen;
|
||||
Standard_Real AA, BB, CC, AIJ, FX, FY, FZ, Fi;
|
||||
math_Vector PTCXCI(1, Npol), PTCYCI(1, Npol), PTCZCI(1, Npol);
|
||||
ERR3d = ERR2d = 0.0;
|
||||
|
||||
MyMultiCurve = MyLeastSquare.BezierValue();
|
||||
|
||||
A = MyLeastSquare.FunctionMatrix();
|
||||
ResolCons Resol(MyMultiLine, MyMultiCurve, FirstP, LastP, myConstraints,
|
||||
A, MyLeastSquare.DerivativeFunctionMatrix());
|
||||
if (!Resol.IsDone()) {
|
||||
Done = Standard_False;
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Calcul de F = Sum||C(ui)-Ptli||2 sur toutes les courbes :
|
||||
// ========================================================================
|
||||
FVal = 0.0;
|
||||
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
if (dimen == 3){
|
||||
MyMultiCurve.Value(j).Point(Ci).Coord(PTCXCI(j),PTCYCI(j),PTCZCI(j));
|
||||
}
|
||||
else{
|
||||
MyMultiCurve.Value(j).Point2d(Ci).Coord(PTCXCI(j), PTCYCI(j));
|
||||
}
|
||||
}
|
||||
|
||||
// Calcul de F:
|
||||
// ============
|
||||
for (i = Adeb; i <= Afin; i++) {
|
||||
AA = 0.0; BB = 0.0; CC = 0.0;
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
AIJ = A(i, j);
|
||||
AA += AIJ*PTCXCI(j);
|
||||
BB += AIJ*PTCYCI(j);
|
||||
if (dimen == 3) {
|
||||
CC += AIJ*PTCZCI(j);
|
||||
}
|
||||
}
|
||||
FX = AA-PTLX(i, Ci);
|
||||
FY = BB-PTLY(i, Ci);
|
||||
MyF(i,Ci) = FX*FX + FY*FY;
|
||||
if (dimen == 3) {
|
||||
FZ = CC-PTLZ(i,Ci);
|
||||
MyF(i, Ci) += FZ*FZ;
|
||||
Fi = MyF(i, Ci);
|
||||
if (Sqrt(Fi) > ERR3d) ERR3d = Sqrt(Fi);
|
||||
}
|
||||
else {
|
||||
Fi = MyF(i, Ci);
|
||||
if (Sqrt(Fi) > ERR2d) ERR2d = Sqrt(Fi);
|
||||
}
|
||||
FVal += Fi;
|
||||
}
|
||||
}
|
||||
F = FVal;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AppParCurves_Function::Perform(const math_Vector& X) {
|
||||
Standard_Integer j;
|
||||
|
||||
myParameters = X;
|
||||
// Resolution moindres carres:
|
||||
// ===========================
|
||||
MyLeastSquare.Perform(myParameters);
|
||||
|
||||
if (!(MyLeastSquare.IsDone())) {
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
for(j = myParameters.Lower(); j <= myParameters.Upper(); j++) {
|
||||
ValGrad_F(j) = 0.0;
|
||||
}
|
||||
|
||||
if (!Contraintes) {
|
||||
MyLeastSquare.ErrorGradient(ValGrad_F, FVal, ERR3d, ERR2d);
|
||||
}
|
||||
else {
|
||||
Standard_Integer Pi, Ci, i, k, dimen;
|
||||
Standard_Integer Npol = Degre+1;
|
||||
Standard_Real Scal, AA, BB, CC, DAA, DBB, DCC;
|
||||
Standard_Real FX, FY, FZ, AIJ, DAIJ, px, py, pz, Fi;
|
||||
AppParCurves_Constraint Cons=AppParCurves_NoConstraint;
|
||||
math_Matrix Grad_F(FirstP, LastP, 1, NbCu, 0.0);
|
||||
math_Vector PTCXCI(1, Npol), PTCYCI(1, Npol), PTCZCI(1, Npol);
|
||||
math_Vector PTCOXCI(1, Npol), PTCOYCI(1, Npol), PTCOZCI(1, Npol);
|
||||
// Standard_Boolean Ext = Standard_True;
|
||||
ERR3d = ERR2d = 0.0;
|
||||
|
||||
math_Matrix PTCOX(1, Npol, 1, NbCu), PTCOY(1, Npol, 1, NbCu),
|
||||
PTCOZ(1, Npol,1, NbCu);
|
||||
math_Matrix PTCX(1, Npol, 1, NbCu), PTCY(1, Npol, 1, NbCu),
|
||||
PTCZ(1, Npol,1, NbCu);
|
||||
Standard_Integer Inc;
|
||||
|
||||
MyMultiCurve = MyLeastSquare.BezierValue();
|
||||
|
||||
for (Ci =1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
if (dimen == 3){
|
||||
MyMultiCurve.Value(j).Point(Ci).Coord(PTCOX(j, Ci),
|
||||
PTCOY(j, Ci),
|
||||
PTCOZ(j, Ci));
|
||||
}
|
||||
else{
|
||||
MyMultiCurve.Value(j).Point2d(Ci).Coord(PTCOX(j, Ci), PTCOY(j, Ci));
|
||||
PTCOZ(j, Ci) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
A = MyLeastSquare.FunctionMatrix();
|
||||
DA = MyLeastSquare.DerivativeFunctionMatrix();
|
||||
|
||||
// Resolution avec contraintes:
|
||||
// ============================
|
||||
|
||||
ResolCons Resol(MyMultiLine, MyMultiCurve, FirstP, LastP,
|
||||
myConstraints, A, DA);
|
||||
if (!Resol.IsDone()) {
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Calcul de F = Sum||C(ui)-Ptli||2 et du gradient non contraint de F pour
|
||||
// chaque point PointIndex.
|
||||
// ========================================================================
|
||||
FVal = 0.0;
|
||||
for(j = FirstP; j <= LastP; j++) {
|
||||
ValGrad_F(j) = 0.0;
|
||||
}
|
||||
|
||||
math_Matrix TrA(A.LowerCol(), A.UpperCol(), A.LowerRow(), A.UpperRow());
|
||||
math_Matrix TrDA(DA.LowerCol(), DA.UpperCol(), DA.LowerRow(), DA.UpperRow());
|
||||
math_Matrix RESTM(A.LowerCol(), A.UpperCol(), A.LowerCol(), A.UpperCol());
|
||||
|
||||
const math_Matrix& K = Resol.ConstraintMatrix();
|
||||
const math_Matrix& DK = Resol.ConstraintDerivative(MyMultiLine, X, Degre, DA);
|
||||
math_Matrix TK(K.LowerCol(), K.UpperCol(), K.LowerRow(), K.UpperRow());
|
||||
TK = K.Transposed();
|
||||
const math_Vector& Vardua = Resol.Duale();
|
||||
math_Matrix KK(K.LowerCol(), K.UpperCol(), Vardua.Lower(), Vardua.Upper());
|
||||
KK = (K.Transposed())*(Resol.InverseMatrix());
|
||||
math_Matrix DTK(DK.LowerCol(), DK.UpperCol(), DK.LowerRow(), DK.UpperRow());
|
||||
DTK = DK.Transposed();
|
||||
TrA = A.Transposed();
|
||||
TrDA = DA.Transposed();
|
||||
RESTM = ((A.Transposed()*A).Inverse());
|
||||
|
||||
math_Vector DPTCO(1, K.ColNumber());
|
||||
math_Matrix DPTCO1(FirstP, LastP, 1, K.ColNumber());
|
||||
math_Vector DKPTC(1, K.RowNumber());
|
||||
|
||||
|
||||
|
||||
|
||||
FVal = 0.0;
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
if (dimen == 3){
|
||||
MyMultiCurve.Value(j).Point(Ci).Coord(PTCX(j, Ci),
|
||||
PTCY(j, Ci),
|
||||
PTCZ(j, Ci));
|
||||
}
|
||||
else{
|
||||
MyMultiCurve.Value(j).Point2d(Ci).Coord(PTCX(j, Ci), PTCY(j,Ci));
|
||||
PTCZ(j, Ci) = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calcul du gradient sans contraintes:
|
||||
// ====================================
|
||||
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
for (i = Adeb; i <= Afin; i++) {
|
||||
AA = 0.0; BB = 0.0; CC = 0.0; DAA = 0.0; DBB = 0.0; DCC = 0.0;
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
AIJ = A(i, j); DAIJ = DA(i, j);
|
||||
px = PTCX(j, Ci); py = PTCY(j, Ci);
|
||||
AA += AIJ*px; BB += AIJ*py;
|
||||
DAA += DAIJ*px; DBB += DAIJ*py;
|
||||
if (dimen == 3) {
|
||||
pz = PTCZ(j, Ci);
|
||||
CC += AIJ*pz; DCC += DAIJ*pz;
|
||||
}
|
||||
}
|
||||
FX = AA-PTLX(i, Ci);
|
||||
FY = BB-PTLY(i, Ci);
|
||||
MyF(i,Ci) = FX*FX + FY*FY;
|
||||
Grad_F(i, Ci) = 2.0*(DAA*FX + DBB*FY);
|
||||
if (dimen == 3) {
|
||||
FZ = CC-PTLZ(i,Ci);
|
||||
MyF(i, Ci) += FZ*FZ;
|
||||
Grad_F(i, Ci) += 2.0*DCC*FZ;
|
||||
Fi = MyF(i, Ci);
|
||||
if (Sqrt(Fi) > ERR3d) ERR3d = Sqrt(Fi);
|
||||
}
|
||||
else {
|
||||
Fi = MyF(i, Ci);
|
||||
if (Sqrt(Fi) > ERR2d) ERR2d = Sqrt(Fi);
|
||||
}
|
||||
FVal += Fi;
|
||||
ValGrad_F(i) += Grad_F(i, Ci);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calcul de DK*PTC:
|
||||
// =================
|
||||
for (i = 1; i <= K.RowNumber(); i++) {
|
||||
Inc = 0;
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
DKPTC(i) = 0.0;
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DKPTC(i) += DK(i, j+Inc)*PTCX(j, Ci)+ DK(i, j+Inc+Npol)*PTCY(j, Ci);
|
||||
if (dimen == 3) {
|
||||
DKPTC(i) += DK(i, j+Inc+2*Npol)*PTCZ(j, Ci);
|
||||
}
|
||||
}
|
||||
if (dimen == 3) Inc = Inc +3*Npol;
|
||||
else Inc = Inc +2*Npol;
|
||||
}
|
||||
}
|
||||
|
||||
math_Vector DERR(DTK.LowerRow(), DTK.UpperRow());
|
||||
DERR = (DTK)*Vardua-KK* ((DKPTC) + K*(DTK)*Vardua);
|
||||
|
||||
// rajout du gradient avec contraintes:
|
||||
// ====================================
|
||||
// dPTCO1/duk = [d(TA)/duk*[A*PTCO-PTL] + TA*dA/duk*PTCO]
|
||||
|
||||
|
||||
Inc = 0;
|
||||
|
||||
math_Vector Errx(A.LowerRow(), A.UpperRow());
|
||||
math_Vector Erry(A.LowerRow(), A.UpperRow());
|
||||
math_Vector Errz(A.LowerRow(), A.UpperRow());
|
||||
math_Vector Scalx(DA.LowerRow(), DA.UpperRow());
|
||||
math_Vector Scaly(DA.LowerRow(), DA.UpperRow());
|
||||
math_Vector Scalz(DA.LowerRow(), DA.UpperRow());
|
||||
math_Vector Erruzax(PTCXCI.Lower(), PTCXCI.Upper());
|
||||
math_Vector Erruzay(PTCYCI.Lower(), PTCYCI.Upper());
|
||||
math_Vector Erruzaz(PTCZCI.Lower(), PTCZCI.Upper());
|
||||
math_Vector TrDAPI(TrDA.LowerRow(), TrDA.UpperRow());
|
||||
math_Vector TrAPI(TrA.LowerRow(), TrA.UpperRow());
|
||||
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
PTCOXCI = PTCOX.Col(Ci);
|
||||
PTCOYCI = PTCOY.Col(Ci);
|
||||
PTCOZCI = PTCOZ.Col(Ci);
|
||||
PTCXCI = PTCX.Col(Ci);
|
||||
PTCYCI = PTCY.Col(Ci);
|
||||
PTCZCI = PTCZ.Col(Ci);
|
||||
|
||||
|
||||
Errx = (A*PTCOXCI - PTLX.Col(Ci));
|
||||
Erry = (A*PTCOYCI - PTLY.Col(Ci));
|
||||
Errz = (A*PTCOZCI - PTLZ.Col(Ci));
|
||||
Scalx = (DA*PTCOXCI); // Scal = DA * PTCO
|
||||
Scaly = (DA*PTCOYCI);
|
||||
Scalz = (DA*PTCOZCI);
|
||||
Erruzax = (PTCXCI - PTCOXCI);
|
||||
Erruzay = (PTCYCI - PTCOYCI);
|
||||
Erruzaz = (PTCZCI - PTCOZCI);
|
||||
|
||||
for (Pi = FirstP; Pi <= LastP; Pi++) {
|
||||
TrDAPI = (TrDA.Col(Pi));
|
||||
TrAPI = (TrA.Col(Pi));
|
||||
Standard_Real Taa = TrAPI*A.Row(Pi);
|
||||
Scal = 0.0;
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DPTCO1(Pi, j + Inc) = (TrDAPI*Errx(Pi)+TrAPI*Scalx(Pi))(j);
|
||||
DPTCO1(Pi, j + Inc+ Npol) = (TrDAPI*Erry(Pi)+TrAPI*Scaly(Pi))(j);
|
||||
Scal += DPTCO1(Pi, j+Inc)* Taa*Erruzax(j) + DPTCO1(Pi, j+Inc+Npol)*Taa*Erruzay(j);
|
||||
if (dimen == 3) {
|
||||
DPTCO1(Pi, j + Inc+ 2*Npol) = (TrDAPI*Errz(Pi)+TrAPI*Scalz(Pi))(j);
|
||||
Scal += DPTCO1(Pi, j+Inc+2*Npol)*Taa*Erruzaz(j);
|
||||
}
|
||||
}
|
||||
ValGrad_F(Pi) = ValGrad_F(Pi) - 2*Scal;
|
||||
}
|
||||
if (dimen == 3) Inc = Inc + 3*Npol;
|
||||
else Inc = Inc +2*Npol;
|
||||
}
|
||||
|
||||
|
||||
// on calcule DPTCO = - RESTM * DPTCO1:
|
||||
|
||||
// Calcul de DPTCO/duk:
|
||||
// dPTCO/duk = -Inv(T(A)*A)*[d(TA)/duk*[A*PTCO-PTL] + TA*dA/duk*PTCO]
|
||||
|
||||
Standard_Integer low=myConstraints->Lower(), upp=myConstraints->Upper();
|
||||
Inc = 0;
|
||||
for (Pi = FirstP; Pi <= LastP; Pi++) {
|
||||
for (i = low; i <= upp; i++) {
|
||||
if (myConstraints->Value(i).Index() == Pi) {
|
||||
Cons = myConstraints->Value(i).Constraint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Cons >= 1) {
|
||||
Inc = 0;
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DPTCO(j+Inc) = 0.0;
|
||||
DPTCO(j+Inc+Npol) = 0.0;
|
||||
if (dimen == 3) DPTCO(j+Inc+2*Npol) = 0.0;
|
||||
for (k = 1; k <= Npol; k++) {
|
||||
DPTCO(j+Inc) = DPTCO(j+Inc) -RESTM(j, k) * DPTCO1(Pi, j+Inc);
|
||||
DPTCO(j+Inc+Npol)=DPTCO(j+Inc+Npol)-RESTM(j, k)*DPTCO1(Pi,j+Inc+Npol);
|
||||
if (dimen == 3) {
|
||||
DPTCO(j+Inc+2*Npol) = DPTCO(j+Inc+2*Npol)
|
||||
-RESTM(j, k) * DPTCO1(Pi, j+Inc+2*Npol);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dimen == 3) Inc += 3*Npol;
|
||||
else Inc += 2*Npol;
|
||||
}
|
||||
|
||||
DERR = DERR-KK*K*DPTCO;
|
||||
|
||||
Inc = 0;
|
||||
for (Ci = 1; Ci <= NbCu; Ci++) {
|
||||
dimen = tabdim->Value(Ci-1);
|
||||
PTCOXCI = PTCOX.Col(Ci);
|
||||
PTCOYCI = PTCOY.Col(Ci);
|
||||
PTCOZCI = PTCOZ.Col(Ci);
|
||||
PTCXCI = PTCX.Col(Ci);
|
||||
PTCYCI = PTCY.Col(Ci);
|
||||
PTCZCI = PTCZ.Col(Ci);
|
||||
Erruzax = (PTCXCI - PTCOXCI);
|
||||
Erruzay = (PTCYCI - PTCOYCI);
|
||||
Erruzaz = (PTCZCI - PTCOZCI);
|
||||
Scal = 0.0;
|
||||
|
||||
for (j = 1; j <= Npol ; j++) {
|
||||
Scal = (A(Pi, j)*Erruzax(j)) * (A(Pi, j)*DERR(j+Inc)) +
|
||||
(A(Pi, j)*Erruzay(j)) * (A(Pi, j)*DERR(j+Inc+Npol));
|
||||
if (dimen == 3) {
|
||||
Scal += (A(Pi, j)*Erruzax(j)) * (A(Pi, j)*DERR(j+Inc+2*Npol));
|
||||
}
|
||||
}
|
||||
|
||||
ValGrad_F(Pi) = ValGrad_F(Pi) + 2*Scal;
|
||||
if (dimen == 3) Inc = Inc +3*Npol;
|
||||
else Inc = Inc + 2*Npol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_Function::NbVariables() const{
|
||||
return NbP;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_Function::Gradient (const math_Vector& X,
|
||||
math_Vector& G) {
|
||||
|
||||
Perform(X);
|
||||
G = ValGrad_F;
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_Function::Values (const math_Vector& X,
|
||||
Standard_Real& F,
|
||||
math_Vector& G) {
|
||||
|
||||
|
||||
Perform(X);
|
||||
F = FVal;
|
||||
G = ValGrad_F;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
const AppParCurves_MultiCurve& AppParCurves_Function::CurveValue() {
|
||||
if (!Contraintes) MyMultiCurve = MyLeastSquare.BezierValue();
|
||||
return MyMultiCurve;
|
||||
}
|
||||
|
||||
|
||||
Standard_Real AppParCurves_Function::Error(const Standard_Integer IPoint,
|
||||
const Standard_Integer CurveIndex) const {
|
||||
return Sqrt(MyF(IPoint, CurveIndex));
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_Function::MaxError3d() const
|
||||
{
|
||||
return ERR3d;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_Function::MaxError2d() const
|
||||
{
|
||||
return ERR2d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const math_Vector& AppParCurves_Function::NewParameters() const
|
||||
{
|
||||
return myParameters;
|
||||
}
|
147
src/AppParCurves/AppParCurves_Gradient.cdl
Executable file
147
src/AppParCurves/AppParCurves_Gradient.cdl
Executable file
@@ -0,0 +1,147 @@
|
||||
-- File: Gradient.cdl
|
||||
-- Created: Thu Jul 25 17:06:33 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
|
||||
generic class Gradient from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This algorithm uses the algorithms LeastSquare,
|
||||
-- ResConstraint and a gradient method to approximate a set
|
||||
-- of points (AppDef_MultiLine) with a minimization of the
|
||||
-- sum(square(|F(i)-Qi|)) by changing the parameter.
|
||||
-- The algorithm used is from of the mathematical
|
||||
-- package: math_BFGS, a gradient method.
|
||||
|
||||
|
||||
|
||||
uses Vector from math,
|
||||
MultipleVarFunctionWithGradient from math,
|
||||
MultiCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves
|
||||
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
NotDone from StdFail
|
||||
|
||||
|
||||
private class ParLeastSquare instantiates LeastSquare from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
private class ResConstraint instantiates ResolConstraint from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
private class ParFunction instantiates Function from AppParCurves
|
||||
(MultiLine, ToolLine, ParLeastSquare, ResConstraint);
|
||||
|
||||
class Gradient_BFGS from AppParCurves
|
||||
inherits BFGS from math
|
||||
uses MultipleVarFunctionWithGradient from math,
|
||||
Vector from math
|
||||
is
|
||||
|
||||
Create ( F : in out MultipleVarFunctionWithGradient from math ;
|
||||
StartingPoint : Vector from math ;
|
||||
Tolerance3d : Real from Standard ;
|
||||
Tolerance2d : Real from Standard ;
|
||||
Eps : Real from Standard ;
|
||||
NbIterations : Integer from Standard = 200 );
|
||||
|
||||
IsSolutionReached ( me ;
|
||||
F : in out MultipleVarFunctionWithGradient from math )
|
||||
returns Boolean from Standard is redefined ;
|
||||
|
||||
fields
|
||||
|
||||
myTol3d : Real from Standard ;
|
||||
myTol2d : Real from Standard ;
|
||||
|
||||
end Gradient_BFGS from AppParCurves ;
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: in out Vector; Deg: Integer;
|
||||
Tol3d, Tol2d: Real; NbIterations: Integer = 200)
|
||||
---Purpose: Tries to minimize the sum (square(||Qui - Bi*Pi||))
|
||||
-- where Pui describe the approximating Bezier curves'Poles
|
||||
-- and Qi the MultiLine points with a parameter ui.
|
||||
-- In this algorithm, the parameters ui are the unknowns.
|
||||
-- The tolerance required on this sum is given by Tol.
|
||||
-- The desired degree of the resulting curve is Deg.
|
||||
|
||||
returns Gradient from AppParCurves;
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if all has been correctly done.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Value(me)
|
||||
---Purpose: returns all the Bezier curves approximating the
|
||||
-- MultiLine SSP after minimization of the parameter.
|
||||
|
||||
returns MultiCurve from AppParCurves
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
Error(me; Index: Integer)
|
||||
---Purpose: returns the difference between the old and the new
|
||||
-- approximation.
|
||||
-- An exception is raised if NotDone.
|
||||
-- An exception is raised if Index<1 or Index>NbParameters.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail,
|
||||
OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
MaxError3d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
MaxError2d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
AverageError(me)
|
||||
---Purpose: returns the average error between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
SCU: MultiCurve from AppParCurves;
|
||||
ParError: Vector from math;
|
||||
AvError: Real;
|
||||
MError3d: Real;
|
||||
MError2d: Real;
|
||||
Done: Boolean;
|
||||
|
||||
end Gradient from AppParCurves;
|
226
src/AppParCurves/AppParCurves_Gradient.gxx
Executable file
226
src/AppParCurves/AppParCurves_Gradient.gxx
Executable file
@@ -0,0 +1,226 @@
|
||||
// File AppParCurves_Gradient.gxx
|
||||
// lpa, le 11/09/91
|
||||
|
||||
|
||||
// Application de la methode du gradient corrige pour minimiser
|
||||
// F = somme(||C(ui, Poles(ui)) - ptli||2.
|
||||
// La methode de gradient conjugue est programmee dans la bibliotheque
|
||||
// mathematique: math_BFGS.
|
||||
// cet algorithme doit etre appele uniquement lorsque on a affaire a un set
|
||||
// de points contraints (ailleurs qu aux extremites). En effet, l appel de la
|
||||
// fonction F a minimiser implique un appel a ParLeastSquare et ResConstraint.
|
||||
// Si ce n est pas le cas, l appel a ResConstraint est equivalent a une
|
||||
// seconde resolution par les moindres carres donc beaucoup de temps perdu.
|
||||
|
||||
|
||||
#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 <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_Array1OfVec.hxx>
|
||||
#include <TColgp_Array1OfVec2d.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <PLib.hxx>
|
||||
|
||||
// #define AppParCurves_Gradient_BFGS BFGS_/**/AppParCurves_Gradient
|
||||
|
||||
|
||||
|
||||
AppParCurves_Gradient::
|
||||
AppParCurves_Gradient(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 j, k, i2, l;
|
||||
Standard_Real UF, DU, Fval = 0.0, FU, DFU;
|
||||
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_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 = Standard_False;
|
||||
|
||||
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_ParFunction MyF(SSP, FirstPoint,LastPoint, TheConstraints, Parameters, Deg);
|
||||
|
||||
|
||||
if (!MyF.Value(Parameters, Fval)) {
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
SCU = MyF.CurveValue();
|
||||
Standard_Integer deg = SCU.NbPoles()-1;
|
||||
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);
|
||||
|
||||
|
||||
// Stockage des Poles des courbes pour projeter:
|
||||
// ============================================
|
||||
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, PLib::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, PLib::NoWeights(), Pt2d, V12d);
|
||||
MyV2d = gp_Vec2d(Pt2d, TabP2d(k));
|
||||
FU += MyV2d*V12d;
|
||||
DFU += V12d.SquareMagnitude();
|
||||
}
|
||||
|
||||
if (DFU >= RealEpsilon()) {
|
||||
DU = FU/DFU;
|
||||
DU = Sign(Min(5.e-02, Abs(DU)), DU);
|
||||
UF += DU;
|
||||
Parameters(j) = UF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!MyF.Value(Parameters, Fval)) {
|
||||
SCU = AppParCurves_MultiCurve();
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
MError3d = MyF.MaxError3d();
|
||||
MError2d = MyF.MaxError2d();
|
||||
|
||||
if (MError3d<= Tol3d && MError2d <= Tol2d) {
|
||||
Done = Standard_True;
|
||||
SCU = MyF.CurveValue();
|
||||
}
|
||||
else if (NbIterations != 0) {
|
||||
// NbIterations de gradient conjugue:
|
||||
// =================================
|
||||
Standard_Real 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) = 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_Gradient::Value() const {
|
||||
return SCU;
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_Gradient::IsDone() const {
|
||||
return Done;
|
||||
}
|
||||
|
||||
|
||||
Standard_Real AppParCurves_Gradient::Error(const Standard_Integer Index) const {
|
||||
return ParError(Index);
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_Gradient::AverageError() const {
|
||||
return AvError;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_Gradient::MaxError3d() const {
|
||||
return MError3d;
|
||||
}
|
||||
|
||||
Standard_Real AppParCurves_Gradient::MaxError2d() const {
|
||||
return MError2d;
|
||||
}
|
||||
|
||||
|
39
src/AppParCurves/AppParCurves_Gradient_BFGS.gxx
Executable file
39
src/AppParCurves/AppParCurves_Gradient_BFGS.gxx
Executable file
@@ -0,0 +1,39 @@
|
||||
// File: AppParCurves_Gradient_BFGS.gxx
|
||||
// Created: Thu Dec 16 13:09:24 1999
|
||||
// Author: Atelier CAS2000
|
||||
// <cas@cageox.paris1.matra-dtv.fr>
|
||||
//-Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
// Redefinition de math_BFGS:
|
||||
// ==========================
|
||||
|
||||
|
||||
AppParCurves_Gradient_BFGS::AppParCurves_Gradient_BFGS(math_MultipleVarFunctionWithGradient& F,
|
||||
const math_Vector& StartingPoint,
|
||||
const Standard_Real Tolerance3d,
|
||||
const Standard_Real Tolerance2d,
|
||||
const Standard_Real Eps,
|
||||
const Standard_Integer NbIterations ):
|
||||
math_BFGS(F, Eps, NbIterations, Eps),
|
||||
myTol3d(Tolerance3d),
|
||||
myTol2d(Tolerance2d)
|
||||
{
|
||||
Perform(F, StartingPoint);
|
||||
}
|
||||
|
||||
Standard_Boolean AppParCurves_Gradient_BFGS::IsSolutionReached(math_MultipleVarFunctionWithGradient& F) const
|
||||
{
|
||||
AppParCurves_ParFunction *F1 = (AppParCurves_ParFunction*) &F;
|
||||
Standard_Boolean Result, Result2;
|
||||
|
||||
Result = (2.0 * fabs(TheMinimum - PreviousMinimum) <=
|
||||
1.e-10 * (fabs(TheMinimum) + fabs(PreviousMinimum))+1.e-12);
|
||||
Standard_Real MErr3d = F1->MaxError3d();
|
||||
Standard_Real MErr2d = F1->MaxError2d();
|
||||
|
||||
Result2 = ((MErr3d <= myTol3d) && (MErr2d <= myTol2d));
|
||||
return (Result || Result2);
|
||||
}
|
||||
|
||||
|
381
src/AppParCurves/AppParCurves_LeastSquare.cdl
Executable file
381
src/AppParCurves/AppParCurves_LeastSquare.cdl
Executable file
@@ -0,0 +1,381 @@
|
||||
-- File: LeastSquare.cdl
|
||||
-- Created: Thu Jul 25 17:24:41 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
generic class LeastSquare from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This class describes the least square fitting of a
|
||||
-- MultiLine using the Householder method from the
|
||||
-- mathematical package.
|
||||
-- The problem to solve is the following one:
|
||||
-- minimizing the sum(|C(ui)- Qi|)2 where Qi are the points of
|
||||
-- the MultiLine and C(ui) the points of the approximating
|
||||
-- curves.
|
||||
|
||||
|
||||
|
||||
uses Matrix from math,
|
||||
Vector from math,
|
||||
IntegerVector from math,
|
||||
Constraint from AppParCurves,
|
||||
MultiCurve from AppParCurves,
|
||||
MultiBSpCurve from AppParCurves,
|
||||
Array1OfInteger from TColStd,
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfInteger from TColStd,
|
||||
HArray1OfReal from TColStd
|
||||
|
||||
|
||||
raises NotDone from StdFail,
|
||||
OutOfRange from Standard,
|
||||
DimensionError from Standard,
|
||||
NoSuchObject from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
FirstCons, LastCons: Constraint;
|
||||
Parameters: Vector from math; NbPol: Integer)
|
||||
---Purpose: given a MultiLine, this algorithm computes the least
|
||||
-- square resolution using the Householder-QR method.
|
||||
-- If the first and/or the last point is a constraint
|
||||
-- point, the value of the tangency or curvature is
|
||||
-- computed in the resolution.
|
||||
-- NbPol is the number of control points wanted
|
||||
-- for the approximating curves.
|
||||
-- The system to solve is the following:
|
||||
-- A X = B.
|
||||
-- Where A is the Bernstein matrix computed with the
|
||||
-- parameters, B the points coordinates and X the poles
|
||||
-- solutions.
|
||||
-- The matrix A is the same for each coordinate x, y and z
|
||||
-- and is also the same for each MultiLine point because
|
||||
-- they are approximated in parallel(so with the same
|
||||
-- parameter, only the vector B changes).
|
||||
|
||||
returns LeastSquare from AppParCurves
|
||||
raises DimensionError from Standard;
|
||||
|
||||
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
FirstCons, LastCons: Constraint; NbPol: Integer)
|
||||
---Purpose: Initializes the fields of the object.
|
||||
|
||||
returns LeastSquare;
|
||||
|
||||
|
||||
Create(SSP: MultiLine; Knots: Array1OfReal; Mults: Array1OfInteger;
|
||||
FirstPoint, LastPoint: Integer;
|
||||
FirstCons, LastCons: Constraint;
|
||||
Parameters: Vector from math; NbPol: Integer)
|
||||
---Purpose: given a MultiLine, this algorithm computes the least
|
||||
-- square resolution using the Householder-QR method.
|
||||
-- If the first and/or the last point is a constraint
|
||||
-- point, the value of the tangency or curvature is
|
||||
-- computed in the resolution.
|
||||
-- Deg is the degree wanted for the approximating curves.
|
||||
-- The system to solve is the following:
|
||||
-- A X = B.
|
||||
-- Where A is the BSpline functions matrix computed with
|
||||
-- <parameters>, B the points coordinates and X the poles
|
||||
-- solutions.
|
||||
-- The matrix A is the same for each coordinate x, y and z
|
||||
-- and is also the same for each MultiLine point because
|
||||
-- they are approximated in parallel(so with the same
|
||||
-- parameter, only the vector B changes).
|
||||
|
||||
returns LeastSquare from AppParCurves
|
||||
raises DimensionError from Standard;
|
||||
|
||||
|
||||
|
||||
Create(SSP: MultiLine; Knots: Array1OfReal; Mults: Array1OfInteger;
|
||||
FirstPoint, LastPoint: Integer;
|
||||
FirstCons, LastCons: Constraint; NbPol: Integer)
|
||||
---Purpose: Initializes the fields of the object.
|
||||
|
||||
returns LeastSquare;
|
||||
|
||||
|
||||
|
||||
Init(me: in out; SSP: MultiLine; FirstPoint, LastPoint: Integer)
|
||||
---Purpose: is used by the constuctors above.
|
||||
|
||||
is static protected;
|
||||
|
||||
|
||||
Perform(me: in out; Parameters: Vector)
|
||||
---Purpose: Is used after having initialized the fields.
|
||||
-- The case "CurvaturePoint" is not treated in this method.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
Perform(me: in out; Parameters: Vector;
|
||||
l1, l2: Real)
|
||||
---Purpose: Is used after having initialized the fields.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- for the two following methods, vectors <V> must be constructed
|
||||
-- as follow:
|
||||
-- V(v1x, v1y, v1z, ....., vnx, vny, vnz, v1x, v1y, ....., vmx, vmy)
|
||||
-- 3d curve 3d curve 2d curve 2d curve
|
||||
--
|
||||
-- the length of V must be Nb3dpoints*3 + Nb2dpoints*2
|
||||
|
||||
|
||||
Perform(me: in out; Parameters: Vector;
|
||||
V1t, V2t: Vector;
|
||||
l1, l2: Real)
|
||||
---Purpose: Is used after having initialized the fields.
|
||||
--- <V1t> is the tangent vector at the first point.
|
||||
--- <V2t> is the tangent vector at the last point.
|
||||
is static;
|
||||
|
||||
Perform(me: in out; Parameters: Vector;
|
||||
V1t, V2t, V1c, V2c: Vector;
|
||||
l1, l2: Real)
|
||||
---Purpose: Is used after having initialized the fields.
|
||||
--- <V1t> is the tangent vector at the first point.
|
||||
--- <V2t> is the tangent vector at the last point.
|
||||
--- <V1c> is the tangent vector at the first point.
|
||||
--- <V2c> is the tangent vector at the last point.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
-------------------------------
|
||||
--- Result methods:
|
||||
-------------------------------
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if all has been correctly done.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
BezierValue(me: in out)
|
||||
---Purpose: returns the result of the approximation, i.e. all the
|
||||
-- Curves.
|
||||
-- An exception is raised if NotDone.
|
||||
|
||||
returns MultiCurve from AppParCurves
|
||||
raises NotDone from StdFail,
|
||||
NoSuchObject from Standard
|
||||
is static;
|
||||
|
||||
|
||||
BSplineValue(me: in out)
|
||||
---Purpose: returns the result of the approximation, i.e. all the
|
||||
-- Curves.
|
||||
-- An exception is raised if NotDone.
|
||||
---C++: return const &
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises NotDone from StdFail,
|
||||
NoSuchObject from Standard
|
||||
is static;
|
||||
|
||||
|
||||
FunctionMatrix(me)
|
||||
---Purpose: returns the function matrix used to approximate the
|
||||
-- set.
|
||||
---C++: return const &
|
||||
|
||||
returns Matrix from math
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
DerivativeFunctionMatrix(me)
|
||||
---Purpose: returns the derivative function matrix used
|
||||
-- to approximate the set.
|
||||
---C++: return const &
|
||||
|
||||
returns Matrix from math
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
ErrorGradient(me: in out; Grad: in out Vector;
|
||||
F: in out Real; MaxE3d, MaxE2d: in out Real)
|
||||
---Purpose: returns the maximum errors between the MultiLine
|
||||
-- and the approximation curves. F is the sum of the square
|
||||
-- distances. Grad is the derivative vector of the
|
||||
-- function F.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
Distance(me: in out)
|
||||
---Purpose: returns the distances between the points of the
|
||||
-- multiline and the approximation curves.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix from math
|
||||
is static;
|
||||
|
||||
|
||||
Error(me: in out; F: in out Real;
|
||||
MaxE3d, MaxE2d: in out Real)
|
||||
---Purpose: returns the maximum errors between the MultiLine
|
||||
-- and the approximation curves. F is the sum of the square
|
||||
-- distances.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
FirstLambda(me)
|
||||
---Purpose: returns the value (P2 - P1)/ V1 if the first point
|
||||
-- was a tangency point.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
LastLambda(me)
|
||||
---Purpose: returns the value (PN - PN-1)/ VN if the last point
|
||||
-- was a tangency point.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
Points(me)
|
||||
---Purpose: returns the matrix of points value.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix
|
||||
is static;
|
||||
|
||||
|
||||
Poles(me)
|
||||
---Purpose: returns the matrix of resulting control points value.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix
|
||||
is static;
|
||||
|
||||
|
||||
KIndex(me)
|
||||
---Purpose: Returns the indexes of the first non null values of
|
||||
-- A and DA.
|
||||
-- The values are non null from Index(ieme point) +1
|
||||
-- to Index(ieme point) + degree +1.
|
||||
---C++: return const&
|
||||
|
||||
returns IntegerVector
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
-------------------------------
|
||||
--- internal methods:
|
||||
-------------------------------
|
||||
|
||||
NbBColumns(me; SSP: MultiLine)
|
||||
---Purpose: returns the number of second member columns.
|
||||
-- Is used internally to initialize the fields.
|
||||
returns Integer
|
||||
is static protected;
|
||||
|
||||
|
||||
TheFirstPoint(me; FirstCons: Constraint; FirstPoint: Integer)
|
||||
---Purpose: returns the first point beeing fitted.
|
||||
returns Integer
|
||||
is static protected;
|
||||
|
||||
|
||||
TheLastPoint(me; LastCons: Constraint; LastPoint: Integer)
|
||||
---Purpose: returns the last point beeing fitted.
|
||||
returns Integer
|
||||
is static protected;
|
||||
|
||||
|
||||
Affect(me: in out; SSP: MultiLine; Index: Integer;
|
||||
Cons: in out Constraint; Vt, Vc: in out Vector)
|
||||
---Purpose: Affects the fields in the case of a constraint point.
|
||||
is static protected;
|
||||
|
||||
|
||||
ComputeFunction(me: in out; Parameters: Vector)
|
||||
---Purpose:
|
||||
is static protected;
|
||||
|
||||
|
||||
SearchIndex(me: in out; Index: in out IntegerVector)
|
||||
is static protected;
|
||||
|
||||
|
||||
MakeTAA(me: in out; TheA, TheB: in out Vector)
|
||||
---Purpose: computes internal matrixes for the resolution
|
||||
is static protected;
|
||||
|
||||
MakeTAA(me: in out; TheA: in out Vector)
|
||||
---Purpose: computes internal matrixes for the resolution
|
||||
is static protected;
|
||||
|
||||
MakeTAA(me: in out; TheA: in out Vector; TheB: in out Matrix)
|
||||
---Purpose: computes internal matrixes for the resolution
|
||||
is static protected;
|
||||
|
||||
fields
|
||||
|
||||
|
||||
FirstConstraint : Constraint from AppParCurves;
|
||||
LastConstraint : Constraint from AppParCurves;
|
||||
SCU: MultiBSpCurve from AppParCurves;
|
||||
myknots: HArray1OfReal from TColStd;
|
||||
mymults: HArray1OfInteger from TColStd;
|
||||
mypoles: Matrix from math;
|
||||
A: Matrix from math;
|
||||
DA: Matrix from math;
|
||||
B2: Matrix from math;
|
||||
mypoints: Matrix from math;
|
||||
Vflatknots: Vector from math;
|
||||
Vec1t: Vector from math;
|
||||
Vec1c: Vector from math;
|
||||
Vec2t: Vector from math;
|
||||
Vec2c: Vector from math;
|
||||
theError: Matrix from math;
|
||||
myindex: IntegerVector from math;
|
||||
|
||||
ERR3d: Real;
|
||||
ERR2d: Real;
|
||||
lambda1: Real;
|
||||
lambda2: Real;
|
||||
|
||||
FirstP: Integer;
|
||||
LastP: Integer;
|
||||
Nlignes: Integer;
|
||||
Ninc: Integer;
|
||||
NA: Integer;
|
||||
myfirstp: Integer;
|
||||
mylastp: Integer;
|
||||
resinit: Integer;
|
||||
resfin: Integer;
|
||||
nbP2d: Integer;
|
||||
nbP: Integer;
|
||||
|
||||
nbpoles: Integer;
|
||||
deg: Integer;
|
||||
|
||||
done: Boolean;
|
||||
iscalculated : Boolean;
|
||||
isready : Boolean;
|
||||
end LeastSquare;
|
||||
|
1553
src/AppParCurves/AppParCurves_LeastSquare.gxx
Executable file
1553
src/AppParCurves/AppParCurves_LeastSquare.gxx
Executable file
File diff suppressed because it is too large
Load Diff
132
src/AppParCurves/AppParCurves_LinearCriteria.cdl
Executable file
132
src/AppParCurves/AppParCurves_LinearCriteria.cdl
Executable file
@@ -0,0 +1,132 @@
|
||||
-- File: AppParCurves_LinearCriteria.cdl
|
||||
-- Created: Thu Sep 11 18:06:06 1997
|
||||
-- Author: Philippe MANGIN
|
||||
-- <pmn@sgi29>
|
||||
---Copyright: Matra Datavision 1997
|
||||
|
||||
|
||||
generic class LinearCriteria from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
inherits SmoothCriterion from AppParCurves
|
||||
|
||||
---Purpose: defined an Linear Criteria to used in variational
|
||||
-- Smoothing of points.
|
||||
|
||||
|
||||
uses
|
||||
Vector from math,
|
||||
Matrix from math,
|
||||
Curve from FEmTool,
|
||||
HAssemblyTable from FEmTool,
|
||||
ElementaryCriterion from FEmTool,
|
||||
HArray2OfInteger from TColStd,
|
||||
HArray1OfReal from TColStd,
|
||||
Array1OfReal from TColStd
|
||||
|
||||
raises
|
||||
NotImplemented,
|
||||
DomainError
|
||||
|
||||
|
||||
|
||||
is
|
||||
Create(SSP: MultiLine;
|
||||
FirstPoint, LastPoint: Integer) returns LinearCriteria;
|
||||
|
||||
SetParameters(me : mutable; Parameters : HArray1OfReal);
|
||||
|
||||
SetCurve(me : mutable; C :Curve from FEmTool)
|
||||
is static;
|
||||
|
||||
GetCurve(me; C : out Curve from FEmTool)
|
||||
is static;
|
||||
|
||||
SetEstimation(me : mutable; E1, E2, E3 : Real)
|
||||
is static;
|
||||
|
||||
EstLength(me : mutable)
|
||||
---C++: return &
|
||||
returns Real is static;
|
||||
|
||||
GetEstimation(me; E1, E2, E3 : out Real)
|
||||
is static;
|
||||
|
||||
AssemblyTable(me)
|
||||
returns HAssemblyTable from FEmTool
|
||||
is static;
|
||||
|
||||
DependenceTable(me)
|
||||
returns HArray2OfInteger from TColStd
|
||||
is static;
|
||||
|
||||
|
||||
QualityValues (me : mutable; J1min, J2min, J3min : Real;
|
||||
J1, J2, J3 : out Real)
|
||||
returns Integer is static;
|
||||
|
||||
ErrorValues(me : mutable;
|
||||
MaxError, QuadraticError, AverageError : out Real)
|
||||
is static;
|
||||
|
||||
Hessian(me : mutable ;
|
||||
Element : Integer;
|
||||
Dimension1 : Integer;
|
||||
Dimension2 : Integer;
|
||||
H : out Matrix from math)
|
||||
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
|
||||
is static;
|
||||
|
||||
|
||||
Gradient(me : mutable;
|
||||
Element : Integer;
|
||||
Dimension : Integer;
|
||||
G : out Vector from math)
|
||||
is static;
|
||||
|
||||
InputVector(me : mutable; X : Vector from math;
|
||||
AssTable : HAssemblyTable from FEmTool)
|
||||
---Purpose: Convert the assembly Vector in an Curve;
|
||||
--
|
||||
raises DomainError;
|
||||
|
||||
SetWeight(me: mutable;
|
||||
QuadraticWeight, QualityWeight : Real;
|
||||
percentJ1, percentJ2, percentJ3 : Real)
|
||||
is static;
|
||||
|
||||
GetWeight(me; QuadraticWeight, QualityWeight : out Real)
|
||||
is static;
|
||||
|
||||
SetWeight(me: mutable;
|
||||
Weight : Array1OfReal)
|
||||
is static;
|
||||
|
||||
BuildCache(me: mutable; E : Integer) is private;
|
||||
|
||||
fields
|
||||
mySSP : MultiLine;
|
||||
myParameters : HArray1OfReal;
|
||||
myCache : HArray1OfReal;
|
||||
myCriteria : ElementaryCriterion from FEmTool[3];
|
||||
myEstimation: Real[3];
|
||||
myQuadraticWeight, myQualityWeight : Real;
|
||||
myPercent : Real[3];
|
||||
myPntWeight : Array1OfReal;
|
||||
myCurve : Curve from FEmTool;
|
||||
myLength : Real;
|
||||
myE : Integer;
|
||||
IF, IL : Integer;
|
||||
end LinearCriteria;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
746
src/AppParCurves/AppParCurves_LinearCriteria.gxx
Executable file
746
src/AppParCurves/AppParCurves_LinearCriteria.gxx
Executable file
@@ -0,0 +1,746 @@
|
||||
// File: AppParCurves_LinearCriteria.gxx
|
||||
// Created: Mon Nov 30 14:58:05 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
#include <PLib_Base.hxx>
|
||||
#include <PLib_JacobiPolynomial.hxx>
|
||||
#include <PLib_HermitJacobi.hxx>
|
||||
#include <GeomAbs_Shape.hxx>
|
||||
#include <TColStd_HArray2OfReal.hxx>
|
||||
#include <FEmTool_LinearTension.hxx>
|
||||
#include <FEmTool_LinearFlexion.hxx>
|
||||
#include <FEmTool_LinearJerk.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <math_Matrix.hxx>
|
||||
#include <math_Gauss.hxx>
|
||||
|
||||
static Standard_Integer order(const Handle(PLib_Base)& B)
|
||||
{
|
||||
return (*( Handle(PLib_HermitJacobi)*)&B)->NivConstr();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
AppParCurves_LinearCriteria::AppParCurves_LinearCriteria(const MultiLine& SSP,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint):
|
||||
mySSP(SSP),
|
||||
myPntWeight(FirstPoint, LastPoint),
|
||||
myE(0)
|
||||
{
|
||||
myPntWeight.Init(1.);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_LinearCriteria::SetParameters(const Handle(TColStd_HArray1OfReal)& Parameters)
|
||||
{
|
||||
myParameters = Parameters;
|
||||
myE = 0; // Cache become invalid.
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_LinearCriteria::SetCurve(const Handle(FEmTool_Curve)& C)
|
||||
{
|
||||
|
||||
if(myCurve.IsNull()) {
|
||||
myCurve = C;
|
||||
|
||||
Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
|
||||
NbDim = myCurve->Dimension(),
|
||||
Order = order(myCurve->Base());
|
||||
|
||||
GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
|
||||
switch (Order) {
|
||||
case 0 : ConstraintOrder = GeomAbs_C0;
|
||||
break;
|
||||
case 1 : ConstraintOrder = GeomAbs_C1;
|
||||
break;
|
||||
case 2 : ConstraintOrder = GeomAbs_C2;
|
||||
}
|
||||
|
||||
myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
|
||||
myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
|
||||
myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
|
||||
|
||||
Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
|
||||
|
||||
myCriteria[0]->Set(Coeff);
|
||||
myCriteria[1]->Set(Coeff);
|
||||
myCriteria[2]->Set(Coeff);
|
||||
}
|
||||
else if (myCurve != C) {
|
||||
|
||||
Standard_Integer OldMxDeg = myCurve->Base()->WorkDegree(),
|
||||
OldNbDim = myCurve->Dimension(),
|
||||
OldOrder = order(myCurve->Base());
|
||||
|
||||
myCurve = C;
|
||||
|
||||
Standard_Integer MxDeg = myCurve->Base()->WorkDegree(),
|
||||
NbDim = myCurve->Dimension(),
|
||||
Order = order(myCurve->Base());
|
||||
|
||||
if(MxDeg != OldMxDeg || Order != OldOrder) {
|
||||
|
||||
GeomAbs_Shape ConstraintOrder=GeomAbs_C0;
|
||||
switch (Order) {
|
||||
case 0 : ConstraintOrder = GeomAbs_C0;
|
||||
break;
|
||||
case 1 : ConstraintOrder = GeomAbs_C1;
|
||||
break;
|
||||
case 2 : ConstraintOrder = GeomAbs_C2;
|
||||
}
|
||||
|
||||
myCriteria[0] = new FEmTool_LinearTension(MxDeg, ConstraintOrder);
|
||||
myCriteria[1] = new FEmTool_LinearFlexion(MxDeg, ConstraintOrder);
|
||||
myCriteria[2] = new FEmTool_LinearJerk (MxDeg, ConstraintOrder);
|
||||
|
||||
Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
|
||||
|
||||
myCriteria[0]->Set(Coeff);
|
||||
myCriteria[1]->Set(Coeff);
|
||||
myCriteria[2]->Set(Coeff);
|
||||
}
|
||||
else if(NbDim != OldNbDim) {
|
||||
|
||||
Handle(TColStd_HArray2OfReal) Coeff = new TColStd_HArray2OfReal(0, 0, 1, NbDim);
|
||||
|
||||
myCriteria[0]->Set(Coeff);
|
||||
myCriteria[1]->Set(Coeff);
|
||||
myCriteria[2]->Set(Coeff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::GetCurve(Handle(FEmTool_Curve)& C) const
|
||||
{
|
||||
C = myCurve;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetEstimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::SetEstimation(const Standard_Real E1,
|
||||
const Standard_Real E2,
|
||||
const Standard_Real E3)
|
||||
{
|
||||
myEstimation[0] = E1;
|
||||
myEstimation[1] = E2;
|
||||
myEstimation[2] = E3;
|
||||
}
|
||||
|
||||
Standard_Real& AppParCurves_LinearCriteria::EstLength()
|
||||
{
|
||||
return myLength;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetEstimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::GetEstimation(Standard_Real& E1,
|
||||
Standard_Real& E2,
|
||||
Standard_Real& E3) const
|
||||
{
|
||||
E1 = myEstimation[0];
|
||||
E2 = myEstimation[1];
|
||||
E3 = myEstimation[2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AssemblyTable
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(FEmTool_HAssemblyTable) AppParCurves_LinearCriteria::AssemblyTable() const
|
||||
{
|
||||
if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::AssemblyTable");
|
||||
|
||||
Standard_Integer NbDim = myCurve->Dimension(),
|
||||
NbElm = myCurve->NbElements(),
|
||||
nc1 = order(myCurve->Base()) + 1;
|
||||
Standard_Integer MxDeg = myCurve->Base()->WorkDegree() ;
|
||||
|
||||
Handle(FEmTool_HAssemblyTable) AssTable = new FEmTool_HAssemblyTable(1, NbDim, 1, NbElm);
|
||||
|
||||
Handle(TColStd_HArray1OfInteger) GlobIndex, Aux;
|
||||
|
||||
Standard_Integer i, el = 1, dim = 1, NbGlobVar = 0, gi0;
|
||||
|
||||
// For dim = 1
|
||||
// For first element (el = 1)
|
||||
GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
|
||||
|
||||
for(i = 0; i < nc1; i++) {
|
||||
NbGlobVar++;
|
||||
GlobIndex->SetValue(i, NbGlobVar);
|
||||
}
|
||||
gi0 = MxDeg - 2 * nc1 + 1;
|
||||
for(i = nc1; i < 2*nc1; i++) {
|
||||
NbGlobVar++;
|
||||
GlobIndex->SetValue(i, NbGlobVar + gi0);
|
||||
}
|
||||
for(i = 2*nc1; i <= MxDeg; i++) {
|
||||
NbGlobVar++;
|
||||
GlobIndex->SetValue(i, NbGlobVar - nc1);
|
||||
}
|
||||
gi0 = NbGlobVar - nc1 + 1;
|
||||
AssTable->SetValue(dim, el, GlobIndex);
|
||||
|
||||
// For rest elements
|
||||
for(el = 2; el <= NbElm; el++) {
|
||||
GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
|
||||
for(i = 0; i < nc1; i++) GlobIndex->SetValue(i, gi0 + i);
|
||||
|
||||
gi0 = MxDeg - 2 * nc1 + 1;
|
||||
for(i = nc1; i < 2*nc1; i++) {
|
||||
NbGlobVar++;
|
||||
GlobIndex->SetValue(i, NbGlobVar + gi0);
|
||||
}
|
||||
for(i = 2*nc1; i <= MxDeg; i++) {
|
||||
NbGlobVar++;
|
||||
GlobIndex->SetValue(i, NbGlobVar - nc1);
|
||||
}
|
||||
gi0 = NbGlobVar - nc1 + 1;
|
||||
AssTable->SetValue(dim, el, GlobIndex);
|
||||
}
|
||||
|
||||
// For other dimensions
|
||||
gi0 = NbGlobVar;
|
||||
for(dim = 2; dim <= NbDim; dim++) {
|
||||
for(el = 1; el <= NbElm; el++) {
|
||||
Aux = AssTable->Value(1, el);
|
||||
GlobIndex = new TColStd_HArray1OfInteger(0, MxDeg);
|
||||
for(i = 0; i <= MxDeg; i++) GlobIndex->SetValue(i, Aux->Value(i) + NbGlobVar);
|
||||
AssTable->SetValue(dim, el, GlobIndex);
|
||||
}
|
||||
NbGlobVar += gi0;
|
||||
}
|
||||
|
||||
return AssTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(TColStd_HArray2OfInteger) AppParCurves_LinearCriteria::DependenceTable() const
|
||||
{
|
||||
if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::DependenceTable");
|
||||
|
||||
Standard_Integer Dim = myCurve->Dimension();
|
||||
|
||||
Handle(TColStd_HArray2OfInteger) DepTab =
|
||||
new TColStd_HArray2OfInteger(1, Dim, 1, Dim, 0);
|
||||
Standard_Integer i;
|
||||
for(i=1; i <= Dim; i++) DepTab->SetValue(i,i,1);
|
||||
|
||||
return DepTab;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : QualityValues
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer AppParCurves_LinearCriteria::QualityValues(const Standard_Real J1min,
|
||||
const Standard_Real J2min,
|
||||
const Standard_Real J3min,
|
||||
Standard_Real& J1,
|
||||
Standard_Real& J2,
|
||||
Standard_Real& J3)
|
||||
{
|
||||
if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::QualityValues");
|
||||
|
||||
Standard_Integer NbDim = myCurve->Dimension(),
|
||||
NbElm = myCurve->NbElements();
|
||||
|
||||
TColStd_Array1OfReal& Knots = myCurve->Knots();
|
||||
Handle(TColStd_HArray2OfReal) Coeff;
|
||||
|
||||
Standard_Integer el, deg = 0, curdeg, i;
|
||||
Standard_Real UFirst, ULast;
|
||||
|
||||
J1 = J2 = J3 = 0.;
|
||||
for(el = 1; el <= NbElm; el++) {
|
||||
|
||||
curdeg = myCurve->Degree(el);
|
||||
if(deg != curdeg) {
|
||||
deg = curdeg;
|
||||
Coeff = new TColStd_HArray2OfReal(0, deg, 1, NbDim);
|
||||
}
|
||||
|
||||
myCurve->GetElement(el, Coeff->ChangeArray2());
|
||||
|
||||
UFirst = Knots(el); ULast = Knots(el + 1);
|
||||
|
||||
myCriteria[0]->Set(Coeff);
|
||||
myCriteria[0]->Set(UFirst, ULast);
|
||||
J1 = J1 + myCriteria[0]->Value();
|
||||
|
||||
myCriteria[1]->Set(Coeff);
|
||||
myCriteria[1]->Set(UFirst, ULast);
|
||||
J2 = J2 + myCriteria[1]->Value();
|
||||
|
||||
myCriteria[2]->Set(Coeff);
|
||||
myCriteria[2]->Set(UFirst, ULast);
|
||||
J3 = J3 + myCriteria[2]->Value();
|
||||
|
||||
}
|
||||
|
||||
// Calculation of ICDANA - see MOTEST.f
|
||||
// Standard_Real JEsMin[3] = {.01, .001, .001}; // from MOTLIS.f
|
||||
Standard_Real JEsMin[3]; JEsMin[0] = J1min; JEsMin[1] = J2min; JEsMin[2] = J3min;
|
||||
Standard_Real ValCri[3]; ValCri[0] = J1; ValCri[1] = J2; ValCri[2] = J3;
|
||||
|
||||
Standard_Integer ICDANA = 0;
|
||||
|
||||
// (2) Test l'amelioration des estimations
|
||||
// (critere sureleve => Non minimisation )
|
||||
|
||||
for(i = 0; i <= 2; i++)
|
||||
if((ValCri[i] < 0.8 * myEstimation[i]) && (myEstimation[i] > JEsMin[i])) {
|
||||
if(ICDANA < 1) ICDANA = 1;
|
||||
if(ValCri[i] < 0.1 * myEstimation[i]) ICDANA = 2;
|
||||
myEstimation[i] = Max(1.05*ValCri[i], JEsMin[i]);
|
||||
}
|
||||
|
||||
|
||||
// (3) Mise a jours des Estimation
|
||||
// (critere sous-estimer => mauvais conditionement)
|
||||
|
||||
if (ValCri[0] > myEstimation[0] * 2) {
|
||||
myEstimation[0] += ValCri[0] * .1;
|
||||
if (ICDANA == 0) {
|
||||
if (ValCri[0] > myEstimation[0] * 10) {
|
||||
ICDANA = 2;
|
||||
}
|
||||
else ICDANA = 1;
|
||||
}
|
||||
else {
|
||||
ICDANA = 2;
|
||||
}
|
||||
}
|
||||
if (ValCri[1] > myEstimation[1] * 20) {
|
||||
myEstimation[1] += ValCri[1] * .1;
|
||||
if (ICDANA == 0) {
|
||||
if (ValCri[1] > myEstimation[1] * 100) {
|
||||
ICDANA = 2;
|
||||
}
|
||||
else ICDANA = 1;
|
||||
}
|
||||
else {
|
||||
ICDANA = 2;
|
||||
}
|
||||
}
|
||||
if (ValCri[2] > myEstimation[2] * 20) {
|
||||
myEstimation[2] += ValCri[2] * .05;
|
||||
if (ICDANA == 0) {
|
||||
if (ValCri[2] > myEstimation[2] * 100) {
|
||||
ICDANA = 2;
|
||||
}
|
||||
else ICDANA = 1;
|
||||
}
|
||||
else {
|
||||
ICDANA = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ICDANA;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ErrorValues
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_LinearCriteria::ErrorValues(Standard_Real& MaxError,
|
||||
Standard_Real& QuadraticError,
|
||||
Standard_Real& AverageError)
|
||||
{
|
||||
if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
|
||||
|
||||
Standard_Integer NbDim = myCurve->Dimension();
|
||||
|
||||
Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
|
||||
|
||||
if(NbDim != (2*myNbP2d + 3*myNbP3d)) Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
|
||||
|
||||
TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
|
||||
TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
|
||||
TColStd_Array1OfReal BasePoint(1,NbDim);
|
||||
gp_Pnt2d P2d;
|
||||
gp_Pnt P3d;
|
||||
|
||||
Standard_Integer i, ipnt, c0 = 0;
|
||||
Standard_Real SqrDist, Dist;
|
||||
|
||||
MaxError = QuadraticError = AverageError = 0.;
|
||||
|
||||
for(i = myParameters->Lower(); i <= myParameters->Upper(); i++) {
|
||||
|
||||
myCurve->D0(myParameters->Value(i), BasePoint);
|
||||
|
||||
|
||||
c0 = 0;
|
||||
ToolLine::Value(mySSP, i, TabP3d);
|
||||
for(ipnt = 1; ipnt <= myNbP3d; ipnt++) {
|
||||
P3d.SetCoord(BasePoint(c0+1), BasePoint(c0+2), BasePoint(c0+3));
|
||||
SqrDist = P3d.SquareDistance(TabP3d(ipnt)); Dist = Sqrt(SqrDist);
|
||||
MaxError = Max(MaxError, Dist);
|
||||
QuadraticError += SqrDist;
|
||||
AverageError += Dist;
|
||||
c0 += 3;
|
||||
}
|
||||
|
||||
if(myNbP3d == 0) ToolLine::Value(mySSP, i, TabP2d);
|
||||
else ToolLine::Value(mySSP, i, TabP3d, TabP2d);
|
||||
for(ipnt = 1; ipnt <= myNbP2d; ipnt++) {
|
||||
P2d.SetCoord(BasePoint(c0+1), BasePoint(c0+2));
|
||||
SqrDist = P2d.SquareDistance(TabP2d(ipnt)); Dist = Sqrt(SqrDist);
|
||||
MaxError = Max(MaxError, Dist);
|
||||
QuadraticError += SqrDist;
|
||||
AverageError += Dist;
|
||||
c0 += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Hessian
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_LinearCriteria::Hessian(const Standard_Integer Element,
|
||||
const Standard_Integer Dimension1,
|
||||
const Standard_Integer Dimension2,
|
||||
math_Matrix& H)
|
||||
{
|
||||
if(myCurve.IsNull()) Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
|
||||
|
||||
if(DependenceTable()->Value(Dimension1, Dimension2) == 0)
|
||||
Standard_DomainError::Raise("AppParCurves_LinearCriteria::Hessian");
|
||||
|
||||
Standard_Integer //NbDim = myCurve->Dimension(),
|
||||
MxDeg = myCurve->Base()->WorkDegree(),
|
||||
// Deg = myCurve->Degree(Element),
|
||||
Order = order(myCurve->Base());
|
||||
|
||||
|
||||
math_Matrix AuxH(0, H.RowNumber()-1, 0, H.ColNumber()-1, 0.);
|
||||
|
||||
TColStd_Array1OfReal& Knots = myCurve->Knots();
|
||||
Standard_Real UFirst, ULast;
|
||||
|
||||
UFirst = Knots(Element); ULast = Knots(Element + 1);
|
||||
|
||||
Standard_Integer icrit;
|
||||
|
||||
// Quality criterion part of Hessian
|
||||
|
||||
H.Init(0);
|
||||
|
||||
for(icrit = 0; icrit <= 2; icrit++) {
|
||||
myCriteria[icrit]->Set(UFirst, ULast);
|
||||
myCriteria[icrit]->Hessian(Dimension1, Dimension2, AuxH);
|
||||
H += (myQualityWeight*myPercent[icrit]/myEstimation[icrit]) * AuxH;
|
||||
}
|
||||
|
||||
// Least square part of Hessian
|
||||
|
||||
AuxH.Init(0.);
|
||||
|
||||
Standard_Real coeff = (ULast - UFirst)/2., curcoeff, poid;
|
||||
Standard_Integer ipnt, ii, degH = 2 * Order+1;
|
||||
|
||||
|
||||
Handle(PLib_Base) myBase = myCurve->Base();
|
||||
Standard_Integer k1, k2, i, j, i0 = H.LowerRow(), j0 = H.LowerCol(), i1, j1,
|
||||
di = myPntWeight.Lower() - myParameters->Lower();
|
||||
|
||||
//BuilCache
|
||||
if (myE != Element) BuildCache(Element);
|
||||
|
||||
// Compute the least square Hessian
|
||||
for(ii=1, ipnt = IF; ipnt <= IL; ipnt++, ii+=(MxDeg+1)) {
|
||||
poid = myPntWeight(di + ipnt) * 2.;
|
||||
const Standard_Real * BV = &myCache->Value(ii);
|
||||
|
||||
// Hermite*Hermite part of matrix
|
||||
for(i = 0; i <= degH; i++) {
|
||||
k1 = (i <= Order)? i : i - Order - 1;
|
||||
curcoeff = Pow(coeff, k1) * poid * BV[i];
|
||||
|
||||
// Hermite*Hermite part of matrix
|
||||
for(j = i; j <= degH; j++) {
|
||||
k2 = (j <= Order)? j : j - Order - 1;
|
||||
AuxH(i, j) += curcoeff * Pow(coeff, k2) * BV[j];
|
||||
}
|
||||
// Hermite*Jacobi part of matrix
|
||||
for(j = degH + 1; j <= MxDeg; j++) {
|
||||
AuxH(i, j) += curcoeff * BV[j];
|
||||
}
|
||||
}
|
||||
|
||||
// Jacoby*Jacobi part of matrix
|
||||
for(i = degH+1; i <= MxDeg; i++) {
|
||||
curcoeff = BV[i] * poid;
|
||||
for(j = i; j <= MxDeg; j++) {
|
||||
AuxH(i, j) += curcoeff * BV[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i1 = i0;
|
||||
for(i = 0; i <= MxDeg; i++) {
|
||||
j1 = j0 + i;
|
||||
for(j = i; j <= MxDeg; j++) {
|
||||
H(i1, j1) += myQuadraticWeight * AuxH(i, j);
|
||||
H(j1, i1) = H(i1, j1);
|
||||
j1++;
|
||||
}
|
||||
i1++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Gradient
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::Gradient(const Standard_Integer Element,
|
||||
const Standard_Integer Dimension,
|
||||
math_Vector& G)
|
||||
{
|
||||
if(myCurve.IsNull())
|
||||
Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
|
||||
|
||||
Standard_Integer myNbP2d = ToolLine::NbP2d(mySSP), myNbP3d = ToolLine::NbP3d(mySSP);
|
||||
|
||||
if(Dimension > (2*myNbP2d + 3*myNbP3d))
|
||||
Standard_DomainError::Raise("AppParCurves_LinearCriteria::ErrorValues");
|
||||
|
||||
TColgp_Array1OfPnt TabP3d(1, Max(1,myNbP3d));
|
||||
TColgp_Array1OfPnt2d TabP2d(1, Max(1,myNbP2d));
|
||||
|
||||
Standard_Boolean In3d;
|
||||
Standard_Integer IndPnt, IndCrd;
|
||||
|
||||
if(Dimension <= 3*myNbP3d) {
|
||||
In3d = Standard_True;
|
||||
IndCrd = Dimension % 3;
|
||||
IndPnt = Dimension / 3;
|
||||
if(IndCrd == 0) IndCrd = 3;
|
||||
else IndPnt++;
|
||||
}
|
||||
else {
|
||||
In3d = Standard_False;
|
||||
IndCrd = (Dimension - 3*myNbP3d) % 2;
|
||||
IndPnt = (Dimension - 3*myNbP3d) / 2;
|
||||
if(IndCrd == 0) IndCrd = 2;
|
||||
else IndPnt++;
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal& Knots = myCurve->Knots();
|
||||
Standard_Real UFirst, ULast, Pnt;
|
||||
UFirst = Knots(Element); ULast = Knots(Element + 1);
|
||||
Standard_Real coeff = (ULast-UFirst)/2;
|
||||
|
||||
Standard_Integer //Deg = myCurve->Degree(Element),
|
||||
Order = order(myCurve->Base());
|
||||
|
||||
Handle(PLib_Base) myBase = myCurve->Base();
|
||||
Standard_Integer MxDeg = myBase->WorkDegree();
|
||||
|
||||
Standard_Real curcoeff;
|
||||
Standard_Integer degH = 2 * Order + 1;
|
||||
Standard_Integer ipnt, k, i, ii, i0 = G.Lower(),
|
||||
di = myPntWeight.Lower() - myParameters->Lower();
|
||||
|
||||
if (myE != Element) BuildCache(Element);
|
||||
const Standard_Real * BV = &myCache->Value(1);
|
||||
BV--;
|
||||
|
||||
G.Init(0.);
|
||||
|
||||
for(ii=1,ipnt = IF; ipnt <= IL; ipnt++) {
|
||||
if(In3d) {
|
||||
ToolLine::Value(mySSP, ipnt, TabP3d);
|
||||
Pnt = TabP3d(IndPnt).Coord(IndCrd);
|
||||
}
|
||||
else {
|
||||
if(myNbP3d == 0) ToolLine::Value(mySSP, ipnt, TabP2d);
|
||||
else ToolLine::Value(mySSP, ipnt, TabP3d, TabP2d);
|
||||
Pnt = TabP2d(IndPnt).Coord(IndCrd);
|
||||
}
|
||||
|
||||
curcoeff = Pnt * myPntWeight(di + ipnt);
|
||||
for(i = 0; i <= MxDeg; i++,ii++)
|
||||
G(i0 + i) += BV[ii] * curcoeff;
|
||||
}
|
||||
|
||||
|
||||
G *= 2. * myQuadraticWeight;
|
||||
|
||||
for(i = 0; i <= degH; i++) {
|
||||
k = (i <= Order)? i : i - Order - 1;
|
||||
curcoeff = Pow(coeff, k);
|
||||
G(i0 + i) *= curcoeff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : InputVector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::InputVector(const math_Vector& X,
|
||||
const Handle(FEmTool_HAssemblyTable)& AssTable)
|
||||
{
|
||||
Standard_Integer NbDim = myCurve->Dimension(),
|
||||
NbElm = myCurve->NbElements() ;
|
||||
Standard_Integer MxDeg = 0 ;
|
||||
MxDeg = myCurve->Base()->WorkDegree();
|
||||
TColStd_Array2OfReal CoeffEl(0, MxDeg, 1, NbDim);
|
||||
|
||||
|
||||
Handle(TColStd_HArray1OfInteger) GlobIndex;
|
||||
|
||||
Standard_Integer el, dim, i, i0 = X.Lower() - 1;
|
||||
|
||||
for(el = 1; el <= NbElm; el++) {
|
||||
for(dim = 1; dim <= NbDim; dim++) {
|
||||
GlobIndex = AssTable->Value(dim, el);
|
||||
for(i = 0; i <= MxDeg; i++) CoeffEl(i, dim) = X(i0 + GlobIndex->Value(i));
|
||||
}
|
||||
myCurve->SetDegree(el, MxDeg);
|
||||
myCurve->SetElement(el, CoeffEl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetWeight
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::SetWeight(const Standard_Real QuadraticWeight,
|
||||
const Standard_Real QualityWeight,
|
||||
const Standard_Real percentJ1,
|
||||
const Standard_Real percentJ2,
|
||||
const Standard_Real percentJ3)
|
||||
{
|
||||
if (QuadraticWeight < 0. || QualityWeight < 0.)
|
||||
Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
|
||||
if (percentJ1 < 0. || percentJ2 < 0. || percentJ3 < 0.)
|
||||
Standard_DomainError::Raise("AppParCurves_LinearCriteria::SetWeight");
|
||||
|
||||
myQuadraticWeight = QuadraticWeight; myQualityWeight = QualityWeight;
|
||||
|
||||
Standard_Real Total = percentJ1 + percentJ2 + percentJ3;
|
||||
myPercent[0] = percentJ1 / Total;
|
||||
myPercent[1] = percentJ2 / Total;
|
||||
myPercent[2] = percentJ3 / Total;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetWeight
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::GetWeight(Standard_Real& QuadraticWeight,
|
||||
Standard_Real& QualityWeight) const
|
||||
{
|
||||
|
||||
QuadraticWeight = myQuadraticWeight; QualityWeight = myQualityWeight;
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetWeight
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::SetWeight(const TColStd_Array1OfReal& Weight)
|
||||
{
|
||||
myPntWeight = Weight;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : BuildCache
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AppParCurves_LinearCriteria::BuildCache(const Standard_Integer Element)
|
||||
{
|
||||
Standard_Real t;
|
||||
Standard_Real UFirst, ULast;
|
||||
Standard_Integer ipnt;
|
||||
|
||||
UFirst = myCurve->Knots()(Element);
|
||||
ULast = myCurve->Knots()(Element + 1);
|
||||
|
||||
IF = 0;
|
||||
for(ipnt = myParameters->Lower(); ipnt <= myParameters->Upper(); ipnt++) {
|
||||
t = myParameters->Value(ipnt);
|
||||
if((t > UFirst && t <= ULast) || (Element == 1 && t == UFirst)) {
|
||||
if (IF == 0) IF=ipnt;
|
||||
IL = ipnt;
|
||||
}
|
||||
else if (t>ULast) break;
|
||||
}
|
||||
|
||||
if (IF != 0) {
|
||||
Handle(PLib_Base) myBase = myCurve->Base();
|
||||
Standard_Integer order = myBase->WorkDegree()+1, ii;
|
||||
myCache = new TColStd_HArray1OfReal (1, (IL-IF+1)*(order));
|
||||
|
||||
ii =1;
|
||||
for(ipnt = IF, ii=1; ipnt <= IL; ipnt++, ii+=order) {
|
||||
Standard_Real * cache = &myCache->ChangeValue(ii);
|
||||
TColStd_Array1OfReal BasicValue(cache[0], 0, order-1);
|
||||
t = myParameters->Value(ipnt);
|
||||
Standard_Real coeff = 2./(ULast - UFirst), c0 = -(ULast + UFirst)/2., s;
|
||||
s = (t + c0) * coeff;
|
||||
myBase->D0(s, BasicValue);
|
||||
}
|
||||
}
|
||||
else { //pas de points dans l'interval.
|
||||
IF = IL;
|
||||
IL--;
|
||||
}
|
||||
myE = Element;
|
||||
}
|
85
src/AppParCurves/AppParCurves_MLineTool.cdl
Executable file
85
src/AppParCurves/AppParCurves_MLineTool.cdl
Executable file
@@ -0,0 +1,85 @@
|
||||
-- File: AppParCurves_MLineTool.cdl
|
||||
-- Created: Wed Jan 20 16:22:17 1993
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@sdsun1>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
|
||||
deferred generic class MLineTool from AppParCurves (MLine as any)
|
||||
|
||||
---Purpose: Template which defines all the services relative to
|
||||
-- a MultiLine for approximation algorithms.
|
||||
|
||||
|
||||
uses Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Vec from gp,
|
||||
Vec2d from gp,
|
||||
Array1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
Array1OfVec from TColgp,
|
||||
Array1OfVec2d from TColgp
|
||||
|
||||
is
|
||||
|
||||
|
||||
FirstPoint(myclass; ML: MLine) returns Integer;
|
||||
---Purpose: Returns the first index of multipoints of the MLine.
|
||||
|
||||
|
||||
LastPoint(myclass; ML: MLine) returns Integer;
|
||||
---Purpose: Returns the last index of multipoints of the MLine.
|
||||
|
||||
|
||||
|
||||
NbP2d(myclass; ML: MLine) returns Integer;
|
||||
---Purpose: Returns the number of 2d points of a MLine.
|
||||
|
||||
|
||||
NbP3d(myclass; ML: MLine) returns Integer;
|
||||
---Purpose: Returns the number of 3d points of a MLine.
|
||||
|
||||
|
||||
|
||||
Value(myclass; ML: MLine; MPointIndex: Integer; tabPt: out Array1OfPnt);
|
||||
---Purpose: returns the 3d points of the multipoint <MPointIndex>
|
||||
-- when only 3d points exist.
|
||||
|
||||
|
||||
Value(myclass; ML: MLine; MPointIndex: Integer;
|
||||
tabPt2d: out Array1OfPnt2d);
|
||||
---Purpose: returns the 2d points of the multipoint <MPointIndex>
|
||||
-- when only 2d points exist.
|
||||
|
||||
|
||||
Value(myclass; ML: MLine; MPointIndex: Integer;
|
||||
tabPt: out Array1OfPnt; tabPt2d: out Array1OfPnt2d);
|
||||
---Purpose: returns the 3d and 2d points of the multipoint
|
||||
-- <MPointIndex>.
|
||||
|
||||
|
||||
Tangency(myclass; ML: MLine; MPointIndex: Integer; tabV: out Array1OfVec)
|
||||
returns Boolean;
|
||||
---Purpose: returns the 3d points of the multipoint <MPointIndex>
|
||||
-- when only 3d points exist.
|
||||
|
||||
|
||||
Tangency(myclass; ML: MLine; MPointIndex: Integer;
|
||||
tabV2d: out Array1OfVec2d)
|
||||
returns Boolean;
|
||||
---Purpose: returns the 2d tangency points of the multipoint
|
||||
-- <MPointIndex> only when 2d points exist.
|
||||
|
||||
|
||||
Tangency(myclass; ML: MLine; MPointIndex: Integer;
|
||||
tabV: out Array1OfVec; tabV2d: out Array1OfVec2d)
|
||||
returns Boolean;
|
||||
---Purpose: returns the 3d and 2d points of the multipoint
|
||||
-- <MPointIndex>.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end MLineTool;
|
1
src/AppParCurves/AppParCurves_MLineTool.gxx
Executable file
1
src/AppParCurves/AppParCurves_MLineTool.gxx
Executable file
@@ -0,0 +1 @@
|
||||
|
206
src/AppParCurves/AppParCurves_MultiBSpCurve.cdl
Executable file
206
src/AppParCurves/AppParCurves_MultiBSpCurve.cdl
Executable file
@@ -0,0 +1,206 @@
|
||||
-- File: AppParCurves_MultiBSpCurve.cdl
|
||||
-- Created: Mon Sep 20 10:27:04 1993
|
||||
-- Author: Modelistation
|
||||
-- <model@zerox>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
class MultiBSpCurve from AppParCurves
|
||||
inherits MultiCurve from AppParCurves
|
||||
|
||||
---Purpose: This class describes a MultiBSpCurve approximating a Multiline.
|
||||
-- Just as a Multiline is a set of a given number of lines, a MultiBSpCurve is a set
|
||||
-- of a specified number of bsplines defined by:
|
||||
-- - A specified number of MultiPoints - the poles of a specified number of curves
|
||||
-- - The degree of approximation identical for each of the specified number of curves.
|
||||
--
|
||||
--
|
||||
-- Example of a MultiBSpCurve composed of a specified number of MultiPoints:
|
||||
--
|
||||
-- P1______P2_____P3______P4________........_____PNbMPoints
|
||||
--
|
||||
-- Q1______Q2_____Q3______Q4________........_____QNbMPoints
|
||||
-- . .
|
||||
-- . .
|
||||
-- . .
|
||||
-- R1______R2_____R3______R4________........_____RNbMPoints
|
||||
--
|
||||
--
|
||||
-- Pi, Qi, ..., Ri are points of dimension 2 or 3.
|
||||
--
|
||||
-- (Pi, Qi, ...Ri), i= 1,...NbPoles are MultiPoints.
|
||||
-- each MultiPoint has got NbPol Poles.
|
||||
-- MultiBSpCurves are created by the SplineValue method in the ComputeLine
|
||||
-- class, and by the Value method in TheVariational class. MultiBSpCurve
|
||||
-- provides the information required to create the BSpline defined by the approximation.
|
||||
|
||||
uses MultiPoint from AppParCurves,
|
||||
HArray1OfMultiPoint from AppParCurves,
|
||||
Array1OfMultiPoint from AppParCurves,
|
||||
Array1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
Array1OfReal from TColStd,
|
||||
Array1OfInteger from TColStd,
|
||||
HArray1OfReal from TColStd,
|
||||
HArray1OfInteger from TColStd,
|
||||
Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Vec from gp,
|
||||
Vec2d from gp,
|
||||
OStream from Standard
|
||||
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard,
|
||||
ConstructionError from Standard
|
||||
|
||||
is
|
||||
|
||||
Create returns MultiBSpCurve;
|
||||
---Purpose: returns an indefinite MultiBSpCurve.
|
||||
|
||||
|
||||
Create(NbPol: Integer)
|
||||
---Purpose: creates a MultiBSpCurve, describing BSpline curves all
|
||||
-- containing the same number of MultiPoint.
|
||||
-- An exception is raised if Degree < 0.
|
||||
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises OutOfRange from Standard;
|
||||
|
||||
|
||||
Create(tabMU: Array1OfMultiPoint; Knots: Array1OfReal;
|
||||
Mults: Array1OfInteger)
|
||||
---Purpose: creates a MultiBSpCurve, describing BSpline curves all
|
||||
-- containing the same number of MultiPoint.
|
||||
-- Each MultiPoint must have NbCurves Poles.
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises ConstructionError from Standard;
|
||||
|
||||
|
||||
|
||||
Create(SC: MultiCurve; Knots: Array1OfReal;
|
||||
Mults: Array1OfInteger)
|
||||
---Purpose: creates a MultiBSpCurve, describing BSpline
|
||||
-- curves, taking control points from <SC>.
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises ConstructionError from Standard;
|
||||
|
||||
|
||||
SetKnots(me: in out; theKnots: Array1OfReal)
|
||||
---Purpose: Knots of the multiBSpCurve are assigned to <theknots>.
|
||||
is static;
|
||||
|
||||
|
||||
SetMultiplicities(me: in out; theMults: Array1OfInteger)
|
||||
---Purpose: Multiplicities of the multiBSpCurve are assigned
|
||||
-- to <theMults>.
|
||||
is static;
|
||||
|
||||
|
||||
Knots(me)
|
||||
---Purpose: Returns an array of Reals containing
|
||||
-- the multiplicities of curves resulting from the approximation.
|
||||
---C++: return const&
|
||||
returns Array1OfReal
|
||||
is static;
|
||||
|
||||
Multiplicities(me)
|
||||
---Purpose: Returns an array of Reals containing the
|
||||
-- multiplicities of curves resulting from the approximation.
|
||||
---C++: return const&
|
||||
returns Array1OfInteger
|
||||
is static;
|
||||
|
||||
|
||||
Degree(me)
|
||||
---Purpose: returns the degree of the curve(s).
|
||||
|
||||
returns Integer
|
||||
is redefined;
|
||||
|
||||
|
||||
Value(me; CuIndex: Integer; U: Real; Pt: out Pnt)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
Value(me; CuIndex: Integer; U: Real; Pt: out Pnt2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
D1(me; CuIndex: Integer; U: Real; Pt: out Pnt; V1: out Vec)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
D1(me; CuIndex: Integer; U: Real; Pt: out Pnt2d; V1: out Vec2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
D2(me; CuIndex: Integer; U: Real; Pt: out Pnt; V1: out Vec; V2: out Vec)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
D2(me; CuIndex: Integer; U: Real; Pt: out Pnt2d;
|
||||
V1: out Vec2d; V2: out Vec2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the BSpline curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is redefined;
|
||||
|
||||
|
||||
Dump(me; o: in out OStream)
|
||||
---Purpose: Prints on the stream o information on the current
|
||||
-- state of the object.
|
||||
-- Is used to redefine the operator <<.
|
||||
|
||||
is redefined;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myknots: HArray1OfReal;
|
||||
mymults: HArray1OfInteger;
|
||||
myDegree : Integer;
|
||||
|
||||
end MultiBSpCurve;
|
295
src/AppParCurves/AppParCurves_MultiBSpCurve.cxx
Executable file
295
src/AppParCurves/AppParCurves_MultiBSpCurve.cxx
Executable file
@@ -0,0 +1,295 @@
|
||||
//File AppParCurves_MultiBSpCurve.cxx
|
||||
|
||||
#include <AppParCurves_MultiBSpCurve.ixx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <AppParCurves_HArray1OfMultiPoint.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeDegree
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Integer ComputeDegree(const TColStd_Array1OfInteger& mults,
|
||||
const Standard_Integer nbPoles)
|
||||
{
|
||||
Standard_Integer i, sum = 0;
|
||||
for (i = mults.Lower(); i <= mults.Upper(); i++) {
|
||||
sum += mults(i);
|
||||
}
|
||||
return sum - nbPoles -1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AppParCurves_MultiBSpCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
AppParCurves_MultiBSpCurve::AppParCurves_MultiBSpCurve() {}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AppParCurves_MultiBSpCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
AppParCurves_MultiBSpCurve::AppParCurves_MultiBSpCurve
|
||||
(const Standard_Integer NbPol):
|
||||
AppParCurves_MultiCurve(NbPol)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AppParCurves_MultiBSpCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
AppParCurves_MultiBSpCurve::AppParCurves_MultiBSpCurve
|
||||
(const AppParCurves_Array1OfMultiPoint& tabMU,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults):
|
||||
AppParCurves_MultiCurve(tabMU)
|
||||
{
|
||||
myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
|
||||
myknots->ChangeArray1() = Knots;
|
||||
mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
|
||||
mymults->ChangeArray1() = Mults;
|
||||
myDegree = ComputeDegree(Mults,NbPoles());
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AppParCurves_MultiBSpCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
AppParCurves_MultiBSpCurve::AppParCurves_MultiBSpCurve
|
||||
(const AppParCurves_MultiCurve& SC,
|
||||
const TColStd_Array1OfReal& Knots,
|
||||
const TColStd_Array1OfInteger& Mults):
|
||||
AppParCurves_MultiCurve(SC)
|
||||
{
|
||||
myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
|
||||
myknots->ChangeArray1() = Knots;
|
||||
mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
|
||||
mymults->ChangeArray1() = Mults;
|
||||
myDegree = ComputeDegree(Mults,NbPoles());
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetKnots
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::SetKnots(const TColStd_Array1OfReal& theKnots)
|
||||
{
|
||||
myknots = new TColStd_HArray1OfReal(theKnots.Lower(), theKnots.Upper());
|
||||
myknots->ChangeArray1() = theKnots;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMultiplicities
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::SetMultiplicities(const TColStd_Array1OfInteger& theMults)
|
||||
{
|
||||
mymults = new TColStd_HArray1OfInteger(theMults.Lower(), theMults.Upper());
|
||||
mymults->ChangeArray1() = theMults;
|
||||
myDegree = ComputeDegree(theMults,NbPoles());
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Knots
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColStd_Array1OfReal& AppParCurves_MultiBSpCurve::Knots() const
|
||||
{
|
||||
return myknots->Array1();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Multiplicities
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const TColStd_Array1OfInteger& AppParCurves_MultiBSpCurve::Multiplicities() const
|
||||
{
|
||||
return mymults->Array1();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Degree
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer AppParCurves_MultiBSpCurve::Degree() const
|
||||
{
|
||||
return myDegree;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::Value (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt& Pt) const {
|
||||
|
||||
if (Dimension(CuIndex) != 3) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D0(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::Value (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt2d& Pt) const {
|
||||
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D0(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : D1
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::D1 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt& Pt, gp_Vec& V1) const {
|
||||
if (Dimension(CuIndex) != 3) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D1(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt,V1);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : D2
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::D2 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U,
|
||||
gp_Pnt& Pt,
|
||||
gp_Vec& V1,
|
||||
gp_Vec& V2) const {
|
||||
if (Dimension(CuIndex) != 3) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D2(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt,V1,V2);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : D1
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::D1 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt2d& Pt, gp_Vec2d& V1) const {
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D1(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt,V1);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : D2
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::D2 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U,
|
||||
gp_Pnt2d& Pt,
|
||||
gp_Vec2d& V1,
|
||||
gp_Vec2d& V2) const {
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPoles(1, tabPoint->Length());
|
||||
Curve(CuIndex, TabPoles);
|
||||
|
||||
BSplCLib::D2(U,0,myDegree,Standard_False,TabPoles,BSplCLib::NoWeights(),
|
||||
myknots->Array1(),mymults->Array1(),Pt,V1,V2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Dump
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AppParCurves_MultiBSpCurve::Dump(Standard_OStream& o) const
|
||||
{
|
||||
o << "AppParCurves_MultiBSpCurve dump:" << endl;
|
||||
o << " It contains " << NbCurves() << " BSpline curves "<< endl;
|
||||
o << " The poles are: " << endl;
|
||||
/* for (Standard_Integer i = 1; i <= NbCurves(); i++) {
|
||||
o << " Curve No. " << i << endl;
|
||||
if (Dimension(i) == 3) {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(j)->Point(i)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(j)->Point(i)).Y() << endl;
|
||||
o << " Pole z = " << (tabPoint->Value(j)->Point(i)).Z() << endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(j)->Point2d(i)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(j)->Point2d(i)).Y() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
281
src/AppParCurves/AppParCurves_MultiCurve.cdl
Executable file
281
src/AppParCurves/AppParCurves_MultiCurve.cdl
Executable file
@@ -0,0 +1,281 @@
|
||||
-- File: MultiCurve.cdl
|
||||
-- Created: Mon Dec 2 13:52:19 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
|
||||
class MultiCurve from AppParCurves
|
||||
|
||||
---Purpose: This class describes a MultiCurve approximating a Multiline.
|
||||
-- As a Multiline is a set of n lines, a MultiCurve is a set
|
||||
-- of n curves. These curves are Bezier curves.
|
||||
-- A MultiCurve is composed of m MultiPoint.
|
||||
-- The approximating degree of these n curves is the same for
|
||||
-- each one.
|
||||
--
|
||||
--
|
||||
-- Example of a MultiCurve composed of MultiPoints:
|
||||
--
|
||||
-- P1______P2_____P3______P4________........_____PNbMPoints
|
||||
--
|
||||
-- Q1______Q2_____Q3______Q4________........_____QNbMPoints
|
||||
-- . .
|
||||
-- . .
|
||||
-- . .
|
||||
-- R1______R2_____R3______R4________........_____RNbMPoints
|
||||
--
|
||||
--
|
||||
-- Pi, Qi, ..., Ri are points of dimension 2 or 3.
|
||||
--
|
||||
-- (Pi, Qi, ...Ri), i= 1,...NbPoles are MultiPoints.
|
||||
-- each MultiPoint has got NbPol Poles.
|
||||
|
||||
|
||||
uses MultiPoint from AppParCurves,
|
||||
HArray1OfMultiPoint from AppParCurves,
|
||||
Array1OfMultiPoint from AppParCurves,
|
||||
Array1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Vec from gp,
|
||||
Vec2d from gp,
|
||||
OStream from Standard
|
||||
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard,
|
||||
ConstructionError from Standard
|
||||
|
||||
is
|
||||
|
||||
Create returns MultiCurve;
|
||||
---Purpose: returns an indefinite MultiCurve.
|
||||
|
||||
|
||||
Create(NbPol: Integer)
|
||||
---Purpose: creates a MultiCurve, describing Bezier curves all
|
||||
-- containing the same number of MultiPoint.
|
||||
-- An exception is raised if Degree < 0.
|
||||
|
||||
|
||||
returns MultiCurve from AppParCurves
|
||||
raises OutOfRange from Standard;
|
||||
|
||||
|
||||
Create(tabMU: Array1OfMultiPoint)
|
||||
---Purpose: creates a MultiCurve, describing Bezier curves all
|
||||
-- containing the same number of MultiPoint.
|
||||
-- Each MultiPoint must have NbCurves Poles.
|
||||
|
||||
returns MultiCurve from AppParCurves
|
||||
raises ConstructionError from Standard;
|
||||
|
||||
|
||||
Delete(me:out) is virtual;
|
||||
---C++: alias "Standard_EXPORT virtual ~AppParCurves_MultiCurve(){Delete();}"
|
||||
|
||||
SetNbPoles(me: in out; nbPoles: Integer)
|
||||
---Purpose: The number of poles of the MultiCurve
|
||||
-- will be set to <nbPoles>.
|
||||
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
SetValue(me: in out; Index: Integer;
|
||||
MPoint: MultiPoint from AppParCurves)
|
||||
---Purpose: sets the MultiPoint of range Index to the value
|
||||
-- <MPoint>.
|
||||
-- An exception is raised if Index <0 or Index >NbMPoint.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
NbCurves(me)
|
||||
---Purpose: Returns the number of curves resulting from the
|
||||
-- approximation of a MultiLine.
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
NbPoles(me)
|
||||
---Purpose: Returns the number of poles on curves resulting from the approximation of a MultiLine.
|
||||
|
||||
returns Integer
|
||||
is virtual;
|
||||
|
||||
|
||||
Degree(me)
|
||||
---Purpose: returns the degree of the curves.
|
||||
|
||||
returns Integer
|
||||
is virtual;
|
||||
|
||||
|
||||
Dimension(me; CuIndex: Integer)
|
||||
---Purpose: returns the dimension of the CuIndex curve.
|
||||
-- An exception is raised if CuIndex<0 or CuIndex>NbCurves.
|
||||
returns Integer
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Curve(me; CuIndex: Integer; TabPnt: in out Array1OfPnt)
|
||||
---Purpose: returns the Pole array of the curve of range CuIndex.
|
||||
-- An exception is raised if the dimension of the curve
|
||||
-- is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Curve(me; CuIndex: Integer; TabPnt: in out Array1OfPnt2d)
|
||||
---Purpose: returns the Pole array of the curve of range CuIndex.
|
||||
-- An exception is raised if the dimension of the curve
|
||||
-- is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Value(me; Index: Integer)
|
||||
---Purpose: returns the Index MultiPoint.
|
||||
-- An exception is raised if Index <0 or Index >Degree+1.
|
||||
---C++: return const&
|
||||
|
||||
returns MultiPoint from AppParCurves
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Pole(me; CuIndex, Nieme: Integer)
|
||||
---Purpose: returns the Nieme pole of the CuIndex curve.
|
||||
-- the curve must be a 3D curve.
|
||||
---C++: return const&
|
||||
|
||||
returns Pnt from gp
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Pole2d(me; CuIndex, Nieme: Integer)
|
||||
---Purpose: returns the Nieme pole of the CuIndex curve.
|
||||
-- the curve must be a 2D curve.
|
||||
---C++: return const&
|
||||
|
||||
returns Pnt2d from gp
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Transform(me: in out; CuIndex: Integer; x, dx, y, dy, z, dz: Real)
|
||||
---Purpose: Applies a transformation to the curve of range
|
||||
-- <CuIndex>.
|
||||
-- newx = x + dx*oldx
|
||||
-- newy = y + dy*oldy for all points of the curve.
|
||||
-- newz = z + dz*oldz
|
||||
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Transform2d(me: in out; CuIndex: Integer; x, dx, y, dy: Real)
|
||||
---Purpose: Applies a transformation to the Curve of range
|
||||
-- <CuIndex>.
|
||||
-- newx = x + dx*oldx
|
||||
-- newy = y + dy*oldy for all points of the curve.
|
||||
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Value(me; CuIndex: Integer; U: Real; Pt: out Pnt)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
|
||||
Value(me; CuIndex: Integer; U: Real; Pt: out Pnt2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
|
||||
D1(me; CuIndex: Integer; U: Real; Pt: out Pnt; V1: out Vec)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
|
||||
D1(me; CuIndex: Integer; U: Real; Pt: out Pnt2d; V1: out Vec2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
D2(me; CuIndex: Integer; U: Real; Pt: out Pnt; V1: out Vec; V2: out Vec)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 3d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
|
||||
D2(me; CuIndex: Integer; U: Real; Pt: out Pnt2d;
|
||||
V1: out Vec2d; V2: out Vec2d)
|
||||
---Purpose: returns the value of the point with a parameter U
|
||||
-- on the Bezier curve number CuIndex.
|
||||
-- An exception is raised if CuIndex <0 or > NbCurves.
|
||||
-- An exception is raised if the curve dimension is 2d.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is virtual;
|
||||
|
||||
|
||||
Dump(me; o: in out OStream)
|
||||
---Purpose: Prints on the stream o information on the current
|
||||
-- state of the object.
|
||||
-- Is used to redefine the operator <<.
|
||||
|
||||
is virtual;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
tabPoint: HArray1OfMultiPoint from AppParCurves is protected;
|
||||
|
||||
|
||||
end MultiCurve;
|
292
src/AppParCurves/AppParCurves_MultiCurve.cxx
Executable file
292
src/AppParCurves/AppParCurves_MultiCurve.cxx
Executable file
@@ -0,0 +1,292 @@
|
||||
//File AppParCurves_MultiCurve.cxx
|
||||
//Lpa, le 3/12/91
|
||||
|
||||
#include <AppParCurves_MultiCurve.ixx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <PLib.hxx>
|
||||
|
||||
|
||||
AppParCurves_MultiCurve::AppParCurves_MultiCurve() {}
|
||||
|
||||
|
||||
AppParCurves_MultiCurve::AppParCurves_MultiCurve (const Standard_Integer NbPol)
|
||||
{
|
||||
tabPoint = new AppParCurves_HArray1OfMultiPoint(1, NbPol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AppParCurves_MultiCurve::AppParCurves_MultiCurve (const AppParCurves_Array1OfMultiPoint& tabMU)
|
||||
{
|
||||
tabPoint = new AppParCurves_HArray1OfMultiPoint(1, tabMU.Length());
|
||||
Standard_Integer i, Lower = tabMU.Lower();
|
||||
for (i = 1; i <= tabMU.Length(); i++) {
|
||||
tabPoint->SetValue(i, tabMU.Value(Lower+i-1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AppParCurves_MultiCurve::Delete()
|
||||
{}
|
||||
|
||||
Standard_Integer AppParCurves_MultiCurve::Dimension (const Standard_Integer Index) const {
|
||||
Standard_Integer Lo = tabPoint->Lower();
|
||||
Standard_Integer nb = tabPoint->Value(Lo).NbPoints() + tabPoint->Value(Lo).NbPoints2d();
|
||||
if ((Index <= 0) || (Index > nb)) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
return tabPoint->Value(Lo).Dimension(Index);
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_MultiCurve::NbCurves () const {
|
||||
if (tabPoint.IsNull())
|
||||
return 0;
|
||||
AppParCurves_MultiPoint MP = tabPoint->Value(1);
|
||||
return MP.NbPoints() + MP.NbPoints2d();
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_MultiCurve::NbPoles() const {
|
||||
if (tabPoint.IsNull())
|
||||
return 0;
|
||||
return tabPoint->Length();
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_MultiCurve::Degree() const {
|
||||
return tabPoint->Length()-1;
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::SetNbPoles(const Standard_Integer nbPoles)
|
||||
{
|
||||
tabPoint = new AppParCurves_HArray1OfMultiPoint(1, nbPoles);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::SetValue (const Standard_Integer Index,
|
||||
const AppParCurves_MultiPoint& MPoint) {
|
||||
|
||||
if ((Index <= 0) || (Index > tabPoint->Length())) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
tabPoint->SetValue(Index, MPoint);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::Curve (const Standard_Integer CuIndex,
|
||||
TColgp_Array1OfPnt& TabPnt) const {
|
||||
if ((CuIndex <= 0)) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
for ( Standard_Integer i = 1; i <= tabPoint->Length(); i++) {
|
||||
TabPnt(i) = tabPoint->Value(i).Point(CuIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::Curve (const Standard_Integer CuIndex,
|
||||
TColgp_Array1OfPnt2d& TabPnt2d) const {
|
||||
if ((CuIndex <= 0)) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
for ( Standard_Integer i = 1; i <= tabPoint->Length(); i++) {
|
||||
TabPnt2d(i) = tabPoint->Value(i).Point2d(CuIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const gp_Pnt& AppParCurves_MultiCurve::Pole(const Standard_Integer CuIndex,
|
||||
const Standard_Integer Nieme) const
|
||||
{
|
||||
if ((CuIndex <= 0) && Nieme <= 0) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
return tabPoint->Value(Nieme).Point(CuIndex);
|
||||
}
|
||||
|
||||
const gp_Pnt2d& AppParCurves_MultiCurve::Pole2d(const Standard_Integer CuIndex,
|
||||
const Standard_Integer Nieme)const
|
||||
{
|
||||
if ((CuIndex <= 0) && Nieme <= 0) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
return tabPoint->Value(Nieme).Point2d(CuIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const AppParCurves_MultiPoint& AppParCurves_MultiCurve::Value (const Standard_Integer Index) const {
|
||||
if ((Index <= 0) || (Index > tabPoint->Length())) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
return tabPoint->Value(Index);
|
||||
}
|
||||
|
||||
void AppParCurves_MultiCurve::Transform(const Standard_Integer CuIndex,
|
||||
const Standard_Real x,
|
||||
const Standard_Real dx,
|
||||
const Standard_Real y,
|
||||
const Standard_Real dy,
|
||||
const Standard_Real z,
|
||||
const Standard_Real dz)
|
||||
{
|
||||
if (Dimension(CuIndex) != 3) Standard_OutOfRange::Raise();
|
||||
|
||||
for (Standard_Integer i = 1 ; i <= tabPoint->Length(); i++) {
|
||||
(tabPoint->ChangeValue(i)).Transform(CuIndex, x, dx, y, dy, z, dz);
|
||||
}
|
||||
}
|
||||
|
||||
void AppParCurves_MultiCurve::Transform2d(const Standard_Integer CuIndex,
|
||||
const Standard_Real x,
|
||||
const Standard_Real dx,
|
||||
const Standard_Real y,
|
||||
const Standard_Real dy)
|
||||
{
|
||||
if (Dimension(CuIndex) != 2) Standard_OutOfRange::Raise();
|
||||
|
||||
for (Standard_Integer i = 1 ; i <= tabPoint->Length(); i++) {
|
||||
(tabPoint->ChangeValue(i)).Transform2d(CuIndex, x, dx, y, dy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::Value (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt& Pt) const {
|
||||
|
||||
if (Dimension(CuIndex) != 3)Standard_OutOfRange::Raise();
|
||||
|
||||
TColgp_Array1OfPnt TabPoles(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPoles(i) = tabPoint->Value(i).Point(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D0 (U, TabPoles,PLib::NoWeights(), Pt);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::Value (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt2d& Pt) const {
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPole(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPole(i) = tabPoint->Value(i).Point2d(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D0 (U, TabPole, PLib::NoWeights(), Pt);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::D1 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U,
|
||||
gp_Pnt& Pt,
|
||||
gp_Vec& V1) const {
|
||||
|
||||
if (Dimension(CuIndex) != 3) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPole(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPole(i) = tabPoint->Value(i).Point(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D1 (U, TabPole, PLib::NoWeights(), Pt, V1);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::D2 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U,
|
||||
gp_Pnt& Pt,
|
||||
gp_Vec& V1,
|
||||
gp_Vec& V2) const {
|
||||
|
||||
if (Dimension(CuIndex) != 3) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt TabPole(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPole(i) = tabPoint->Value(i).Point(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D2 (U, TabPole, PLib::NoWeights(), Pt, V1, V2);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::D1 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U, gp_Pnt2d& Pt, gp_Vec2d& V1) const {
|
||||
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPole(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPole(i) = tabPoint->Value(i).Point2d(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D1 (U, TabPole, PLib::NoWeights(), Pt, V1);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::D2 (const Standard_Integer CuIndex,
|
||||
const Standard_Real U,
|
||||
gp_Pnt2d& Pt,
|
||||
gp_Vec2d& V1,
|
||||
gp_Vec2d& V2) const {
|
||||
|
||||
if (Dimension(CuIndex) != 2) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
|
||||
TColgp_Array1OfPnt2d TabPole(1, tabPoint->Length());
|
||||
|
||||
for (Standard_Integer i =1 ; i <= tabPoint->Length(); i++) {
|
||||
TabPole(i) = tabPoint->Value(i).Point2d(CuIndex);
|
||||
}
|
||||
|
||||
BSplCLib::D2(U, TabPole, PLib::NoWeights(), Pt, V1, V2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AppParCurves_MultiCurve::Dump(Standard_OStream& o) const
|
||||
{
|
||||
o << "AppParCurves_MultiCurve dump:" << endl;
|
||||
o << " It contains " << NbCurves() << " Bezier curves of degree " << tabPoint->Length()-1 << endl;
|
||||
o << " The poles are: " << endl;
|
||||
/* for (Standard_Integer i = 1; i <= NbCurves(); i++) {
|
||||
o << " Curve No. " << i << endl;
|
||||
if (Dimension(i) == 3) {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(j)->Point(i)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(j)->Point(i)).Y() << endl;
|
||||
o << " Pole z = " << (tabPoint->Value(j)->Point(i)).Z() << endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(j)->Point2d(i)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(j)->Point2d(i)).Y() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
180
src/AppParCurves/AppParCurves_MultiPoint.cdl
Executable file
180
src/AppParCurves/AppParCurves_MultiPoint.cdl
Executable file
@@ -0,0 +1,180 @@
|
||||
-- File: MultiPoint.cdl
|
||||
-- Created: Mon Dec 2 14:03:31 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
|
||||
class MultiPoint from AppParCurves
|
||||
---Purpose: This class describes Points composing a MultiPoint.
|
||||
-- These points can be 2D or 3D. The user must first give the
|
||||
-- 3D Points and then the 2D Points.
|
||||
-- They are Poles of a Bezier Curve.
|
||||
-- This class is used either to define data input or
|
||||
-- results when performing the approximation of several lines in parallel.
|
||||
|
||||
|
||||
uses Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Vec from gp,
|
||||
Vec2d from gp,
|
||||
Array1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
HArray1OfPnt from TColgp,
|
||||
HArray1OfPnt2d from TColgp,
|
||||
OStream from Standard,
|
||||
TShared from MMgt
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
|
||||
is
|
||||
|
||||
Create returns MultiPoint;
|
||||
---Purpose: creates an indefinite MultiPoint.
|
||||
|
||||
|
||||
Create(NbPoints, NbPoints2d: Integer)
|
||||
---Purpose: constructs a set of Points used to approximate a
|
||||
-- Multiline.
|
||||
-- These Points can be of 2 or 3 dimensions.
|
||||
-- Points will be initialized with SetPoint and SetPoint2d.
|
||||
-- NbPoints is the number of 3D Points.
|
||||
-- NbPoints2d is the number of 2D Points.
|
||||
|
||||
returns MultiPoint from AppParCurves;
|
||||
|
||||
|
||||
Create(tabP: Array1OfPnt)
|
||||
---Purpose: creates a MultiPoint only composed of 3D points.
|
||||
|
||||
returns MultiPoint from AppParCurves;
|
||||
|
||||
|
||||
Create(tabP2d: Array1OfPnt2d)
|
||||
---Purpose: creates a MultiPoint only composed of 2D points.
|
||||
|
||||
returns MultiPoint from AppParCurves;
|
||||
|
||||
|
||||
Create(tabP: Array1OfPnt; tabP2d: Array1OfPnt2d)
|
||||
---Purpose: constructs a set of Points used to approximate a
|
||||
-- Multiline.
|
||||
-- These Points can be of 2 or 3 dimensions.
|
||||
-- Points will be initialized with SetPoint and SetPoint2d.
|
||||
-- NbPoints is the total number of Points.
|
||||
|
||||
returns MultiPoint from AppParCurves;
|
||||
|
||||
|
||||
Delete(me:out) is virtual;
|
||||
---C++: alias "Standard_EXPORT virtual ~AppParCurves_MultiPoint(){Delete();}"
|
||||
|
||||
SetPoint(me: in out; Index: Integer; Point: Pnt)
|
||||
---Purpose: the 3d Point of range Index of this MultiPoint is
|
||||
-- set to <Point>.
|
||||
-- An exception is raised if Index < 0 or
|
||||
-- Index > number of 3d Points.
|
||||
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
Point(me; Index: Integer)
|
||||
---Purpose: returns the 3d Point of range Index.
|
||||
-- An exception is raised if Index < 0 or
|
||||
-- Index < number of 3d Points.
|
||||
---C++: return const&
|
||||
|
||||
returns Pnt from gp
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
SetPoint2d(me: in out; Index: Integer; Point: Pnt2d)
|
||||
---Purpose: The 2d Point of range Index is set to <Point>.
|
||||
-- An exception is raised if Index > 3d Points or
|
||||
-- Index > total number of Points.
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Point2d(me; Index: Integer)
|
||||
---Purpose: returns the 2d Point of range Index.
|
||||
-- An exception is raised if index <= number of
|
||||
-- 3d Points or Index > total number of Points.
|
||||
---C++: return const&
|
||||
|
||||
returns Pnt2d from gp
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
Dimension(me; Index: Integer)
|
||||
---Purpose: returns the dimension of the point of range Index.
|
||||
-- An exception is raised if Index <0 or Index > NbCurves.
|
||||
---C++: inline
|
||||
|
||||
returns Integer
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
NbPoints(me)
|
||||
---Purpose: returns the number of points of dimension 3D.
|
||||
---C++: inline
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
NbPoints2d(me)
|
||||
---Purpose: returns the number of points of dimension 2D.
|
||||
---C++: inline
|
||||
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
|
||||
Transform(me: in out; CuIndex: Integer; x, dx, y, dy, z, dz: Real)
|
||||
---Purpose: Applies a transformation to the curve of range
|
||||
-- <CuIndex>.
|
||||
-- newx = x + dx*oldx
|
||||
-- newy = y + dy*oldy for all points of the curve.
|
||||
-- newz = z + dz*oldz
|
||||
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Transform2d(me: in out; CuIndex: Integer; x, dx, y, dy: Real)
|
||||
---Purpose: Applies a transformation to the Curve of range
|
||||
-- <CuIndex>.
|
||||
-- newx = x + dx*oldx
|
||||
-- newy = y + dy*oldy for all points of the curve.
|
||||
|
||||
raises OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
Dump(me; o: in out OStream)
|
||||
---Purpose: Prints on the stream o information on the current
|
||||
-- state of the object.
|
||||
-- Is used to redefine the operator <<.
|
||||
is virtual;
|
||||
|
||||
fields
|
||||
|
||||
ttabPoint : TShared from MMgt is protected;
|
||||
ttabPoint2d: TShared from MMgt is protected;
|
||||
nbP : Integer is protected;
|
||||
nbP2d : Integer is protected;
|
||||
|
||||
end MultiPoint;
|
||||
|
183
src/AppParCurves/AppParCurves_MultiPoint.cxx
Executable file
183
src/AppParCurves/AppParCurves_MultiPoint.cxx
Executable file
@@ -0,0 +1,183 @@
|
||||
//File AppParCurves_MultiPoint.cxx
|
||||
//Lpa, le 3/12/91
|
||||
|
||||
|
||||
#include <AppParCurves_MultiPoint.ixx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <TColgp_HArray1OfPnt2d.hxx>
|
||||
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
#define tabPoint (*(Handle_TColgp_HArray1OfPnt*)&ttabPoint)
|
||||
#define tabPoint2d (*(Handle_TColgp_HArray1OfPnt2d*)&ttabPoint2d)
|
||||
|
||||
AppParCurves_MultiPoint::AppParCurves_MultiPoint() {}
|
||||
|
||||
|
||||
AppParCurves_MultiPoint::AppParCurves_MultiPoint (const Standard_Integer NbPoles,
|
||||
const Standard_Integer NbPoles2d)
|
||||
{
|
||||
nbP = NbPoles;
|
||||
nbP2d = NbPoles2d;
|
||||
if (nbP != 0) {
|
||||
Handle(TColgp_HArray1OfPnt) tab3d =
|
||||
new TColgp_HArray1OfPnt(1, NbPoles);
|
||||
ttabPoint = tab3d;
|
||||
}
|
||||
if (nbP2d != 0) {
|
||||
Handle(TColgp_HArray1OfPnt2d) tab2d =
|
||||
new TColgp_HArray1OfPnt2d(1, NbPoles2d);
|
||||
ttabPoint2d = tab2d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
AppParCurves_MultiPoint::AppParCurves_MultiPoint(const TColgp_Array1OfPnt& tabP)
|
||||
{
|
||||
nbP2d = 0;
|
||||
nbP = tabP.Length();
|
||||
Handle(TColgp_HArray1OfPnt) tab3d =
|
||||
new TColgp_HArray1OfPnt(1, nbP);
|
||||
ttabPoint = tab3d;
|
||||
Standard_Integer Lower = tabP.Lower();
|
||||
TColgp_Array1OfPnt& P3d = tabPoint->ChangeArray1();
|
||||
for (Standard_Integer i = 1; i <= tabP.Length(); i++) {
|
||||
P3d.SetValue(i, tabP.Value(Lower+i-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
AppParCurves_MultiPoint::AppParCurves_MultiPoint(const TColgp_Array1OfPnt2d& tabP2d)
|
||||
{
|
||||
nbP = 0;
|
||||
nbP2d = tabP2d.Length();
|
||||
Handle(TColgp_HArray1OfPnt2d) tab2d =
|
||||
new TColgp_HArray1OfPnt2d(1, nbP2d);
|
||||
ttabPoint2d = tab2d;
|
||||
Standard_Integer Lower = tabP2d.Lower();
|
||||
TColgp_Array1OfPnt2d& P2d = tabPoint2d->ChangeArray1();
|
||||
for (Standard_Integer i = 1; i <= nbP2d; i++) {
|
||||
P2d.SetValue(i, tabP2d.Value(Lower+i-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AppParCurves_MultiPoint::AppParCurves_MultiPoint(const TColgp_Array1OfPnt& tabP,
|
||||
const TColgp_Array1OfPnt2d& tabP2d)
|
||||
{
|
||||
nbP = tabP.Length();
|
||||
nbP2d = tabP2d.Length();
|
||||
Handle(TColgp_HArray1OfPnt) t3d =
|
||||
new TColgp_HArray1OfPnt(1, nbP);
|
||||
ttabPoint = t3d;
|
||||
|
||||
Handle(TColgp_HArray1OfPnt2d) t2d =
|
||||
new TColgp_HArray1OfPnt2d(1, nbP2d);
|
||||
ttabPoint2d = t2d;
|
||||
|
||||
TColgp_Array1OfPnt& P3d = tabPoint->ChangeArray1();
|
||||
Standard_Integer i, Lower = tabP.Lower();
|
||||
for (i = 1; i <= nbP; i++) {
|
||||
P3d.SetValue(i, tabP.Value(Lower+i-1));
|
||||
}
|
||||
Lower = tabP2d.Lower();
|
||||
TColgp_Array1OfPnt2d& P2d = tabPoint2d->ChangeArray1();
|
||||
for (i = 1; i <= nbP2d; i++) {
|
||||
P2d.SetValue(i, tabP2d.Value(Lower+i-1));
|
||||
}
|
||||
}
|
||||
|
||||
void AppParCurves_MultiPoint::Delete()
|
||||
{}
|
||||
|
||||
void AppParCurves_MultiPoint::Transform(const Standard_Integer CuIndex,
|
||||
const Standard_Real x,
|
||||
const Standard_Real dx,
|
||||
const Standard_Real y,
|
||||
const Standard_Real dy,
|
||||
const Standard_Real z,
|
||||
const Standard_Real dz)
|
||||
{
|
||||
if (Dimension(CuIndex) != 3) Standard_OutOfRange::Raise();
|
||||
|
||||
gp_Pnt P, newP;
|
||||
P = Point(CuIndex);
|
||||
newP.SetCoord(x + P.X()*dx, y + P.Y()*dy, z + P.Z()*dz);
|
||||
tabPoint->SetValue(CuIndex, newP);
|
||||
}
|
||||
|
||||
|
||||
void AppParCurves_MultiPoint::Transform2d(const Standard_Integer CuIndex,
|
||||
const Standard_Real x,
|
||||
const Standard_Real dx,
|
||||
const Standard_Real y,
|
||||
const Standard_Real dy)
|
||||
{
|
||||
if (Dimension(CuIndex) != 2) Standard_OutOfRange::Raise();
|
||||
|
||||
gp_Pnt2d P, newP;
|
||||
P = Point2d(CuIndex);
|
||||
newP.SetCoord(x + P.X()*dx, y + P.Y()*dy);
|
||||
SetPoint2d(CuIndex, newP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AppParCurves_MultiPoint::SetPoint (const Standard_Integer Index,
|
||||
const gp_Pnt& Point) {
|
||||
Standard_OutOfRange_Raise_if((Index <= 0) || (Index > nbP), "");
|
||||
tabPoint->SetValue(Index, Point);
|
||||
}
|
||||
|
||||
|
||||
const gp_Pnt& AppParCurves_MultiPoint::Point (const Standard_Integer Index) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if((Index <= 0) || (Index > nbP), "");
|
||||
return tabPoint->Value(Index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AppParCurves_MultiPoint::SetPoint2d (const Standard_Integer Index,
|
||||
const gp_Pnt2d& Point)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if((Index <= nbP) || (Index > nbP+nbP2d), "");
|
||||
tabPoint2d->SetValue(Index-nbP, Point);
|
||||
}
|
||||
|
||||
|
||||
const gp_Pnt2d& AppParCurves_MultiPoint::Point2d (const Standard_Integer Index) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if((Index <= nbP) || (Index > nbP+nbP2d), "");
|
||||
return tabPoint2d->Value(Index-nbP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AppParCurves_MultiPoint::Dump(Standard_OStream& o) const
|
||||
{
|
||||
o << "AppParCurves_MultiPoint dump:" << endl;
|
||||
o << "It contains " << NbPoints() << " 3d points and " << NbPoints2d() <<" 2d points." << endl;
|
||||
/*
|
||||
if (Dimension(i) == 3) {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(i)->Point(j)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(i)->Point(j)).Y() << endl;
|
||||
o << " Pole z = " << (tabPoint->Value(i)->Point(j)).Z() << endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (Standard_Integer j = 1; j <= tabPoint->Length(); j++) {
|
||||
o << " Pole No. " << j << ": " << endl;
|
||||
o << " Pole x = " << (tabPoint->Value(i)->Point2d(j)).X() << endl;
|
||||
o << " Pole y = " << (tabPoint->Value(i)->Point2d(j)).Y() << endl;
|
||||
}
|
||||
*/
|
||||
}
|
39
src/AppParCurves/AppParCurves_MultiPoint.lxx
Executable file
39
src/AppParCurves/AppParCurves_MultiPoint.lxx
Executable file
@@ -0,0 +1,39 @@
|
||||
// File AppParCurves_MultiPoint.lxx
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
|
||||
|
||||
inline Standard_OStream& operator<<(Standard_OStream& o,
|
||||
const AppParCurves_MultiPoint& M)
|
||||
{
|
||||
M.Dump(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline Standard_Integer AppParCurves_MultiPoint::NbPoints() const {
|
||||
return nbP;
|
||||
}
|
||||
|
||||
|
||||
inline Standard_Integer AppParCurves_MultiPoint::NbPoints2d() const {
|
||||
return nbP2d;
|
||||
}
|
||||
|
||||
|
||||
inline Standard_Integer AppParCurves_MultiPoint::Dimension(const Standard_Integer Index) const
|
||||
{
|
||||
if (Index < 0 || Index > (nbP + nbP2d)) {
|
||||
Standard_OutOfRange::Raise();
|
||||
}
|
||||
if (Index <= nbP) {
|
||||
return 3;
|
||||
}
|
||||
else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
120
src/AppParCurves/AppParCurves_Projection.cdl
Executable file
120
src/AppParCurves/AppParCurves_Projection.cdl
Executable file
@@ -0,0 +1,120 @@
|
||||
-- File: AppParCurves_Projection.cdl
|
||||
-- Created: Thu Jun 24 16:27:02 1993
|
||||
-- Author: Modelistation
|
||||
-- <model@nonox>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
generic class Projection from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This algorithm uses the algorithms LeastSquare,
|
||||
-- ResConstraint and a Projection method to approximate a set
|
||||
-- of points (AppDef_MultiLine) with a minimization of the
|
||||
-- sum(square(|F(i)-Qi|)) by changing the parameter.
|
||||
|
||||
|
||||
|
||||
uses Vector from math,
|
||||
MultiCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves
|
||||
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
NotDone from StdFail
|
||||
|
||||
|
||||
private class ProLeastSquare instantiates LeastSquare from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
private class ProConstraint instantiates ResolConstraint from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
private class ProFunction instantiates Function from AppParCurves
|
||||
(MultiLine, ToolLine, ProLeastSquare, ProConstraint);
|
||||
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
Parameters: in out Vector; Deg: Integer;
|
||||
Tol3d, Tol2d: Real; NbIterations: Integer = 200)
|
||||
---Purpose: Tries to minimize the sum (square(||Qui - Bi*Pi||))
|
||||
-- where Pui describe the approximating Bezier curves'Poles
|
||||
-- and Qi the MultiLine points with a parameter ui.
|
||||
-- In this algorithm, the parameters ui are the unknowns.
|
||||
-- The tolerance required on this sum is given by Tol.
|
||||
-- The desired degree of the resulting curve is Deg.
|
||||
-- SSP is returned with the new parameter.
|
||||
|
||||
returns Projection from AppParCurves;
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if all has been correctly done.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Value(me)
|
||||
---Purpose: returns all the Bezier curves approximating the
|
||||
-- MultiLine SSP after minimization of the parameter.
|
||||
|
||||
returns MultiCurve from AppParCurves
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
Error(me; Index: Integer)
|
||||
---Purpose: returns the difference between the old and the new
|
||||
-- approximation.
|
||||
-- An exception is raised if NotDone.
|
||||
-- An exception is raised if Index<1 or Index>NbParameters.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail,
|
||||
OutOfRange from Standard
|
||||
is static;
|
||||
|
||||
|
||||
MaxError3d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
MaxError2d(me)
|
||||
---Purpose: returns the maximum difference between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
AverageError(me)
|
||||
---Purpose: returns the average error between the old and the
|
||||
-- new approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
SCU: MultiCurve from AppParCurves;
|
||||
ParError: Vector from math;
|
||||
AvError: Real;
|
||||
MError3d: Real;
|
||||
MError2d: Real;
|
||||
Done: Boolean;
|
||||
|
||||
end Projection from AppParCurves;
|
223
src/AppParCurves/AppParCurves_Projection.gxx
Executable file
223
src/AppParCurves/AppParCurves_Projection.gxx
Executable file
@@ -0,0 +1,223 @@
|
||||
// File AppParCurves_Projection.gxx
|
||||
// lpa, le 11/09/91
|
||||
|
||||
|
||||
|
||||
#define No_Standard_RangeError
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <AppParCurves_Constraint.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 <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_Array1OfVec.hxx>
|
||||
#include <TColgp_Array1OfVec2d.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
132
src/AppParCurves/AppParCurves_ResolConstraint.cdl
Executable file
132
src/AppParCurves/AppParCurves_ResolConstraint.cdl
Executable file
@@ -0,0 +1,132 @@
|
||||
-- File: ResolConstraint.cdl
|
||||
-- Created: Thu Jul 25 16:56:48 1991
|
||||
-- Author: Laurent PAINNOT
|
||||
-- <lpa@topsn3>
|
||||
---Copyright: Matra Datavision 1991, 1992
|
||||
|
||||
|
||||
|
||||
generic class ResolConstraint from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This classe describes the algorithm to find the approximate
|
||||
-- solution of a MultiLine with constraints. The resolution
|
||||
-- algorithm is the Uzawa method. See the math package
|
||||
-- for more information.
|
||||
-- All the tangencies of MultiPointConstraint's points
|
||||
-- will be colinear.
|
||||
-- Be careful of the curvature: it is possible to have some
|
||||
-- curvAature points only for one curve. In this case, the Uzawa
|
||||
-- method is used with a non-linear resolution, much more longer.
|
||||
|
||||
|
||||
uses Matrix from math,
|
||||
Vector from math,
|
||||
Array1OfInteger from TColStd,
|
||||
MultiCurve from AppParCurves,
|
||||
HArray1OfConstraintCouple from AppParCurves
|
||||
|
||||
|
||||
raises OutOfRange from Standard
|
||||
|
||||
is
|
||||
|
||||
Create(SSP: MultiLine; SCurv: in out MultiCurve;
|
||||
FirstPoint, LastPoint: Integer;
|
||||
Constraints: HArray1OfConstraintCouple;
|
||||
Bern, DerivativeBern: Matrix; Tolerance: Real = 1.0e-10)
|
||||
---Purpose: Given a MultiLine SSP with constraints points, this
|
||||
-- algorithm finds the best curve solution to approximate it.
|
||||
-- The poles from SCurv issued for example from the least
|
||||
-- squares are used as a guess solution for the uzawa
|
||||
-- algorithm. The tolerance used in the Uzawa algorithms
|
||||
-- is Tolerance.
|
||||
-- A is the Bernstein matrix associated to the MultiLine
|
||||
-- and DA is the derivative bernstein matrix.(They can come
|
||||
-- from an approximation with ParLeastSquare.)
|
||||
-- The MultiCurve is modified. New MultiPoles are given.
|
||||
|
||||
|
||||
returns ResolConstraint from AppParCurves;
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if all has been correctly done.
|
||||
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
Error(me)
|
||||
---Purpose: returns the maximum difference value between the curve
|
||||
-- and the given points.
|
||||
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
|
||||
ConstraintMatrix(me)
|
||||
---Purpose:
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix
|
||||
is static;
|
||||
|
||||
|
||||
Duale(me)
|
||||
---Purpose: returns the duale variables of the system.
|
||||
---C++: return const&
|
||||
returns Vector
|
||||
is static;
|
||||
|
||||
|
||||
ConstraintDerivative(me: in out; SSP: MultiLine; Parameters: Vector;
|
||||
Deg: Integer; DA: Matrix)
|
||||
---Purpose: Returns the derivative of the constraint matrix.
|
||||
---C++: return const&
|
||||
returns Matrix
|
||||
is static;
|
||||
|
||||
|
||||
InverseMatrix(me)
|
||||
---Purpose: returns the Inverse of Cont*Transposed(Cont), where
|
||||
-- Cont is the constraint matrix for the algorithm.
|
||||
---C++: return const&
|
||||
|
||||
returns Matrix
|
||||
is static;
|
||||
|
||||
NbConstraints(me; SSP: MultiLine; FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple)
|
||||
---Purpose: is used internally to create the fields.
|
||||
|
||||
returns Integer
|
||||
is static protected;
|
||||
|
||||
|
||||
NbColumns(me; SSP: MultiLine; Deg: Integer)
|
||||
---Purpose: is internally used for the fields creation.
|
||||
|
||||
returns Integer
|
||||
is static protected;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
Done: Boolean;
|
||||
Err: Real;
|
||||
Cont: Matrix;
|
||||
DeCont: Matrix;
|
||||
Secont: Vector;
|
||||
CTCinv: Matrix;
|
||||
Vardua: Vector;
|
||||
IncPass: Integer;
|
||||
IncTan: Integer;
|
||||
IncCurv: Integer;
|
||||
IPas: Array1OfInteger;
|
||||
ITan: Array1OfInteger;
|
||||
ICurv: Array1OfInteger;
|
||||
|
||||
end ResolConstraint;
|
936
src/AppParCurves/AppParCurves_ResolConstraint.gxx
Executable file
936
src/AppParCurves/AppParCurves_ResolConstraint.gxx
Executable file
@@ -0,0 +1,936 @@
|
||||
// File AppParCurves_ResolConstraint.gxx
|
||||
// lpa, le 11/09/91
|
||||
|
||||
|
||||
// Approximation d un ensemble de points contraints (MultiLine) avec une
|
||||
// solution approchee (MultiCurve). L algorithme utilise est l algorithme
|
||||
// d Uzawa du package mathematique.
|
||||
|
||||
#define No_Standard_RangeError
|
||||
#define No_Standard_OutOfRange
|
||||
|
||||
#include <math_Vector.hxx>
|
||||
#include <math_Matrix.hxx>
|
||||
#include <AppParCurves_Constraint.hxx>
|
||||
#include <AppParCurves_ConstraintCouple.hxx>
|
||||
#include <AppParCurves_MultiPoint.hxx>
|
||||
#include <AppParCurves.hxx>
|
||||
#include <Standard_DimensionError.hxx>
|
||||
#include <math_Uzawa.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColStd_Array2OfInteger.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_Array1OfVec.hxx>
|
||||
#include <TColgp_Array1OfVec2d.hxx>
|
||||
|
||||
|
||||
AppParCurves_ResolConstraint::
|
||||
AppParCurves_ResolConstraint(const MultiLine& SSP,
|
||||
AppParCurves_MultiCurve& SCurv,
|
||||
const Standard_Integer FirstPoint,
|
||||
const Standard_Integer LastPoint,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints,
|
||||
const math_Matrix& Bern,
|
||||
const math_Matrix& DerivativeBern,
|
||||
const Standard_Real Tolerance):
|
||||
Cont(1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints),
|
||||
1, NbColumns(SSP, SCurv.NbPoles()-1), 0.0),
|
||||
DeCont(1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints),
|
||||
1, NbColumns(SSP, SCurv.NbPoles()-1), 0.0),
|
||||
Secont(1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints), 0.0),
|
||||
CTCinv(1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints),
|
||||
1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints)),
|
||||
Vardua(1, NbConstraints(SSP, FirstPoint,
|
||||
LastPoint, TheConstraints)),
|
||||
IPas(1, LastPoint-FirstPoint+1),
|
||||
ITan(1, LastPoint-FirstPoint+1),
|
||||
ICurv(1, LastPoint-FirstPoint+1)
|
||||
{
|
||||
Standard_Integer i, j, k, NbCu= SCurv.NbCurves();
|
||||
// Standard_Integer Npt, Nptl = LastPoint-FirstPoint+1;
|
||||
Standard_Integer Npt;
|
||||
Standard_Integer Inc3, IncSec, IncCol, IP, CCol;
|
||||
Standard_Integer myindex, Def = SCurv.NbPoles()-1;
|
||||
Standard_Integer nb3d, nb2d, Npol= Def+1, Npol2 = 2*Npol;
|
||||
Standard_Real T1, T2, T3, Tmax, Daij;
|
||||
Standard_Boolean Ok;
|
||||
gp_Vec V;
|
||||
gp_Vec2d V2d;
|
||||
gp_Pnt Poi;
|
||||
gp_Pnt2d Poi2d;
|
||||
AppParCurves_ConstraintCouple mycouple;
|
||||
AppParCurves_Constraint FC = AppParCurves_NoConstraint,
|
||||
LC = AppParCurves_NoConstraint, Cons;
|
||||
|
||||
|
||||
|
||||
// Boucle de calcul du nombre de points de passage afin de dimensionner
|
||||
// les matrices.
|
||||
IncPass = 0;
|
||||
IncTan = 0;
|
||||
IncCurv = 0;
|
||||
for (i = TheConstraints->Lower(); i <= TheConstraints->Upper(); i++) {
|
||||
mycouple = TheConstraints->Value(i);
|
||||
myindex = mycouple.Index();
|
||||
Cons = mycouple.Constraint();
|
||||
if (myindex == FirstPoint) FC = Cons;
|
||||
if (myindex == LastPoint) LC = Cons;
|
||||
if (Cons >= 1) {
|
||||
IncPass++; // IncPass = nbre de points de passage.
|
||||
IPas(IncPass) = myindex;
|
||||
}
|
||||
if (Cons >= 2) {
|
||||
IncTan++; // IncTan= nbre de points de tangence.
|
||||
ITan(IncTan) = myindex;
|
||||
}
|
||||
if (Cons == 3) {
|
||||
IncCurv++; // IncCurv = nbre de pts de courbure.
|
||||
ICurv(IncCurv) = myindex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (IncPass == 0) {
|
||||
Done = Standard_True;
|
||||
return;
|
||||
}
|
||||
|
||||
nb3d = ToolLine::NbP3d(SSP);
|
||||
nb2d = ToolLine::NbP2d(SSP);
|
||||
Standard_Integer mynb3d=nb3d, mynb2d=nb2d;
|
||||
if (nb3d == 0) mynb3d = 1;
|
||||
if (nb2d == 0) mynb2d = 1;
|
||||
CCol = nb3d* 3 + nb2d* 2;
|
||||
|
||||
|
||||
// Declaration et initialisation des matrices et vecteurs de contraintes:
|
||||
math_Matrix ContInit(1, IncPass, 1, Npol);
|
||||
math_Vector Start(1, CCol*Npol);
|
||||
TColStd_Array2OfInteger Ibont(1, NbCu, 1, IncTan);
|
||||
|
||||
|
||||
// Remplissage de Cont pour les points de passage:
|
||||
// =================================================
|
||||
for (i =1; i <= IncPass; i++) { // Cette partie ne depend que de Bernstein
|
||||
Npt = IPas(i);
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
ContInit(i, j) = Bern(Npt, j);
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= CCol; i++) {
|
||||
Cont.Set(IncPass*(i-1)+1, IncPass*i, Npol*(i-1)+1, Npol*i, ContInit);
|
||||
}
|
||||
|
||||
|
||||
// recuperation des vecteurs de depart pour Uzawa. Ce vecteur represente les
|
||||
// poles de SCurv.
|
||||
// Remplissage de secont et resolution.
|
||||
|
||||
TColgp_Array1OfVec tabV(1, mynb3d);
|
||||
TColgp_Array1OfVec2d tabV2d(1, mynb2d);
|
||||
TColgp_Array1OfPnt tabP(1, mynb3d);
|
||||
TColgp_Array1OfPnt2d tabP2d(1, mynb2d);
|
||||
|
||||
Inc3 = CCol*IncPass +1;
|
||||
IncCol = 0;
|
||||
IncSec = 0;
|
||||
for (k = 1; k <= NbCu; k++) {
|
||||
if (k <= nb3d) {
|
||||
for (i = 1; i <= IncTan; i++) {
|
||||
Npt = ITan(i);
|
||||
// choix du maximum de tangence pour exprimer la colinearite:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
V.Coord(T1, T2, T3);
|
||||
Tmax = Abs(T1);
|
||||
Ibont(k, i) = 1;
|
||||
if (Abs(T2) > Tmax) {
|
||||
Tmax = Abs(T2);
|
||||
Ibont(k, i) = 2;
|
||||
}
|
||||
if (Abs(T3) > Tmax) {
|
||||
Tmax = Abs(T3);
|
||||
Ibont(k, i) = 3;
|
||||
}
|
||||
if (Ibont(k, i) == 3) {
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j+ Npol + IncCol) = Daij*T3/Tmax;
|
||||
Cont(Inc3, j + Npol2 + IncCol) = -Daij *T2/Tmax;
|
||||
Cont(Inc3+1, j+ IncCol) = Daij* T3/Tmax;
|
||||
Cont(Inc3+1, j+ Npol2 + IncCol) = -Daij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k, i) == 1) {
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T3/Tmax;
|
||||
Cont(Inc3, j + Npol2 + IncCol) = -Daij *T1/Tmax;
|
||||
Cont(Inc3+1, j+ IncCol) = Daij* T2/Tmax;
|
||||
Cont(Inc3+1, j+ Npol +IncCol) = -Daij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k, i) == 2) {
|
||||
for (j = 1; j <= Def+1; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j+ Npol + IncCol) = Daij*T3/Tmax;
|
||||
Cont(Inc3, j + Npol2 + IncCol) = -Daij *T2/Tmax;
|
||||
Cont(Inc3+1, j+ IncCol) = Daij* T2/Tmax;
|
||||
Cont(Inc3+1, j+ Npol + IncCol) = -Daij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
Inc3 = Inc3 + 2;
|
||||
}
|
||||
|
||||
// Remplissage du second membre:
|
||||
for (i = 1; i <= IncPass; i++) {
|
||||
ToolLine::Value(SSP, IPas(i), tabP);
|
||||
Poi = tabP(k);
|
||||
Secont(i + IncSec) = Poi.X();
|
||||
Secont(i + IncPass + IncSec) = Poi.Y();
|
||||
Secont(i + 2*IncPass + IncSec) = Poi.Z();
|
||||
}
|
||||
IncSec = IncSec + 3*IncPass;
|
||||
|
||||
// Vecteur de depart:
|
||||
for (j =1; j <= Npol; j++) {
|
||||
Poi = SCurv.Value(j).Point(k);
|
||||
Start(j + IncCol) = Poi.X();
|
||||
Start(j+ Npol + IncCol) = Poi.Y();
|
||||
Start(j + Npol2 + IncCol) = Poi.Z();
|
||||
}
|
||||
IncCol = IncCol + 3*Npol;
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
for (i = 1; i <= IncTan; i++) {
|
||||
Npt = ITan(i);
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k-nb3d);
|
||||
T1 = V2d.X();
|
||||
T2 = V2d.Y();
|
||||
Tmax = Abs(T1);
|
||||
Ibont(k, i) = 1;
|
||||
if (Abs(T2) > Tmax) {
|
||||
Tmax = Abs(T2);
|
||||
Ibont(k, i) = 2;
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
Inc3 = Inc3 +1;
|
||||
}
|
||||
|
||||
// Remplissage du second membre:
|
||||
for (i = 1; i <= IncPass; i++) {
|
||||
ToolLine::Value(SSP, IPas(i), tabP2d);
|
||||
Poi2d = tabP2d(i-nb3d);
|
||||
Secont(i + IncSec) = Poi2d.X();
|
||||
Secont(i + IncPass + IncSec) = Poi2d.Y();
|
||||
}
|
||||
IncSec = IncSec + 2*IncPass;
|
||||
|
||||
// Remplissage du vecteur de depart:
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Poi2d = SCurv.Value(j).Point2d(k);
|
||||
Start(j + IncCol) = Poi2d.X();
|
||||
Start(j + Npol + IncCol) = Poi2d.Y();
|
||||
}
|
||||
IncCol = IncCol + Npol2;
|
||||
}
|
||||
}
|
||||
|
||||
// Equations exprimant le meme rapport de tangence sur chaque courbe:
|
||||
// On prend les coordonnees les plus significatives.
|
||||
|
||||
Inc3 = Inc3 -1;
|
||||
for (i =1; i <= IncTan; i++) {
|
||||
IncCol = 0;
|
||||
Npt = ITan(i);
|
||||
for (k = 1; k <= NbCu-1; k++) {
|
||||
Inc3 = Inc3 + 1;
|
||||
if (Ibont(k, i) == 1) {
|
||||
if (k <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
T1 = V.X();
|
||||
IP = 3*Npol;
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k-nb3d);
|
||||
T1 = V2d.X();
|
||||
IP = 2*Npol;
|
||||
}
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1x et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1x et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
else if (Ibont(k+1,i) == 3) { // Relations entre T1x et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k,i) == 2) {
|
||||
if (k <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
IP = 3*Npol;
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k-nb3d);
|
||||
T1 = V2d.Y();
|
||||
IP = 2*Npol;
|
||||
}
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1y et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
|
||||
}
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1y et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
|
||||
}
|
||||
else if (Ibont(k+1,i)== 3) { // Relations entre T1y et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
T1 = V.Z();
|
||||
IP = 3*Npol;
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1z et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1z et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1-nb3d);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
|
||||
else if (Ibont(k+1,i)==3) { // Relations entre T1z et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
Cont(Inc3, j + 2*Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Equations concernant la courbure:
|
||||
|
||||
|
||||
/* Inc3 = Inc3 +1;
|
||||
IncCol = 0;
|
||||
for (k = 1; k <= NbCu; k++) {
|
||||
for (i = 1; i <= IncCurv; i++) {
|
||||
Npt = ICurv(i);
|
||||
AppDef_MultiPointConstraint MP = SSP.Value(Npt);
|
||||
DDA = SecondDerivativeBern(Parameters(Npt));
|
||||
if (SSP.Value(1).Dimension(k) == 3) {
|
||||
C1 = MP.Curv(k).X();
|
||||
C2 = MP.Curv(k).Y();
|
||||
C3 = MP.Curv(k).Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
D2Aij = DDA(j);
|
||||
Cont(Inc3, j + IncCol) = D2Aij;
|
||||
Cont(Inc3, j + Npol2 + IncCol) = -C2*Daij;
|
||||
Cont(Inc3, j + Npol + IncCol) = C3*Daij;
|
||||
|
||||
Cont(Inc3+1, j + Npol + IncCol) = D2Aij;
|
||||
Cont(Inc3+1, j +IncCol) = -C3*Daij;
|
||||
Cont(Inc3+1, j + Npol2 + IncCol) = C1*Daij;
|
||||
|
||||
Cont(Inc3+2, j + Npol2+IncCol) = D2Aij;
|
||||
Cont(Inc3+2, j + Npol+IncCol) = -C1*Daij;
|
||||
Cont(Inc3+2, j + IncCol) = C2*Daij;
|
||||
}
|
||||
Inc3 = Inc3 + 3;
|
||||
}
|
||||
else { // Dimension 2:
|
||||
C1 = MP.Curv2d(k).X();
|
||||
C2 = MP.Curv2d(k).Y();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DerivativeBern(Npt, j);
|
||||
D2Aij = DDA(j);
|
||||
Cont(Inc3, j + IncCol) = D2Aij*C1;
|
||||
Cont(Inc3+1, j + Npol + IncCol) = D2Aij*C2;
|
||||
}
|
||||
Inc3 = Inc3 + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// Resolution par Uzawa:
|
||||
|
||||
math_Uzawa UzaResol(Cont, Secont, Start, Tolerance);
|
||||
if (!(UzaResol.IsDone())) {
|
||||
Done = Standard_False;
|
||||
return;
|
||||
}
|
||||
CTCinv = UzaResol.InverseCont();
|
||||
UzaResol.Duale(Vardua);
|
||||
for (i = 1; i <= CTCinv.RowNumber(); i++) {
|
||||
for (j = i; j <= CTCinv.RowNumber(); j++) {
|
||||
CTCinv(i, j) = CTCinv(j, i);
|
||||
}
|
||||
}
|
||||
Done = Standard_True;
|
||||
math_Vector VecPoles (1, CCol*Npol);
|
||||
VecPoles = UzaResol.Value();
|
||||
|
||||
Standard_Integer polinit = 1, polfin=Npol;
|
||||
if (FC >= 1) polinit = 2;
|
||||
if (LC >= 1) polfin = Npol-1;
|
||||
|
||||
for (i = polinit; i <= polfin; i++) {
|
||||
IncCol = 0;
|
||||
AppParCurves_MultiPoint MPol(nb3d, nb2d);
|
||||
for (k = 1; k <= NbCu; k++) {
|
||||
if (k <= nb3d) {
|
||||
gp_Pnt Pol(VecPoles(IncCol + i),
|
||||
VecPoles(IncCol + Npol +i),
|
||||
VecPoles(IncCol + 2*Npol + i));
|
||||
MPol.SetPoint(k, Pol);
|
||||
IncCol = IncCol + 3*Npol;
|
||||
}
|
||||
else {
|
||||
gp_Pnt2d Pol2d(VecPoles(IncCol + i),
|
||||
VecPoles(IncCol + Npol + i));
|
||||
MPol.SetPoint2d(k, Pol2d);
|
||||
IncCol = IncCol + 2*Npol;
|
||||
}
|
||||
}
|
||||
SCurv.SetValue(i, MPol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Standard_Boolean AppParCurves_ResolConstraint::IsDone () const {
|
||||
return Done;
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_ResolConstraint::
|
||||
NbConstraints(const MultiLine& SSP,
|
||||
const Standard_Integer,
|
||||
const Standard_Integer,
|
||||
const Handle(AppParCurves_HArray1OfConstraintCouple)&
|
||||
TheConstraints)
|
||||
const
|
||||
{
|
||||
// Boucle de calcul du nombre de points de passage afin de dimensionner
|
||||
// les matrices.
|
||||
Standard_Integer IncPass, IncTan, IncCurv, CCol;
|
||||
Standard_Integer i;
|
||||
AppParCurves_Constraint Cons;
|
||||
|
||||
IncPass = 0;
|
||||
IncTan = 0;
|
||||
IncCurv = 0;
|
||||
|
||||
for (i = TheConstraints->Lower(); i <= TheConstraints->Upper(); i++) {
|
||||
Cons = (TheConstraints->Value(i)).Constraint();
|
||||
if (Cons >= 1) {
|
||||
IncPass++; // IncPass = nbre de points de passage.
|
||||
}
|
||||
if (Cons >= 2) {
|
||||
IncTan++; // IncTan= nbre de points de tangence.
|
||||
}
|
||||
if (Cons == 3) {
|
||||
IncCurv++; // IncCurv = nbre de pts de courbure.
|
||||
}
|
||||
}
|
||||
Standard_Integer nb3d = ToolLine::NbP3d(SSP);
|
||||
Standard_Integer nb2d = ToolLine::NbP2d(SSP);
|
||||
CCol = nb3d* 3 + nb2d* 2;
|
||||
|
||||
return CCol*IncPass + IncTan*(CCol-1) + 3*IncCurv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Standard_Integer AppParCurves_ResolConstraint::NbColumns(const MultiLine& SSP,
|
||||
const Standard_Integer Deg)
|
||||
const
|
||||
{
|
||||
Standard_Integer nb3d = ToolLine::NbP3d(SSP);
|
||||
Standard_Integer nb2d = ToolLine::NbP2d(SSP);
|
||||
Standard_Integer CCol = nb3d* 3 + nb2d* 2;
|
||||
|
||||
return CCol*(Deg+1);
|
||||
}
|
||||
|
||||
const math_Matrix& AppParCurves_ResolConstraint::ConstraintMatrix() const
|
||||
{
|
||||
return Cont;
|
||||
}
|
||||
|
||||
const math_Matrix& AppParCurves_ResolConstraint::InverseMatrix() const
|
||||
{
|
||||
return CTCinv;
|
||||
}
|
||||
|
||||
|
||||
const math_Vector& AppParCurves_ResolConstraint::Duale() const
|
||||
{
|
||||
return Vardua;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const math_Matrix& AppParCurves_ResolConstraint::
|
||||
ConstraintDerivative(const MultiLine& SSP,
|
||||
const math_Vector& Parameters,
|
||||
const Standard_Integer Deg,
|
||||
const math_Matrix& DA)
|
||||
{
|
||||
Standard_Integer i, j, k, nb2d, nb3d, CCol, Inc3, IncCol, Npt;
|
||||
Standard_Integer Npol, Npol2, NbCu =ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP);
|
||||
Standard_Integer IP;
|
||||
Standard_Real Daij;
|
||||
Npol = Deg+1; Npol2 = 2*Npol;
|
||||
Standard_Boolean Ok;
|
||||
TColStd_Array2OfInteger Ibont(1, NbCu, 1, IncTan);
|
||||
math_Matrix DeCInit(1, IncPass, 1, Npol);
|
||||
math_Vector DDA(1, Npol);
|
||||
gp_Vec V;
|
||||
gp_Vec2d V2d;
|
||||
Standard_Real T1, T2, T3, Tmax, DDaij;
|
||||
// Standard_Integer FirstP = IPas(1);
|
||||
nb3d = ToolLine::NbP3d(SSP);
|
||||
nb2d = ToolLine::NbP2d(SSP);
|
||||
Standard_Integer mynb3d = nb3d, mynb2d = nb2d;
|
||||
if (nb3d == 0) mynb3d = 1;
|
||||
if (nb2d == 0) mynb2d = 1;
|
||||
CCol = nb3d* 3 + nb2d* 2;
|
||||
|
||||
TColgp_Array1OfVec tabV(1, mynb3d);
|
||||
TColgp_Array1OfVec2d tabV2d(1, mynb2d);
|
||||
TColgp_Array1OfPnt tabP(1, mynb3d);
|
||||
TColgp_Array1OfPnt2d tabP2d(1, mynb2d);
|
||||
|
||||
for (i = 1; i <= DeCont.RowNumber(); i++)
|
||||
for (j = 1; j <= DeCont.ColNumber(); j++)
|
||||
DeCont(i, j) = 0.0;
|
||||
|
||||
|
||||
// Remplissage de DK pour les points de passages:
|
||||
|
||||
for (i =1; i <= IncPass; i++) {
|
||||
Npt = IPas(i);
|
||||
for (j = 1; j <= Npol; j++) DeCInit(i, j) = DA(Npt, j);
|
||||
}
|
||||
for (i = 1; i <= CCol; i++) {
|
||||
DeCont.Set(IncPass*(i-1)+1, IncPass*i, Npol*(i-1)+1, Npol*i, DeCInit);
|
||||
}
|
||||
|
||||
|
||||
// Pour les points de tangence:
|
||||
|
||||
Inc3 = CCol*IncPass +1;
|
||||
IncCol = 0;
|
||||
|
||||
for (k = 1; k <= NbCu; k++) {
|
||||
if (k <= nb3d) {
|
||||
for (i = 1; i <= IncTan; i++) {
|
||||
Npt = ITan(i);
|
||||
// MultiPoint MPoint = ToolLine::Value(SSP, Npt);
|
||||
// choix du maximum de tangence pour exprimer la colinearite:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
V.Coord(T1, T2, T3);
|
||||
Tmax = Abs(T1);
|
||||
Ibont(k, i) = 1;
|
||||
if (Abs(T2) > Tmax) {
|
||||
Tmax = Abs(T2);
|
||||
Ibont(k, i) = 2;
|
||||
}
|
||||
if (Abs(T3) > Tmax) {
|
||||
Tmax = Abs(T3);
|
||||
Ibont(k, i) = 3;
|
||||
}
|
||||
AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA);
|
||||
if (Ibont(k, i) == 3) {
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DDaij = DDA(j);
|
||||
DeCont(Inc3, j+ Npol + IncCol) = DDaij*T3/Tmax;
|
||||
DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T2/Tmax;
|
||||
DeCont(Inc3+1, j+ IncCol) = DDaij* T3/Tmax;
|
||||
DeCont(Inc3+1, j+ Npol2 + IncCol) = -DDaij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k, i) == 1) {
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DDaij = DDA(j);
|
||||
DeCont(Inc3, j + IncCol) = DDaij*T3/Tmax;
|
||||
DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T1/Tmax;
|
||||
DeCont(Inc3+1, j+ IncCol) = DDaij* T2/Tmax;
|
||||
DeCont(Inc3+1, j+ Npol +IncCol) = -DDaij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k, i) == 2) {
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DDaij = DDA(j);
|
||||
DeCont(Inc3, j+ Npol + IncCol) = DDaij*T3/Tmax;
|
||||
DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T2/Tmax;
|
||||
DeCont(Inc3+1, j+ IncCol) = DDaij* T2/Tmax;
|
||||
DeCont(Inc3+1, j+ Npol + IncCol) = -DDaij*T1/Tmax;
|
||||
}
|
||||
}
|
||||
Inc3 = Inc3 + 2;
|
||||
}
|
||||
IncCol = IncCol + 3*Npol;
|
||||
}
|
||||
else {
|
||||
for (i = 1; i <= IncTan; i++) {
|
||||
Npt = ITan(i);
|
||||
AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA);
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k);
|
||||
V2d.Coord(T1, T2);
|
||||
Tmax = Abs(T1);
|
||||
Ibont(k, i) = 1;
|
||||
if (Abs(T2) > Tmax) {
|
||||
Tmax = Abs(T2);
|
||||
Ibont(k, i) = 2;
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
DDaij = DDA(j);
|
||||
DeCont(Inc3, j + IncCol) = DDaij*T2;
|
||||
DeCont(Inc3, j + Npol + IncCol) = -DDaij*T1;
|
||||
}
|
||||
Inc3 = Inc3 +1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Equations exprimant le meme rapport de tangence sur chaque courbe:
|
||||
// On prend les coordonnees les plus significatives.
|
||||
|
||||
Inc3 = Inc3 -1;
|
||||
for (i =1; i <= IncTan; i++) {
|
||||
IncCol = 0;
|
||||
Npt = ITan(i);
|
||||
AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA);
|
||||
// MultiPoint MP = ToolLine::Value(SSP, Npt);
|
||||
for (k = 1; k <= NbCu-1; k++) {
|
||||
Inc3 = Inc3 + 1;
|
||||
if (Ibont(k, i) == 1) {
|
||||
if (k <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
T1 = V.X();
|
||||
IP = 3*Npol;
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k);
|
||||
T1 = V2d.X();
|
||||
IP = 2*Npol;
|
||||
}
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1x et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1x et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
else if (Ibont(k+1,i) == 3) { // Relations entre T1x et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
else if (Ibont(k,i) == 2) {
|
||||
if (k <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
T1 = V.Y();
|
||||
IP = 3*Npol;
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k);
|
||||
T1 = V2d.Y();
|
||||
IP = 2*Npol;
|
||||
}
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1y et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA( j);
|
||||
Cont(Inc3, j + Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
|
||||
}
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1y et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
|
||||
}
|
||||
else if (Ibont(k+1,i)== 3) { // Relations entre T1y et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k);
|
||||
T1 = V.Z();
|
||||
IP = 3*Npol;
|
||||
if (Ibont(k+1, i) == 1) { // Relations entre T1z et T2x:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.X();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.X();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
|
||||
else if (Ibont(k+1, i) == 2) { // Relations entre T1z et T2y:
|
||||
if ((k+1) <= nb3d) {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Y();
|
||||
}
|
||||
else {
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV2d);
|
||||
V2d = tabV2d(k+1);
|
||||
T2 = V2d.Y();
|
||||
}
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
|
||||
else if (Ibont(k+1,i)==3) { // Relations entre T1z et T2z:
|
||||
Ok = ToolLine::Tangency(SSP, Npt, tabV);
|
||||
V = tabV(k+1);
|
||||
T2 = V.Z();
|
||||
for (j = 1; j <= Npol; j++) {
|
||||
Daij = DDA(j);
|
||||
Cont(Inc3, j + 2*Npol + IncCol) = Daij*T2;
|
||||
Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1;
|
||||
}
|
||||
IncCol = IncCol + IP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DeCont;
|
||||
}
|
110
src/AppParCurves/AppParCurves_SmoothCriterion.cdl
Executable file
110
src/AppParCurves/AppParCurves_SmoothCriterion.cdl
Executable file
@@ -0,0 +1,110 @@
|
||||
-- File: AppParCurves_SmoothCriterion.cdl
|
||||
-- Created: Thu Sep 11 18:06:06 1997
|
||||
-- Author: Philippe MANGIN
|
||||
-- <pmn@sgi29>
|
||||
---Copyright: Matra Datavision 1997
|
||||
|
||||
|
||||
deferred class SmoothCriterion from AppParCurves
|
||||
inherits TShared from MMgt
|
||||
|
||||
---Purpose: defined criterion to smooth points in curve
|
||||
|
||||
|
||||
uses
|
||||
Vector from math,
|
||||
Matrix from math,
|
||||
Curve from FEmTool,
|
||||
HAssemblyTable from FEmTool,
|
||||
HArray2OfInteger from TColStd,
|
||||
HArray1OfReal from TColStd,
|
||||
Array1OfReal from TColStd
|
||||
|
||||
raises
|
||||
NotImplemented,
|
||||
DomainError
|
||||
|
||||
|
||||
|
||||
is
|
||||
SetParameters(me : mutable; Parameters : HArray1OfReal)
|
||||
is deferred;
|
||||
|
||||
SetCurve(me : mutable; C :Curve from FEmTool)
|
||||
is deferred;
|
||||
|
||||
GetCurve(me; C : out Curve from FEmTool)
|
||||
is deferred;
|
||||
|
||||
SetEstimation(me : mutable; E1, E2, E3 : Real)
|
||||
is deferred;
|
||||
|
||||
EstLength(me : mutable)
|
||||
---C++: return &
|
||||
returns Real is deferred;
|
||||
|
||||
GetEstimation(me; E1, E2, E3 : out Real)
|
||||
is deferred;
|
||||
|
||||
AssemblyTable(me)
|
||||
returns HAssemblyTable from FEmTool
|
||||
is deferred;
|
||||
|
||||
DependenceTable(me)
|
||||
returns HArray2OfInteger from TColStd
|
||||
is deferred;
|
||||
|
||||
QualityValues (me : mutable; J1min, J2min, J3min : Real;
|
||||
J1, J2, J3 : out Real)
|
||||
returns Integer is deferred;
|
||||
|
||||
ErrorValues(me : mutable;
|
||||
MaxError, QuadraticError, AverageError : out Real)
|
||||
is deferred;
|
||||
|
||||
Hessian(me : mutable ;
|
||||
Element : Integer;
|
||||
Dimension1 : Integer;
|
||||
Dimension2 : Integer;
|
||||
H : out Matrix from math)
|
||||
raises DomainError -- If DependenceTable(Dimension1,Dimension2) is False
|
||||
is deferred;
|
||||
|
||||
|
||||
Gradient(me : mutable;
|
||||
Element : Integer;
|
||||
Dimension : Integer;
|
||||
G : out Vector from math)
|
||||
is deferred;
|
||||
|
||||
InputVector(me : mutable; X : Vector from math;
|
||||
AssTable : HAssemblyTable from FEmTool)
|
||||
---Purpose: Convert the assembly Vector in an Curve;
|
||||
--
|
||||
raises DomainError is deferred;
|
||||
|
||||
SetWeight(me: mutable;
|
||||
QuadraticWeight, QualityWeight : Real;
|
||||
percentJ1, percentJ2, percentJ3 : Real)
|
||||
is deferred;
|
||||
|
||||
GetWeight(me; QuadraticWeight, QualityWeight : out Real)
|
||||
is deferred;
|
||||
|
||||
SetWeight(me: mutable;
|
||||
Weight : Array1OfReal)
|
||||
is deferred;
|
||||
|
||||
end SmoothCriterion;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
7
src/AppParCurves/AppParCurves_SmoothCriterion.cxx
Executable file
7
src/AppParCurves/AppParCurves_SmoothCriterion.cxx
Executable file
@@ -0,0 +1,7 @@
|
||||
// File: AppParCurves_SmoothCriterion.cxx
|
||||
// Created: Mon Nov 30 14:47:09 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
#include <AppParCurves_SmoothCriterion.ixx>
|
432
src/AppParCurves/AppParCurves_Variational.cdl
Executable file
432
src/AppParCurves/AppParCurves_Variational.cdl
Executable file
@@ -0,0 +1,432 @@
|
||||
-- File: AppParCurves_Variational.cdl
|
||||
-- Created: Tue May 14 11:04:08 1996
|
||||
-- Author: Philippe MANGIN / Jeannine PANCIATICI
|
||||
-- <pmn@sgi29>
|
||||
-- Igor FEOKTISTOV - correction 14/12/98
|
||||
---Copyright: Matra Datavision 1996
|
||||
|
||||
|
||||
generic class Variational from AppParCurves
|
||||
(MultiLine as any;
|
||||
ToolLine as any) -- as ToolLine(MultiLine)
|
||||
|
||||
|
||||
---Purpose: This class is used to smooth N points with constraints
|
||||
-- by minimization of quadratic criterium but also
|
||||
-- variational criterium in order to obtain " fair Curve "
|
||||
--
|
||||
|
||||
uses Matrix from math,
|
||||
Vector from math,
|
||||
HArray1OfReal from TColStd,
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfInteger from TColStd,
|
||||
Shape from GeomAbs,
|
||||
HArray1OfConstraintCouple from AppParCurves,
|
||||
MultiBSpCurve from AppParCurves,
|
||||
SmoothCriterion from AppParCurves,
|
||||
Curve from FEmTool,
|
||||
Assembly from FEmTool,
|
||||
Base from PLib,
|
||||
Constraint from AppParCurves
|
||||
|
||||
raises OutOfRange from Standard,
|
||||
DimensionError from Standard,
|
||||
DomainError from Standard,
|
||||
ConstructionError from Standard,
|
||||
NotDone from StdFail,
|
||||
VectorWithNullMagnitude from gp
|
||||
|
||||
class MyCriterion instantiates LinearCriteria from AppParCurves
|
||||
(MultiLine, ToolLine);
|
||||
|
||||
|
||||
is
|
||||
Create(SSP: MultiLine;
|
||||
FirstPoint, LastPoint: Integer;
|
||||
TheConstraints: HArray1OfConstraintCouple;
|
||||
MaxDegree: Integer = 14;
|
||||
MaxSegment: Integer = 100;
|
||||
Continuity : Shape from GeomAbs = GeomAbs_C2;
|
||||
WithMinMax : Boolean = Standard_False;
|
||||
WithCutting: Boolean = Standard_True;
|
||||
Tolerance : Real = 1.0;
|
||||
NbIterations: Integer = 2)
|
||||
---Purpose: Constructor.
|
||||
-- Initialization of the fields.
|
||||
-- warning : Nc0 : number of PassagePoint consraints
|
||||
-- Nc2 : number of TangencyPoint constraints
|
||||
-- Nc3 : number of CurvaturePoint constraints
|
||||
-- if
|
||||
-- ((MaxDegree-Continuity)*MaxSegment -Nc0 - 2*Nc1
|
||||
-- -3*Nc2)
|
||||
-- is negative
|
||||
-- The problem is over-constrained.
|
||||
--
|
||||
-- Limitation : The MultiLine has to be composed by
|
||||
-- only one Line ( Dimension 2 or 3).
|
||||
|
||||
returns Variational from AppParCurves;
|
||||
|
||||
|
||||
Approximate(me : in out)
|
||||
---Purpose: Makes the approximation with the current fields.
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
|
||||
-- ==================== The Selectors ===========================
|
||||
|
||||
IsCreated(me)
|
||||
---Purpose: returns True if the creation is done
|
||||
-- and correspond to the current fields.
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
|
||||
IsDone(me)
|
||||
---Purpose: returns True if the approximation is ok
|
||||
-- and correspond to the current fields.
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
IsOverConstrained(me)
|
||||
---Purpose: returns True if the problem is overconstrained
|
||||
-- in this case, approximation cannot be done.
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
Value(me)
|
||||
---Purpose: returns all the BSpline curves approximating the
|
||||
-- MultiLine SSP after minimization of the parameter.
|
||||
|
||||
returns MultiBSpCurve from AppParCurves
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
MaxError(me)
|
||||
---Purpose: returns the maximum of the distances between
|
||||
-- the points of the multiline and the approximation
|
||||
-- curves.
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
MaxErrorIndex(me)
|
||||
---Purpose: returns the index of the MultiPoint of ErrorMax
|
||||
returns Integer
|
||||
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
|
||||
QuadraticError(me)
|
||||
---Purpose: returns the quadratic average of the distances between
|
||||
-- the points of the multiline and the approximation
|
||||
-- curves.
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
Distance(me : in out ; mat : out Matrix from math)
|
||||
---Purpose: returns the distances between the points of the
|
||||
-- multiline and the approximation curves.
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
AverageError(me)
|
||||
---Purpose: returns the average error between
|
||||
-- the MultiLine and the approximation.
|
||||
|
||||
returns Real
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
Parameters(me)
|
||||
---Purpose: returns the parameters uses to the approximations
|
||||
---C++: return const&
|
||||
|
||||
returns HArray1OfReal
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
Knots(me)
|
||||
---Purpose: returns the knots uses to the approximations
|
||||
---C++: return const&
|
||||
returns HArray1OfReal
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
Criterium(me; VFirstOrder,
|
||||
VSecondOrder,
|
||||
VThirdOrder : out Real)
|
||||
---Purpose: returns the values of the quality criterium.
|
||||
raises NotDone from StdFail
|
||||
is static;
|
||||
|
||||
CriteriumWeight(me ;
|
||||
Percent1, Percent2, Percent3 : out Real)
|
||||
---Purpose: returns the Weights (as percent) associed to the criterium used in
|
||||
-- the optimization.
|
||||
is static;
|
||||
|
||||
MaxDegree(me)
|
||||
---Purpose: returns the Maximum Degree used in the approximation
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
MaxSegment(me)
|
||||
---Purpose: returns the Maximum of segment used in the approximation
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
Continuity(me)
|
||||
---Purpose: returns the Continuity used in the approximation
|
||||
returns Shape from GeomAbs
|
||||
is static;
|
||||
|
||||
|
||||
WithMinMax(me)
|
||||
---Purpose: returns if the approximation search to minimize the
|
||||
-- maximum Error or not.
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
WithCutting(me)
|
||||
---Purpose: returns if the approximation can insert new Knots or not.
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
Tolerance(me)
|
||||
---Purpose: returns the tolerance used in the approximation.
|
||||
returns Real
|
||||
is static;
|
||||
|
||||
NbIterations(me)
|
||||
---Purpose: returns the number of iterations used in the approximation.
|
||||
returns Integer
|
||||
is static;
|
||||
|
||||
Dump(me ; o : in out OStream)
|
||||
---Purpose: Prints on the stream o information on the current state
|
||||
-- of the object.
|
||||
-- MaxError,MaxErrorIndex,AverageError,QuadraticError,Criterium
|
||||
-- Distances,Degre,Nombre de poles, parametres, noeuds
|
||||
is static;
|
||||
|
||||
SetConstraints(me:in out; aConstrainst:HArray1OfConstraintCouple)
|
||||
---Purpose: Define the constraints to approximate
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
SetParameters(me:in out; param : HArray1OfReal)
|
||||
---Purpose: Defines the parameters used by the approximations.
|
||||
raises DimensionError
|
||||
is static;
|
||||
|
||||
SetKnots(me:in out; knots : HArray1OfReal)
|
||||
---Purpose: Defines the knots used by the approximations
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
raises DimensionError,
|
||||
DomainError
|
||||
is static;
|
||||
|
||||
SetMaxDegree(me: in out; Degree : Integer)
|
||||
---Purpose: Define the Maximum Degree used in the approximation
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
SetMaxSegment(me: in out; NbSegment : Integer)
|
||||
---Purpose: Define the maximum number of segments used in the approximation
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
SetContinuity(me: in out; C : Shape from GeomAbs)
|
||||
---Purpose: Define the Continuity used in the approximation
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
raises ConstructionError from Standard
|
||||
is static;
|
||||
|
||||
|
||||
SetWithMinMax(me: in out; MinMax : Boolean)
|
||||
---Purpose: Define if the approximation search to minimize the
|
||||
-- maximum Error or not.
|
||||
is static;
|
||||
|
||||
SetWithCutting(me : in out; Cutting : Boolean )
|
||||
---Purpose: Define if the approximation can insert new Knots or not.
|
||||
-- If this value is incompatible with the others fields
|
||||
-- this method modify nothing and returns false
|
||||
returns Boolean
|
||||
is static;
|
||||
|
||||
SetCriteriumWeight(me : in out;
|
||||
Percent1, Percent2, Percent3 : Real)
|
||||
---Purpose: define the Weights (as percent) associed to the criterium used in
|
||||
-- the optimization.
|
||||
--
|
||||
raises DomainError -- if Percent <= 0
|
||||
is static;
|
||||
|
||||
SetCriteriumWeight(me : in out;
|
||||
Order : Integer;
|
||||
Percent : Real)
|
||||
---Purpose: define the Weight (as percent) associed to the
|
||||
-- criterium Order used in the optimization : Others
|
||||
-- weights are updated.
|
||||
raises DomainError, -- if Percent < 0
|
||||
OutOfRange -- if Order < 1 or Order > 3
|
||||
is static;
|
||||
|
||||
SetTolerance(me:in out; Tol : Real)
|
||||
---Purpose: define the tolerance used in the approximation.
|
||||
is static;
|
||||
|
||||
SetNbIterations(me:in out; Iter : Integer)
|
||||
---Purpose: define the number of iterations used in the approximation.
|
||||
raises DomainError -- if Iter < 1
|
||||
is static;
|
||||
|
||||
|
||||
-- ====================== The Private methods ======================
|
||||
|
||||
TheMotor(me : in out;
|
||||
J : in out SmoothCriterion from AppParCurves;
|
||||
WQuadratic, WQuality : Real;
|
||||
TheCurve : in out Curve from FEmTool;
|
||||
Ecarts : out Array1OfReal from TColStd) is private;
|
||||
|
||||
Adjusting(me : in out;
|
||||
J : in out SmoothCriterion from AppParCurves;
|
||||
WQuadratic, WQuality : in out Real;
|
||||
TheCurve : in out Curve from FEmTool;
|
||||
Ecarts : out Array1OfReal from TColStd) is private;
|
||||
|
||||
Optimization(me;
|
||||
J : in out SmoothCriterion from AppParCurves;
|
||||
A : in out Assembly from FEmTool;
|
||||
ToAssemble : in Boolean;
|
||||
EpsDeg : Real;
|
||||
Curve : out Curve from FEmTool;
|
||||
Parameters : Array1OfReal from TColStd) is private;
|
||||
|
||||
Project(me; C : Curve from FEmTool;
|
||||
Ti : Array1OfReal from TColStd;
|
||||
ProjTi : out Array1OfReal from TColStd;
|
||||
Distance : out Array1OfReal from TColStd;
|
||||
NumPoints : out Integer;
|
||||
MaxErr, QuaErr, AveErr : out Real;
|
||||
NbIterations: Integer=2) is private;
|
||||
|
||||
ACR(me; Curve : in out Curve from FEmTool;
|
||||
Ti : in out Array1OfReal from TColStd;
|
||||
Decima: Integer) is private;
|
||||
|
||||
SplitCurve(me; InCurve : Curve from FEmTool;
|
||||
Ti : Array1OfReal from TColStd;
|
||||
CurveTol: Real;
|
||||
OutCurve: out Curve from FEmTool;
|
||||
iscut : out Boolean) is private;
|
||||
|
||||
Init(me : in out)
|
||||
raises NotDone from StdFail,
|
||||
ConstructionError from Standard,
|
||||
DimensionError from Standard
|
||||
is private;
|
||||
|
||||
InitSmoothCriterion(me : in out)
|
||||
is private;
|
||||
|
||||
InitParameters(me : in out; Length : out Real)
|
||||
raises ConstructionError from Standard
|
||||
is private;
|
||||
|
||||
InitCriterionEstimations(me; Length : Real; J1, J2, J3 : out Real)
|
||||
is private;
|
||||
|
||||
EstTangent(me; ipnt : Integer; VTang : out Vector from math)
|
||||
is private;
|
||||
|
||||
EstSecnd(me; ipnt : Integer; VTang1, VTang2 : Vector from math;
|
||||
Length : Real; VScnd : out Vector from math)
|
||||
is private;
|
||||
|
||||
InitCutting(me; aBase : Base from PLib; CurvTol : Real;
|
||||
aCurve : out Curve from FEmTool)
|
||||
raises ConstructionError from Standard
|
||||
is private;
|
||||
|
||||
AssemblingConstraints(me; Curve : Curve from FEmTool;
|
||||
Parameters : Array1OfReal from TColStd;
|
||||
CBLONG : Real from Standard;
|
||||
A : out Assembly from FEmTool)
|
||||
is private;
|
||||
|
||||
InitTthetaF(me : in out; ndimen : Integer from Standard;
|
||||
typcon : Constraint from AppParCurves;
|
||||
begin : Integer from Standard;
|
||||
jndex : Integer from Standard)
|
||||
returns Boolean
|
||||
is private;
|
||||
|
||||
|
||||
fields
|
||||
-- Description of the points to smooth and the constraints
|
||||
mySSP : MultiLine;
|
||||
myNbP3d : Integer;
|
||||
myNbP2d : Integer;
|
||||
myDimension : Integer;
|
||||
myFirstPoint : Integer;
|
||||
myLastPoint : Integer;
|
||||
myNbPoints : Integer;
|
||||
myTabPoints : HArray1OfReal;
|
||||
myConstraints : HArray1OfConstraintCouple;
|
||||
myNbConstraints : Integer;
|
||||
myTabConstraints : HArray1OfReal;
|
||||
myNbPassPoints : Integer;
|
||||
myNbTangPoints : Integer;
|
||||
myNbCurvPoints : Integer;
|
||||
myTypConstraints : HArray1OfInteger;
|
||||
myTtheta : HArray1OfReal;
|
||||
myTfthet : HArray1OfReal;
|
||||
|
||||
-- Context parameters
|
||||
myMaxDegree : Integer;
|
||||
myMaxSegment : Integer;
|
||||
myNbIterations: Integer;
|
||||
myTolerance : Real;
|
||||
|
||||
-- Options
|
||||
myContinuity : Shape from GeomAbs;
|
||||
myNivCont : Integer;
|
||||
myWithMinMax : Boolean;
|
||||
myWithCutting: Boolean;
|
||||
myPercent : Real[3];
|
||||
myCriterium : Real[4];
|
||||
mySmoothCriterion : SmoothCriterion from AppParCurves;
|
||||
|
||||
-- output
|
||||
myParameters : HArray1OfReal;
|
||||
myKnots : HArray1OfReal;
|
||||
myMBSpCurve : MultiBSpCurve;
|
||||
|
||||
myMaxError : Real;
|
||||
myMaxErrorIndex: Integer;
|
||||
myAverageError : Real;
|
||||
myIsCreated : Boolean;
|
||||
myIsDone : Boolean;
|
||||
myIsOverConstr : Boolean;
|
||||
|
||||
end Variational;
|
1120
src/AppParCurves/AppParCurves_Variational.gxx
Executable file
1120
src/AppParCurves/AppParCurves_Variational.gxx
Executable file
File diff suppressed because it is too large
Load Diff
358
src/AppParCurves/AppParCurves_Variational_1.gxx
Executable file
358
src/AppParCurves/AppParCurves_Variational_1.gxx
Executable file
@@ -0,0 +1,358 @@
|
||||
// File: AppParCurves_Variational_1.gxx
|
||||
// Created: Wed Sep 17 18:29:12 1997
|
||||
// Author: Philippe MANGIN /Igor Feoktistov (1998)
|
||||
// <pmn@sgi29>
|
||||
|
||||
|
||||
#include <SortTools_StraightInsertionSortOfReal.hxx>
|
||||
#include <TCollection_CompareOfReal.hxx>
|
||||
#include <TColStd_HArray2OfInteger.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <TColStd_Array2OfInteger.hxx>
|
||||
#include <FEmTool_Assembly.hxx>
|
||||
#include <FEmTool_AssemblyTable.hxx>
|
||||
#include <FEmTool_Curve.hxx>
|
||||
|
||||
//====================== Private Methodes =============================//
|
||||
//=======================================================================
|
||||
//function : TheMotor
|
||||
//purpose : Smoothing's motor like STRIM routine "MOTLIS"
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::TheMotor(
|
||||
Handle(AppParCurves_SmoothCriterion)& J,
|
||||
// const Standard_Real WQuadratic,
|
||||
const Standard_Real ,
|
||||
const Standard_Real WQuality,
|
||||
Handle(FEmTool_Curve)& TheCurve,
|
||||
TColStd_Array1OfReal& Ecarts)
|
||||
{
|
||||
// ...
|
||||
|
||||
const Standard_Real BigValue = 1.e37, SmallValue = 1.e-6, SmallestValue = 1.e-9;
|
||||
|
||||
// SortTools_StraightInsertionSortOfReal Sort;
|
||||
TCollection_CompareOfReal CompReal;
|
||||
Handle(TColStd_HArray1OfReal) CurrentTi, NewTi, OldTi;
|
||||
Handle(TColStd_HArray2OfInteger) Dependence;
|
||||
Standard_Boolean lestim, lconst, ToOptim, iscut;
|
||||
Standard_Boolean isnear, again = Standard_True;
|
||||
Standard_Integer NbEst, ICDANA, NumPnt, Iter;
|
||||
Standard_Integer MaxNbEst =5;
|
||||
Standard_Real VOCRI[3] = {BigValue, BigValue, BigValue}, EROLD = BigValue,
|
||||
VALCRI[3], ERRMAX, ERRMOY, ERRQUA;
|
||||
Standard_Real CBLONG, LNOLD;
|
||||
Standard_Integer NbrPnt = myLastPoint - myFirstPoint + 1;
|
||||
Standard_Integer NbrConstraint = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
Handle(FEmTool_Curve) CCurrent, COld, CNew;
|
||||
Standard_Real EpsLength;// = 1.e-6 * CBLONG / NbrPnt;
|
||||
Standard_Real EpsDeg; // = Min(WQuality * .1, CBLONG * .001);
|
||||
|
||||
Standard_Real e1, e2, e3;
|
||||
Standard_Real J1min, J2min, J3min;
|
||||
Standard_Integer iprog;
|
||||
|
||||
// (0) Init
|
||||
|
||||
J->GetEstimation(e1, e2, e3);
|
||||
J1min = 1.e-8; J2min = J3min = (e1 + 1.e-8) * 1.e-6;
|
||||
|
||||
if(e1 < J1min) e1 = J1min;// Like in
|
||||
if(e2 < J2min) e2 = J2min;// MOTLIS
|
||||
if(e3 < J3min) e3 = J3min;
|
||||
|
||||
|
||||
J->SetEstimation(e1, e2, e3);
|
||||
|
||||
CCurrent = TheCurve;
|
||||
CurrentTi = new TColStd_HArray1OfReal(1, myParameters->Length());
|
||||
CurrentTi->ChangeArray1() = myParameters->Array1();
|
||||
OldTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
|
||||
OldTi->ChangeArray1() = CurrentTi->Array1();
|
||||
COld = CCurrent;
|
||||
LNOLD = CBLONG = J->EstLength();
|
||||
Dependence = J->DependenceTable();
|
||||
|
||||
J->SetCurve(CCurrent);
|
||||
FEmTool_Assembly * TheAssembly =
|
||||
new FEmTool_Assembly (Dependence->Array2(), J->AssemblyTable());
|
||||
|
||||
//============ Optimization ============================
|
||||
// Standard_Integer inagain = 0;
|
||||
while (again) {
|
||||
|
||||
// (1) Loop Optimization / Estimation
|
||||
lestim = Standard_True;
|
||||
lconst = Standard_True;
|
||||
NbEst = 0;
|
||||
|
||||
J->SetCurve(CCurrent);
|
||||
|
||||
while(lestim) {
|
||||
|
||||
// (1.1) Curve's Optimization.
|
||||
EpsLength = SmallValue * CBLONG / NbrPnt;
|
||||
CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
|
||||
CCurrent->NbElements(), CCurrent->Base(), EpsLength);
|
||||
CNew->Knots() = CCurrent->Knots();
|
||||
|
||||
J->SetParameters(CurrentTi);
|
||||
EpsDeg = Min(WQuality * .1, CBLONG * .001);
|
||||
|
||||
Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
|
||||
|
||||
lconst = Standard_False;
|
||||
|
||||
// (1.2) calcul des criteres de qualites et amelioration
|
||||
// des estimation.
|
||||
ICDANA = J->QualityValues(J1min, J2min, J3min,
|
||||
VALCRI[0], VALCRI[1], VALCRI[2]);
|
||||
|
||||
if(ICDANA > 0) lconst = Standard_True;
|
||||
|
||||
J->ErrorValues(ERRMAX, ERRQUA, ERRMOY);
|
||||
|
||||
isnear = ((Sqrt(ERRQUA / NbrPnt) < 2*WQuality) &&
|
||||
(myNbIterations > 1));
|
||||
|
||||
// (1.3) Optimisation des ti par proj orthogonale
|
||||
// et calcul de l'erreur aux points.
|
||||
|
||||
if (isnear) {
|
||||
NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
|
||||
Project(CNew, CurrentTi->Array1(),
|
||||
NewTi->ChangeArray1(),
|
||||
Ecarts, NumPnt,
|
||||
ERRMAX, ERRQUA, ERRMOY, 2);
|
||||
}
|
||||
else NewTi = CurrentTi;
|
||||
|
||||
|
||||
// (1.4) Progression's test
|
||||
iprog = 0;
|
||||
if ((EROLD > WQuality) && (ERRMAX < 0.95*EROLD)) iprog++;
|
||||
if ((EROLD > WQuality) && (ERRMAX < 0.8*EROLD)) iprog++;
|
||||
if ((EROLD > WQuality) && (ERRMAX < WQuality)) iprog++;
|
||||
if ((EROLD > WQuality) && (ERRMAX < 0.99*EROLD)
|
||||
&& (ERRMAX < 1.1*WQuality)) iprog++;
|
||||
if ( VALCRI[0] < 0.975 * VOCRI[0]) iprog++;
|
||||
if ( VALCRI[0] < 0.9 * VOCRI[0]) iprog++;
|
||||
if ( VALCRI[1] < 0.95 * VOCRI[1]) iprog++;
|
||||
if ( VALCRI[1] < 0.8 * VOCRI[1]) iprog++;
|
||||
if ( VALCRI[2] < 0.95 * VOCRI[2]) iprog++;
|
||||
if ( VALCRI[2] < 0.8 * VOCRI[2]) iprog++;
|
||||
if ((VOCRI[1]>SmallestValue)&&(VOCRI[2]>SmallestValue)) {
|
||||
if ((VALCRI[1]/VOCRI[1] + 2*VALCRI[2]/VOCRI[2]) < 2.8) iprog++;
|
||||
}
|
||||
|
||||
if (iprog < 2 && NbEst == 0 ) {
|
||||
// (1.5) Invalidation of new knots.
|
||||
VALCRI[0] = VOCRI[0];
|
||||
VALCRI[1] = VOCRI[1];
|
||||
VALCRI[2] = VOCRI[2];
|
||||
ERRMAX = EROLD;
|
||||
CBLONG = LNOLD;
|
||||
CCurrent = COld;
|
||||
CurrentTi = OldTi;
|
||||
|
||||
goto L8000; // exit
|
||||
}
|
||||
|
||||
VOCRI[0] = VALCRI[0];
|
||||
VOCRI[1] = VALCRI[1];
|
||||
VOCRI[2] = VALCRI[2];
|
||||
LNOLD = CBLONG;
|
||||
EROLD = ERRMAX;
|
||||
|
||||
CCurrent = CNew;
|
||||
CurrentTi = NewTi;
|
||||
|
||||
// (1.6) Test if the Estimations seems OK, else repeat
|
||||
NbEst++;
|
||||
lestim = ( (NbEst<MaxNbEst) && (ICDANA == 2)&& (iprog > 0) );
|
||||
|
||||
if (lestim && isnear) {
|
||||
// (1.7) Optimization of ti by ACR.
|
||||
// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
Standard_Integer Decima = 4;
|
||||
|
||||
CCurrent->Length(0., 1., CBLONG);
|
||||
J->EstLength() = CBLONG;
|
||||
|
||||
ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
|
||||
lconst = Standard_True;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// (2) loop of parametric / geometric optimization
|
||||
|
||||
Iter = 1;
|
||||
ToOptim = ((Iter < myNbIterations) && (isnear));
|
||||
|
||||
while(ToOptim) {
|
||||
Iter++;
|
||||
// (2.1) Save curent results
|
||||
VOCRI[0] = VALCRI[0];
|
||||
VOCRI[1] = VALCRI[1];
|
||||
VOCRI[2] = VALCRI[2];
|
||||
EROLD = ERRMAX;
|
||||
LNOLD = CBLONG;
|
||||
COld = CCurrent;
|
||||
OldTi->ChangeArray1() = CurrentTi->Array1();
|
||||
|
||||
// (2.2) Optimization des ti by ACR.
|
||||
// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
Standard_Integer Decima = 4;
|
||||
|
||||
CCurrent->Length(0., 1., CBLONG);
|
||||
J->EstLength() = CBLONG;
|
||||
|
||||
ACR(CCurrent, CurrentTi->ChangeArray1(), Decima);
|
||||
lconst = Standard_True;
|
||||
|
||||
// (2.3) Optimisation des courbes
|
||||
EpsLength = SmallValue * CBLONG / NbrPnt;
|
||||
|
||||
CNew = new (FEmTool_Curve) (CCurrent->Dimension(),
|
||||
CCurrent->NbElements(), CCurrent->Base(), EpsLength);
|
||||
CNew->Knots() = CCurrent->Knots();
|
||||
|
||||
J->SetParameters(CurrentTi);
|
||||
|
||||
EpsDeg = Min(WQuality * .1, CBLONG * .001);
|
||||
Optimization(J, *TheAssembly, lconst, EpsDeg, CNew, CurrentTi->Array1());
|
||||
|
||||
CCurrent = CNew;
|
||||
|
||||
// (2.4) calcul des criteres de qualites et amelioration
|
||||
// des estimation.
|
||||
|
||||
ICDANA = J->QualityValues(J1min, J2min, J3min, VALCRI[0], VALCRI[1], VALCRI[2]);
|
||||
if(ICDANA > 0) lconst = Standard_True;
|
||||
|
||||
J->GetEstimation(e1, e2, e3);
|
||||
// (2.5) Optimisation des ti par proj orthogonale
|
||||
|
||||
NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
|
||||
Project(CCurrent, CurrentTi->Array1(),
|
||||
NewTi->ChangeArray1(),
|
||||
Ecarts, NumPnt,
|
||||
ERRMAX, ERRQUA, ERRMOY, 2);
|
||||
|
||||
// (2.6) Test de non regression
|
||||
|
||||
Standard_Integer iregre = 0;
|
||||
if (NbrConstraint < NbrPnt) {
|
||||
if ( (ERRMAX > WQuality) && (ERRMAX > 1.05*EROLD)) iregre++;
|
||||
if ( (ERRMAX > WQuality) && (ERRMAX > 2*EROLD)) iregre++;
|
||||
if ( (EROLD > WQuality) && (ERRMAX <= 0.5*EROLD)) iregre--;
|
||||
}
|
||||
Standard_Real E1, E2, E3;
|
||||
J->GetEstimation(E1, E2, E3);
|
||||
if ( (VALCRI[0] > E1) && (VALCRI[0] > 1.1*VOCRI[0])) iregre++;
|
||||
if ( (VALCRI[1] > E2) && (VALCRI[1] > 1.1*VOCRI[1])) iregre++;
|
||||
if ( (VALCRI[2] > E3) && (VALCRI[2] > 1.1*VOCRI[2])) iregre++;
|
||||
|
||||
|
||||
if (iregre >= 2) {
|
||||
// if (iregre >= 1) {
|
||||
// (2.7) on restaure l'iteration precedente
|
||||
VALCRI[0] = VOCRI[0];
|
||||
VALCRI[1] = VOCRI[1];
|
||||
VALCRI[2] = VOCRI[2];
|
||||
ERRMAX = EROLD;
|
||||
CBLONG = LNOLD;
|
||||
CCurrent = COld;
|
||||
CurrentTi->ChangeArray1() = OldTi->Array1();
|
||||
ToOptim = Standard_False;
|
||||
}
|
||||
else { // Iteration is Ok.
|
||||
CCurrent = CNew;
|
||||
CurrentTi = NewTi;
|
||||
}
|
||||
if (Iter >= myNbIterations) ToOptim = Standard_False;
|
||||
}
|
||||
|
||||
// (3) Decoupe eventuelle
|
||||
|
||||
if ( (CCurrent->NbElements() < myMaxSegment) && myWithCutting ) {
|
||||
|
||||
// (3.1) Sauvgarde de l'etat precedent
|
||||
VOCRI[0] = VALCRI[0];
|
||||
VOCRI[1] = VALCRI[1];
|
||||
VOCRI[2] = VALCRI[2];
|
||||
EROLD = ERRMAX;
|
||||
COld = CCurrent;
|
||||
OldTi->ChangeArray1() = CurrentTi->Array1();
|
||||
|
||||
// (3.2) On arrange les ti : Trie + recadrage sur (0,1)
|
||||
// ---> On trie, afin d'assurer l'ordre par la suite.
|
||||
// Sort.Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
SortTools_StraightInsertionSortOfReal::Sort(CurrentTi->ChangeArray1(), CompReal);
|
||||
|
||||
if ((CurrentTi->Value(1)!= 0.) ||
|
||||
(CurrentTi->Value(NbrPnt)!= 1.)) {
|
||||
Standard_Real t, DelatT =
|
||||
1.0 /(CurrentTi->Value(NbrPnt)-CurrentTi->Value(1));
|
||||
for (Standard_Integer ii=2; ii<NbrPnt; ii++) {
|
||||
t = (CurrentTi->Value(ii)-CurrentTi->Value(1))*DelatT;
|
||||
CurrentTi->SetValue(ii, t);
|
||||
}
|
||||
CurrentTi->SetValue(1, 0.);
|
||||
CurrentTi->SetValue(NbrPnt, 1.);
|
||||
}
|
||||
|
||||
// (3.3) Insert new Knots
|
||||
|
||||
SplitCurve(CCurrent, CurrentTi->Array1(), EpsLength, CNew, iscut);
|
||||
if (!iscut) again = Standard_False;
|
||||
else {
|
||||
CCurrent = CNew;
|
||||
// New Knots => New Assembly.
|
||||
J->SetCurve(CNew);
|
||||
delete TheAssembly;
|
||||
TheAssembly = new FEmTool_Assembly (Dependence->Array2(),
|
||||
J->AssemblyTable());
|
||||
}
|
||||
}
|
||||
else { again = Standard_False;}
|
||||
}
|
||||
|
||||
// ================ Great loop end ===================
|
||||
|
||||
L8000:
|
||||
|
||||
// (4) Compute the best Error.
|
||||
NewTi = new (TColStd_HArray1OfReal) (1, CurrentTi->Length());
|
||||
Project(CCurrent, CurrentTi->Array1(),
|
||||
NewTi->ChangeArray1(),
|
||||
Ecarts, NumPnt,
|
||||
ERRMAX, ERRQUA, ERRMOY, 10);
|
||||
|
||||
// (5) field's update
|
||||
|
||||
TheCurve = CCurrent;
|
||||
J->EstLength() = CBLONG;
|
||||
myParameters->ChangeArray1() = NewTi->Array1();
|
||||
myCriterium[0] = ERRQUA;
|
||||
myCriterium[1] = Sqrt(VALCRI[0]);
|
||||
myCriterium[2] = Sqrt(VALCRI[1]);
|
||||
myCriterium[3] = Sqrt(VALCRI[2]);
|
||||
myMaxError = ERRMAX;
|
||||
myMaxErrorIndex = NumPnt;
|
||||
if(NbrPnt > NbrConstraint)
|
||||
myAverageError = ERRMOY / (NbrPnt - NbrConstraint);
|
||||
else
|
||||
myAverageError = ERRMOY / NbrConstraint;
|
||||
|
||||
delete TheAssembly;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
102
src/AppParCurves/AppParCurves_Variational_2.gxx
Executable file
102
src/AppParCurves/AppParCurves_Variational_2.gxx
Executable file
@@ -0,0 +1,102 @@
|
||||
// File: AppParCurves_Variational_2.gxx
|
||||
// Created: Mon Dec 7 09:29:07 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
#include <math_Matrix.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
#include <TColStd_Array2OfReal.hxx>
|
||||
#include <PLib_Base.hxx>
|
||||
#include <PLib_JacobiPolynomial.hxx>
|
||||
#include <PLib_HermitJacobi.hxx>
|
||||
#include <FEmTool_HAssemblyTable.hxx>
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Optimization
|
||||
//purpose : (like FORTRAN subroutine MINIMI)
|
||||
//=======================================================================
|
||||
void AppParCurves_Variational::Optimization(Handle(AppParCurves_SmoothCriterion)& J,
|
||||
FEmTool_Assembly& A,
|
||||
const Standard_Boolean ToAssemble,
|
||||
const Standard_Real EpsDeg,
|
||||
Handle(FEmTool_Curve)& Curve,
|
||||
const TColStd_Array1OfReal& Parameters) const
|
||||
{
|
||||
Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
|
||||
NbElm = Curve->NbElements(),
|
||||
NbDim = Curve->Dimension();
|
||||
|
||||
Handle(FEmTool_HAssemblyTable) AssTable;
|
||||
|
||||
math_Matrix H(0, MxDeg, 0, MxDeg);
|
||||
math_Vector G(0, MxDeg), Sol(1, A.NbGlobVar());
|
||||
|
||||
Standard_Integer el, dim;
|
||||
|
||||
A.GetAssemblyTable(AssTable);
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
|
||||
Standard_Real CBLONG = J->EstLength();
|
||||
|
||||
// Updating Assembly
|
||||
if (ToAssemble)
|
||||
A.NullifyMatrix();
|
||||
A.NullifyVector();
|
||||
|
||||
|
||||
for (el = 1; el <= NbElm; el++) {
|
||||
if (ToAssemble) {
|
||||
J->Hessian(el, 1, 1, H);
|
||||
for(dim = 1; dim <= NbDim; dim++)
|
||||
A.AddMatrix(el, dim, dim, H);
|
||||
}
|
||||
|
||||
for(dim = 1; dim <= NbDim; dim++) {
|
||||
J->Gradient(el, dim, G);
|
||||
A.AddVector(el, dim, G);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Solution of system
|
||||
if (ToAssemble) {
|
||||
if(NbConstr != 0) { //Treatment of constraints
|
||||
AssemblingConstraints(Curve, Parameters, CBLONG, A);
|
||||
}
|
||||
A.Solve();
|
||||
}
|
||||
A.Solution(Sol);
|
||||
|
||||
|
||||
// Updating J
|
||||
J->SetCurve(Curve);
|
||||
J->InputVector(Sol, AssTable);
|
||||
|
||||
// Updating Curve and reduction of degree
|
||||
|
||||
Standard_Integer Newdeg;
|
||||
Standard_Real MaxError;
|
||||
|
||||
if(NbConstr == 0) {
|
||||
for(el = 1; el <= NbElm; el++) {
|
||||
Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
TColStd_Array1OfReal& TabInt = Curve->Knots();
|
||||
Standard_Integer Icnt = 1, p0 = Parameters.Lower() - myFirstPoint, point;
|
||||
for(el = 1; el <= NbElm; el++) {
|
||||
while((Icnt < NbConstr) &&
|
||||
(Parameters(p0 + myTypConstraints->Value(2 * Icnt - 1)) <= TabInt(el))) Icnt++;
|
||||
point = p0 + myTypConstraints->Value(2 * Icnt - 1);
|
||||
if(Parameters(point) <= TabInt(el) || Parameters(point) >= TabInt(el + 1))
|
||||
Curve->ReduceDegree(el, EpsDeg, Newdeg, MaxError);
|
||||
else
|
||||
if(Curve->Degree(el) < MxDeg) Curve->SetDegree(el, MxDeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
123
src/AppParCurves/AppParCurves_Variational_3.gxx
Executable file
123
src/AppParCurves/AppParCurves_Variational_3.gxx
Executable file
@@ -0,0 +1,123 @@
|
||||
// File: AppParCurves_Variational_3.gxx
|
||||
// Created: Tue Dec 8 09:08:54 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
|
||||
void AppParCurves_Variational::Project(const Handle(FEmTool_Curve)& C,
|
||||
const TColStd_Array1OfReal& Ti,
|
||||
TColStd_Array1OfReal& ProjTi,
|
||||
TColStd_Array1OfReal& Distance,
|
||||
Standard_Integer& NumPoints,
|
||||
Standard_Real& MaxErr,
|
||||
Standard_Real& QuaErr,
|
||||
Standard_Real& AveErr,
|
||||
const Standard_Integer NbIterations) const
|
||||
|
||||
{
|
||||
// Initialisation
|
||||
|
||||
const Standard_Real Seuil = 1.e-9, Eps = 1.e-12;
|
||||
|
||||
MaxErr = QuaErr = AveErr = 0.;
|
||||
|
||||
Standard_Integer Ipnt, NItCv, Iter, i, i0 = -myDimension, d0 = Distance.Lower() - 1;
|
||||
|
||||
Standard_Real TNew, Dist, T0, Dist0, F1, F2, Aux, DF, Ecart;
|
||||
|
||||
Standard_Boolean EnCour;
|
||||
|
||||
TColStd_Array1OfReal ValOfC(1, myDimension), FirstDerOfC(1, myDimension),
|
||||
SecndDerOfC(1, myDimension);
|
||||
|
||||
for(Ipnt = 1; Ipnt <= ProjTi.Length(); Ipnt++) {
|
||||
|
||||
i0 += myDimension;
|
||||
|
||||
TNew = Ti(Ipnt);
|
||||
|
||||
EnCour = Standard_True;
|
||||
NItCv = 0;
|
||||
Iter = 0;
|
||||
C->D0(TNew, ValOfC);
|
||||
|
||||
Dist = 0;
|
||||
for(i = 1; i <= myDimension; i++) {
|
||||
Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
|
||||
Dist += Aux * Aux;
|
||||
}
|
||||
Dist = Sqrt(Dist);
|
||||
|
||||
// ------- Newton's method for solving (C'(t),C(t) - P) = 0
|
||||
|
||||
while( EnCour ) {
|
||||
|
||||
Iter++;
|
||||
T0 = TNew;
|
||||
Dist0 = Dist;
|
||||
|
||||
C->D2(TNew, SecndDerOfC);
|
||||
C->D1(TNew, FirstDerOfC);
|
||||
|
||||
F1 = F2 = 0.;
|
||||
for(i = 1; i <= myDimension; i++) {
|
||||
Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
|
||||
DF = FirstDerOfC(i);
|
||||
F1 += Aux*DF; // (C'(t),C(t) - P)
|
||||
F2 += DF*DF + Aux * SecndDerOfC(i); // ((C'(t),C(t) - P))'
|
||||
}
|
||||
|
||||
if(Abs(F2) < Eps)
|
||||
EnCour = Standard_False;
|
||||
else {
|
||||
// Formula of Newton x(k+1) = x(k) - F(x(k))/F'(x(k))
|
||||
TNew -= F1 / F2;
|
||||
if(TNew < 0.) TNew = 0.;
|
||||
if(TNew > 1.) TNew = 1.;
|
||||
|
||||
|
||||
// Analysis of result
|
||||
|
||||
C->D0(TNew, ValOfC);
|
||||
|
||||
Dist = 0;
|
||||
for(i = 1; i <= myDimension; i++) {
|
||||
Aux = ValOfC(i) - myTabPoints->Value(i0 + i);
|
||||
Dist += Aux * Aux;
|
||||
}
|
||||
Dist = Sqrt(Dist);
|
||||
|
||||
Ecart = Dist0 - Dist;
|
||||
|
||||
if(Ecart <= -Seuil) {
|
||||
// Pas d'amelioration on s'arrete
|
||||
EnCour = Standard_False;
|
||||
TNew = T0;
|
||||
Dist = Dist0;
|
||||
}
|
||||
else if(Ecart <= Seuil)
|
||||
// Convergence
|
||||
NItCv++;
|
||||
else
|
||||
NItCv = 0;
|
||||
|
||||
if((NItCv >= 2) || (Iter >= NbIterations)) EnCour = Standard_False;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProjTi(Ipnt) = TNew;
|
||||
Distance(d0 + Ipnt) = Dist;
|
||||
if(Dist > MaxErr) {
|
||||
MaxErr = Dist;
|
||||
NumPoints = Ipnt;
|
||||
}
|
||||
QuaErr += Dist * Dist;
|
||||
AveErr += Dist;
|
||||
}
|
||||
|
||||
NumPoints = NumPoints + myFirstPoint - 1;// Setting NumPoints to interval [myFirstPoint, myLastPoint]
|
||||
|
||||
}
|
123
src/AppParCurves/AppParCurves_Variational_4.gxx
Executable file
123
src/AppParCurves/AppParCurves_Variational_4.gxx
Executable file
@@ -0,0 +1,123 @@
|
||||
// File: AppParCurves_Variational_4.gxx
|
||||
// Created: Tue Dec 8 12:31:51 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
void AppParCurves_Variational::ACR(Handle(FEmTool_Curve)& Curve,
|
||||
TColStd_Array1OfReal& Ti,
|
||||
const Standard_Integer Decima) const
|
||||
{
|
||||
|
||||
const Standard_Real Eps = 1.e-8;
|
||||
|
||||
TColStd_Array1OfReal& Knots = Curve->Knots();
|
||||
Standard_Integer NbrPnt = Ti.Length(), TiFirst = Ti.Lower(), TiLast = Ti.Upper(),
|
||||
KFirst = Knots.Lower(), KLast = Knots.Upper();
|
||||
|
||||
Standard_Real CbLong, DeltaT, VTest, UNew, UOld, DU, TPara, TOld, DTInv, Ratio;
|
||||
Standard_Integer ipnt, ii, IElm, IOld, POld, PCnt, ICnt=0;
|
||||
Standard_Integer NbCntr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
|
||||
// (1) Calcul de la longueur de courbe
|
||||
|
||||
Curve->Length(Ti(TiFirst), Ti(TiLast), CbLong);
|
||||
|
||||
// (2) Mise de l'acr dans Ti
|
||||
|
||||
if(NbrPnt >= 2) {
|
||||
|
||||
// (2.0) Initialisation
|
||||
DeltaT = (Ti(TiLast) - Ti(TiFirst)) / Decima;
|
||||
VTest = Ti(TiFirst) + DeltaT;
|
||||
|
||||
if(NbCntr > 0) {
|
||||
PCnt = myTypConstraints->Value(1) - myFirstPoint + TiFirst;
|
||||
ICnt = 1;
|
||||
}
|
||||
else
|
||||
PCnt = TiLast + 1;
|
||||
|
||||
UOld = 0.;
|
||||
|
||||
TOld = Ti(TiFirst);
|
||||
POld = TiFirst;
|
||||
|
||||
IElm = KFirst;
|
||||
IOld = IElm;
|
||||
|
||||
Ti(TiFirst) = 0.;
|
||||
|
||||
for(ipnt = TiFirst + 1; ipnt <= TiLast; ipnt++) {
|
||||
|
||||
while((ICnt <= NbCntr) && (PCnt < ipnt)) {
|
||||
ICnt++;
|
||||
PCnt = myTypConstraints->Value(2*ICnt-1) - myFirstPoint + TiFirst;
|
||||
}
|
||||
|
||||
TPara = Ti(ipnt);
|
||||
|
||||
if(TPara >= VTest || PCnt == ipnt) {
|
||||
|
||||
if ( Ti(TiLast) - TPara <= 1.e-2*DeltaT) {
|
||||
ipnt = TiLast;
|
||||
TPara = Ti(ipnt);
|
||||
}
|
||||
// (2.2), (2.3) Cacul la longueur de courbe
|
||||
Curve->Length(Ti(TiFirst), TPara, UNew);
|
||||
|
||||
UNew /= CbLong;
|
||||
|
||||
while(Knots(IElm + 1) < TPara && IElm < KLast - 1) IElm++;
|
||||
|
||||
// (2.4) Mise a jours des parametres de decoupe
|
||||
DTInv = 1. / (TPara - TOld);
|
||||
DU = UNew - UOld;
|
||||
|
||||
for(ii = IOld+1; ii <= IElm; ii++) {
|
||||
Ratio = (Knots(ii) - TOld) * DTInv;
|
||||
Knots(ii) = UOld + Ratio * DU;
|
||||
}
|
||||
|
||||
// (2.5) Mise a jours des parametres de points.
|
||||
|
||||
//Very strange loop, because it never works (POld+1 > ipnt-1)
|
||||
for(ii = POld+1; ii <= ipnt-1; ii++) {
|
||||
Ratio = ( Ti(ii) - TOld ) * DTInv;
|
||||
Ti(ii) = UOld + Ratio * DU;
|
||||
}
|
||||
|
||||
Ti(ipnt) = UNew;
|
||||
|
||||
UOld = UNew;
|
||||
IOld = IElm;
|
||||
TOld = TPara;
|
||||
POld = ipnt;
|
||||
|
||||
}
|
||||
// --> Nouveau seuil parametrique pour le decimage
|
||||
|
||||
if(TPara >= VTest) {
|
||||
// ii = RealToInt((TPara - VTest + Eps) / DeltaT);
|
||||
// VTest += (ii + 1) * DeltaT;
|
||||
VTest += Ceiling((TPara - VTest + Eps) / DeltaT) * DeltaT;
|
||||
if(VTest > 1. - Eps) VTest = 1.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- On ajuste les valeurs extremes
|
||||
|
||||
Ti(TiFirst) = 0.;
|
||||
Ti(TiLast) = 1.;
|
||||
ii = TiLast - 1;
|
||||
while ( Ti(ii) > Knots(KLast) ) {
|
||||
Ti(ii) = 1.;
|
||||
--ii;
|
||||
}
|
||||
Knots(KFirst) = 0.;
|
||||
Knots(KLast) = 1.;
|
||||
|
||||
}
|
||||
|
||||
|
141
src/AppParCurves/AppParCurves_Variational_5.gxx
Executable file
141
src/AppParCurves/AppParCurves_Variational_5.gxx
Executable file
@@ -0,0 +1,141 @@
|
||||
// File: AppParCurves_Variational_5.gxx
|
||||
// Created: Thu Dec 10 14:32:36 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
#include <SortTools_ShellSortOfReal.hxx>
|
||||
#include <TCollection_CompareOfReal.hxx>
|
||||
#include <PLib_Base.hxx>
|
||||
|
||||
//----------------------------------------------------------//
|
||||
// Standard_Integer NearIndex //
|
||||
// Purpose: searching nearest index of TabPar corresponding //
|
||||
// given value T (is similar to fortran routine MSRRE2) //
|
||||
//----------------------------------------------------------//
|
||||
|
||||
static Standard_Integer NearIndex(const Standard_Real T,
|
||||
const TColStd_Array1OfReal& TabPar,
|
||||
const Standard_Real Eps, Standard_Integer& Flag)
|
||||
{
|
||||
Standard_Integer Loi = TabPar.Lower(), Upi = TabPar.Upper();
|
||||
|
||||
Flag = 0;
|
||||
|
||||
if(T < TabPar(Loi)) { Flag = -1; return Loi;}
|
||||
if(T > TabPar(Upi)) { Flag = 1; return Upi;}
|
||||
|
||||
Standard_Integer Ibeg = Loi, Ifin = Upi, Imidl;
|
||||
|
||||
while(Ibeg + 1 != Ifin) {
|
||||
Imidl = (Ibeg + Ifin) / 2;
|
||||
if((T >= TabPar(Ibeg)) && (T <= TabPar(Imidl)))
|
||||
Ifin = Imidl;
|
||||
else
|
||||
Ibeg = Imidl;
|
||||
}
|
||||
|
||||
if(Abs(T - TabPar(Ifin)) < Eps) return Ifin;
|
||||
|
||||
return Ibeg;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------//
|
||||
// void GettingKnots //
|
||||
// Purpose: calculating values of new Knots for elements //
|
||||
// with degree that is equal Deg //
|
||||
//----------------------------------------------------------//
|
||||
|
||||
static void GettingKnots(const TColStd_Array1OfReal& TabPar,
|
||||
const Handle(FEmTool_Curve)& InCurve,
|
||||
const Standard_Integer Deg,
|
||||
Standard_Integer& NbElm,
|
||||
TColStd_Array1OfReal& NewKnots)
|
||||
|
||||
{
|
||||
|
||||
const Standard_Real Eps = 1.e-12;
|
||||
|
||||
TColStd_Array1OfReal& OldKnots = InCurve->Knots();
|
||||
Standard_Integer NbMaxOld = InCurve->NbElements();
|
||||
Standard_Integer NbMax = NewKnots.Upper(), Ipt, Ipt1, Ipt2;
|
||||
Standard_Integer el = 0, i1 = OldKnots.Lower(), i0 = i1 - 1, Flag;
|
||||
Standard_Real TPar;
|
||||
|
||||
while((NbElm < NbMax) && (el < NbMaxOld)) {
|
||||
|
||||
el++; i0++; i1++; // i0, i1 are indexes of left and right knots of element el
|
||||
|
||||
if(InCurve->Degree(el) == Deg) {
|
||||
|
||||
NbElm++;
|
||||
|
||||
Ipt1 = NearIndex(OldKnots(i0), TabPar, Eps, Flag);
|
||||
if(Flag != 0) Ipt1 = TabPar.Lower();
|
||||
Ipt2 = NearIndex(OldKnots(i1), TabPar, Eps, Flag);
|
||||
if(Flag != 0) Ipt2 = TabPar.Upper();
|
||||
|
||||
if(Ipt2 - Ipt1 >= 1) {
|
||||
|
||||
Ipt = (Ipt1 + Ipt2) / 2;
|
||||
if(2 * Ipt == Ipt1 + Ipt2)
|
||||
TPar = 2. * TabPar(Ipt);
|
||||
else
|
||||
TPar = TabPar(Ipt) + TabPar(Ipt + 1);
|
||||
|
||||
NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1) + TPar) / 4.;
|
||||
}
|
||||
else
|
||||
NewKnots(NbElm) = (OldKnots(i0) + OldKnots(i1)) / 2.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppParCurves_Variational::SplitCurve(const Handle(FEmTool_Curve)& InCurve,
|
||||
const TColStd_Array1OfReal& Ti,
|
||||
const Standard_Real CurveTol,
|
||||
Handle(FEmTool_Curve)& OutCurve,
|
||||
Standard_Boolean& iscut) const
|
||||
{
|
||||
Standard_Integer NbElmOld = InCurve->NbElements();
|
||||
|
||||
if(NbElmOld >= myMaxSegment) {iscut = Standard_False; return;}
|
||||
#ifdef DEB
|
||||
Standard_Integer MaxDegree =
|
||||
#endif
|
||||
InCurve->Base()->WorkDegree();
|
||||
Standard_Integer NbElm = NbElmOld;
|
||||
TColStd_Array1OfReal NewKnots(NbElm + 1, myMaxSegment);
|
||||
#ifndef DEB
|
||||
GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree(), NbElm, NewKnots);
|
||||
GettingKnots(Ti, InCurve, InCurve->Base()->WorkDegree() - 1, NbElm, NewKnots);
|
||||
#else
|
||||
GettingKnots(Ti, InCurve, MaxDegree, NbElm, NewKnots);
|
||||
GettingKnots(Ti, InCurve, MaxDegree - 1, NbElm, NewKnots);
|
||||
|
||||
#endif
|
||||
if(NbElm > NbElmOld) {
|
||||
|
||||
iscut = Standard_True;
|
||||
|
||||
OutCurve = new FEmTool_Curve(InCurve->Dimension(), NbElm, InCurve->Base(), CurveTol);
|
||||
TColStd_Array1OfReal& OutKnots = OutCurve->Knots();
|
||||
TColStd_Array1OfReal& InKnots = InCurve->Knots();
|
||||
|
||||
Standard_Integer i, i0 = OutKnots.Lower();
|
||||
for(i = InKnots.Lower(); i <= InKnots.Upper(); i++) OutKnots(i) = InKnots(i);
|
||||
for(i = NbElmOld + 1; i <= NbElm; i++) OutKnots(i + i0) = NewKnots(i);
|
||||
|
||||
// SortTools_ShellSortOfReal Sort;
|
||||
TCollection_CompareOfReal CompReal;
|
||||
|
||||
// Sort.Sort(OutKnots, CompReal);
|
||||
SortTools_ShellSortOfReal::Sort(OutKnots, CompReal);
|
||||
}
|
||||
else
|
||||
iscut = Standard_False;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
615
src/AppParCurves/AppParCurves_Variational_6.gxx
Executable file
615
src/AppParCurves/AppParCurves_Variational_6.gxx
Executable file
@@ -0,0 +1,615 @@
|
||||
// File: AppParCurves_Variational_6.gxx
|
||||
// Created: Mon Dec 21 10:31:30 1998
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559
|
||||
|
||||
#include <PLib_Base.hxx>
|
||||
#include <PLib_JacobiPolynomial.hxx>
|
||||
#include <PLib_HermitJacobi.hxx>
|
||||
#include <FEmTool_Curve.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : InitSmoothCriterion
|
||||
//purpose : Initializes the SmoothCriterion
|
||||
//
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::InitSmoothCriterion()
|
||||
{
|
||||
|
||||
const Standard_Real Eps2 = 1.e-6, Eps3 = 1.e-9;
|
||||
// const Standard_Real J1 = .01, J2 = .001, J3 = .001;
|
||||
|
||||
|
||||
|
||||
Standard_Real Length;
|
||||
|
||||
InitParameters(Length);
|
||||
|
||||
mySmoothCriterion->SetParameters(myParameters);
|
||||
|
||||
Standard_Real E1, E2, E3;
|
||||
|
||||
InitCriterionEstimations(Length, E1, E2, E3);
|
||||
/*
|
||||
J1 = 1.e-8; J2 = J3 = (E1 + 1.e-8) * 1.e-6;
|
||||
|
||||
if(E1 < J1) E1 = J1;
|
||||
if(E2 < J2) E2 = J2;
|
||||
if(E3 < J3) E3 = J3;
|
||||
*/
|
||||
mySmoothCriterion->EstLength() = Length;
|
||||
mySmoothCriterion->SetEstimation(E1, E2, E3);
|
||||
|
||||
Standard_Real WQuadratic, WQuality;
|
||||
|
||||
if(!myWithMinMax && myTolerance != 0.)
|
||||
WQuality = myTolerance;
|
||||
else if (myTolerance == 0.)
|
||||
WQuality = 1.;
|
||||
else
|
||||
WQuality = Max(myTolerance, Eps2 * Length);
|
||||
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
WQuadratic = Sqrt((Standard_Real)(myNbPoints - NbConstr)) * WQuality;
|
||||
if(WQuadratic > Eps3) WQuadratic = 1./ WQuadratic;
|
||||
|
||||
if(WQuadratic == 0.) WQuadratic = Max(Sqrt(E1), 1.);
|
||||
|
||||
|
||||
mySmoothCriterion->SetWeight(WQuadratic, WQuality,
|
||||
myPercent[0], myPercent[1], myPercent[2]);
|
||||
|
||||
|
||||
Handle(PLib_Base) TheBase = new PLib_HermitJacobi(myMaxDegree, myContinuity);
|
||||
Handle(FEmTool_Curve) TheCurve;
|
||||
Standard_Integer NbElem;
|
||||
Standard_Real CurvTol = Eps2 * Length / myNbPoints;
|
||||
|
||||
// Decoupe de l'intervalle en fonction des contraintes
|
||||
if(myWithCutting == Standard_True && NbConstr != 0) {
|
||||
|
||||
InitCutting(TheBase, CurvTol, TheCurve);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
NbElem = 1;
|
||||
TheCurve = new FEmTool_Curve(myDimension, NbElem, TheBase, CurvTol);
|
||||
TheCurve->Knots().SetValue(TheCurve->Knots().Lower(),
|
||||
myParameters->Value(myFirstPoint));
|
||||
TheCurve->Knots().SetValue(TheCurve->Knots().Upper(),
|
||||
myParameters->Value(myLastPoint));
|
||||
|
||||
}
|
||||
|
||||
mySmoothCriterion->SetCurve(TheCurve);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : InitParameters
|
||||
//purpose : Calculation of initial estimation of the multicurve's length
|
||||
// and parameters for multipoints.
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::InitParameters(Standard_Real& Length)
|
||||
{
|
||||
|
||||
const Standard_Real Eps1 = Precision::Confusion() * .01;
|
||||
|
||||
Standard_Real aux, dist;
|
||||
Standard_Integer i, i0, i1 = 0, ipoint;
|
||||
|
||||
|
||||
Length = 0.;
|
||||
myParameters->SetValue(myFirstPoint, Length);
|
||||
|
||||
for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint; ipoint++) {
|
||||
i0 = i1; i1 += myDimension;
|
||||
dist = 0;
|
||||
for(i = 1; i <= myDimension; i++) {
|
||||
aux = myTabPoints->Value(i1 + i) - myTabPoints->Value(i0 + i);
|
||||
dist += aux * aux;
|
||||
}
|
||||
Length += Sqrt(dist);
|
||||
myParameters->SetValue(ipoint, Length);
|
||||
}
|
||||
|
||||
|
||||
if(Length <= Eps1)
|
||||
Standard_ConstructionError::Raise("AppParCurves_Variational::InitParameters");
|
||||
|
||||
|
||||
for(ipoint = myFirstPoint + 1; ipoint <= myLastPoint - 1; ipoint++)
|
||||
myParameters->SetValue(ipoint, myParameters->Value(ipoint) / Length);
|
||||
|
||||
myParameters->SetValue(myLastPoint, 1.);
|
||||
|
||||
// Avec peu de point il y a sans doute sous estimation ...
|
||||
if(myNbPoints < 10) Length *= (1. + 0.1 / (myNbPoints - 1));
|
||||
}
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : InitCriterionEstimations
|
||||
//purpose : Calculation of initial estimation of the linear criteria
|
||||
//
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::InitCriterionEstimations(const Standard_Real Length,
|
||||
Standard_Real& E1,
|
||||
Standard_Real& E2,
|
||||
Standard_Real& E3) const
|
||||
{
|
||||
E1 = Length * Length;
|
||||
|
||||
const Standard_Real Eps1 = Precision::Confusion() * .01;
|
||||
|
||||
math_Vector VTang1(1, myDimension), VTang2(1, myDimension), VTang3(1, myDimension),
|
||||
VScnd1(1, myDimension), VScnd2(1, myDimension), VScnd3(1, myDimension);
|
||||
|
||||
// ========== Treatment of first point =================
|
||||
|
||||
Standard_Integer ipnt = myFirstPoint;
|
||||
|
||||
EstTangent(ipnt, VTang1);
|
||||
ipnt++;
|
||||
EstTangent(ipnt, VTang2);
|
||||
ipnt++;
|
||||
EstTangent(ipnt, VTang3);
|
||||
|
||||
ipnt = myFirstPoint;
|
||||
EstSecnd(ipnt, VTang1, VTang2, Length, VScnd1);
|
||||
ipnt++;
|
||||
EstSecnd(ipnt, VTang1, VTang3, Length, VScnd2);
|
||||
|
||||
// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 Begin
|
||||
// Standard_Real Delta = .5 * (myParameters->Value(ipnt) - myParameters->Value(--ipnt));
|
||||
Standard_Integer anInd = ipnt;
|
||||
Standard_Real Delta = .5 * (myParameters->Value(anInd) - myParameters->Value(--ipnt));
|
||||
// Modified by skv - Fri Apr 8 14:58:12 2005 OCC8559 End
|
||||
|
||||
if(Delta <= Eps1) Delta = 1.;
|
||||
|
||||
E2 = VScnd1.Norm2() * Delta;
|
||||
|
||||
E3 = (Delta > Eps1) ? VScnd2.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
|
||||
// ========== Treatment of internal points =================
|
||||
|
||||
Standard_Integer CurrPoint = 2;
|
||||
|
||||
for(ipnt = myFirstPoint + 1; ipnt < myLastPoint; ipnt++) {
|
||||
|
||||
Delta = .5 * (myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1));
|
||||
|
||||
if(CurrPoint == 1) {
|
||||
if(ipnt + 1 != myLastPoint) {
|
||||
EstTangent(ipnt + 2, VTang3);
|
||||
EstSecnd(ipnt + 1, VTang1, VTang3, Length, VScnd2);
|
||||
}
|
||||
else
|
||||
EstSecnd(ipnt + 1, VTang1, VTang2, Length, VScnd2);
|
||||
|
||||
E2 += VScnd1.Norm2() * Delta;
|
||||
E3 += (Delta > Eps1) ? VScnd2.Subtracted(VScnd3).Norm2() / (4. * Delta) : 0.;
|
||||
|
||||
}
|
||||
else if(CurrPoint == 2) {
|
||||
if(ipnt + 1 != myLastPoint) {
|
||||
EstTangent(ipnt + 2, VTang1);
|
||||
EstSecnd(ipnt + 1, VTang2, VTang1, Length, VScnd3);
|
||||
}
|
||||
else
|
||||
EstSecnd(ipnt + 1, VTang2, VTang3, Length, VScnd3);
|
||||
|
||||
E2 += VScnd2.Norm2() * Delta;
|
||||
E3 += (Delta > Eps1) ? VScnd3.Subtracted(VScnd1).Norm2() / (4. * Delta) : 0.;
|
||||
|
||||
}
|
||||
else {
|
||||
if(ipnt + 1 != myLastPoint) {
|
||||
EstTangent(ipnt + 2, VTang2);
|
||||
EstSecnd(ipnt + 1, VTang3, VTang2, Length, VScnd1);
|
||||
}
|
||||
else
|
||||
EstSecnd(ipnt + 1, VTang3, VTang1, Length, VScnd1);
|
||||
|
||||
E2 += VScnd3.Norm2() * Delta;
|
||||
E3 += (Delta > Eps1) ? VScnd1.Subtracted(VScnd2).Norm2() / (4. * Delta) : 0.;
|
||||
|
||||
}
|
||||
|
||||
CurrPoint++; if(CurrPoint == 4) CurrPoint = 1;
|
||||
}
|
||||
|
||||
// ========== Treatment of last point =================
|
||||
|
||||
Delta = .5 * (myParameters->Value(myLastPoint) - myParameters->Value(myLastPoint - 1));
|
||||
if(Delta <= Eps1) Delta = 1.;
|
||||
|
||||
Standard_Real aux;
|
||||
|
||||
if(CurrPoint == 1) {
|
||||
|
||||
E2 += VScnd1.Norm2() * Delta;
|
||||
aux = VScnd1.Subtracted(VScnd3).Norm2();
|
||||
E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
|
||||
|
||||
}
|
||||
else if(CurrPoint == 2) {
|
||||
|
||||
E2 += VScnd2.Norm2() * Delta;
|
||||
aux = VScnd2.Subtracted(VScnd1).Norm2();
|
||||
E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
E2 += VScnd3.Norm2() * Delta;
|
||||
aux = VScnd3.Subtracted(VScnd2).Norm2();
|
||||
E3 += (Delta > Eps1) ? aux / (4. * Delta) : aux;
|
||||
|
||||
}
|
||||
|
||||
aux = Length * Length;
|
||||
|
||||
E2 *= aux; E3 *= aux;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : EstTangent
|
||||
//purpose : Calculation of estimation of the Tangent
|
||||
// (see fortran routine MMLIPRI)
|
||||
//=======================================================================
|
||||
//
|
||||
|
||||
void AppParCurves_Variational::EstTangent(const Standard_Integer ipnt,
|
||||
math_Vector& VTang) const
|
||||
|
||||
{
|
||||
Standard_Integer i ;
|
||||
const Standard_Real Eps1 = Precision::Confusion() * .01;
|
||||
const Standard_Real EpsNorm = 1.e-9;
|
||||
|
||||
Standard_Real Wpnt = 1.;
|
||||
|
||||
|
||||
if(ipnt == myFirstPoint) {
|
||||
// Estimation at first point
|
||||
if(myNbPoints < 3)
|
||||
Wpnt = 0.;
|
||||
else {
|
||||
|
||||
Standard_Integer adr1 = 1, adr2 = adr1 + myDimension,
|
||||
adr3 = adr2 + myDimension;
|
||||
|
||||
math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
|
||||
math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
|
||||
math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
|
||||
|
||||
// Parabolic interpolation
|
||||
// if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
|
||||
// first derivative for t=0 is A1 = ((d2-1)*P1 + P2 - d2*P3)/(d*(1-d))
|
||||
// d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*d
|
||||
Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
|
||||
Standard_Real V2 = 0.;
|
||||
if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
|
||||
if(V2 > Eps1) {
|
||||
Standard_Real d = V1 / (V1 + V2), d1;
|
||||
d1 = 1. / (d * (1 - d)); d *= d;
|
||||
VTang = ((d - 1.) * Pnt1 + Pnt2 - d * Pnt3) * d1;
|
||||
}
|
||||
else {
|
||||
// Simple 2-point estimation
|
||||
|
||||
VTang = Pnt2 - Pnt1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ipnt == myLastPoint) {
|
||||
// Estimation at last point
|
||||
if(myNbPoints < 3)
|
||||
Wpnt = 0.;
|
||||
else {
|
||||
|
||||
Standard_Integer adr1 = (myLastPoint - 3) * myDimension + 1,
|
||||
adr2 = adr1 + myDimension,
|
||||
adr3 = adr2 + myDimension;
|
||||
|
||||
math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
|
||||
math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
|
||||
math_Vector Pnt3((Standard_Real*)&myTabPoints->Value(adr3), 1, myDimension);
|
||||
|
||||
// Parabolic interpolation
|
||||
// if we have parabolic interpolation: F(t) = A0 + A1*t + A2*t*t,
|
||||
// first derivative for t=1 is 2*A2 + A1 = ((d2+1)*P1 - P2 - d2*P3)/(d*(1-d))
|
||||
// d= |P2-P1|/(|P2-P1|+|P3-P2|), d2 = d*(d-2)
|
||||
Standard_Real V1 = Pnt2.Subtracted(Pnt1).Norm();
|
||||
Standard_Real V2 = 0.;
|
||||
if(V1 > Eps1) V2 = Pnt3.Subtracted(Pnt2).Norm();
|
||||
if(V2 > Eps1) {
|
||||
Standard_Real d = V1 / (V1 + V2), d1;
|
||||
d1 = 1. / (d * (1 - d)); d *= d - 2;
|
||||
VTang = ((d + 1.) * Pnt1 - Pnt2 - d * Pnt3) * d1;
|
||||
}
|
||||
else {
|
||||
// Simple 2-point estimation
|
||||
|
||||
VTang = Pnt3 - Pnt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Standard_Integer adr1 = (ipnt - myFirstPoint - 1) * myDimension + 1,
|
||||
adr2 = adr1 + 2 * myDimension;
|
||||
|
||||
math_Vector Pnt1((Standard_Real*)&myTabPoints->Value(adr1), 1, myDimension);
|
||||
math_Vector Pnt2((Standard_Real*)&myTabPoints->Value(adr2), 1, myDimension);
|
||||
|
||||
VTang = Pnt2 - Pnt1;
|
||||
|
||||
}
|
||||
|
||||
Standard_Real Vnorm = VTang.Norm();
|
||||
|
||||
if(Vnorm <= EpsNorm)
|
||||
VTang.Init(0.);
|
||||
else
|
||||
VTang /= Vnorm;
|
||||
|
||||
// Estimation with constraints
|
||||
|
||||
Standard_Real Wcnt = 0.;
|
||||
Standard_Integer IdCnt = 1;
|
||||
|
||||
// Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
|
||||
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
math_Vector VCnt(1, myDimension, 0.);
|
||||
|
||||
if(NbConstr > 0) {
|
||||
|
||||
while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
|
||||
IdCnt <= NbConstr) IdCnt++;
|
||||
if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
|
||||
(myTypConstraints->Value(2 * IdCnt) >= 1)) {
|
||||
Wcnt = 1.;
|
||||
Standard_Integer i0 = 2 * myDimension * (IdCnt - 1), k = 0;
|
||||
for( i = 1; i <= myNbP3d; i++) {
|
||||
for(Standard_Integer j = 1; j <= 3; j++)
|
||||
VCnt(++k) = myTabConstraints->Value(++i0);
|
||||
i0 += 3;
|
||||
}
|
||||
for(i = 1; i <= myNbP2d; i++) {
|
||||
for(Standard_Integer j = 1; j <= 2; j++)
|
||||
VCnt(++k) = myTabConstraints->Value(++i0);
|
||||
i0 += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Averaging of estimation
|
||||
|
||||
Standard_Real Denom = Wpnt + Wcnt;
|
||||
if(Denom == 0.) Denom = 1.;
|
||||
else Denom = 1. / Denom;
|
||||
|
||||
VTang = (Wpnt * VTang + Wcnt * VCnt) * Denom;
|
||||
|
||||
Vnorm = VTang.Norm();
|
||||
|
||||
if(Vnorm <= EpsNorm)
|
||||
VTang.Init(0.);
|
||||
else
|
||||
VTang /= Vnorm;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : EstSecnd
|
||||
//purpose : Calculation of estimation of the second derivative
|
||||
// (see fortran routine MLIMSCN)
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::EstSecnd(const Standard_Integer ipnt,
|
||||
const math_Vector& VTang1,
|
||||
const math_Vector& VTang2,
|
||||
const Standard_Real Length,
|
||||
math_Vector& VScnd) const
|
||||
{
|
||||
Standard_Integer i ;
|
||||
|
||||
const Standard_Real Eps = 1.e-9;
|
||||
|
||||
Standard_Real Wpnt = 1.;
|
||||
|
||||
Standard_Real aux;
|
||||
|
||||
if(ipnt == myFirstPoint)
|
||||
aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt);
|
||||
else if(ipnt == myLastPoint)
|
||||
aux = myParameters->Value(ipnt) - myParameters->Value(ipnt - 1);
|
||||
else
|
||||
aux = myParameters->Value(ipnt + 1) - myParameters->Value(ipnt - 1);
|
||||
|
||||
if(aux <= Eps)
|
||||
aux = 1.;
|
||||
else
|
||||
aux = 1. / aux;
|
||||
|
||||
VScnd = (VTang2 - VTang1) * aux;
|
||||
|
||||
// Estimation with constraints
|
||||
|
||||
Standard_Real Wcnt = 0.;
|
||||
Standard_Integer IdCnt = 1;
|
||||
|
||||
// Warning!! Here it is suppoused that all points are in range [myFirstPoint, myLastPoint]
|
||||
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
math_Vector VCnt(1, myDimension, 0.);
|
||||
|
||||
if(NbConstr > 0) {
|
||||
|
||||
while(myTypConstraints->Value(2 * IdCnt - 1) < ipnt &&
|
||||
IdCnt <= NbConstr) IdCnt++;
|
||||
|
||||
if((myTypConstraints->Value(2 * IdCnt - 1) == ipnt) &&
|
||||
(myTypConstraints->Value(2 * IdCnt) >= 2)) {
|
||||
Wcnt = 1.;
|
||||
Standard_Integer i0 = 2 * myDimension * (IdCnt - 1) + 3, k = 0;
|
||||
for( i = 1; i <= myNbP3d; i++) {
|
||||
for(Standard_Integer j = 1; j <= 3; j++)
|
||||
VCnt(++k) = myTabConstraints->Value(++i0);
|
||||
i0 += 3;
|
||||
}
|
||||
i0--;
|
||||
for(i = 1; i <= myNbP2d; i++) {
|
||||
for(Standard_Integer j = 1; j <= 2; j++)
|
||||
VCnt(++k) = myTabConstraints->Value(++i0);
|
||||
i0 += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Averaging of estimation
|
||||
|
||||
Standard_Real Denom = Wpnt + Wcnt;
|
||||
if(Denom == 0.) Denom = 1.;
|
||||
else Denom = 1. / Denom;
|
||||
|
||||
VScnd = (Wpnt * VScnd + (Wcnt * Length) * VCnt) * Denom;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//function : InitCutting
|
||||
//purpose : Realisation of curve's cutting a priory accordingly to
|
||||
// constraints (see fortran routine MLICUT)
|
||||
//=======================================================================
|
||||
//
|
||||
void AppParCurves_Variational::InitCutting(const Handle(PLib_Base)& aBase,
|
||||
const Standard_Real CurvTol,
|
||||
Handle(FEmTool_Curve)& aCurve) const
|
||||
{
|
||||
|
||||
// Definition of number of elements
|
||||
Standard_Integer ORCMx = -1, NCont = 0, i, kk, NbElem;
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
|
||||
for(i = 1; i <= NbConstr; i++) {
|
||||
kk = Abs(myTypConstraints->Value(2 * i)) + 1;
|
||||
ORCMx = Max(ORCMx, kk);
|
||||
NCont += kk;
|
||||
}
|
||||
|
||||
if(ORCMx > myMaxDegree - myNivCont)
|
||||
Standard_ConstructionError::Raise("AppParCurves_Variational::InitCutting");
|
||||
|
||||
Standard_Integer NLibre = Max(myMaxDegree - myNivCont - (myMaxDegree + 1) / 4,
|
||||
myNivCont + 1);
|
||||
|
||||
NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
|
||||
|
||||
while((NbElem > myMaxSegment) && (NLibre < myMaxDegree - myNivCont)) {
|
||||
|
||||
NLibre++;
|
||||
NbElem = (NCont % NLibre == 0) ? NCont / NLibre : NCont / NLibre + 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(NbElem > myMaxSegment)
|
||||
Standard_ConstructionError::Raise("AppParCurves_Variational::InitCutting");
|
||||
|
||||
|
||||
aCurve = new FEmTool_Curve(myDimension, NbElem, aBase, CurvTol);
|
||||
|
||||
Standard_Integer NCnt = (NCont - 1) / NbElem + 1;
|
||||
Standard_Integer NPlus = NbElem - (NCnt * NbElem - NCont);
|
||||
|
||||
TColStd_Array1OfReal& Knot = aCurve->Knots();
|
||||
|
||||
Standard_Integer IDeb = 0, IFin = NbConstr + 1,
|
||||
NDeb = 0, NFin = 0,
|
||||
IndEl = Knot.Lower(), IUpper = Knot.Upper(),
|
||||
NbEl = 0;
|
||||
|
||||
|
||||
Knot(IndEl) = myParameters->Value(myFirstPoint);
|
||||
Knot(IUpper) = myParameters->Value(myLastPoint);
|
||||
|
||||
while(NbElem - NbEl > 1) {
|
||||
|
||||
IndEl++; NbEl++;
|
||||
if(NPlus == 0) NCnt--;
|
||||
|
||||
while(NDeb < NCnt && IDeb < IFin) {
|
||||
IDeb++;
|
||||
NDeb += Abs(myTypConstraints->Value(2 * IDeb)) + 1;
|
||||
}
|
||||
|
||||
if(NDeb == NCnt) {
|
||||
NDeb = 0;
|
||||
if(NPlus == 1 &&
|
||||
myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) > Knot(IndEl - 1))
|
||||
|
||||
Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
|
||||
else
|
||||
Knot(IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IDeb - 1)) +
|
||||
myParameters->Value(myTypConstraints->Value(2 * IDeb + 1))) / 2;
|
||||
|
||||
}
|
||||
else {
|
||||
NDeb -= NCnt;
|
||||
Knot(IndEl) = myParameters->Value(myTypConstraints->Value(2 * IDeb - 1));
|
||||
}
|
||||
|
||||
NPlus--;
|
||||
if(NPlus == 0) NCnt--;
|
||||
|
||||
if(NbElem - NbEl == 1) break;
|
||||
|
||||
NbEl++;
|
||||
|
||||
while(NFin < NCnt && IDeb < IFin) {
|
||||
IFin--;
|
||||
NFin += Abs(myTypConstraints->Value(2 * IFin)) + 1;
|
||||
}
|
||||
|
||||
if(NFin == NCnt) {
|
||||
NFin = 0;
|
||||
Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
|
||||
myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
|
||||
}
|
||||
else {
|
||||
NFin -= NCnt;
|
||||
if(myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) < Knot(IUpper - IndEl + 1))
|
||||
Knot(IUpper + 1 - IndEl) = myParameters->Value(myTypConstraints->Value(2 * IFin - 1));
|
||||
else
|
||||
Knot(IUpper + 1 - IndEl) = (myParameters->Value(myTypConstraints->Value(2 * IFin - 1)) +
|
||||
myParameters->Value(myTypConstraints->Value(2 * IFin - 3))) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
175
src/AppParCurves/AppParCurves_Variational_7.gxx
Executable file
175
src/AppParCurves/AppParCurves_Variational_7.gxx
Executable file
@@ -0,0 +1,175 @@
|
||||
// File: AppParCurves_Variational_1.gxx
|
||||
// Created: Wed Sep 17 18:29:12 1997
|
||||
// Author: Philippe MANGIN
|
||||
// <pmn@sgi29>
|
||||
|
||||
|
||||
|
||||
//====================== 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
281
src/AppParCurves/AppParCurves_Variational_8.gxx
Executable file
281
src/AppParCurves/AppParCurves_Variational_8.gxx
Executable file
@@ -0,0 +1,281 @@
|
||||
// File: AppParCurves_Variational_8.gxx
|
||||
// Created: Mon Feb 15 18:46:25 1999
|
||||
// Author: Igor FEOKTISTOV
|
||||
// <ifv@paradox.nnov.matra-dtv.fr>
|
||||
|
||||
#include <PLib_Base.hxx>
|
||||
#include <PLib_JacobiPolynomial.hxx>
|
||||
#include <PLib_HermitJacobi.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
|
||||
void AppParCurves_Variational::AssemblingConstraints(const Handle(FEmTool_Curve)& Curve,
|
||||
const TColStd_Array1OfReal& Parameters,
|
||||
const Standard_Real CBLONG,
|
||||
FEmTool_Assembly& A ) const
|
||||
{
|
||||
|
||||
Standard_Integer MxDeg = Curve->Base()->WorkDegree(),
|
||||
NbElm = Curve->NbElements(),
|
||||
NbDim = Curve->Dimension();
|
||||
|
||||
TColStd_Array1OfReal G0(0, MxDeg), G1(0, MxDeg), G2(0, MxDeg);
|
||||
math_Vector V0((Standard_Real*)&G0(0), 0, MxDeg),
|
||||
V1((Standard_Real*)&G1(0), 0, MxDeg),
|
||||
V2((Standard_Real*)&G2(0), 0, MxDeg);
|
||||
|
||||
Standard_Integer IndexOfConstraint, Ng3d, Ng2d, NBeg2d, NPass, NgPC1,
|
||||
NTang3d, NTang2d,
|
||||
Point, TypOfConstr,
|
||||
p0 = Parameters.Lower() - myFirstPoint,
|
||||
curel = 1, el, i, ipnt, ityp, j, k, pnt, curdim,
|
||||
jt, Ntheta = 6 * myNbP3d + 2 * myNbP2d;
|
||||
Standard_Integer NbConstr = myNbPassPoints + myNbTangPoints + myNbCurvPoints;
|
||||
|
||||
// Ng3d = 3 * NbConstr + 2 * myNbTangPoints + 5 * myNbCurvPoints;
|
||||
// Ng2d = 2 * NbConstr + 1 * myNbTangPoints + 3 * myNbCurvPoints;
|
||||
Ng3d = 3 * NbConstr + 3 * myNbTangPoints + 5 * myNbCurvPoints;
|
||||
Ng2d = 2 * NbConstr + 2 * myNbTangPoints + 3 * myNbCurvPoints;
|
||||
NBeg2d = Ng3d * myNbP3d;
|
||||
// NgPC1 = NbConstr + myNbCurvPoints;
|
||||
NgPC1 = NbConstr + myNbTangPoints + myNbCurvPoints;
|
||||
NPass = 0;
|
||||
NTang3d = 3 * NgPC1;
|
||||
NTang2d = 2 * NgPC1;
|
||||
|
||||
TColStd_Array1OfReal& Intervals = Curve->Knots();
|
||||
|
||||
Standard_Real t, R1, R2;
|
||||
|
||||
Handle(PLib_Base) myBase = Curve->Base();
|
||||
Handle(PLib_HermitJacobi) myHermitJacobi = (*((Handle(PLib_HermitJacobi)*)&myBase));
|
||||
Standard_Integer Order = myHermitJacobi->NivConstr() + 1;
|
||||
|
||||
Standard_Real UFirst, ULast, coeff, c0, mfact, mfact1;
|
||||
|
||||
A.NullifyConstraint();
|
||||
|
||||
ipnt = -1;
|
||||
ityp = 0;
|
||||
for(i = 1; i <= NbConstr; i++) {
|
||||
|
||||
ipnt += 2; ityp += 2;
|
||||
|
||||
Point = myTypConstraints->Value(ipnt);
|
||||
TypOfConstr = myTypConstraints->Value(ityp);
|
||||
|
||||
t = Parameters(p0 + Point);
|
||||
|
||||
for(el = curel; el <= NbElm; ) {
|
||||
if( t <= Intervals(++el) ) {
|
||||
curel = el - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UFirst = Intervals(curel); ULast = Intervals(curel + 1);
|
||||
coeff = (ULast - UFirst)/2.; c0 = (ULast + UFirst)/2.;
|
||||
|
||||
t = (t - c0) / coeff;
|
||||
|
||||
if(TypOfConstr == 0) {
|
||||
myBase->D0(t, G0);
|
||||
for(k = 1; k < Order; k++) {
|
||||
mfact = Pow(coeff, k);
|
||||
G0(k) *= mfact;
|
||||
G0(k + Order) *= mfact;
|
||||
}
|
||||
}
|
||||
else if(TypOfConstr == 1) {
|
||||
myBase->D1(t, G0, G1);
|
||||
for(k = 1; k < Order; k++) {
|
||||
mfact = Pow(coeff, k);
|
||||
G0(k) *= mfact;
|
||||
G0(k + Order) *= mfact;
|
||||
G1(k) *= mfact;
|
||||
G1(k + Order) *= mfact;
|
||||
}
|
||||
mfact = 1./coeff;
|
||||
for(k = 0; k <= MxDeg; k++) {
|
||||
G1(k) *= mfact;
|
||||
}
|
||||
}
|
||||
else {
|
||||
myBase->D2(t, G0, G1, G2);
|
||||
for(k = 1; k < Order; k++) {
|
||||
mfact = Pow(coeff, k);
|
||||
G0(k) *= mfact;
|
||||
G0(k + Order) *= mfact;
|
||||
G1(k) *= mfact;
|
||||
G1(k + Order) *= mfact;
|
||||
G2(k) *= mfact;
|
||||
G2(k + Order) *= mfact;
|
||||
}
|
||||
mfact = 1. / coeff;
|
||||
mfact1 = mfact / coeff;
|
||||
for(k = 0; k <= MxDeg; k++) {
|
||||
G1(k) *= mfact;
|
||||
G2(k) *= mfact1;
|
||||
}
|
||||
}
|
||||
|
||||
NPass++;
|
||||
|
||||
j = NbDim * (Point - myFirstPoint);
|
||||
Standard_Integer n0 = NPass;
|
||||
curdim = 0;
|
||||
for(pnt = 1; pnt <= myNbP3d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 3; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
j +=3;
|
||||
n0 += Ng3d;
|
||||
}
|
||||
|
||||
n0 = NPass + NBeg2d;
|
||||
for(pnt = 1; pnt <= myNbP2d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 2; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V0, myTabPoints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
j +=2;
|
||||
n0 += Ng2d;
|
||||
}
|
||||
|
||||
/* if(TypOfConstr == 1) {
|
||||
|
||||
IndexOfConstraint = NTang3d + 1;
|
||||
jt = Ntheta * (i - 1);
|
||||
for(pnt = 1; pnt <= myNbP3d; pnt++) {
|
||||
for(k = 1; k <= 3; k++) {
|
||||
A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
|
||||
A.AddConstraint(IndexOfConstraint + 1, curel, k, myTtheta->Value(jt + 3 + k) * V1, 0.);
|
||||
}
|
||||
IndexOfConstraint += Ng3d;
|
||||
jt += 6;
|
||||
}
|
||||
|
||||
IndexOfConstraint = NBeg2d + NTang2d + 1;
|
||||
for(pnt = 1; pnt <= myNbP2d; pnt++) {
|
||||
for(k = 1; k <= 2; k++) {
|
||||
A.AddConstraint(IndexOfConstraint, curel, k, myTtheta->Value(jt + k) * V1, 0.);
|
||||
}
|
||||
IndexOfConstraint += Ng2d;
|
||||
jt += 2;
|
||||
}
|
||||
|
||||
NTang3d += 2;
|
||||
NTang2d += 1;
|
||||
} */
|
||||
if(TypOfConstr == 1) {
|
||||
|
||||
NPass++;
|
||||
n0 = NPass;
|
||||
j = 2 * NbDim * (i - 1);
|
||||
curdim = 0;
|
||||
for(pnt = 1; pnt <= myNbP3d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 3; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
n0 += Ng3d;
|
||||
j += 6;
|
||||
}
|
||||
|
||||
n0 = NPass + NBeg2d;
|
||||
for(pnt = 1; pnt <= myNbP2d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 2; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
n0 += Ng2d;
|
||||
j += 4;
|
||||
}
|
||||
}
|
||||
if(TypOfConstr == 2) {
|
||||
|
||||
NPass++;
|
||||
n0 = NPass;
|
||||
j = 2 * NbDim * (i - 1);
|
||||
curdim = 0;
|
||||
for(pnt = 1; pnt <= myNbP3d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 3; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
n0 += Ng3d;
|
||||
j += 6;
|
||||
}
|
||||
|
||||
n0 = NPass + NBeg2d;
|
||||
for(pnt = 1; pnt <= myNbP2d; pnt++) {
|
||||
IndexOfConstraint = n0;
|
||||
for(k = 1; k <= 2; k++) {
|
||||
curdim++;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, V1, CBLONG * myTabConstraints->Value(j + k));
|
||||
IndexOfConstraint += NgPC1;
|
||||
}
|
||||
n0 += Ng2d;
|
||||
j += 4;
|
||||
}
|
||||
|
||||
j = 2 * NbDim * (i - 1) + 3;
|
||||
jt = Ntheta * (i - 1);
|
||||
IndexOfConstraint = NTang3d + 1;
|
||||
curdim = 0;
|
||||
for(pnt = 1; pnt <= myNbP3d; pnt++) {
|
||||
R1 = 0.; R2 = 0.;
|
||||
for(k = 1; k <= 3; k++) {
|
||||
R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
|
||||
R2 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + 3 + k);
|
||||
}
|
||||
R1 *= CBLONG * CBLONG;
|
||||
R2 *= CBLONG * CBLONG;
|
||||
for(k = 1; k <= 3; k++) {
|
||||
curdim++;
|
||||
if(k > 1) R1 = R2 = 0.;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
|
||||
A.AddConstraint(IndexOfConstraint + 1, curel, curdim, myTfthet->Value(jt + 3 + k) * V2, R2);
|
||||
}
|
||||
IndexOfConstraint += Ng3d;
|
||||
j += 6;
|
||||
jt += 6;
|
||||
}
|
||||
|
||||
j--;
|
||||
IndexOfConstraint = NBeg2d + NTang2d + 1;
|
||||
for(pnt = 1; pnt <= myNbP2d; pnt++) {
|
||||
R1 = 0.;
|
||||
for(k = 1; k <= 2; k++) {
|
||||
R1 += myTabConstraints->Value(j + k) * myTtheta->Value(jt + k);
|
||||
}
|
||||
R1 *= CBLONG * CBLONG;
|
||||
for(k = 1; k <= 2; k++) {
|
||||
curdim++;
|
||||
if(k > 1) R1 = 0.;
|
||||
A.AddConstraint(IndexOfConstraint, curel, curdim, myTfthet->Value(jt + k) * V2, R1);
|
||||
}
|
||||
IndexOfConstraint += Ng2d;
|
||||
j += 4;
|
||||
jt += 2;
|
||||
}
|
||||
|
||||
NTang3d += 2;
|
||||
NTang2d += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
99
src/AppParCurves/AppParCurves_Variational_9.gxx
Executable file
99
src/AppParCurves/AppParCurves_Variational_9.gxx
Executable file
@@ -0,0 +1,99 @@
|
||||
// File: AppParCurves_Variational_9.gxx
|
||||
// Created: Fri Feb 19 11:09:11 1999
|
||||
// Author: Sergey KHROMOV
|
||||
// <skv@pronox.nnov.matra-dtv.fr>
|
||||
|
||||
static Standard_Boolean NotParallel(gp_Vec& T, gp_Vec& V)
|
||||
{
|
||||
V = T;
|
||||
V.SetX(V.X() + 1.);
|
||||
if (V.CrossMagnitude(T) > 1.e-12)
|
||||
return Standard_True;
|
||||
V.SetY(V.Y() + 1.);
|
||||
if (V.CrossMagnitude(T) > 1.e-12)
|
||||
return Standard_True;
|
||||
V.SetZ(V.Z() + 1.);
|
||||
if (V.CrossMagnitude(T) > 1.e-12)
|
||||
return Standard_True;
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean AppParCurves_Variational::InitTthetaF(const Standard_Integer ndimen,
|
||||
const AppParCurves_Constraint typcon,
|
||||
const Standard_Integer begin,
|
||||
const Standard_Integer jndex)
|
||||
{
|
||||
if ((ndimen < 2)||(ndimen >3))
|
||||
return Standard_False;
|
||||
gp_Vec T, V;
|
||||
gp_Vec theta1, theta2;
|
||||
gp_Vec F;
|
||||
Standard_Real XX, XY, YY, XZ, YZ, ZZ;
|
||||
|
||||
if ((typcon == AppParCurves_TangencyPoint)||(typcon == AppParCurves_CurvaturePoint))
|
||||
{
|
||||
T.SetX(myTabConstraints->Value(jndex));
|
||||
T.SetY(myTabConstraints->Value(jndex + 1));
|
||||
if (ndimen == 3)
|
||||
T.SetZ(myTabConstraints->Value(jndex + 2));
|
||||
else
|
||||
T.SetZ(0.);
|
||||
if (ndimen == 2)
|
||||
{
|
||||
V.SetX(0.);
|
||||
V.SetY(0.);
|
||||
V.SetZ(1.);
|
||||
}
|
||||
if (ndimen == 3)
|
||||
if (!NotParallel(T, V))
|
||||
return Standard_False;
|
||||
theta1 = V ^ T;
|
||||
theta1.Normalize();
|
||||
myTtheta->SetValue(begin, theta1.X());
|
||||
myTtheta->SetValue(begin + 1, theta1.Y());
|
||||
if (ndimen == 3)
|
||||
{
|
||||
theta2 = T ^ theta1;
|
||||
theta2.Normalize();
|
||||
myTtheta->SetValue(begin + 2, theta1.Z());
|
||||
myTtheta->SetValue(begin + 3, theta2.X());
|
||||
myTtheta->SetValue(begin + 4, theta2.Y());
|
||||
myTtheta->SetValue(begin + 5, theta2.Z());
|
||||
}
|
||||
|
||||
// Calculation of myTfthet
|
||||
if (typcon == AppParCurves_CurvaturePoint)
|
||||
{
|
||||
XX = Pow(T.X(), 2);
|
||||
XY = T.X() * T.Y();
|
||||
YY = Pow(T.Y(), 2);
|
||||
if (ndimen == 2)
|
||||
{
|
||||
F.SetX(YY * theta1.X() - XY * theta1.Y());
|
||||
F.SetY(XX * theta1.Y() - XY * theta1.X());
|
||||
myTfthet->SetValue(begin, F.X());
|
||||
myTfthet->SetValue(begin + 1, F.Y());
|
||||
}
|
||||
if (ndimen == 3)
|
||||
{
|
||||
XZ = T.X() * T.Z();
|
||||
YZ = T.Y() * T.Z();
|
||||
ZZ = Pow(T.Z(), 2);
|
||||
|
||||
F.SetX((ZZ + YY) * theta1.X() - XY * theta1.Y() - XZ * theta1.Z());
|
||||
F.SetY((XX + ZZ) * theta1.Y() - XY * theta1.X() - YZ * theta1.Z());
|
||||
F.SetZ((XX + YY) * theta1.Z() - XZ * theta1.X() - YZ * theta1.Y());
|
||||
myTfthet->SetValue(begin, F.X());
|
||||
myTfthet->SetValue(begin + 1, F.Y());
|
||||
myTfthet->SetValue(begin + 2, F.Z());
|
||||
F.SetX((ZZ + YY) * theta2.X() - XY * theta2.Y() - XZ * theta2.Z());
|
||||
F.SetY((XX + ZZ) * theta2.Y() - XY * theta2.X() - YZ * theta2.Z());
|
||||
F.SetZ((XX + YY) * theta2.Z() - XZ * theta2.X() - YZ * theta2.Y());
|
||||
myTfthet->SetValue(begin + 3, F.X());
|
||||
myTfthet->SetValue(begin + 4, F.Y());
|
||||
myTfthet->SetValue(begin + 5, F.Z());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
9
src/AppParCurves/FILES
Executable file
9
src/AppParCurves/FILES
Executable file
@@ -0,0 +1,9 @@
|
||||
AppParCurves_Variational_1.gxx
|
||||
AppParCurves_Variational_2.gxx
|
||||
AppParCurves_Variational_3.gxx
|
||||
AppParCurves_Variational_4.gxx
|
||||
AppParCurves_Variational_5.gxx
|
||||
AppParCurves_Variational_6.gxx
|
||||
AppParCurves_Variational_7.gxx
|
||||
AppParCurves_Variational_8.gxx
|
||||
AppParCurves_Variational_9.gxx
|
Reference in New Issue
Block a user