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:
@@ -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;
|
||||
|
@@ -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 ;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -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() ;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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''')
|
||||
|
Reference in New Issue
Block a user