1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

0023620: Follow up of 0022939 - make Bezier curve/surface evaluation thread-safe

1. Remove cache from Geom_BezierCurve, Geom2d_BezierCurve and Geom_BezierSurface
2. Add cache for Bezier curves into GeomAdaptor_Curve, Geom2dAdaptor_Curve and GeomAdaptor_Surface
3. Update comments in corresponding cache classes
4. Avoid frequent down-casting to B-splines in adaptors
This commit is contained in:
azv
2015-11-02 09:33:04 +03:00
committed by bugmaster
parent 525ec87c53
commit c8b5b3d89e
11 changed files with 555 additions and 883 deletions

View File

@@ -27,7 +27,6 @@
#define No_Standard_DimensionError
#include <BSplCLib.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_Geometry.hxx>
#include <gp.hxx>
@@ -64,8 +63,7 @@ static Standard_Boolean Rational(const TColStd_Array1OfReal& W)
//purpose :
//=======================================================================
Geom_BezierCurve::Geom_BezierCurve(const TColgp_Array1OfPnt& Poles):
validcache(0), parametercache(0.), spanlenghtcache(1.)
Geom_BezierCurve::Geom_BezierCurve(const TColgp_Array1OfPnt& Poles)
{
Standard_Integer nbpoles = Poles.Length();
if(nbpoles < 2 || nbpoles > (Geom_BezierCurve::MaxDegree() + 1))
@@ -87,8 +85,7 @@ validcache(0), parametercache(0.), spanlenghtcache(1.)
//=======================================================================
Geom_BezierCurve::Geom_BezierCurve(const TColgp_Array1OfPnt& Poles,
const TColStd_Array1OfReal& Weights):
validcache(0), parametercache(0.), spanlenghtcache(1.)
const TColStd_Array1OfReal& Weights)
{
// copy the poles
Standard_Integer nbpoles = Poles.Length();
@@ -360,8 +357,6 @@ void Geom_BezierCurve::Reverse ()
cweights(nbpoles-i+1) = w;
}
}
UpdateCoefficients();
}
//=======================================================================
@@ -383,21 +378,21 @@ void Geom_BezierCurve::Segment(const Standard_Real U1, const Standard_Real U2)
{
closed = (Abs(Value(U1).Distance (Value(U2))) <= Precision::Confusion());
if(!CoefficientsOK(0.)) UpdateCoefficients(0.);
TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()), 1, 2 * (Degree() + 1));
TColgp_HArray1OfPnt coeffs(1, poles->Size());
if (IsRational()) {
PLib::Trimming(U1,U2,coeffs->ChangeArray1(),
&wcoeffs->ChangeArray1());
PLib::CoefficientsPoles(coeffs->Array1(),
&wcoeffs->Array1(),
poles->ChangeArray1(),
&weights->ChangeArray1());
TColStd_Array1OfReal wcoeffs(1, poles->Size());
BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
poles->Array1(), &weights->Array1(), coeffs, &wcoeffs);
PLib::Trimming(U1, U2, coeffs, &wcoeffs);
PLib::CoefficientsPoles(coeffs, &wcoeffs, poles->ChangeArray1(), &weights->ChangeArray1());
}
else {
PLib::Trimming(U1,U2,coeffs->ChangeArray1(), PLib::NoWeights());
PLib::CoefficientsPoles(coeffs->Array1(), PLib::NoWeights(),
poles->ChangeArray1(), PLib::NoWeights());
BSplCLib::BuildCache(0.0, 1.0, 0, Degree(), bidflatknots,
poles->Array1(), BSplCLib::NoWeights(), coeffs, BSplCLib::NoWeights());
PLib::Trimming(U1, U2, coeffs, PLib::NoWeights());
PLib::CoefficientsPoles(coeffs, PLib::NoWeights(), poles->ChangeArray1(), PLib::NoWeights());
}
UpdateCoefficients();
}
//=======================================================================
@@ -417,7 +412,6 @@ void Geom_BezierCurve::SetPole (const Standard_Integer Index,
if (Index == 1 || Index == cpoles.Length()) {
closed = (cpoles(1).Distance(cpoles(NbPoles())) <= Precision::Confusion());
}
UpdateCoefficients();
}
//=======================================================================
@@ -456,7 +450,6 @@ void Geom_BezierCurve::SetWeight(const Standard_Integer Index,
// set weights of 1.
weights = new TColStd_HArray1OfReal(1,nbpoles);
wcoeffs = new TColStd_HArray1OfReal(1,nbpoles);
weights->Init(1.);
}
@@ -464,13 +457,8 @@ void Geom_BezierCurve::SetWeight(const Standard_Integer Index,
cweights(Index) = Weight;
// is it turning into non rational
if (wasrat) {
if (!Rational(cweights)) {
weights.Nullify();
wcoeffs.Nullify();
}
}
UpdateCoefficients();
if (wasrat && !Rational(cweights))
weights.Nullify();
}
//=======================================================================
@@ -540,18 +528,7 @@ Standard_Integer Geom_BezierCurve::Degree () const
void Geom_BezierCurve::D0 (const Standard_Real U, gp_Pnt& P ) const
{
// Idee lumineuse sacrifiee sur l autel des performances.
//
// if(!CoefficientsOK(U))
// ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
if (IsRational())
BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
&wcoeffs->Array1(),
P);
else
BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(), BSplCLib::NoWeights(), P);
BSplCLib::D0(U, Poles(), Weights(), P);
}
//=======================================================================
@@ -561,20 +538,7 @@ void Geom_BezierCurve::D0 (const Standard_Real U, gp_Pnt& P ) const
void Geom_BezierCurve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V1) const
{
// Idee lumineuse sacrifiee sur l autel des performances.
//
// if(!CoefficientsOK(U))
// ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
if (IsRational())
BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
&wcoeffs->Array1(),
P,V1);
else
BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
BSplCLib::NoWeights(),
P,V1);
BSplCLib::D1(U, Poles(), Weights(), P, V1);
}
//=======================================================================
@@ -587,20 +551,7 @@ void Geom_BezierCurve::D2 (const Standard_Real U,
gp_Vec& V1,
gp_Vec& V2) const
{
// Idee lumineuse sacrifiee sur l autel des performances.
//
// if(!CoefficientsOK(U))
// ((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
if (IsRational())
BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
&wcoeffs->Array1(),
P,V1,V2);
else
BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
BSplCLib::NoWeights(),
P,V1,V2);
BSplCLib::D2(U, Poles(), Weights(), P, V1, V2);
}
//=======================================================================
@@ -614,18 +565,7 @@ void Geom_BezierCurve::D3 (const Standard_Real U,
gp_Vec& V2,
gp_Vec& V3) const
{
if(!CoefficientsOK(U))
((Geom_BezierCurve*)(void*)this)->UpdateCoefficients(U);
if (IsRational())
BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
&wcoeffs->Array1(),
P,V1,V2,V3);
else
BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache,
coeffs->Array1(),
BSplCLib::NoWeights(),
P,V1,V2,V3);
BSplCLib::D3(U, Poles(), Weights(), P, V1, V2, V3);
}
//=======================================================================
@@ -792,8 +732,6 @@ void Geom_BezierCurve::Transform (const gp_Trsf& T)
for (Standard_Integer i = 1; i <= nbpoles; i++)
cpoles (i).Transform(T);
UpdateCoefficients();
}
//=======================================================================
@@ -865,58 +803,10 @@ void Geom_BezierCurve::Init
// set fields
poles = Poles;
coeffs = new TColgp_HArray1OfPnt (1,nbpoles);
if (rational) {
if (rational)
weights = Weights;
wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0);
}
else {
weights.Nullify();
wcoeffs.Nullify();
}
UpdateCoefficients();
}
//=======================================================================
//function : CoefficientsOK
//purpose :
//=======================================================================
Standard_Boolean Geom_BezierCurve::CoefficientsOK(const Standard_Real U)const
{
return (validcache && ((parametercache == 0. && U < 1.) ||
(parametercache == 1. && U >= 1.)));
}
//=======================================================================
//function : UpdateCoefficients
//purpose :
//=======================================================================
//void Geom_BezierCurve::UpdateCoefficients(const Standard_Real U)
void Geom_BezierCurve::UpdateCoefficients(const Standard_Real )
{
maxderivinvok = 0;
parametercache = 0.;
//
// Idee lumineuse sacrifiee sur l autel des performances.
// if (U >= 1.) parametercache = 1.;
TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()),
1, 2*(Degree()+1));
if (IsRational())
BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
bidflatknots,poles->Array1(),
&weights->Array1(),
coeffs->ChangeArray1(),
&wcoeffs->ChangeArray1());
else
BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(),
bidflatknots,poles->Array1(),
BSplCLib::NoWeights(),
coeffs->ChangeArray1(),
BSplCLib::NoWeights());
validcache = 1;
weights.Nullify();
}

View File

@@ -29,6 +29,8 @@
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GeomAbs_Shape.hxx>
#include <BSplCLib.hxx>
class Standard_ConstructionError;
class Standard_DimensionError;
class Standard_RangeError;
@@ -304,7 +306,15 @@ public:
//!
//! Raised if the length of W is not equal to the number of poles.
Standard_EXPORT void Weights (TColStd_Array1OfReal& W) const;
//! Returns all the weights of the curve.
const TColStd_Array1OfReal* Weights() const
{
if (!weights.IsNull())
return &weights->Array1();
return BSplCLib::NoWeights();
}
//! Applies the transformation T to this Bezier curve.
Standard_EXPORT void Transform (const gp_Trsf& T) Standard_OVERRIDE;
@@ -344,25 +354,12 @@ private:
//! Update rational and closed.
//!
//! if nbpoles < 2 or nbboles > MaDegree + 1
Standard_EXPORT void Init (const Handle(TColgp_HArray1OfPnt)& Poles, const Handle(TColStd_HArray1OfReal)& Weights);
//! returns true if the coefficients have been
//! computed with the right value of cacheparameter
//! for the given U value.
Standard_EXPORT Standard_Boolean CoefficientsOK (const Standard_Real U) const;
//! Recompute the coeficients.
Standard_EXPORT void UpdateCoefficients (const Standard_Real U = 0.0);
void Init (const Handle(TColgp_HArray1OfPnt)& Poles, const Handle(TColStd_HArray1OfReal)& Weights);
Standard_Boolean rational;
Standard_Boolean closed;
Handle(TColgp_HArray1OfPnt) poles;
Handle(TColStd_HArray1OfReal) weights;
Handle(TColgp_HArray1OfPnt) coeffs;
Handle(TColStd_HArray1OfReal) wcoeffs;
Standard_Integer validcache;
Standard_Real parametercache;
Standard_Real spanlenghtcache;
Standard_Real maxderivinv;
Standard_Boolean maxderivinvok;

View File

@@ -28,7 +28,6 @@
#include <BSplCLib.hxx>
#include <BSplSLib.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_Curve.hxx>
@@ -362,11 +361,6 @@ static void DeleteRatPoleRow
Geom_BezierSurface::Geom_BezierSurface
(const TColgp_Array2OfPnt& SurfacePoles):
ucacheparameter(0.),
vcacheparameter(0.),
ucachespanlenght(1.),
vcachespanlenght(1.),
validcache(0),
maxderivinvok(Standard_False)
{
Standard_Integer NbUPoles = SurfacePoles.ColLength();
@@ -397,11 +391,6 @@ Geom_BezierSurface::Geom_BezierSurface
Geom_BezierSurface::Geom_BezierSurface
(const TColgp_Array2OfPnt& SurfacePoles,
const TColStd_Array2OfReal& PoleWeights ):
ucacheparameter(0.),
vcacheparameter(0.),
ucachespanlenght(1.),
vcachespanlenght(1.),
validcache(0),
maxderivinvok(Standard_False)
{
Standard_Integer NbUPoles = SurfacePoles.ColLength();
@@ -472,20 +461,13 @@ Geom_BezierSurface::Geom_BezierSurface
Geom_BezierSurface::Geom_BezierSurface
(const Handle(TColgp_HArray2OfPnt)& SurfacePoles,
const Handle(TColgp_HArray2OfPnt)& SurfaceCoefs,
const Handle(TColStd_HArray2OfReal)& PoleWeights,
const Handle(TColStd_HArray2OfReal)& CoefWeights,
const Standard_Boolean IsURational,
const Standard_Boolean IsVRational)
:maxderivinvok(Standard_False)
{
urational = IsURational;
vrational = IsVRational;
ucachespanlenght = 1.;
vcachespanlenght = 1.;
validcache = 1;
ucacheparameter =0.;
vcacheparameter = 0.;
Standard_Integer NbUPoles = SurfacePoles->ColLength();
Standard_Integer NbVPoles = SurfacePoles->RowLength();
@@ -493,17 +475,9 @@ Geom_BezierSurface::Geom_BezierSurface
1,NbVPoles) ;
poles->ChangeArray2() = SurfacePoles->Array2();
coeffs = new TColgp_HArray2OfPnt (1,SurfaceCoefs->ColLength(),
1,SurfaceCoefs->RowLength()) ;
coeffs->ChangeArray2() = SurfaceCoefs->Array2();
if ( urational || vrational) {
weights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
weights->ChangeArray2() = PoleWeights->Array2();
wcoeffs = new TColStd_HArray2OfReal (1,SurfaceCoefs->ColLength(),
1,SurfaceCoefs->RowLength()) ;
wcoeffs->ChangeArray2() = CoefWeights->Array2();
}
}
@@ -554,10 +528,6 @@ void Geom_BezierSurface::ExchangeUV ()
Standard_Boolean temp = urational;
urational = vrational;
vrational = temp;
coeffs = new TColgp_HArray2OfPnt (LC, UC, LR, UR);
wcoeffs = new TColStd_HArray2OfReal (LC, UC, LR, UR);
UpdateCoefficients();
}
//=======================================================================
@@ -680,11 +650,6 @@ void Geom_BezierSurface::InsertPoleColAfter
}
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
UpdateCoefficients();
}
//=======================================================================
@@ -723,14 +688,8 @@ void Geom_BezierSurface::InsertPoleColAfter
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
Rational(weights->Array2(), urational, vrational);
UpdateCoefficients();
}
//=======================================================================
@@ -796,12 +755,6 @@ void Geom_BezierSurface::InsertPoleRowAfter (const Standard_Integer UIndex,
}
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
UpdateCoefficients();
}
//=======================================================================
@@ -840,14 +793,8 @@ void Geom_BezierSurface::InsertPoleRowAfter
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
Rational(weights->Array2(), urational, vrational);
UpdateCoefficients();
}
//=======================================================================
@@ -907,11 +854,6 @@ void Geom_BezierSurface::RemovePoleCol (const Standard_Integer VIndex)
}
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
UpdateCoefficients();
}
//=======================================================================
@@ -948,11 +890,6 @@ void Geom_BezierSurface::RemovePoleRow (const Standard_Integer UIndex)
}
poles = npoles;
weights = nweights;
coeffs = new TColgp_HArray2OfPnt(1,poles->ColLength(),
1,poles->RowLength());
wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
1,poles->RowLength());
UpdateCoefficients();
}
//=======================================================================
@@ -970,11 +907,46 @@ void Geom_BezierSurface::Segment
Handle(TColgp_HArray2OfPnt) Coefs;
Handle(TColStd_HArray2OfReal) WCoefs;
if (validcache == 0) UpdateCoefficients(0., 0.);
Standard_Integer aMinDegree = UDegree() <= VDegree() ? UDegree() : VDegree();
Standard_Integer aMaxDegree = UDegree() > VDegree() ? UDegree() : VDegree();
Coefs = new TColgp_HArray2OfPnt(1, aMaxDegree + 1, 1, aMinDegree + 1);
if (rat)
WCoefs = new TColStd_HArray2OfReal(1, aMaxDegree + 1, 1, aMinDegree + 1);
TColStd_Array1OfReal biduflatknots(BSplCLib::FlatBezierKnots(UDegree()), 1, 2 * (UDegree() + 1));
TColStd_Array1OfReal bidvflatknots(BSplCLib::FlatBezierKnots(VDegree()), 1, 2 * (VDegree() + 1));
Standard_Real uparameter_11 = 0.5;
Standard_Real uspanlenght_11 = 0.5;
Standard_Real vparameter_11 = 0.5;
Standard_Real vspanlenght_11 = 0.5;
if (urational || vrational) {
BSplSLib::BuildCache(uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11, 0, 0,
UDegree(), VDegree(), 0, 0,
biduflatknots, bidvflatknots,
poles->Array2(),
&weights->Array2(),
Coefs->ChangeArray2(),
&WCoefs->ChangeArray2());
}
else {
BSplSLib::BuildCache(uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11, 0, 0,
UDegree(), VDegree(), 0, 0,
biduflatknots, bidvflatknots,
poles->Array2(),
BSplSLib::NoWeights(),
Coefs->ChangeArray2(),
BSplSLib::NoWeights());
}
// Attention si udeg <= vdeg u et v sont intervertis
// dans les coeffs, il faut donc tout transposer.
if(UDegree() <= VDegree()) {
Handle(TColgp_HArray2OfPnt) coeffs = Coefs;
Handle(TColStd_HArray2OfReal) wcoeffs = WCoefs;
Standard_Integer ii, jj;
Coefs = new (TColgp_HArray2OfPnt)(1,UDegree()+1,1,VDegree()+1);
if (rat) {
@@ -986,10 +958,6 @@ void Geom_BezierSurface::Segment
if (rat) WCoefs->SetValue(ii, jj, wcoeffs->Value(jj,ii));
}
}
else {
Coefs = coeffs;
if (rat) {WCoefs = wcoeffs;}
}
// Trim dans la base cannonique et Update des Poles et Coeffs
@@ -1014,7 +982,6 @@ void Geom_BezierSurface::Segment
PLib::CoefficientsPoles (Coefs->Array2(), PLib::NoWeights2(),
poles->ChangeArray2(), PLib::NoWeights2());
}
UpdateCoefficients();
}
//=======================================================================
@@ -1034,7 +1001,6 @@ void Geom_BezierSurface::SetPole
VIndex > Poles.RowLength() ) Standard_OutOfRange::Raise();
Poles (UIndex, VIndex) = P;
UpdateCoefficients();
}
//=======================================================================
@@ -1111,8 +1077,6 @@ void Geom_BezierSurface::SetPoleCol (const Standard_Integer VIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (I, VIndex) = CPoles (I);
}
UpdateCoefficients();
}
//=======================================================================
@@ -1134,7 +1098,6 @@ void Geom_BezierSurface::SetPoleRow (const Standard_Integer UIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (UIndex, I) = CPoles (I);
}
UpdateCoefficients();
}
//=======================================================================
@@ -1181,16 +1144,12 @@ void Geom_BezierSurface::SetWeight (const Standard_Integer UIndex,
Standard_Boolean wasrat = (urational||vrational);
if (!wasrat) {
// a weight of 1. does not turn to rational
if (Abs(Weight - 1.) <= gp::Resolution()) {
UpdateCoefficients(); //Pour l'appel via SetPole
if (Abs(Weight - 1.) <= gp::Resolution())
return;
}
// set weights of 1.
weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength(), 1.);
wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength());
}
TColStd_Array2OfReal & Weights = weights->ChangeArray2();
@@ -1208,14 +1167,8 @@ void Geom_BezierSurface::SetWeight (const Standard_Integer UIndex,
}
// is it turning into non rational
if (wasrat) {
if (!(urational || vrational)) {
weights.Nullify();
wcoeffs.Nullify();
}
}
UpdateCoefficients(); //Dans tous cas :Attention a SetPoleCol !
if (wasrat && !(urational || vrational))
weights.Nullify();
}
//=======================================================================
@@ -1234,8 +1187,6 @@ void Geom_BezierSurface::SetWeightCol
// set weights of 1.
weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength(), 1.);
wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength());
}
TColStd_Array2OfReal & Weights = weights->ChangeArray2();
@@ -1257,14 +1208,8 @@ void Geom_BezierSurface::SetWeightCol
Rational(Weights, urational, vrational);
// is it turning into non rational
if (wasrat) {
if (!(urational || vrational)) {
weights.Nullify();
wcoeffs.Nullify();
}
}
UpdateCoefficients();
if (wasrat && !(urational || vrational))
weights.Nullify();
}
//=======================================================================
@@ -1283,8 +1228,6 @@ void Geom_BezierSurface::SetWeightRow
// set weights of 1.
weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength(), 1.);
wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
1, poles->RowLength());
}
TColStd_Array2OfReal & Weights = weights->ChangeArray2();
@@ -1309,14 +1252,8 @@ void Geom_BezierSurface::SetWeightRow
Rational(Weights, urational, vrational);
// is it turning into non rational
if (wasrat) {
if (!(urational || vrational)) {
weights.Nullify();
wcoeffs.Nullify();
}
}
UpdateCoefficients();
if (wasrat && !(urational || vrational))
weights.Nullify();
}
//=======================================================================
@@ -1352,7 +1289,6 @@ void Geom_BezierSurface::UReverse ()
}
}
}
UpdateCoefficients();
}
//=======================================================================
@@ -1399,7 +1335,6 @@ void Geom_BezierSurface::VReverse ()
}
}
}
UpdateCoefficients();
}
//=======================================================================
@@ -1448,60 +1383,30 @@ void Geom_BezierSurface::D0 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P ) const
{
if (validcache == 1) {
//
// XAB : cet algorithme devient instable pour les hauts degres
// RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
// sur [-1,1].
//
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (urational || vrational) {
BSplSLib::CacheD0(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
&wcoeffs->Array2(),
P);
}
else {
BSplSLib::CacheD0(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
BSplSLib::NoWeights(),
P);
}
Standard_Real array_u[2];
Standard_Real array_v[2];
Standard_Integer mult_u[2];
Standard_Integer mult_v[2];
TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
BSplSLib::D0(U, V, 1, 1, poles->Array2(),
&weights->Array2(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P);
}
else {
Standard_Real array_u[2] ;
Standard_Real array_v[2] ;
Standard_Integer mult_u[2] ;
Standard_Integer mult_v[2] ;
TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
BSplSLib::D0(U, V, 1,1,poles->Array2(),
&weights->Array2(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P) ;
}
else {
BSplSLib::D0(U, V, 1,1,poles->Array2(),
BSplSLib::NoWeights(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P) ;
}
BSplSLib::D0(U, V, 1, 1, poles->Array2(),
BSplSLib::NoWeights(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P);
}
}
@@ -1517,59 +1422,29 @@ void Geom_BezierSurface::D1
gp_Vec& D1U,
gp_Vec& D1V ) const
{
if (validcache == 1) {
//
// XAB : cet algorithme devient instable pour les hauts degres
// RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
// sur [-1,1].
//
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (urational || vrational) {
BSplSLib::CacheD1(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
&wcoeffs->Array2(),
P, D1U, D1V);
}
else {
BSplSLib::CacheD1(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
BSplSLib::NoWeights(),
P, D1U, D1V);
}
Standard_Real array_u[2];
Standard_Real array_v[2];
Standard_Integer mult_u[2];
Standard_Integer mult_v[2];
TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
BSplSLib::D1(U, V, 1, 1, poles->Array2(),
&weights->Array2(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P, D1U, D1V);
}
else {
Standard_Real array_u[2] ;
Standard_Real array_v[2] ;
Standard_Integer mult_u[2] ;
Standard_Integer mult_v[2] ;
TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
BSplSLib::D1(U, V, 1,1,poles->Array2(),
&weights->Array2(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P,D1U, D1V) ;
}
else {
BSplSLib::D1(U, V, 1,1,poles->Array2(),
BSplSLib::NoWeights(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P,D1U, D1V) ;
}
BSplSLib::D1(U, V, 1, 1, poles->Array2(),
BSplSLib::NoWeights(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P, D1U, D1V);
}
}
@@ -1585,63 +1460,31 @@ void Geom_BezierSurface::D2
gp_Vec& D1U, gp_Vec& D1V,
gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV ) const
{
if (validcache == 1) {
//
// XAB : cet algorithme devient instable pour les hauts degres
// RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
// sur [-1,1].
//
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (urational || vrational) {
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::CacheD2(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
&wcoeffs->Array2(),
P, D1U, D1V, D2U, D2UV , D2V);
}
else {
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::CacheD2(U, V, UDegree(), VDegree(),
uparameter_11, vparameter_11,
uspanlenght_11, vspanlenght_11,
coeffs->Array2(),
BSplSLib::NoWeights(),
P, D1U, D1V, D2U, D2UV , D2V);
}
Standard_Real array_u[2];
Standard_Real array_v[2];
Standard_Integer mult_u[2];
Standard_Integer mult_v[2];
TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::D2(U, V, 1, 1, poles->Array2(),
&weights->Array2(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P, D1U, D1V, D2U, D2V, D2UV);
}
else {
Standard_Real array_u[2] ;
Standard_Real array_v[2] ;
Standard_Integer mult_u[2] ;
Standard_Integer mult_v[2] ;
TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
if (urational || vrational) {
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::D2(U, V, 1,1,poles->Array2(),
&weights->Array2(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P,D1U, D1V, D2U, D2V , D2UV) ;
}
else {
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::D2(U, V, 1,1,poles->Array2(),
BSplSLib::NoWeights(),
biduknots,bidvknots,&bidumults,&bidvmults,
UDegree(),VDegree(),
urational,vrational,Standard_False,Standard_False,
P,D1U, D1V, D2U, D2V, D2UV ) ;
}
//-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB
BSplSLib::D2(U, V, 1, 1, poles->Array2(),
BSplSLib::NoWeights(),
biduknots, bidvknots, &bidumults, &bidvmults,
UDegree(), VDegree(),
urational, vrational, Standard_False, Standard_False,
P, D1U, D1V, D2U, D2V, D2UV);
}
}
@@ -1946,7 +1789,6 @@ void Geom_BezierSurface::Transform (const gp_Trsf& T)
Poles (I, J).Transform (T);
}
}
UpdateCoefficients();
}
//=======================================================================
@@ -2072,7 +1914,7 @@ void Geom_BezierSurface::Resolution(const Standard_Real Tolerance3D,
Handle(Geom_Geometry) Geom_BezierSurface::Copy() const
{
Handle(Geom_BezierSurface) S = new Geom_BezierSurface
(poles, coeffs, weights, wcoeffs, urational, vrational);
(poles, weights, urational, vrational);
return S;
}
@@ -2085,70 +1927,11 @@ void Geom_BezierSurface::Init
(const Handle(TColgp_HArray2OfPnt)& Poles,
const Handle(TColStd_HArray2OfReal)& Weights)
{
Standard_Integer NbUPoles = Poles->ColLength();
Standard_Integer NbVPoles = Poles->RowLength();
Standard_Integer maxcls = Max(NbUPoles, NbVPoles);
Standard_Integer mincls = Min(NbUPoles, NbVPoles);
// set fields
poles = Poles;
coeffs = new TColgp_HArray2OfPnt (1,maxcls,1,mincls);
if (urational || vrational) {
poles = Poles;
if (urational || vrational)
weights = Weights;
wcoeffs = new TColStd_HArray2OfReal (1,maxcls,1,mincls);
}
else {
else
weights.Nullify();
wcoeffs.Nullify();
}
UpdateCoefficients();
}
//=======================================================================
//function : UpdateCoefficients
//purpose :
//=======================================================================
void Geom_BezierSurface::UpdateCoefficients(const Standard_Real ,
const Standard_Real )
{
maxderivinvok = Standard_False;
ucacheparameter = 0.;
TColStd_Array1OfReal biduflatknots(BSplCLib::FlatBezierKnots(UDegree()),
1, 2*(UDegree()+1));
vcacheparameter = 0.;
TColStd_Array1OfReal bidvflatknots(BSplCLib::FlatBezierKnots(VDegree()),
1, 2*(VDegree()+1));
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if ( urational || vrational ) {
BSplSLib::BuildCache(uparameter_11,vparameter_11,
uspanlenght_11,vspanlenght_11,0,0,
UDegree(),VDegree(),0,0,
biduflatknots,bidvflatknots,
poles->Array2(),
&weights->Array2(),
coeffs->ChangeArray2(),
&wcoeffs->ChangeArray2());
}
else {
BSplSLib::BuildCache(uparameter_11,vparameter_11,
uspanlenght_11,vspanlenght_11,0,0,
UDegree(),VDegree(),0,0,
biduflatknots,bidvflatknots,
poles->Array2(),
BSplSLib::NoWeights(),
coeffs->ChangeArray2(),
BSplSLib::NoWeights());
}
validcache = 1;
}

View File

@@ -31,6 +31,8 @@
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GeomAbs_Shape.hxx>
#include <BSplSLib.hxx>
class Standard_ConstructionError;
class Standard_DimensionError;
class Standard_RangeError;
@@ -471,7 +473,12 @@ public:
//! Raised if the length of P in the U an V direction is not equal to
//! NbUPoles and NbVPoles.
Standard_EXPORT void Poles (TColgp_Array2OfPnt& P) const;
//! Returns the poles of the Bezier surface.
const TColgp_Array2OfPnt& Poles() const
{
return poles->Array2();
}
//! Returns the degree of the surface in the U direction it is
//! NbUPoles - 1
@@ -504,6 +511,13 @@ public:
//! equal to NbUPoles and NbVPoles.
Standard_EXPORT void Weights (TColStd_Array2OfReal& W) const;
//! Returns the weights of the Bezier surface.
const TColStd_Array2OfReal* Weights() const
{
if (!weights.IsNull())
return &weights->Array2();
return BSplSLib::NoWeights();
}
//! Returns True if the first control points row and the
//! last control points row are identical. The tolerance
@@ -582,7 +596,7 @@ protected:
private:
Standard_EXPORT Geom_BezierSurface(const Handle(TColgp_HArray2OfPnt)& SurfacePoles, const Handle(TColgp_HArray2OfPnt)& SurfaceCoefficients, const Handle(TColStd_HArray2OfReal)& PoleWeights, const Handle(TColStd_HArray2OfReal)& CoefficientWeights, const Standard_Boolean IsURational, const Standard_Boolean IsVRational);
Geom_BezierSurface(const Handle(TColgp_HArray2OfPnt)& SurfacePoles, const Handle(TColStd_HArray2OfReal)& PoleWeights, const Standard_Boolean IsURational, const Standard_Boolean IsVRational);
//! Set poles to Poles, weights to Weights (not
//! copied).
@@ -591,22 +605,13 @@ private:
//! coefficient 1.
//!
//! if nbpoles < 2 or nbpoles > MaDegree
Standard_EXPORT void Init (const Handle(TColgp_HArray2OfPnt)& Poles, const Handle(TColStd_HArray2OfReal)& Weights);
void Init (const Handle(TColgp_HArray2OfPnt)& Poles, const Handle(TColStd_HArray2OfReal)& Weights);
//! Recompute the coeficients.
Standard_EXPORT void UpdateCoefficients (const Standard_Real U = 0.0, const Standard_Real V = 0.0);
Standard_Boolean urational;
Standard_Boolean vrational;
Handle(TColgp_HArray2OfPnt) poles;
Handle(TColStd_HArray2OfReal) weights;
Handle(TColgp_HArray2OfPnt) coeffs;
Handle(TColStd_HArray2OfReal) wcoeffs;
Standard_Real ucacheparameter;
Standard_Real vcacheparameter;
Standard_Real ucachespanlenght;
Standard_Real vcachespanlenght;
Standard_Integer validcache;
Standard_Real umaxderivinv;
Standard_Real vmaxderivinv;
Standard_Boolean maxderivinvok;