1
0
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:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

160
src/AppParCurves/AppParCurves.cdl Executable file
View 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
View 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;
}
}

View 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;

View 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();
}

View 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;

View 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;
}

View 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);
}

View 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;

View 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;
}

View 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;

View 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;
}

View 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;

View 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;
}

View 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);
}

View 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;

File diff suppressed because it is too large Load Diff

View 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;

View 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;
}

View 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;

View File

@@ -0,0 +1 @@

View 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;

View 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;
}
}
}
*/
}

View 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;

View 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;
}
}
}
*/
}

View 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;

View 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;
}
*/
}

View 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;
}
}

View 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;

View 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;
}

View 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;

View 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;
}

View 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;

View 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>

View 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;

File diff suppressed because it is too large Load Diff

View 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;
}

View 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);
}
}
}

View 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]
}

View 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.;
}

View 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;
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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
View 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