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

0024682: Move out B-spline cache from curves and surfaces to dedicated classes BSplCLib_Cache and BSplSLib_Cache

1. B-spline cache was moved into separated classes: BSplCLib_Cache for 2D and 3D curves and BSplSLib_Cache for surfaces.

2. The cache is used now in corresponding adaptor classes (Geom2dAdaptor_Curve, GeomAdaptor_Curve and GeomAdaptor_Surface) when the curve or surface is a B-spline.

3. Algorithms were changed to use adaptors for B-spline calculations instead of curves or surfaces.

4. Precised calculation of derivatives of surface of revolution is implemented for the points of surface placed on the axis of revolution (Geom_SurfaceOfRevolution.cxx)

5. Small modifications are made to adjust algorithms to new behavior of B-spline calculation.

6. Test cases were modified according to the modern behavior.

7. Changes in BOPAlgo_WireSplitter, BOPTools_AlgoTools, BRepLib_CheckCurveOnSurface and ShapeAnalysis_Wire to use adaptors instead of geometric entities

8. Allow Geom2dAdaptor and GeomAdaptor in case of offset curve to use corresponding adaptor for basis curve

Modification of test-cases according to the new behavior.
This commit is contained in:
azv
2015-05-28 13:36:57 +03:00
committed by bugmaster
parent 9176540c64
commit 94f71cad33
137 changed files with 4104 additions and 2503 deletions

View File

@@ -120,8 +120,7 @@ uses Array1OfInteger from TColStd,
Vec from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom,
Shape from GeomAbs,
Mutex from Standard
Shape from GeomAbs
raises ConstructionError from Standard,
@@ -590,17 +589,6 @@ is
---Purpose :
-- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real.
IsCacheValid(me; Parameter : Real) returns Boolean
---Purpose :
-- Tells whether the Cache is valid for the
-- given parameter
-- Warnings : the parameter must be normalized within
-- the period if the curve is periodic. Otherwise
-- the answer will be false
--
is static private;
Continuity (me) returns Shape from GeomAbs;
---Purpose :
@@ -789,6 +777,15 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of K is not equal to the number of knots.
Knots (me)
returns Array1OfReal from TColStd
---Purpose : returns the knot values of the B-spline curve;
-- Warning
-- A knot with a multiplicity greater than 1 is not
-- repeated in the knot table. The Multiplicity function
-- can be used to obtain the multiplicity of each knot.
---C++ : return const &
is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
@@ -845,6 +842,12 @@ is
-- Standard_DimensionError if the array K is not of
-- the appropriate length.Returns the knots sequence.
raises DimensionError;
KnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : returns the knots of the B-spline curve.
-- Knots with multiplicit greater than 1 are repeated
---C++ : return const &
is static;
@@ -910,6 +913,11 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of M is not equal to NbKnots.
Multiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : returns the multiplicity of the knots of the curve.
---C++ : return const &
is static;
NbKnots (me) returns Integer;
@@ -933,6 +941,11 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of P is not equal to the number of poles.
Poles (me)
returns Array1OfPnt from TColgp
---Purpose : Returns the poles of the B-spline curve;
---C++ : return const &
is static;
StartPoint (me) returns Pnt;
@@ -954,6 +967,11 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of W is not equal to NbPoles.
Weights (me)
returns Array1OfReal from TColStd
---Purpose : Returns the weights of the B-spline curve;
---C++ : return const &
is static;
@@ -981,20 +999,10 @@ is
Copy (me) returns like me;
---Purpose: Creates a new object which is a copy of this BSpline curve.
InvalidateCache(me : mutable)
---Purpose : Invalidates the cache. This has to be private
-- this has to be private
is static private;
UpdateKnots(me : mutable)
---Purpose : Recompute the flatknots, the knotsdistribution, the continuity.
is static private;
ValidateCache(me : mutable ; Parameter : Real)
is static private;
---Purpose : updates the cache and validates it
IsEqual(me; theOther : BSplineCurve from Geom;
thePreci : Real from Standard ) returns Boolean;
@@ -1015,34 +1023,7 @@ fields
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
cachepoles : HArray1OfPnt from TColgp;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
cacheweights : HArray1OfReal from TColStd;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1] see below
validcache : Integer;
-- = 1 the cache is valid
-- = 0 the cache is invalid
parametercache : Real;
-- Parameter at which the Taylor expension is stored in
-- the cache
spanlenghtcache : Real;
-- Since the Taylor expansion is normalized in the
-- cache to evaluate the cache one has to use
-- (Parameter - parametercache) / nspanlenghtcache
spanindexcache : Integer;
-- the span for which the cache is valid if
-- validcache is 1
-- usefull to evaluate the parametric resolution
maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bspline-cache
end;

View File

@@ -125,12 +125,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
{
// check
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
// copy arrays
@@ -145,11 +144,6 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -174,11 +168,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
// check
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom_BSplineCurve");
@@ -197,11 +191,9 @@ Geom_BSplineCurve::Geom_BSplineCurve
poles = new TColgp_HArray1OfPnt(1,Poles.Length());
poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
knots = new TColStd_HArray1OfReal(1,Knots.Length());
@@ -211,9 +203,6 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@@ -598,7 +587,7 @@ void Geom_BSplineCurve::Segment(const Standard_Real U1,
BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
NewU2,periodic,FromU1,ToU2,index2,U);
if ( Abs(knots->Value(index2+1)-U) <= Eps)
if ( Abs(knots->Value(index2+1)-U) <= Eps || index2 == index1)
index2++;
Standard_Integer nbknots = index2 - index1 + 1;
@@ -974,7 +963,6 @@ void Geom_BSplineCurve::SetPole
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise();
poles->SetValue (Index, P);
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@@ -1023,7 +1011,6 @@ void Geom_BSplineCurve::SetWeight
rational = !weights.IsNull();
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@@ -1032,11 +1019,11 @@ void Geom_BSplineCurve::SetWeight
//=======================================================================
void Geom_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
const gp_Pnt& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
{
if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
@@ -1047,12 +1034,11 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0);
gp_Vec Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) {
poles->ChangeArray1() = npoles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1061,14 +1047,13 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
//purpose :
//=======================================================================
void Geom_BSplineCurve::
MovePointAndTangent(const Standard_Real U,
const gp_Pnt& P,
const gp_Vec& Tangent,
const Standard_Real Tolerance,
const Standard_Integer StartingCondition,
const Standard_Integer EndingCondition,
Standard_Integer& ErrorStatus)
void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U,
const gp_Pnt& P,
const gp_Vec& Tangent,
const Standard_Real Tolerance,
const Standard_Integer StartingCondition,
const Standard_Integer EndingCondition,
Standard_Integer& ErrorStatus)
{
Standard_Integer ii ;
if (IsPeriodic()) {
@@ -1086,26 +1071,24 @@ MovePointAndTangent(const Standard_Real U,
delta_derivative) ;
gp_Vec delta(P0, P);
for (ii = 1 ; ii <= 3 ; ii++) {
delta_derivative.SetCoord(ii,
Tangent.Coord(ii)- delta_derivative.Coord(ii)) ;
delta_derivative.SetCoord(ii, Tangent.Coord(ii)-delta_derivative.Coord(ii));
}
BSplCLib::MovePointAndTangent(U,
delta,
delta_derivative,
Tolerance,
deg,
rational,
StartingCondition,
EndingCondition,
poles->Array1(),
weights->Array1(),
flatknots->Array1(),
new_poles,
ErrorStatus) ;
delta,
delta_derivative,
Tolerance,
deg,
rational,
StartingCondition,
EndingCondition,
poles->Array1(),
weights->Array1(),
flatknots->Array1(),
new_poles,
ErrorStatus) ;
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@@ -1119,11 +1102,11 @@ void Geom_BSplineCurve::UpdateKnots()
rational = !weights.IsNull();
Standard_Integer MaxKnotMult = 0;
BSplCLib::KnotAnalysis (deg,
periodic,
knots->Array1(),
mults->Array1(),
knotSet, MaxKnotMult);
BSplCLib::KnotAnalysis(deg,
periodic,
knots->Array1(),
mults->Array1(),
knotSet, MaxKnotMult);
if (knotSet == GeomAbs_Uniform && !periodic) {
flatknots = knots;
@@ -1132,10 +1115,10 @@ void Geom_BSplineCurve::UpdateKnots()
flatknots = new TColStd_HArray1OfReal
(1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
BSplCLib::KnotSequence (knots->Array1(),
mults->Array1(),
deg,periodic,
flatknots->ChangeArray1());
BSplCLib::KnotSequence(knots->Array1(),
mults->Array1(),
deg,periodic,
flatknots->ChangeArray1());
}
if (MaxKnotMult == 0) smooth = GeomAbs_CN;
@@ -1148,36 +1131,6 @@ void Geom_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : Invalidate the Cache
//purpose : as the name says
//=======================================================================
void Geom_BSplineCurve::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : check if the Cache is valid
//purpose : as the name says
//=======================================================================
Standard_Boolean Geom_BSplineCurve::IsCacheValid
(const Standard_Real U) const
{
//Roman Lygin 26.12.08, performance improvements
//1. avoided using NewParameter = (U - parametercache) / spanlenghtcache
//to check against [0, 1), as division is CPU consuming
//2. minimized use of if, as branching is also CPU consuming
Standard_Real aDelta = U - parametercache;
return ( validcache &&
(aDelta >= 0.0e0) &&
((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) );
}
//=======================================================================
@@ -1200,83 +1153,3 @@ void Geom_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const
}
}
//=======================================================================
//function : Validate the Cache
//purpose : that is compute the cache so that it is valid
//=======================================================================
void Geom_BSplineCurve::ValidateCache(const Standard_Real Parameter)
{
Standard_Real NewParameter ;
Standard_Integer LocalIndex = 0 ;
//
// check if the degree did not change
//
if (cachepoles->Upper() < deg + 1)
cachepoles = new TColgp_HArray1OfPnt(1,deg + 1);
if (rational)
{
if (cacheweights.IsNull() || cacheweights->Upper() < deg + 1)
cacheweights = new TColStd_HArray1OfReal(1,deg + 1);
}
else if (!cacheweights.IsNull())
cacheweights.Nullify();
BSplCLib::LocateParameter(deg,
(flatknots->Array1()),
(BSplCLib::NoMults()),
Parameter,
periodic,
LocalIndex,
NewParameter);
spanindexcache = LocalIndex ;
if (Parameter == flatknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
parametercache = flatknots->Value(LocalIndex) ;
if (LocalIndex == flatknots->Upper() - deg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// spanindexcache to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ;
}
else {
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
}
else {
parametercache = flatknots->Value(LocalIndex) ;
spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ;
}
if (rational) {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
weights->Array1(),
cachepoles->ChangeArray1(),
cacheweights->ChangeArray1()) ;
}
else {
BSplCLib::BuildCache(parametercache,
spanlenghtcache,
periodic,
deg,
(flatknots->Array1()),
poles->Array1(),
*((TColStd_Array1OfReal*) NULL),
cachepoles->ChangeArray1(),
*((TColStd_Array1OfReal*) NULL)) ;
}
validcache = 1 ;
}

View File

@@ -30,7 +30,6 @@
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_Mutex.hxx>
#include <Precision.hxx>
#define POLES (poles->Array1())
@@ -181,33 +180,24 @@ Standard_Integer Geom_BSplineCurve::Degree () const
void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
{
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
cacheweights->Array1(),
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P);
}
else
else
{
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P);
}
}
@@ -221,36 +211,25 @@ void Geom_BSplineCurve::D1 (const Standard_Real U,
gp_Pnt& P,
gp_Vec& V1) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
{
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
cacheweights->Array1(),
P,
V1);
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1);
}
else
else
{
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
P,
V1);
knots->Array1(), mults->Array1(),
P, V1);
}
}
@@ -264,37 +243,25 @@ void Geom_BSplineCurve::D2(const Standard_Real U,
gp_Vec& V1,
gp_Vec& V2) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
{
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2);
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2);
}
else {
BSplCLib::CacheD2(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2);
else
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2);
}
}
@@ -309,41 +276,25 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
gp_Vec& V2,
gp_Vec& V3) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
Standard_Integer aSpanIndex = 0;
Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (rational)
{
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2,
V3) ;
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
}
else
else
{
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2,
V3) ;
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
}
}
@@ -352,19 +303,19 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
//purpose :
//=======================================================================
gp_Vec Geom_BSplineCurve::DN (const Standard_Real U,
const Standard_Integer N ) const
gp_Vec Geom_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N) const
{
gp_Vec V;
if (rational) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(),
FKNOTS,FMULTS,V);
weights->Array1(),
FKNOTS,FMULTS,V);
}
else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
}
return V;
}
@@ -437,6 +388,11 @@ void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
{
return knots->Array1();
}
//=======================================================================
//function : KnotSequence
//purpose :
@@ -449,6 +405,11 @@ void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//=======================================================================
//function : LastUKnotIndex
//purpose :
@@ -668,6 +629,11 @@ void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//=======================================================================
//function : NbKnots
//purpose :
@@ -708,6 +674,11 @@ void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const
P = poles->Array1();
}
const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
{
return poles->Array1();
}
//=======================================================================
//function : StartPoint
//purpose :
@@ -757,6 +728,13 @@ void Geom_BSplineCurve::Weights
}
}
const TColStd_Array1OfReal& Geom_BSplineCurve::Weights() const
{
if (IsRational())
return weights->Array1();
return BSplCLib::NoWeights();
}
//=======================================================================
//function : IsRational
//purpose :
@@ -778,7 +756,6 @@ void Geom_BSplineCurve::Transform
TColgp_Array1OfPnt & CPoles = poles->ChangeArray1();
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
InvalidateCache() ;
maxderivinvok = 0;
}

View File

@@ -147,8 +147,7 @@ uses Array1OfInteger from TColStd,
BSplKnotDistribution from GeomAbs,
Curve from Geom,
Geometry from Geom,
Shape from GeomAbs,
Mutex from Standard
Shape from GeomAbs
raises ConstructionError from Standard,
DimensionError from Standard,
@@ -919,16 +918,6 @@ is
-- |1.0, 2.0, 0.5|
-- if Weights = |1.0, 2.0, 0.5| returns False
-- |1.0, 2.0, 0.5|
IsCacheValid(me; UParameter, VParameter : Real) returns Boolean ;
---Purpose :
-- Tells whether the Cache is valid for the
-- given parameter
-- Warnings : the parameter must be normalized within
-- the period if the curve is periodic. Otherwise
-- the answer will be false
--
Bounds (me; U1, U2, V1, V2 : out Real);
---Purpose :
@@ -1017,6 +1006,11 @@ is
---Purpose :
-- Raised if the length of P in the U and V direction
-- is not equal to NbUpoles and NbVPoles.
Poles (me)
returns Array2OfPnt from TColgp
---Purpose : Returns the poles of the B-spline surface.
---C++ : return const &
is static;
UDegree (me) returns Integer;
@@ -1055,6 +1049,11 @@ is
---Purpose :
-- Raised if the length of Ku is not equal to the number of knots
-- in the U direction.
UKnots (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots in the U direction.
---C++ : return const &
is static;
UKnotSequence (me; Ku : out Array1OfReal from TColStd)
@@ -1066,6 +1065,15 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of Ku is not equal to NbUPoles + UDegree + 1
UKnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the uknots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
--- Example :
-- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
UMultiplicity (me; UIndex : Integer) returns Integer
@@ -1083,6 +1091,11 @@ is
---Purpose :
-- Raised if the length of Mu is not equal to the number of
-- knots in the U direction.
UMultiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : Returns the multiplicities of the knots in the U direction.
---C++ : return const &
is static;
VDegree (me) returns Integer;
@@ -1120,6 +1133,11 @@ is
---Purpose :
-- Raised if the length of Kv is not equal to the number of
-- knots in the V direction.
VKnots (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots in the V direction.
---C++ : return const &
is static;
VKnotSequence (me; Kv : out Array1OfReal from TColStd)
@@ -1131,6 +1149,15 @@ is
raises DimensionError;
---Purpose :
-- Raised if the length of Kv is not equal to NbVPoles + VDegree + 1
VKnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the vknots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
--- Example :
-- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
VMultiplicity (me; VIndex : Integer) returns Integer
@@ -1148,6 +1175,11 @@ is
---Purpose :
-- Raised if the length of Mv is not equal to the number of
-- knots in the V direction.
VMultiplicities (me)
returns Array1OfInteger from TColStd
---Purpose : Returns the multiplicities of the knots in the V direction.
---C++ : return const &
is static;
Weight (me; UIndex, VIndex : Integer) returns Real
@@ -1164,6 +1196,11 @@ is
---Purpose :
-- Raised if the length of W in the U and V direction is
-- not equal to NbUPoles and NbVPoles.
Weights (me)
returns Array2OfReal from TColStd
---Purpose : Returns the weights of the B-spline surface.
---C++ : return const &
is static;
@@ -1389,16 +1426,6 @@ is
is static private;
InvalidateCache(me : mutable)
---Purpose : Invalidates the cache. This has to be private this has to be private
is static private;
ValidateCache(me : mutable ; UParameter : Real;
VParameter : Real)
is static private;
---Purpose : updates the cache and validates it
fields
@@ -1420,68 +1447,8 @@ fields
vknots : HArray1OfReal from TColStd;
umults : HArray1OfInteger from TColStd;
vmults : HArray1OfInteger from TColStd;
-- Inplementation of the cache on surfaces
cachepoles : HArray2OfPnt from TColgp;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1]x[0 1]. The Taylor expension of lower degree
-- is stored as consecutive Pnt in the array that is
-- if udeg <= vdeg than the array stores the following
--
-- (2,0) (3,0)
-- (1,0) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- (2,1) (3,1)
-- (0,1) (1,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- Otherwise it is stored in the following fashion
--
--
-- (0,2) (0,3)
-- (0,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- (1,2) (1,3)
-- (1,0) (1,1) f (u0,v0) f (u0,v0)
-- f (u0,v0) f (u0,v0) ------------- -----------
-- 2 3!
--
-- The size of the array is (1,Max degree) (1, Min degree)
--
cacheweights : HArray2OfReal from TColStd;
-- Taylor expansion of the poles function, in homogeneous
-- form if the curve is rational. The taylor expansion
-- is normalized so that the span corresponds to
-- [0 1]x[0 1]. The Taylor expension of lower degree
-- is stored as consecutive Real in the array as explained above
ucacheparameter : Real ;
vcacheparameter : Real ;
-- Parameters at which the Taylor expension is stored in
-- the cache
ucachespanlenght : Real ;
vcachespanlenght : Real ;
-- Since the Taylor expansion is normalized in the
-- cache to evaluate the cache one has to use
-- (UParameter - uparametercache) / ucachespanlenght
-- (VParameter - vparametercache) / vcachespanlenght
ucachespanindex : Integer ;
vcachespanindex : Integer ;
-- the span for which the cache is valid if
-- validcache is 1
validcache : Integer ;
-- usefull to evaluate the parametric resolutions
umaxderivinv : Real from Standard;
vmaxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bsplinesurface-cache
umaxderivinv : Real from Standard;
vmaxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
end;

View File

@@ -165,8 +165,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
maxderivinvok(0)
{
Standard_Integer MinDegree,
MaxDegree ;
// check
@@ -196,19 +194,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1) ;
cacheweights.Nullify() ;
ucacheparameter = 0.0e0 ;
vcacheparameter = 0.0e0 ;
ucachespanlenght = 1.0e0 ;
vcachespanlenght = 1.0e0 ;
ucachespanindex = 0 ;
vcachespanindex = 0 ;
validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
@@ -238,8 +223,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vdeg(VDegree),
maxderivinvok(0)
{
Standard_Integer MinDegree,
MaxDegree ;
// check weights
if (Weights.ColLength() != Poles.ColLength())
@@ -289,21 +272,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1) ;
if (urational || vrational) {
cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1,
1,MinDegree + 1);
}
ucacheparameter = 0.0e0 ;
vcacheparameter = 0.0e0 ;
ucachespanlenght = 1.0e0 ;
vcachespanlenght = 1.0e0 ;
ucachespanindex = 0 ;
vcachespanindex = 0 ;
validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
@@ -1258,8 +1226,6 @@ void Geom_BSplineSurface::UpdateUKnots()
default : Usmooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
@@ -1298,18 +1264,8 @@ void Geom_BSplineSurface::UpdateVKnots()
default : Vsmooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : InvalidateCache
//purpose : Invalidates the Cache of the surface
//=======================================================================
void Geom_BSplineSurface::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : Normalizes the parameters if the curve is periodic
@@ -1362,177 +1318,6 @@ void Geom_BSplineSurface::PeriodicNormalization
}
}
//=======================================================================
//function : ValidateCache
//purpose : function that validates the cache of the surface
//=======================================================================
void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter,
const Standard_Real Vparameter)
{
Standard_Real NewParameter ;
Standard_Integer LocalIndex = 0 ;
Standard_Integer MinDegree,
MaxDegree ;
//
// check if the degree did not change
//
MinDegree = Min(udeg,vdeg) ;
MaxDegree = Max(udeg,vdeg) ;
if (cachepoles->ColLength() < MaxDegree + 1 ||
cachepoles->RowLength() < MinDegree + 1) {
cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1,MinDegree + 1);
}
//
// Verif + poussee pour les poids
//
if (urational || vrational) {
if (cacheweights.IsNull()) {
cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1,MinDegree + 1);
}
else {
if (cacheweights->ColLength() < MaxDegree + 1 ||
cacheweights->RowLength() < MinDegree + 1) {
cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1,MinDegree + 1);
}
}
}
else if (!cacheweights.IsNull())
cacheweights.Nullify();
BSplCLib::LocateParameter(udeg,
(ufknots->Array1()),
(BSplCLib::NoMults()),
Uparameter,
uperiodic,
LocalIndex,
NewParameter);
ucachespanindex = LocalIndex ;
if (Uparameter == ufknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
ucacheparameter = ufknots->Value(LocalIndex) ;
if (LocalIndex == ufknots->Upper() - udeg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// cachespanindex to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ;
}
else {
ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
}
}
else {
ucacheparameter = ufknots->Value(LocalIndex) ;
ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
}
LocalIndex = 0 ;
BSplCLib::LocateParameter(vdeg,
(vfknots->Array1()),
(BSplCLib::NoMults()),
Vparameter,
vperiodic,
LocalIndex,
NewParameter);
vcachespanindex = LocalIndex ;
if (Vparameter == vfknots->Value(LocalIndex + 1)) {
LocalIndex += 1 ;
vcacheparameter = vfknots->Value(LocalIndex) ;
if (LocalIndex == vfknots->Upper() - vdeg) {
//
// for the last span if the parameter is outside of
// the domain of the curve than use the last knot
// and normalize with the last span Still set the
// cachespanindex to flatknots->Upper() - deg so that
// the IsCacheValid will know for sure we are extending
// the Bspline
//
vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ;
}
else {
vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
}
}
else {
vcacheparameter = vfknots->Value(LocalIndex) ;
vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
}
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,
uperiodic,
vperiodic,
udeg,
vdeg,
ucachespanindex,
vcachespanindex,
(ufknots->Array1()),
(vfknots->Array1()),
poles->Array2(),
weights->Array2(),
cachepoles->ChangeArray2(),
cacheweights->ChangeArray2()) ;
}
else {
BSplSLib::BuildCache(uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
uperiodic,
vperiodic,
udeg,
vdeg,
ucachespanindex,
vcachespanindex,
(ufknots->Array1()),
(vfknots->Array1()),
poles->Array2(),
*((TColStd_Array2OfReal*) NULL),
cachepoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL)) ;
}
validcache = 1 ;
}
//=======================================================================
//function : IsCacheValid
//purpose : function that checks for the validity of the cache of the
// surface
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsCacheValid
(const Standard_Real U,
const Standard_Real V) const
{
//Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
Standard_Real aDeltaU = U - ucacheparameter;
Standard_Real aDeltaV = V - vcacheparameter;
return ( validcache &&
(aDeltaU >= 0.0e0) &&
((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) &&
(aDeltaV >= 0.0e0) &&
((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) );
}
//=======================================================================
//function : SetWeight
//purpose :
@@ -1550,7 +1335,6 @@ void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
}
Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
Rational(Weights, urational, vrational);
InvalidateCache();
}
//=======================================================================
@@ -1583,8 +1367,6 @@ void Geom_BSplineSurface::SetWeightCol
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
InvalidateCache();
}
//=======================================================================
@@ -1619,6 +1401,5 @@ void Geom_BSplineSurface::SetWeightRow
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
InvalidateCache();
}

View File

@@ -109,48 +109,15 @@ Standard_Boolean Geom_BSplineSurface::IsCNv
void Geom_BSplineSurface::D0(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P) const
gp_Pnt& P) const
{
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P) ;
}
else {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P) ;
}
BSplSLib::D0(aNewU,aNewV,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P);
}
//=======================================================================
@@ -160,56 +127,25 @@ void Geom_BSplineSurface::D0(const Standard_Real U,
void Geom_BSplineSurface::D1(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
Standard_Integer uindex = 0, vindex = 0;
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
if (cacheweights.IsNull()) {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V) ;
}
else {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V) ;
}
BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P, D1U, D1V);
}
//=======================================================================
@@ -218,64 +154,30 @@ void Geom_BSplineSurface::D1(const Standard_Real U,
//=======================================================================
void Geom_BSplineSurface::D2 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
{
Standard_Real new_u(U), new_v(V);
PeriodicNormalization(new_u, new_v);
Standard_Real aNewU = U;
Standard_Real aNewV = V;
PeriodicNormalization(aNewU, aNewV);
Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
Standard_Mutex::Sentry aSentry(MySurface->myMutex);
Standard_Integer uindex = 0, vindex = 0;
if(!IsCacheValid(new_u, new_v))
MySurface->ValidateCache(new_u, new_v);
BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
else {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
}
BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P, D1U, D1V, D2U, D2V, D2UV);
}
//=======================================================================
//function : D3
@@ -542,6 +444,11 @@ void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const
P = poles->Array2();
}
const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const
{
return poles->Array2();
}
//=======================================================================
//function : UIso
//purpose :
@@ -645,6 +552,11 @@ void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const
Ku = uknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const
{
return uknots->Array1();
}
//=======================================================================
//function : VKnots
//purpose :
@@ -656,6 +568,11 @@ void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const
Kv = vknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const
{
return vknots->Array1();
}
//=======================================================================
//function : UKnotSequence
//purpose :
@@ -667,6 +584,11 @@ void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const
Ku = ufknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const
{
return ufknots->Array1();
}
//=======================================================================
//function : VKnotSequence
//purpose :
@@ -678,6 +600,11 @@ void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const
Kv = vfknots->Array1();
}
const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const
{
return vfknots->Array1();
}
//=======================================================================
//function : UMultiplicity
//purpose :
@@ -701,6 +628,11 @@ void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const
Mu = umults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const
{
return umults->Array1();
}
//=======================================================================
//function : VIso
//purpose :
@@ -798,6 +730,11 @@ void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const
Mv = vmults->Array1();
}
const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const
{
return vmults->Array1();
}
//=======================================================================
//function : Weight
//purpose :
@@ -826,6 +763,13 @@ void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const
W = weights->Array2();
}
const TColStd_Array2OfReal& Geom_BSplineSurface::Weights() const
{
if (urational || vrational)
return weights->Array2();
return BSplSLib::NoWeights();
}
//=======================================================================
//function : Transform
//purpose :
@@ -839,8 +783,6 @@ void Geom_BSplineSurface::Transform (const gp_Trsf& T)
VPoles (i, j).Transform (T);
}
}
InvalidateCache();
}
//=======================================================================
@@ -1555,8 +1497,6 @@ void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
}
InvalidateCache();
}
//=======================================================================
@@ -1593,8 +1533,6 @@ void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex,
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
}
InvalidateCache();
}
//=======================================================================
@@ -1620,7 +1558,6 @@ void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
const gp_Pnt& P)
{
poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
InvalidateCache();
}
//=======================================================================
@@ -1676,7 +1613,6 @@ void Geom_BSplineSurface::MovePoint(const Standard_Real U,
poles->ChangeArray2() = npoles;
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================

View File

@@ -39,6 +39,7 @@
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
typedef Geom_OffsetCurve OffsetCurve;
typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve);
@@ -62,6 +63,13 @@ static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true if the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(
const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1,
gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative);
//=======================================================================
@@ -319,10 +327,8 @@ void Geom_OffsetCurve::D2 (const Standard_Real U, Pnt& P, Vec& V1, Vec& V2) cons
//purpose :
//=======================================================================
void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& P, Vec& theV1, Vec& V2, Vec& V3)
const {
void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec& theV2, Vec& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
@@ -336,137 +342,15 @@ const {
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, P, theV1, V2, V3);
Vec V4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec aV4 = basisCurve->DN (theU, 4);
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, aV4);
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex + 1);
V3 = -basisCurve->DN (theU, anIndex + 2);
V4 = -basisCurve->DN (theU, anIndex + 3);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex + 1);
V3 = basisCurve->DN (theU, anIndex + 2);
V4 = basisCurve->DN (theU, anIndex + 3);
}
}//if(V1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real R6 = R3 * R3;
Standard_Real R7 = R5 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
if (R7 <= gp::Resolution()) {
if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2));
D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 -
15.0*Dr*Dr*Dr/R6 - D3r));
D3Ndir.Multiply (offsetValue/R);
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec(D3Ndir));
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2)));
D2Ndir.Multiply (offsetValue / R);
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// V3 = P"' (U) :
D3Ndir.Divide (R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5))));
D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 -
15.0*Dr*Dr*Dr/R7 - D3r));
D3Ndir.Multiply (offsetValue);
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec(D3Ndir));
// V2 = P" (U) :
D2Ndir.Divide (R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3)));
D2Ndir.Multiply (offsetValue);
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec(DNdir));
}
//P (U) :
D0(theU,P);
CSLib_Offset::D3(theP, theV1, theV2, theV3, aV4, direction, offsetValue,
IsDirectionChange, theP, theV1, theV2, theV3);
}
@@ -508,68 +392,13 @@ Vec Geom_OffsetCurve::DN (const Standard_Real U, const Standard_Integer N) const
void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
gp_Pnt& thePbasis, gp_Vec& theV1basis)const
{
const Standard_Real aTol = gp::Resolution();
{
basisCurve->D1(theU, thePbasis, theV1basis);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, theV1basis);
basisCurve->D1 (theU, thePbasis, theV1basis);
Standard_Real Ndu = theV1basis.Magnitude();
if(Ndu <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
Ndu = V.Magnitude();
}
while((Ndu <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
gp_Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
theV1basis = -V;
else
theV1basis = V;
Ndu = theV1basis.Magnitude();
}//if(Ndu <= aTol)
XYZ Ndir = (theV1basis.XYZ()).Crossed (direction.XYZ());
Standard_Real R = Ndir.Modulus();
if (R <= gp::Resolution())
Geom_UndefinedValue::Raise("Exception: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Ndir.Multiply (offsetValue/R);
Ndir.Add (thePbasis.XYZ());
theP.SetXYZ(Ndir);
CSLib_Offset::D0(thePbasis, theV1basis, direction, offsetValue, IsDirectionChange, theP);
}
//=======================================================================
@@ -578,96 +407,21 @@ void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
//=======================================================================
void Geom_OffsetCurve::D1 ( const Standard_Real theU,
Pnt& P , Pnt& PBasis ,
Vec& theV1, Vec& V1basis, Vec& V2basis) const {
Pnt& theP , Pnt& thePBasis ,
Vec& theV1, Vec& theV1basis, Vec& theV2basis) const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
const Standard_Real aTol = gp::Resolution();
basisCurve->D2 (theU, thePBasis, theV1basis, theV2basis);
basisCurve->D2 (theU, PBasis, V1basis, V2basis);
theV1 = V1basis;
Vec V2 = V2basis;
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1basis, theV2basis);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = - basisCurve->DN (theU, anIndex+1);
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
}
V2basis = V2;
V1basis = theV1;
}//if(theV1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
if (R3 <= gp::Resolution()) {
//We try another computation but the stability is not very good.
if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue * Dr/R3));
theV1.Add (Vec(DNdir));
}
D0(theU,P);
CSLib_Offset::D1(thePBasis, theV1basis, theV2basis, direction, offsetValue, IsDirectionChange, theP, theV1);
}
@@ -676,11 +430,11 @@ void Geom_OffsetCurve::D1 ( const Standard_Real theU,
//purpose :
//=======================================================================
void Geom_OffsetCurve::D2 (const Standard_Real theU,
Pnt& P , Pnt& PBasis ,
Vec& theV1 , Vec& V2 ,
Vec& V1basis, Vec& V2basis, Vec& V3basis) const {
void Geom_OffsetCurve::D2 (const Standard_Real theU,
Pnt& theP, Pnt& thePBasis,
Vec& theV1, Vec& theV2,
Vec& theV1basis, Vec& theV2basis, Vec& theV3basis) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
@@ -689,129 +443,15 @@ void Geom_OffsetCurve::D2 (const Standard_Real theU,
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, PBasis, V1basis, V2basis, V3basis);
basisCurve->D3 (theU, thePBasis, theV1basis, theV2basis, theV3basis);
theV1 = V1basis;
V2 = V2basis;
Vec V3 = V3basis;
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
if(theV1basis.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1basis, theV2basis, theV3basis);
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum-anUinfium;
const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
Vec V;
do
{
V = basisCurve->DN(theU,++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
Pnt P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
{
theV1 = -V;
V2 = -basisCurve->DN (theU, anIndex+1);
V3 = -basisCurve->DN (theU, anIndex + 2);
IsDirectionChange = Standard_True;
}
else
{
theV1 = V;
V2 = basisCurve->DN (theU, anIndex+1);
V3 = basisCurve->DN (theU, anIndex + 2);
}
V2basis = V2;
V1basis = theV1;
}//if(V1.Magnitude() <= aTol)
XYZ OffsetDir = direction.XYZ();
XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
Standard_Real R2 = Ndir.SquareModulus();
Standard_Real R = Sqrt (R2);
Standard_Real R3 = R2 * R;
Standard_Real R4 = R2 * R2;
Standard_Real R5 = R3 * R2;
Standard_Real Dr = Ndir.Dot (DNdir);
Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
if (R5 <= gp::Resolution()) {
//We try another computation but the stability is not very good
//dixit ISG.
if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
// V2 = P" (U) :
Standard_Real R4 = R2 * R2;
D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply (offsetValue / R);
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec(DNdir));
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Add (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
)
);
if(IsDirectionChange)
V2=-V2;
V2.Add (Vec(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec(DNdir));
}
//P (U) :
D0(theU,P);
CSLib_Offset::D2(thePBasis, theV1basis, theV2basis, theV3basis, direction, offsetValue,
IsDirectionChange, theP, theV1, theV2);
}
@@ -929,3 +569,57 @@ GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec& theD1, gp_Vec& theD2,
gp_Vec& theD3, gp_Vec& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theCurve->FirstParameter();
const Standard_Real anUsupremum = theCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3;
Standard_Real du;
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
du = 0.0;
else
du = anUsupremum - anUinfium;
const Standard_Real aDelta = Max(du * DivisionFactor, MinStep);
//Derivative is approximated by Taylor-series
Standard_Integer anIndex = 1; //Derivative order
gp_Vec V;
do
{
V = theCurve->DN(theU, ++anIndex);
}
while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt P1, P2;
theCurve->D0(Min(theU, u), P1);
theCurve->D0(Max(theU, u), P2);
gp_Vec V1(P1, P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@@ -397,6 +397,10 @@ void Geom_SurfaceOfRevolution::D1
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
@@ -463,6 +467,10 @@ void Geom_SurfaceOfRevolution::D2
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
@@ -558,6 +566,10 @@ void Geom_SurfaceOfRevolution::D3
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
@@ -763,6 +775,11 @@ void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
@@ -818,6 +835,11 @@ void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
@@ -896,6 +918,11 @@ void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U,
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
// If the point is placed on the axis of revolution then derivatives on U are undefined.
// Manually set them to zero.
if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')