1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-02 17:46:22 +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

@ -14,6 +14,7 @@
#include <Standard_NotImplemented.hxx>
#include <Adaptor3d_TopolTool.ixx>
#include <Precision.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <gp_Cone.hxx>
#include <gp_Pnt.hxx>
@ -1080,6 +1081,10 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
Standard_Integer l;
// Calculations of B-spline values will be made using adaptor,
// because it caches the data for performance
GeomAdaptor_Surface aBSplAdaptor(aBS);
anUFlg(1) = Standard_True;
anUFlg(nbsu) = Standard_True;
//myNbSamplesU = 2;
@ -1095,10 +1100,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
}
t2 = anUPars(j);
gp_Pnt p1 = aBS->Value(t2, t1);
// gp_Pnt p1 = aBS->Value(t2, t1);
gp_Pnt p1 = aBSplAdaptor.Value(t2, t1);
for(k = j+2; k <= nbsu; ++k) {
t2 = anUPars(k);
gp_Pnt p2 = aBS->Value(t2, t1);
// gp_Pnt p2 = aBS->Value(t2, t1);
gp_Pnt p2 = aBSplAdaptor.Value(t2, t1);
//gce_MakeLin MkLin(p1, p2);
//const gp_Lin& lin = MkLin.Value();
@ -1113,7 +1120,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break;
}
gp_Pnt pp = aBS->Value(anUPars(l), t1);
// gp_Pnt pp = aBS->Value(anUPars(l), t1);
gp_Pnt pp = aBSplAdaptor.Value(anUPars(l), t1);
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;
@ -1180,10 +1188,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
}
t2 = aVPars(j);
gp_Pnt p1 = aBS->Value(t1, t2);
// gp_Pnt p1 = aBS->Value(t1, t2);
gp_Pnt p1 = aBSplAdaptor.Value(t1, t2);
for(k = j+2; k <= nbsv; ++k) {
t2 = aVPars(k);
gp_Pnt p2 = aBS->Value(t1, t2);
// gp_Pnt p2 = aBS->Value(t1, t2);
gp_Pnt p2 = aBSplAdaptor.Value(t1, t2);
if(p1.SquareDistance(p2) <= tol) continue;
//gce_MakeLin MkLin(p1, p2);
@ -1197,7 +1207,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break;
}
gp_Pnt pp = aBS->Value(t1, aVPars(l));
// gp_Pnt pp = aBS->Value(t1, aVPars(l));
gp_Pnt pp = aBSplAdaptor.Value(t1, aVPars(l));
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;

View File

@ -762,8 +762,8 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
aTV1=aTV - dt;
}
//
aC2D->D0 (aTV1, aPV1);
aC2D->D0 (aTV, aPV);
aGAC2D.D0 (aTV1, aPV1);
aGAC2D.D0 (aTV, aPV);
//
aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
//
@ -1017,15 +1017,15 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
aTolInt=1.e-10;
//
BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol);
aGAC1.Load(aC2D, aT1, aT2);
//
aTV=BRep_Tool::Parameter (aV, aE, myFace);
aC2D->D0(aTV, aPV);
aGAC1.D0(aTV, aPV);
//
aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
//
aGAC1.Load(aC2D, aT1, aT2);
aC2D->D0(aT1, aP1);
aC2D->D0(aT2, aP2);
aGAC1.D0(aT1, aP1);
aGAC1.D0(aT2, aP2);
aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
//
for (i=0; i<2; ++i) {
@ -1066,7 +1066,7 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
}
//
aT=aT1max + aCf*dT;
aC2D->D0(aT, aP);
aGAC1.D0(aT, aP);
gp_Vec2d aV2D(aPV, aP);
gp_Dir2d aDir2D(aV2D);
//

View File

@ -1281,10 +1281,10 @@ Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
dU=-dU;
}
//
aC2D->D0(aU, aP2D0);
aBAC2D.D0(aU, aP2D0);
for(i=2; i<=aNbS; i++) {
aU=aU1+(i-1)*dU;
aC2D->D0(aU, aP2D1);
aBAC2D.D0(aU, aP2D1);
aP2D0.Coord(aX0, aY0);
aP2D1.Coord(aX1, aY1);
//

View File

@ -111,7 +111,7 @@ static
static
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
const Handle(Geom_Surface)& aS,
const GeomAdaptor_Surface& aS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2);
@ -558,7 +558,7 @@ void CorrectWires(const TopoDS_Face& aFx)
aT=BRep_Tool::Parameter(aV, aE);
//
aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP);
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) {
aD2max=aD2;
@ -586,7 +586,7 @@ void CorrectWires(const TopoDS_Face& aFx)
continue;
}
//
aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
if (aD2>aD2max) {
aD2max=aD2;
}
@ -606,7 +606,7 @@ void CorrectWires(const TopoDS_Face& aFx)
//=======================================================================
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
const Handle(Geom_Surface)& aS,
const GeomAdaptor_Surface& aGAS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2)
{
@ -650,7 +650,7 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
}
//
aP2D = aPoint.Value();
aS->D0(aP2D.X(), aP2D.Y(), aP);
aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD=aPV.SquareDistance(aP);
if (aD > aDist) {
aDist = 1.01 * aD;

View File

@ -74,8 +74,8 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast);
aC3D->D0(aT, aPc);
GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
@ -97,8 +97,8 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
Handle(Geom_Curve) aC3D=aC.Curve();
aC3D->D0(aT, aPc);
GeomAdaptor_Curve aCA( aC.Curve() );
aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;

View File

@ -108,7 +108,7 @@ inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
}
static
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d);
@ -1653,14 +1653,15 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
if(C2d.IsNull())
continue;
Geom2dAdaptor_Curve aCA(C2d);
aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
aPnt = C2d->Value(aParam);
aPnt = aCA.Value(aParam);
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
continue;
CurveDirForParameter(C2d, aParam, aPnt, aDer);
CurveDirForParameter(aCA, aParam, aPnt, aDer);
if (aVOrientation == anE.Orientation())
aDer.Reverse();
@ -1753,21 +1754,21 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
//function : CurveDirForParameter
//purpose :
//=======================================================================
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d)
void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d)
{
Standard_Real aTol=gp::Resolution();
Standard_Integer i;
aC2d->D1(aPrm, Pnt, aVec2d);
aC2d.D1(aPrm, Pnt, aVec2d);
//
if (aVec2d.Magnitude() <= aTol) {
for (i = 2; i <= 100; i++){
aVec2d = aC2d->DN(aPrm, i);
aVec2d = aC2d.DN(aPrm, i);
if (aVec2d.Magnitude() > aTol) {
break;
break;
}
}
}

View File

@ -2232,10 +2232,10 @@ void TrimEdge (const TopoDS_Edge& E,
// otherwise preserve only one of its representations.
//----------------------------------------------------------
if (!BRep_Tool::Degenerated(E)) {
Standard_Real aParTol = 2.0 * Precision::PConfusion();
for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) ||
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) {
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= aParTol) {
if(k+1 == TheVer.Length()) {
StoreInMap(TheVer(k), TheVer(k+1), MapVV);

View File

@ -26,6 +26,7 @@
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomProjLib.hxx>
@ -56,12 +57,12 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
const Standard_Real theFirst,
const Standard_Real theLast)
:
myCurve(theC3D),
myPCurve(theC2D),
mySurf(theSurf),
myFirst(theFirst),
myLast(theLast)
{
myCurve = new GeomAdaptor_HCurve(theC3D);
myPCurve = new Geom2dAdaptor_HCurve(theC2D);
mySurf = new GeomAdaptor_HSurface(theSurf);
}
//
virtual Standard_Integer NbVariables() const {
@ -160,9 +161,9 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
return ((myFirst <= theParam) && (theParam <= myLast));
}
Handle(Geom_Curve) myCurve;
Handle(Geom2d_Curve) myPCurve;
Handle(Geom_Surface) mySurf;
Handle(GeomAdaptor_HCurve) myCurve;
Handle(Geom2dAdaptor_HCurve) myPCurve;
Handle(GeomAdaptor_HSurface) mySurf;
Standard_Real myFirst;
Standard_Real myLast;
};

View File

@ -773,7 +773,7 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
Standard_Real cl = C->LastParameter();
Standard_Real epsilon = Precision::PConfusion();
Standard_Boolean periodic = C->IsPeriodic();
GeomAdaptor_Curve aCA(C);
TopoDS_Vertex V1,V2;
if (periodic) {
@ -813,14 +813,15 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
gp_Pnt P1,P2;
if (!p1inf) P1 = C->Value(p1);
if (!p2inf) P2 = C->Value(p2);
if (!p1inf) P1 = aCA.Value(p1);
if (!p2inf) P2 = aCA.Value(p2);
Standard_Real preci = BRepLib::Precision();
BRep_Builder B;
// check for closed curve
Standard_Boolean closed = Standard_False;
Standard_Boolean degenerated = Standard_False;
if (!p1inf && !p2inf)
closed = (P1.Distance(P2) <= preci);
@ -836,13 +837,19 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
V2 = V1;
else {
if (!V1.IsSame(V2)) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
}
else if (P1.Distance(BRep_Tool::Pnt(V1)) >
Max(preci,BRep_Tool::Tolerance(V1))) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
Max(preci,BRep_Tool::Tolerance(V1))) {
myError = BRepLib_DifferentPointsOnClosedCurve;
return;
}
else
{
gp_Pnt PM = aCA.Value((p1+p2)/2);
if (P1.Distance(PM) < preci)
degenerated = Standard_True;
}
}
}
@ -898,6 +905,7 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
B.Add(E,V2);
}
B.Range(E,p1,p2);
B.Degenerated(E, degenerated);
myError = BRepLib_EdgeDone;
Done();

View File

@ -104,6 +104,8 @@ uses TColStd, gp, TColgp, math, GeomAbs
is
imported transient class Cache;
imported EvaluatorFunction ;
@ -2063,6 +2065,30 @@ is
-- If rational computes the homogeneous Taylor expension
-- for the numerator and stores it in CachePoles
BuildCache(theParameter : Real;
theSpanDomain : Real;
thePeriodicFlag : Boolean ;
theDegree : Integer;
theFlatKnots : Array1OfReal from TColStd ;
thePoles : Array1OfPnt from TColgp;
theWeights : Array1OfReal from TColStd ;
theCacheArray : in out Array2OfReal from TColStd) ;
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplCLib_Cache.
BuildCache(theParameter : Real;
theSpanDomain : Real;
thePeriodicFlag : Boolean ;
theDegree : Integer;
theFlatKnots : Array1OfReal from TColStd ;
thePoles : Array1OfPnt2d from TColgp;
theWeights : Array1OfReal from TColStd ;
theCacheArray : in out Array2OfReal from TColStd) ;
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplCLib_Cache.
PolesCoefficients(Poles : Array1OfPnt2d from TColgp;
CachePoles : in out Array1OfPnt2d from TColgp);
---Warning: To be used for Beziercurves ONLY!!!
@ -2454,6 +2480,7 @@ is
-- all u1 and u0 in the domain of the curve f(u)
-- | u1 - u0 | < UTolerance and
-- we have |f (u1) - f (u0)| < Tolerance3D
end BSplCLib;

View File

@ -73,6 +73,7 @@ void BSplCLib::Hunt (const Array1OfReal& XX,
{
// replaced by simple dichotomy (RLE)
Ilc = XX.Lower();
if (XX.Length() <= 1) return;
const Standard_Real *px = &XX(Ilc);
px -= Ilc;

View File

@ -0,0 +1,362 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BSplCLib_Cache.hxx>
#include <BSplCLib.hxx>
#include <NCollection_LocalArray.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
IMPLEMENT_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BSplCLib_Cache, Standard_Transient)
//! Converts handle of array of Standard_Real into the pointer to Standard_Real
static Standard_Real* ConvertArray(const Handle_TColStd_HArray2OfReal& theHArray)
{
const TColStd_Array2OfReal& anArray = theHArray->Array2();
return (Standard_Real*) &(anArray(anArray.LowerRow(), anArray.LowerCol()));
}
BSplCLib_Cache::BSplCLib_Cache()
{
myPolesWeights.Nullify();
myIsRational = Standard_False;
mySpanStart = 0.0;
mySpanLength = 0.0;
mySpanIndex = 0;
myDegree = 0;
myFlatKnots.Nullify();
}
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights)
{
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
BuildCache(aCacheParam, theDegree, thePeriodic,
theFlatKnots, thePoles2d, theWeights);
}
BSplCLib_Cache::BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights)
{
Standard_Real aCacheParam = theFlatKnots.Value(theFlatKnots.Lower() + theDegree);
BuildCache(aCacheParam, theDegree, thePeriodic,
theFlatKnots, thePoles, theWeights);
}
Standard_Boolean BSplCLib_Cache::IsCacheValid(Standard_Real theParameter) const
{
Standard_Real aNewParam = theParameter;
if (!myFlatKnots.IsNull())
PeriodicNormalization(myFlatKnots->Array1(), aNewParam);
Standard_Real aDelta = aNewParam - mySpanStart;
return (aDelta >= 0.0 && (aDelta < mySpanLength || mySpanIndex == mySpanIndexMax));
}
void BSplCLib_Cache::PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const
{
Standard_Real aPeriod = theFlatKnots.Value(theFlatKnots.Upper() - myDegree) -
theFlatKnots.Value(myDegree + 1) ;
if (theParameter < theFlatKnots.Value(myDegree + 1))
{
Standard_Real aScale = IntegerPart(
(theFlatKnots.Value(myDegree + 1) - theParameter) / aPeriod);
theParameter += aPeriod * (aScale + 1.0);
}
if (theParameter > theFlatKnots.Value(theFlatKnots.Upper() - myDegree))
{
Standard_Real aScale = IntegerPart(
(theParameter - theFlatKnots.Value(theFlatKnots.Upper() - myDegree)) / aPeriod);
theParameter -= aPeriod * (aScale + 1.0);
}
}
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights)
{
// Normalize theParameter for periodical B-splines
Standard_Real aNewParam = theParameter;
if (thePeriodic)
{
PeriodicNormalization(theFlatKnots, aNewParam);
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
myFlatKnots->ChangeArray1() = theFlatKnots;
}
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
myFlatKnots.Nullify();
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 3 : 2;
if (theDegree > myDegree)
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
myDegree = theDegree;
mySpanIndex = 0;
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
aNewParam, thePeriodic, mySpanIndex, aNewParam);
mySpanStart = theFlatKnots.Value(mySpanIndex);
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
// Calculate new cache data
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
theFlatKnots, thePoles2d, theWeights,
myPolesWeights->ChangeArray2());
}
void BSplCLib_Cache::BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights)
{
// Create list of knots with repetitions and normalize theParameter for periodical B-splines
Standard_Real aNewParam = theParameter;
if (thePeriodic)
{
PeriodicNormalization(theFlatKnots, aNewParam);
myFlatKnots = new TColStd_HArray1OfReal(1, theFlatKnots.Length());
myFlatKnots->ChangeArray1() = theFlatKnots;
}
else if (!myFlatKnots.IsNull()) // Periodical curve became non-periodical
myFlatKnots.Nullify();
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 4 : 3;
if (theDegree > myDegree)
myPolesWeights = new TColStd_HArray2OfReal(1, theDegree + 1, 1, aPWColNumber);
myDegree = theDegree;
mySpanIndex = 0;
BSplCLib::LocateParameter(theDegree, theFlatKnots, BSplCLib::NoMults(),
aNewParam, thePeriodic, mySpanIndex, aNewParam);
mySpanStart = theFlatKnots.Value(mySpanIndex);
mySpanLength = theFlatKnots.Value(mySpanIndex + 1) - mySpanStart;
mySpanIndexMax = theFlatKnots.Length() - 1 - theDegree;
// Calculate new cache data
BSplCLib::BuildCache(mySpanStart, mySpanLength, thePeriodic, theDegree,
theFlatKnots, thePoles, theWeights,
myPolesWeights->ChangeArray2());
}
void BSplCLib_Cache::CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
// Temporary container. The maximal size of this container is defined by:
// 1) maximal derivative for cache evaluation, which is 3, plus one row for function values,
// 2) and maximal dimension of the point, which is 3, plus one column for weights.
Standard_Real aTmpContainer[16];
// When the PLib::RationaDerivative needs to be called, use temporary container
Standard_Real* aPntDeriv = myIsRational ? aTmpContainer : &theDerivArray;
// When the degree of curve is lesser than the requested derivative,
// nullify array cells corresponding to greater derivatives
Standard_Integer aDerivative = theDerivative;
if (myDegree < theDerivative)
{
aDerivative = myDegree;
for (Standard_Integer ind = myDegree * aDimension; ind < (theDerivative + 1) * aDimension; ind++)
{
aPntDeriv[ind] = 0.0;
(&theDerivArray)[ind] = 0.0; // should be cleared separately, because aPntDeriv may look to another memory area
}
}
PLib::EvalPolynomial(aNewParameter, aDerivative, myDegree, aDimension,
aPolesArray[0], aPntDeriv[0]);
// Unnormalize derivatives since those are computed normalized
Standard_Real aFactor = 1.0;
for (Standard_Integer deriv = 1; deriv <= aDerivative; deriv++)
{
aFactor /= mySpanLength;
for (Standard_Integer ind = 0; ind < aDimension; ind++)
aPntDeriv[aDimension * deriv + ind] *= aFactor;
}
if (myIsRational) // calculate derivatives divided by weights derivatives
PLib::RationalDerivative(aDerivative, aDerivative, aDimension - 1, aPntDeriv[0], theDerivArray);
}
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
aDimension, myDegree * aDimension,
aPolesArray[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[2]);
}
void BSplCLib_Cache::D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const
{
Standard_Real aNewParameter = theParameter;
if (!myFlatKnots.IsNull()) // B-spline is periodical
PeriodicNormalization(myFlatKnots->Array1(), aNewParameter);
aNewParameter = (aNewParameter - mySpanStart) / mySpanLength;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
PLib::NoDerivativeEvalPolynomial(aNewParameter, myDegree,
aDimension, myDegree * aDimension,
aPolesArray[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[3]);
}
void BSplCLib_Cache::D1(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
}
void BSplCLib_Cache::D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[8]; // result storage (point and derivative coordinates)
this->CalculateDerivative(theParameter, 1, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
}
void BSplCLib_Cache::D2(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent, gp_Vec2d& theCurvature) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
theCurvature.SetCoord(aPntDeriv[aDimension<<1], aPntDeriv[(aDimension<<1) + 1]);
}
void BSplCLib_Cache::D2(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent, gp_Vec& theCurvature) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[12]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 2, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
theCurvature.SetCoord(aPntDeriv[aDimension<<1], aPntDeriv[(aDimension<<1) + 1], aPntDeriv[(aDimension<<1) + 2]);
}
void BSplCLib_Cache::D3(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature,
gp_Vec2d& theTorsion) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1]);
Standard_Integer aShift = aDimension << 1;
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
aShift += aDimension;
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1]);
}
void BSplCLib_Cache::D3(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const
{
Standard_Integer aDimension = myPolesWeights->RowLength(); // number of columns
Standard_Real aPntDeriv[16]; // result storage (point and derivatives coordinates)
this->CalculateDerivative(theParameter, 3, aPntDeriv[0]);
if (myIsRational) // the size of aPntDeriv was changed by PLib::RationalDerivative
aDimension -= 1;
thePoint.SetCoord(aPntDeriv[0], aPntDeriv[1], aPntDeriv[2]);
theTangent.SetCoord(aPntDeriv[aDimension], aPntDeriv[aDimension + 1], aPntDeriv[aDimension + 2]);
Standard_Integer aShift = aDimension << 1;
theCurvature.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
aShift += aDimension;
theTorsion.SetCoord(aPntDeriv[aShift], aPntDeriv[aShift + 1], aPntDeriv[aShift + 2]);
}

View File

@ -0,0 +1,182 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BSplCLib_Cache_Headerfile
#define _BSplCLib_Cache_Headerfile
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Transient.hxx>
#include <Handle_TColStd_HArray1OfReal.hxx>
#include <Handle_TColStd_HArray2OfReal.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Vec.hxx>
class Handle(BSplCLib_Cache);
class TColStd_Array1OfReal;
class TColgp_Array1OfPnt;
class TColgp_Array1OfPnt2d;
#ifndef NOWEIGHTS_CURVE
#define NOWEIGHTS_CURVE (*((TColStd_Array1OfReal*) NULL))
#endif
//! \brief A cache class for B-spline curves.
//!
//! Defines all data, that can be cached on a span of B-spline curve.
//! The data should be recalculated in going from span to span.
class BSplCLib_Cache : public Standard_Transient
{
public:
//! Default constructor
Standard_EXPORT BSplCLib_Cache();
//! Constructor for caching of 2D curves
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles2d array of poles of 2D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Constructor for caching of 3D curves
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles array of poles of 3D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplCLib_Cache(const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Verifies validity of the cache using flat parameter of the point
//! \param theParameter parameter of the point placed in the span
Standard_EXPORT Standard_Boolean IsCacheValid(Standard_Real theParameter) const;
//! Recomputes the cache data for 2D curves. Does not verify validity of the cache
//! \param theParameter the value on the knot's axis to identify the span
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles2d array of poles of 2D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt2d& thePoles2d,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Recomputes the cache data for 3D curves. Does not verify validity of the cache
//! \param theParameter the value on the knot's axis to identify the span
//! \param theDegree degree of the B-spline
//! \param thePeriodic identify the B-spline is periodic
//! \param theFlatKnots knots of B-spline curve (with repetitions)
//! \param thePoles array of poles of 3D B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameter,
const Standard_Integer& theDegree,
const Standard_Boolean& thePeriodic,
const TColStd_Array1OfReal& theFlatKnots,
const TColgp_Array1OfPnt& thePoles,
const TColStd_Array1OfReal& theWeights = NOWEIGHTS_CURVE);
//! Calculates the point on B-spline in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt2d& thePoint) const;
Standard_EXPORT void D0(const Standard_Real& theParameter, gp_Pnt& thePoint) const;
//! Calculates the point on B-spline and its first derivative in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (first derivatives) for B-spline in the calculated point
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt2d& thePoint, gp_Vec2d& theTangent) const;
Standard_EXPORT void D1(const Standard_Real& theParameter, gp_Pnt& thePoint, gp_Vec& theTangent) const;
//! Calculates the point on B-spline and two derivatives in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
Standard_EXPORT void D2(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature) const;
Standard_EXPORT void D2(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature) const;
//! Calculates the point on B-spline and three derivatives in the selected point
//! \param[in] theParameter parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangent tangent vector (1st derivatives) for B-spline in the calculated point
//! \param[out] theCurvature curvature vector (2nd derivatives) for B-spline in the calculated point
//! \param[out] theTorsion second curvature vector (3rd derivatives) for B-spline in the calculated point
Standard_EXPORT void D3(const Standard_Real& theParameter,
gp_Pnt2d& thePoint,
gp_Vec2d& theTangent,
gp_Vec2d& theCurvature,
gp_Vec2d& theTorsion) const;
Standard_EXPORT void D3(const Standard_Real& theParameter,
gp_Pnt& thePoint,
gp_Vec& theTangent,
gp_Vec& theCurvature,
gp_Vec& theTorsion) const;
DEFINE_STANDARD_RTTI(BSplCLib_Cache)
protected:
//! Normalizes the parameter for periodical B-splines
//! \param theFlatKnots knots with repetitions
//! \param theParameter the value to be normalized into the knots array
void PeriodicNormalization(const TColStd_Array1OfReal& theFlatKnots, Standard_Real& theParameter) const;
//! Fills array of derivatives in the selected point of the B-spline
//! \param[in] theParameter parameter of the calculation
//! \param[in] theDerivative maximal derivative to be calculated (computes all derivatives lesser than specified)
//! \param[out] theDerivArray result array of derivatives (with size (theDerivative+1)*(PntDim+1),
//! where PntDim = 2 or 3 is a dimension of B-spline curve)
void CalculateDerivative(const Standard_Real& theParameter,
const Standard_Integer& theDerivative,
Standard_Real& theDerivArray) const;
private:
Handle(TColStd_HArray2OfReal) myPolesWeights; ///< array of poles and weights of calculated cache
// the array has following structure:
// x1 y1 [z1] [w1]
// x2 y2 [z2] [w2] etc
// for 2D-curves there is no z conponent, for non-rational curves there is no weight
Standard_Boolean myIsRational; ///< identifies the rationality of B-spline
Standard_Real mySpanStart; ///< parameter for the first point of the span
Standard_Real mySpanLength; ///< length of the span
Standard_Integer mySpanIndex; ///< index of the span on B-spline curve
Standard_Integer mySpanIndexMax; ///< maximal number of spans on B-spline curve
Standard_Integer myDegree; ///< degree of B-spline
Handle(TColStd_HArray1OfReal) myFlatKnots; ///< knots of B-spline (used for periodic normalization of parameters, exists only for periodical splines)
};
DEFINE_STANDARD_HANDLE(BSplCLib_Cache, Standard_Transient)
#endif

View File

@ -19,6 +19,7 @@
// xab : 12-Mar-96 : added MovePointAndTangent
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <gp_Vec2d.hxx>
#include <Standard_ConstructionError.hxx>
#include <PLib.hxx>
@ -1089,6 +1090,65 @@ void BSplCLib::BuildCache
}
}
void BSplCLib::BuildCache(const Standard_Real theParameter,
const Standard_Real theSpanDomain,
const Standard_Boolean thePeriodicFlag,
const Standard_Integer theDegree,
const TColStd_Array1OfReal& theFlatKnots,
const Array1OfPoints& thePoles,
const TColStd_Array1OfReal& theWeights,
TColStd_Array2OfReal& theCacheArray)
{
Standard_Real aParam = theParameter;
Standard_Integer anIndex = 0;
Standard_Integer aDimension;
Standard_Boolean isRational;
BSplCLib_DataContainer dc(theDegree);
PrepareEval(aParam,
anIndex,
aDimension,
isRational,
theDegree,
thePeriodicFlag,
thePoles,
theWeights,
theFlatKnots,
(BSplCLib::NoMults()),
dc);
//
// Watch out : PrepareEval checks if locally the Bspline is polynomial
// therefore rational flag could be set to False even if there are
// Weights. The Dimension is set accordingly.
//
Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the curve is locally polynomial
(&theWeights != NULL && !isRational) ? aDimension + 1 : aDimension;
BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles);
Standard_Real aCoeff = 1.0;
Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
Standard_Real* aPolyCoeffs = dc.poles;
for (Standard_Integer i = 0; i <= theDegree; i++)
{
for (Standard_Integer j = 0; j< aDimension; j++)
aCache[j] = aPolyCoeffs[j] * aCoeff;
aCoeff *= theSpanDomain / (i+1);
aPolyCoeffs += aDimension;
aCache += aDimension;
if (aCacheShift > aDimension)
{
aCache[0] = 0.0;
aCache++;
}
}
if (aCacheShift > aDimension)
theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
}
//=======================================================================
//function : Interpolate
//purpose :

View File

@ -4,4 +4,5 @@ BSplCLib_3.cxx
BSplCLib_BzSyntaxes.cxx
BSplCLib_CurveComputation.gxx
BSplCLib_EvaluatorFunction.hxx
BSplCLib_Cache.hxx
BSplCLib_Cache.cxx

View File

@ -71,6 +71,8 @@ uses TColStd, gp, TColgp
is
imported transient class Cache;
imported EvaluatorFunction ;
---Purpose:
@ -465,6 +467,19 @@ is
--
--
BuildCache(theU, theV : Real;
theUSpanDomain, theVSpanDomain : Real;
theUPeriodic, theVPeriodic : Boolean;
theUDegree, theVDegree : Integer;
theUIndex, theVIndex : Integer;
theUFlatKnots, theVFlatKnots : Array1OfReal from TColStd;
thePoles : Array2OfPnt from TColgp;
theWeights : Array2OfReal from TColStd;
theCacheArray : in out Array2OfReal from TColStd);
---Purpose: Perform the evaluation of the Taylor expansion
-- of the Bspline normalized between 0 and 1.
-- Structure of result optimized for BSplSLib_Cache.
CacheD0(U,V : Real;
UDegree,VDegree : Integer;
UCacheParameter,VCacheParameter : Real;

View File

@ -2043,6 +2043,101 @@ void BSplSLib::BuildCache
}
}
void BSplSLib::BuildCache(const Standard_Real theU,
const Standard_Real theV,
const Standard_Real theUSpanDomain,
const Standard_Real theVSpanDomain,
const Standard_Boolean theUPeriodicFlag,
const Standard_Boolean theVPeriodicFlag,
const Standard_Integer theUDegree,
const Standard_Integer theVDegree,
const Standard_Integer theUIndex,
const Standard_Integer theVIndex,
const TColStd_Array1OfReal& theUFlatKnots,
const TColStd_Array1OfReal& theVFlatKnots,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights,
TColStd_Array2OfReal& theCacheArray)
{
Standard_Boolean flag_u_or_v;
Standard_Integer d1, d2;
Standard_Real u1, u2;
Standard_Boolean isRationalOnParam = (&theWeights != NULL);
Standard_Boolean isRational;
BSplSLib_DataContainer dc(theUDegree, theVDegree);
flag_u_or_v =
PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree,
isRationalOnParam, isRationalOnParam,
theUPeriodicFlag, theVPeriodicFlag,
thePoles, theWeights,
theUFlatKnots, theVFlatKnots,
(BSplCLib::NoMults()), (BSplCLib::NoMults()),
u1, u2, d1, d2, isRational, dc);
Standard_Integer d2p1 = d2 + 1;
Standard_Integer aDimension = isRational ? 4 : 3;
Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial
(isRationalOnParam && !isRational) ? aDimension + 1 : aDimension;
Standard_Real aDomains[2];
// aDomains[0] corresponds to variable with minimal degree
// aDomains[1] corresponds to variable with maximal degree
if (flag_u_or_v)
{
aDomains[0] = theUSpanDomain;
aDomains[1] = theVSpanDomain;
}
else
{
aDomains[0] = theVSpanDomain;
aDomains[1] = theUSpanDomain;
}
BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles);
for (Standard_Integer kk = 0; kk <= d1 ; kk++)
BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1));
Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
Standard_Real* aPolyCoeffs = dc.poles;
Standard_Real aFactors[2];
// aFactors[0] corresponds to variable with minimal degree
// aFactors[1] corresponds to variable with maximal degree
aFactors[1] = 1.0;
Standard_Integer aRow, aCol, i;
Standard_Real aCoeff;
for (aRow = 0; aRow <= d2; aRow++)
{
aFactors[0] = 1.0;
for (aCol = 0; aCol <= d1; aCol++)
{
aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension;
aCoeff = aFactors[0] * aFactors[1];
for (i = 0; i < aDimension; i++)
aCache[i] = aPolyCoeffs[i] * aCoeff;
aCache += aCacheShift;
aFactors[0] *= aDomains[0] / (aCol + 1);
}
aFactors[1] *= aDomains[1] / (aRow + 1);
}
// Fill the weights for the surface which is not locally polynomial
if (aCacheShift > aDimension)
{
aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
aCache += aCacheShift - 1;
for (aRow = 0; aRow <= d2; aRow++)
for (aCol = 0; aCol <= d1; aCol++)
{
*aCache = 0.0;
aCache += aCacheShift;
}
theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
}
}
//=======================================================================
//function : CacheD0
//purpose : Evaluates the polynomial cache of the Bspline Curve

View File

@ -0,0 +1,407 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BSplSLib_Cache.hxx>
#include <BSplSLib.hxx>
#include <NCollection_LocalArray.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
IMPLEMENT_STANDARD_HANDLE(BSplSLib_Cache, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(BSplSLib_Cache, Standard_Transient)
//! Converts handle of array of Standard_Real into the pointer to Standard_Real
static Standard_Real* ConvertArray(const Handle_TColStd_HArray2OfReal& theHArray)
{
const TColStd_Array2OfReal& anArray = theHArray->Array2();
return (Standard_Real*) &(anArray(anArray.LowerRow(), anArray.LowerCol()));
}
BSplSLib_Cache::BSplSLib_Cache()
{
myPolesWeights.Nullify();
myIsRational = Standard_False;
mySpanStart[0] = mySpanStart[1] = 0.0;
mySpanLength[0] = mySpanLength[1] = 0.0;
mySpanIndex[0] = mySpanIndex[1] = 0;
myDegree[0] = myDegree[1] = 0;
myFlatKnots[0].Nullify();
myFlatKnots[1].Nullify();
}
BSplSLib_Cache::BSplSLib_Cache(const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights)
{
Standard_Real aU = theFlatKnotsU.Value(theFlatKnotsU.Lower() + theDegreeU);
Standard_Real aV = theFlatKnotsV.Value(theFlatKnotsV.Lower() + theDegreeV);
BuildCache(aU, aV,
theDegreeU, thePeriodicU, theFlatKnotsU,
theDegreeV, thePeriodicV, theFlatKnotsV,
thePoles, theWeights);
}
Standard_Boolean BSplSLib_Cache::IsCacheValid(Standard_Real theParameterU,
Standard_Real theParameterV) const
{
Standard_Real aNewU = theParameterU;
Standard_Real aNewV = theParameterV;
if (!myFlatKnots[0].IsNull())
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
if (!myFlatKnots[1].IsNull())
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
Standard_Real aDelta0 = aNewU - mySpanStart[0];
Standard_Real aDelta1 = aNewV - mySpanStart[1];
return (aDelta0 >= -mySpanLength[0] && (aDelta0 < mySpanLength[0] || mySpanIndex[0] == mySpanIndexMax[0]) &&
aDelta1 >= -mySpanLength[1] && (aDelta1 < mySpanLength[1] || mySpanIndex[1] == mySpanIndexMax[1]));
}
void BSplSLib_Cache::PeriodicNormalization(const Standard_Integer& theDegree,
const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const
{
Standard_Real aPeriod = theFlatKnots.Value(theFlatKnots.Upper() - theDegree) -
theFlatKnots.Value(theDegree + 1) ;
if (theParameter < theFlatKnots.Value(theDegree + 1))
{
Standard_Real aScale = IntegerPart(
(theFlatKnots.Value(theDegree + 1) - theParameter) / aPeriod);
theParameter += aPeriod * (aScale + 1.0);
}
if (theParameter > theFlatKnots.Value(theFlatKnots.Upper() - theDegree))
{
Standard_Real aScale = IntegerPart(
(theParameter - theFlatKnots.Value(theFlatKnots.Upper() - theDegree)) / aPeriod);
theParameter -= aPeriod * (aScale + 1.0);
}
}
void BSplSLib_Cache::BuildCache(const Standard_Real& theParameterU,
const Standard_Real& theParameterV,
const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights)
{
// Normalize the parameters for periodical B-splines
Standard_Real aNewParamU = theParameterU;
if (thePeriodicU)
{
PeriodicNormalization(theDegreeU, theFlatKnotsU, aNewParamU);
myFlatKnots[0] = new TColStd_HArray1OfReal(1, theFlatKnotsU.Length());
myFlatKnots[0]->ChangeArray1() = theFlatKnotsU;
}
else if (!myFlatKnots[0].IsNull()) // Periodical curve became non-periodical
myFlatKnots[0].Nullify();
Standard_Real aNewParamV = theParameterV;
if (thePeriodicV)
{
PeriodicNormalization(theDegreeV, theFlatKnotsV, aNewParamV);
myFlatKnots[1] = new TColStd_HArray1OfReal(1, theFlatKnotsV.Length());
myFlatKnots[1]->ChangeArray1() = theFlatKnotsV;
}
else if (!myFlatKnots[1].IsNull()) // Periodical curve became non-periodical
myFlatKnots[1].Nullify();
Standard_Integer aMinDegree = Min(theDegreeU, theDegreeV);
Standard_Integer aMaxDegree = Max(theDegreeU, theDegreeV);
// Change the size of cached data if needed
myIsRational = (&theWeights != NULL);
Standard_Integer aPWColNumber = myIsRational ? 4 : 3;
if (theDegreeU > myDegree[0] || theDegreeV > myDegree[1])
myPolesWeights = new TColStd_HArray2OfReal(1, aMaxDegree + 1, 1, aPWColNumber * (aMinDegree + 1));
myDegree[0] = theDegreeU;
myDegree[1] = theDegreeV;
mySpanIndex[0] = mySpanIndex[1] = 0;
BSplCLib::LocateParameter(theDegreeU, theFlatKnotsU, BSplCLib::NoMults(), aNewParamU,
thePeriodicU, mySpanIndex[0], aNewParamU);
BSplCLib::LocateParameter(theDegreeV, theFlatKnotsV, BSplCLib::NoMults(), aNewParamV,
thePeriodicV, mySpanIndex[1], aNewParamV);
mySpanLength[0] = (theFlatKnotsU.Value(mySpanIndex[0] + 1) - theFlatKnotsU.Value(mySpanIndex[0])) * 0.5;
mySpanStart[0] = theFlatKnotsU.Value(mySpanIndex[0]) + mySpanLength[0];
mySpanLength[1] = (theFlatKnotsV.Value(mySpanIndex[1] + 1) - theFlatKnotsV.Value(mySpanIndex[1])) * 0.5;
mySpanStart[1] = theFlatKnotsV.Value(mySpanIndex[1]) + mySpanLength[1];
mySpanIndexMax[0] = theFlatKnotsU.Length() - 1 - theDegreeU;
mySpanIndexMax[1] = theFlatKnotsV.Length() - 1 - theDegreeV;
// Calculate new cache data
BSplSLib::BuildCache(mySpanStart[0], mySpanStart[1],
mySpanLength[0], mySpanLength[1],
thePeriodicU, thePeriodicV,
theDegreeU, theDegreeV,
mySpanIndex[0], mySpanIndex[1],
theFlatKnotsU, theFlatKnotsV,
thePoles, theWeights, myPolesWeights->ChangeArray2());
}
void BSplSLib_Cache::D0(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) / mySpanLength[0];
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) / mySpanLength[1];
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPoint[4];
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(aCacheCols); // array for intermediate results
// Calculate intermediate value of cached polynomial along columns
PLib::NoDerivativeEvalPolynomial(aParameters[1], aMinMaxDegree[1],
aCacheCols, aMinMaxDegree[1] * aCacheCols,
aPolesArray[0], aTransientCoeffs[0]);
// Calculate total value
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0],
aDimension, aDimension * aMinMaxDegree[0],
aTransientCoeffs[0], aPoint[0]);
thePoint.SetCoord(aPoint[0], aPoint[1], aPoint[2]);
if (myIsRational)
thePoint.ChangeCoord().Divide(aPoint[3]);
}
void BSplSLib_Cache::D1(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
Standard_Real anInvU = 1.0 / mySpanLength[0];
Standard_Real anInvV = 1.0 / mySpanLength[1];
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) * anInvU;
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) * anInvV;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPntDeriv[16]; // result storage (point and derivative coordinates)
for (Standard_Integer i = 0; i< 16; i++) aPntDeriv[i] = 0.0;
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(aCacheCols<<1); // array for intermediate results
// Calculate intermediate values and derivatives of bivariate polynomial along variable with maximal degree
PLib::EvalPolynomial(aParameters[1], 1, aMinMaxDegree[1], aCacheCols, aPolesArray[0], aTransientCoeffs[0]);
// Calculate a point on surface and a derivative along variable with minimal degree
PLib::EvalPolynomial(aParameters[0], 1, aMinMaxDegree[0], aDimension, aTransientCoeffs[0], aPntDeriv[0]);
// Calculate derivative along variable with maximal degree
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0], aDimension,
aMinMaxDegree[0] * aDimension, aTransientCoeffs[aCacheCols],
aPntDeriv[aDimension<<1]);
Standard_Real* aResult = aPntDeriv;
Standard_Real aTempStorage[12];
if (myIsRational) // calculate derivatives divided by weight's derivatives
{
BSplSLib::RationalDerivative(1, 1, 1, 1, aPntDeriv[0], aTempStorage[0]);
aResult = aTempStorage;
aDimension--;
}
thePoint.SetCoord(aResult[0], aResult[1], aResult[2]);
if (myDegree[0] > myDegree[1])
{
theTangentV.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theTangentU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
else
{
theTangentU.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theTangentV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
theTangentU.Multiply(anInvU);
theTangentV.Multiply(anInvV);
}
void BSplSLib_Cache::D2(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV,
gp_Vec& theCurvatureU,
gp_Vec& theCurvatureV,
gp_Vec& theCurvatureUV) const
{
Standard_Real aNewU = theU;
Standard_Real aNewV = theV;
Standard_Real anInvU = 1.0 / mySpanLength[0];
Standard_Real anInvV = 1.0 / mySpanLength[1];
if (!myFlatKnots[0].IsNull()) // B-spline is U-periodical
PeriodicNormalization(myDegree[0], myFlatKnots[0]->Array1(), aNewU);
aNewU = (aNewU - mySpanStart[0]) * anInvU;
if (!myFlatKnots[1].IsNull()) // B-spline is V-periodical
PeriodicNormalization(myDegree[1], myFlatKnots[1]->Array1(), aNewV);
aNewV = (aNewV - mySpanStart[1]) * anInvV;
Standard_Real* aPolesArray = ConvertArray(myPolesWeights);
Standard_Real aPntDeriv[36]; // result storage (point and derivative coordinates)
for (Standard_Integer i = 0; i < 36; i++) aPntDeriv[i] = 0.0;
Standard_Integer aDimension = myIsRational ? 4 : 3;
Standard_Integer aCacheCols = myPolesWeights->RowLength();
Standard_Integer aMinMaxDegree[2] = {Min(myDegree[0], myDegree[1]),
Max(myDegree[0], myDegree[1])};
Standard_Real aParameters[2];
if (myDegree[0] > myDegree[1])
{
aParameters[0] = aNewV;
aParameters[1] = aNewU;
}
else
{
aParameters[0] = aNewU;
aParameters[1] = aNewV;
}
NCollection_LocalArray<Standard_Real> aTransientCoeffs(3 * aCacheCols); // array for intermediate results
// Calculating derivative to be evaluate and
// nulling transient coefficients when max or min derivative is less than 2
Standard_Integer aMinMaxDeriv[2] = {Min(2, aMinMaxDegree[0]),
Min(2, aMinMaxDegree[1])};
for (Standard_Integer i = aMinMaxDeriv[1] + 1; i < 3; i++)
{
Standard_Integer index = i * aCacheCols;
for (Standard_Integer j = 0; j < aCacheCols; j++)
aTransientCoeffs[index++] = 0.0;
}
// Calculate intermediate values and derivatives of bivariate polynomial along variable with maximal degree
PLib::EvalPolynomial(aParameters[1], aMinMaxDeriv[1], aMinMaxDegree[1],
aCacheCols, aPolesArray[0], aTransientCoeffs[0]);
// Calculate a point on surface and a derivatives along variable with minimal degree
PLib::EvalPolynomial(aParameters[0], aMinMaxDeriv[0], aMinMaxDegree[0],
aDimension, aTransientCoeffs[0], aPntDeriv[0]);
// Calculate derivative along variable with maximal degree and mixed derivative
PLib::EvalPolynomial(aParameters[0], 1, aMinMaxDegree[0], aDimension,
aTransientCoeffs[aCacheCols], aPntDeriv[3 * aDimension]);
// Calculate second derivative along variable with maximal degree
PLib::NoDerivativeEvalPolynomial(aParameters[0], aMinMaxDegree[0], aDimension,
aMinMaxDegree[0] * aDimension, aTransientCoeffs[aCacheCols<<1],
aPntDeriv[6 * aDimension]);
Standard_Real* aResult = aPntDeriv;
Standard_Real aTempStorage[36];
if (myIsRational) // calculate derivatives divided by weight's derivatives
{
BSplSLib::RationalDerivative(2, 2, 2, 2, aPntDeriv[0], aTempStorage[0]);
aResult = aTempStorage;
aDimension--;
}
thePoint.SetCoord(aResult[0], aResult[1], aResult[2]);
if (myDegree[0] > myDegree[1])
{
theTangentV.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theCurvatureV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theTangentU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theCurvatureUV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += (aDimension << 1);
theCurvatureU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
else
{
theTangentU.SetCoord(aResult[aDimension], aResult[aDimension + 1], aResult[aDimension + 2]);
Standard_Integer aShift = aDimension<<1;
theCurvatureU.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theTangentV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += aDimension;
theCurvatureUV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
aShift += (aDimension << 1);
theCurvatureV.SetCoord(aResult[aShift], aResult[aShift + 1], aResult[aShift + 2]);
}
theTangentU.Multiply(anInvU);
theTangentV.Multiply(anInvV);
theCurvatureU.Multiply(anInvU * anInvU);
theCurvatureV.Multiply(anInvV * anInvV);
theCurvatureUV.Multiply(anInvU * anInvV);
}

View File

@ -0,0 +1,161 @@
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BSplSLib_Cache_Headerfile
#define _BSplSLib_Cache_Headerfile
#include <Standard.hxx>
#include <Standard_Macro.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Transient.hxx>
#include <Handle_TColStd_HArray1OfReal.hxx>
#include <Handle_TColStd_HArray2OfReal.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
class Handle(BSplSLib_Cache);
class TColgp_Array2OfPnt;
class TColStd_Array1OfInteger;
class TColStd_Array1OfReal;
class TColStd_Array2OfReal;
#ifndef NOWEIGHTS_SURF
#define NOWEIGHTS_SURF (*((TColStd_Array2OfReal*) NULL))
#endif
//! \brief A cache class for B-spline surfaces.
//!
//! Defines all data, that can be cached on a span of B-spline surface.
//! The data should be recalculated in going from span to span.
class BSplSLib_Cache : public Standard_Transient
{
public:
//! Default constructor
Standard_EXPORT BSplSLib_Cache();
//! Constructor for caching of the span for B-spline surface
//! \param theDegreeU degree along the first parameter (U) of the B-spline
//! \param thePeriodicU identify the B-spline is periodical along U axis
//! \param theFlatKnotsU knots of B-spline curve (with repetition) along U axis
//! \param theDegreeV degree alogn the second parameter (V) of the B-spline
//! \param thePeriodicV identify the B-spline is periodical along V axis
//! \param theFlatKnotsV knots of B-spline curve (with repetition) along V axis
//! \param thePoles array of poles of the B-spline surface
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT BSplSLib_Cache(const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights = NOWEIGHTS_SURF);
//! Verifies validity of the cache using parameters of the point
//! \param theParameterU first parameter of the point placed in the span
//! \param theParameterV second parameter of the point placed in the span
Standard_EXPORT Standard_Boolean IsCacheValid(Standard_Real theParameterU,
Standard_Real theParameterV) const;
//! Recomputes the cache data. Does not verify validity of the cache
//! \param theParameterU the parametric value on the U axis to identify the span
//! \param theParameterV the parametric value on the V axis to identify the span
//! \param theDegreeU degree of the B-spline along U axis
//! \param thePeriodicU identify the B-spline is periodic along U axis
//! \param theFlatKnotsU flat knots of B-spline surface along U axis
//! \param theDegreeV degree of the B-spline along V axis
//! \param thePeriodicV identify the B-spline is periodic along V axis
//! \param theFlatKnotsV flat knots of B-spline surface along V axis
//! \param thePoles array of poles of B-spline
//! \param theWeights array of weights of corresponding poles
Standard_EXPORT void BuildCache(const Standard_Real& theParameterU,
const Standard_Real& theParameterV,
const Standard_Integer& theDegreeU,
const Standard_Boolean& thePeriodicU,
const TColStd_Array1OfReal& theFlatKnotsU,
const Standard_Integer& theDegreeV,
const Standard_Boolean& thePeriodicV,
const TColStd_Array1OfReal& theFlatKnotsV,
const TColgp_Array2OfPnt& thePoles,
const TColStd_Array2OfReal& theWeights = NOWEIGHTS_SURF);
//! Calculates the point on B-spline for specified parameters
//! \param[in] theU first parameter for calculation of the value
//! \param[in] theV second parameter for calculation of the value
//! \param[out] thePoint the result of calculation (the point on the B-spline)
Standard_EXPORT void D0(const Standard_Real& theU, const Standard_Real& theV, gp_Pnt& thePoint) const;
//! Calculates the point on B-spline and its first derivative
//! \param[in] theU first parameter of calculation of the value
//! \param[in] theV second parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on the B-spline)
//! \param[out] theTangentU tangent vector along U axis in the calculated point
//! \param[out] theTangentV tangent vector along V axis in the calculated point
Standard_EXPORT void D1(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV) const;
//! Calculates the point on B-spline and derivatives till second order
//! \param[in] theU first parameter of calculation of the value
//! \param[in] theV second parameter of calculation of the value
//! \param[out] thePoint the result of calculation (the point on B-spline)
//! \param[out] theTangentU tangent vector along U axis in the calculated point
//! \param[out] theTangentV tangent vector along V axis in the calculated point
//! \param[out] theCurvatureU curvature vector (2nd derivative on U) along U axis
//! \param[out] theCurvatureV curvature vector (2nd derivative on V) along V axis
//! \param[out] theCurvatureUV 2nd mixed derivative on U anv V
Standard_EXPORT void D2(const Standard_Real& theU,
const Standard_Real& theV,
gp_Pnt& thePoint,
gp_Vec& theTangentU,
gp_Vec& theTangentV,
gp_Vec& theCurvatureU,
gp_Vec& theCurvatureV,
gp_Vec& theCurvatureUV) const;
DEFINE_STANDARD_RTTI(BSplSLib_Cache)
protected:
//! Normalizes the parameter for periodical B-splines
//! \param[in] theDegree degree of B-spline along selected direction
//! \param[in] theFlatKnots knots with repetitions along selected direction
//! \param[in,out] theParameter the value to be normalized into the knots array
void PeriodicNormalization(const Standard_Integer& theDegree,
const TColStd_Array1OfReal& theFlatKnots,
Standard_Real& theParameter) const;
private:
Handle(TColStd_HArray2OfReal) myPolesWeights; ///< array of poles and weights of calculated cache
// the array has following structure:
// x11 y11 z11 [w11] x12 y12 z12 [w12] ...
// x21 y21 z21 [w21] x22 y22 z22 [w22] etc
// for non-rational surfaces there is no weight;
// size of array: (max(myDegree)+1) * A*(min(myDegree)+1), where A = 4 or 3
Standard_Boolean myIsRational; ///< identifies the rationality of B-spline
Standard_Real mySpanStart[2]; ///< parameters (u, v) for the frst point of the span
Standard_Real mySpanLength[2]; ///< lengths of the span along corresponding parameter
Standard_Integer mySpanIndex[2]; ///< indexes of the span on B-spline surface
Standard_Integer mySpanIndexMax[2]; ///< maximal indexes of span
Standard_Integer myDegree[2]; ///< degrees of B-spline for each parameter
Handle(TColStd_HArray1OfReal) myFlatKnots[2]; ///< arrays of knots of B-spline
// (used for periodic normalization of parameters, Null for non-periodical splines)
};
DEFINE_STANDARD_HANDLE(BSplSLib_Cache, Standard_Transient)
#endif

View File

@ -1,3 +1,4 @@
BSplSLib_BzSyntaxes.cxx
BSplSLib_EvaluatorFunction.hxx
BSplSLib_Cache.hxx
BSplSLib_Cache.cxx

View File

@ -165,7 +165,13 @@ gp_Dir& Normal
// if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag;
}
else
{ Normal = gp_Dir (D1UvD1V); Status = Defined; }
{
// Firstly normalize tangent vectors D1U and D1V (this method is more stable)
gp_Dir aD1U(D1U);
gp_Dir aD1V(D1V);
Normal = gp_Dir(aD1U.Crossed(aD1V));
Status = Defined;
}
}

470
src/CSLib/CSLib_Offset.cxx Normal file
View File

@ -0,0 +1,470 @@
// Copyright (c) 2015-... OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <CSLib_Offset.hxx>
#include <gp_Dir2d.hxx>
#include <gp_XY.hxx>
#include <Geom_UndefinedValue.hxx>
#include <Geom_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Standard_NullValue.hxx>
// ========== Offset values for 2D curves ==========
void CSLib_Offset::D0(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseDeriv,
Standard_Real theOffset,
Standard_Boolean , // unused
gp_Pnt2d& theResPoint)
{
if (theBaseDeriv.SquareMagnitude() <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Undefined normal vector "
"because tangent vector has zero-magnitude!");
gp_Dir2d aNormal(theBaseDeriv.Y(), -theBaseDeriv.X());
theResPoint.SetCoord(theBasePoint.X() + aNormal.X() * theOffset,
theBasePoint.Y() + aNormal.Y() * theOffset);
}
void CSLib_Offset::D1(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
Standard_Real theOffset,
Standard_Boolean , // unused
gp_Pnt2d& theResPoint,
gp_Vec2d& theResDeriv)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
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())
{
if (R2 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good.
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffset / R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better
DNdir.Multiply(theOffset / R);
DNdir.Subtract(Ndir.Multiplied(theOffset * Dr / R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffset, Standard_False, theResPoint);
// P'(u)
theResDeriv = theBaseD1.Added(gp_Vec2d(DNdir));
}
void CSLib_Offset::D2(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
gp_XY D2Ndir(theBaseD3.Y(), -theBaseD3.X());
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())
{
if (R4 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good dixit ISG.
// V2 = P" (U) :
D2Ndir.Subtract(DNdir.Multiplied (2.0 * Dr / R2));
D2Ndir.Add(Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
D2Ndir.Multiply(theOffset / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffset / R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better.
// V2 = P" (U) :
D2Ndir.Multiply(theOffset / R);
D2Ndir.Subtract(DNdir.Multiplied (2.0 * theOffset * Dr / R3));
D2Ndir.Add (Ndir.Multiplied(theOffset * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U)
DNdir.Multiply(theOffset / R);
DNdir.Subtract(Ndir.Multiplied(theOffset * Dr / R3));
}
// P(u) :
D0(theBasePoint, theBaseD1, theOffset, theIsDirectionChange, theResPoint);
// P'(u) :
theResD1 = theBaseD1.Added(gp_Vec2d(DNdir));
// P"(u) :
if (theIsDirectionChange)
theResD2 = -theBaseD2;
else
theResD2 = theBaseD2;
theResD2.Add(gp_Vec2d(D2Ndir));
}
void CSLib_Offset::D3(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
const gp_Vec2d& theBaseD4,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2,
gp_Vec2d& theResD3)
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
// P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
// (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
gp_XY Ndir(theBaseD1.Y(), -theBaseD1.X());
gp_XY DNdir(theBaseD2.Y(), -theBaseD2.X());
gp_XY D2Ndir(theBaseD3.Y(), -theBaseD3.X());
gp_XY D3Ndir(theBaseD4.Y(), -theBaseD4.X());
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())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good dixit ISG.
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * theOffset * Dr / R2));
D3Ndir.Subtract (
(DNdir.Multiplied ((3.0 * theOffset) * ((D2r/R2) + (Dr*Dr)/R4))));
D3Ndir.Add (Ndir.Multiplied (
(theOffset * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r))));
D3Ndir.Multiply (theOffset/R);
// 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 (theOffset / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffset/R2);
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is better.
// V3 = P"' (U) :
D3Ndir.Multiply (theOffset/R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * theOffset * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied (
((3.0 * theOffset) * ((D2r/R3) + (Dr*Dr)/R5))) );
D3Ndir.Add (Ndir.Multiplied (
(theOffset * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))));
// V2 = P" (U) :
D2Ndir.Multiply (theOffset/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * theOffset * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied (
theOffset * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U) :
DNdir.Multiply (theOffset/R);
DNdir.Subtract (Ndir.Multiplied (theOffset*Dr/R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffset, theIsDirectionChange, theResPoint);
// P'(u)
theResD1 = theBaseD1.Added(gp_Vec2d(DNdir));
// P"(u)
theResD2 = theBaseD2.Added(gp_Vec2d(D2Ndir));
// P"'(u)
if (theIsDirectionChange)
theResD3 = -theBaseD3;
else
theResD3 = theBaseD3;
theResD3.Add(gp_Vec2d(D2Ndir));
}
// ========== Offset values for 3D curves ==========
void CSLib_Offset::D0(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseDeriv,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean , // unused
gp_Pnt& theResPoint)
{
gp_XYZ Ndir = (theBaseDeriv.XYZ()).Crossed(theOffsetDirection.XYZ());
Standard_Real R = Ndir.Modulus();
if (R <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Ndir.Multiply(theOffsetValue / R);
Ndir.Add(theBasePoint.XYZ());
theResPoint.SetXYZ(Ndir);
}
void CSLib_Offset::D1(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean , // unused
gp_Pnt& theResPoint,
gp_Vec& theResDeriv)
{
// 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))
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
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()) {
if (R2 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good.
DNdir.Multiply(R);
DNdir.Subtract(Ndir.Multiplied(Dr / R));
DNdir.Multiply(theOffsetValue / R2);
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better
DNdir.Multiply(theOffsetValue / R);
DNdir.Subtract(Ndir.Multiplied(theOffsetValue * Dr / R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, Standard_False, theResPoint);
// P'(u)
theResDeriv = theBaseD1.Added(gp_Vec(DNdir));
}
void CSLib_Offset::D2(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2)
{
// 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))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D2Ndir = (theBaseD3.XYZ()).Crossed(theOffsetDirection.XYZ());
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()) {
if (R4 <= gp::Resolution())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
//We try another computation but the stability is not very good
//dixit ISG.
// 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 (theOffsetValue / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffsetValue/R2);
}
else {
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V2 = P" (U) :
D2Ndir.Multiply (theOffsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * theOffsetValue * Dr / R3));
D2Ndir.Add (Ndir.Multiplied (theOffsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
// V1 = P' (U) :
DNdir.Multiply (theOffsetValue/R);
DNdir.Subtract (Ndir.Multiplied (theOffsetValue*Dr/R3));
}
// P(u) :
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, theIsDirectionChange, theResPoint);
// P'(u) :
theResD1 = theBaseD1.Added(gp_Vec(DNdir));
// P"(u) :
if (theIsDirectionChange)
theResD2 = -theBaseD2;
else
theResD2 = theBaseD2;
theResD2.Add(gp_Vec(D2Ndir));
}
void CSLib_Offset::D3(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Vec& theBaseD4,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2,
gp_Vec& theResD3)
{
// 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))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
//P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2) * D2Ndir -
// (3.0 * D2r / R2) * DNdir + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
gp_XYZ Ndir = (theBaseD1.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ DNdir = (theBaseD2.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D2Ndir = (theBaseD3.XYZ()).Crossed(theOffsetDirection.XYZ());
gp_XYZ D3Ndir = (theBaseD4.XYZ()).Crossed(theOffsetDirection.XYZ());
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())
Standard_NullValue::Raise("CSLib_Offset: Null derivative");
// 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 (theOffsetValue/R);
// 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 (theOffsetValue / R);
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (theOffsetValue/R2);
}
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 (theOffsetValue);
// 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 (theOffsetValue);
// V1 = P' (U) :
DNdir.Multiply (theOffsetValue/R);
DNdir.Subtract (Ndir.Multiplied (theOffsetValue*Dr/R3));
}
// P(u)
D0(theBasePoint, theBaseD1, theOffsetDirection, theOffsetValue, theIsDirectionChange, theResPoint);
// P'(u)
theResD1 = theBaseD1.Added(gp_Vec(DNdir));
// P"(u)
theResD2 = theBaseD2.Added(gp_Vec(D2Ndir));
// P"'(u)
if (theIsDirectionChange)
theResD3 = -theBaseD3;
else
theResD3 = theBaseD3;
theResD3.Add(gp_Vec(D2Ndir));
}

190
src/CSLib/CSLib_Offset.hxx Normal file
View File

@ -0,0 +1,190 @@
// Copyright (c) 2015-... OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _CSLib_Offset_Headerfile
#define _CSLib_Offset_Headerfile
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Standard.hxx>
/** \namespace CSLib_Offset
* \brief Provides a number of static methods to calculate values and derivatives
* of an offset curves and surfaces using values and derivatives of
* a base curve/surface.
*/
namespace CSLib_Offset
{
/** \brief Calculate value of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseDeriv derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
*/
Standard_EXPORT void D0(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseDeriv,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint);
/** \brief Calculate value of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseDeriv derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
*/
Standard_EXPORT void D0(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseDeriv,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint);
/** \brief Calculate value and the first derivative of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
* \param[out] theResDeriv derivative on offset curve
*/
Standard_EXPORT void D1(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResDeriv);
/** \brief Calculate value and the first derivative of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative (not used)
* \param[out] theResPoint point on offset curve
* \param[out] theResDeriv derivative on offset curve
*/
Standard_EXPORT void D1(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResDeriv);
/** \brief Calculate value and two derivatives of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
*/
Standard_EXPORT void D2(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2);
/** \brief Calculate value and two derivatives of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
*/
Standard_EXPORT void D2(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2);
/** \brief Calculate value and three derivatives of offset curve in 2D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theBaseD4 fourth derivative on a base curve
* \param[in] theOffset size of offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
* \param[out] theResD3 third derivative on offset curve
*/
Standard_EXPORT void D3(const gp_Pnt2d& theBasePoint,
const gp_Vec2d& theBaseD1,
const gp_Vec2d& theBaseD2,
const gp_Vec2d& theBaseD3,
const gp_Vec2d& theBaseD4,
Standard_Real theOffset,
Standard_Boolean theIsDirectionChange,
gp_Pnt2d& theResPoint,
gp_Vec2d& theResD1,
gp_Vec2d& theResD2,
gp_Vec2d& theResD3);
/** \brief Calculate value and three derivatives of offset curve in 3D
* \param[in] theBasePoint point on a base curve
* \param[in] theBaseD1 first derivative on a base curve
* \param[in] theBaseD2 second derivative on a base curve
* \param[in] theBaseD3 third derivative on a base curve
* \param[in] theBaseD4 fourth derivative on a base curve
* \param[in] theOffsetDirection direction of the offset
* \param[in] theOffsetValue length of the offset
* \param[in] theIsDirectionChange shows that it is necessary to consider the direction of derivative
* \param[out] theResPoint point on offset curve
* \param[out] theResD1 first derivative on offset curve
* \param[out] theResD2 second derivative on offset curve
* \param[out] theResD3 third derivative on offset curve
*/
Standard_EXPORT void D3(const gp_Pnt& theBasePoint,
const gp_Vec& theBaseD1,
const gp_Vec& theBaseD2,
const gp_Vec& theBaseD3,
const gp_Vec& theBaseD4,
const gp_Dir& theOffsetDirection,
Standard_Real theOffsetValue,
Standard_Boolean theIsDirectionChange,
gp_Pnt& theResPoint,
gp_Vec& theResD1,
gp_Vec& theResD2,
gp_Vec& theResD3);
}
#endif // _CSLib_Offset_Headerfile

2
src/CSLib/FILES Normal file
View File

@ -0,0 +1,2 @@
CSLib_Offset.hxx
CSLib_Offset.cxx

View File

@ -146,6 +146,34 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
IntExtIsDone = IntExtIsDone || mydone;
}
mydone = IntExtIsDone;
// Additional checking if the point is on the first or last point of the curve and does not added yet
if (mydist1 < Precision::SquareConfusion() || mydist2 < Precision::SquareConfusion())
{
Standard_Boolean isFirstAdded = Standard_False;
Standard_Boolean isLastAdded = Standard_False;
Standard_Integer aNbPoints = mypoint.Length();
for (i = 1; i <= aNbPoints; i++)
{
U = mypoint.Value(i).Parameter();
if (Abs(U - myuinf) < mytolu)
isFirstAdded = Standard_True;
else if (Abs(myusup - U) < mytolu)
isLastAdded = Standard_True;
}
if (!isFirstAdded && mydist1 < Precision::SquareConfusion())
{
mySqDist.Prepend(mydist1);
myismin.Prepend(Standard_True);
mypoint.Prepend(ThePOnC(myuinf, Pf));
}
if (!isLastAdded && mydist2 < Precision::SquareConfusion())
{
mySqDist.Append(mydist2);
myismin.Append(Standard_True);
mypoint.Append(ThePOnC(myusup, Pl));
}
}
return;
}
}

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''')

View File

@ -124,8 +124,7 @@ uses Array1OfInteger from TColStd,
Vec2d from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom2d,
Shape from GeomAbs,
Mutex from Standard
Shape from GeomAbs
raises ConstructionError from Standard,
DimensionError from Standard,
@ -642,17 +641,6 @@ is
-- 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 :
-- Returns the global continuity of the curve :
@ -843,6 +831,11 @@ 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;
---C++ : return const &
is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
@ -854,6 +847,15 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of K is not equal to NbPoles + Degree + 1
KnotSequence (me)
returns Array1OfReal from TColStd
---Purpose : Returns the knots sequence.
-- In this sequence the knots with a multiplicity greater than 1
-- are repeated.
-- Example :
-- K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
---C++ : return const &
is static;
@ -919,6 +921,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;
@ -942,6 +949,11 @@ is
raises DimensionError;
--- Purpose :
-- Raised if the length of P is not equal to the number of poles.
Poles (me)
returns Array1OfPnt2d from TColgp
---Purpose : Returns the poles of the B-spline curve;
---C++ : return const &
is static;
StartPoint (me) returns Pnt2d;
@ -963,6 +975,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;
@ -996,17 +1013,8 @@ is
UpdateKnots(me : mutable)
---Purpose: Recompute the flatknots, the knotsdistribution, the continuity.
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 ; Parameter : Real)
is static private;
---Purpose : updates the cache and validates it
fields
rational : Boolean;
@ -1019,35 +1027,7 @@ fields
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
cachepoles : HArray1OfPnt2d 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 - refcache) * normcache
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

@ -123,12 +123,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
{
// check
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
// copy arrays
@ -142,10 +141,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@ -169,11 +164,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
// check
CheckCurveData (Poles,
Knots,
Mults,
Degree,
Periodic);
CheckCurveData(Poles,
Knots,
Mults,
Degree,
Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch");
@ -192,11 +187,9 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
poles = new TColgp_HArray1OfPnt2d(1,Poles.Length());
poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt2d(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());
@ -206,10 +199,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults;
UpdateKnots();
parametercache = 0.0e0 ;
spanlenghtcache = 0.0e0 ;
spanindexcache = 0 ;
}
//=======================================================================
@ -1090,7 +1079,6 @@ void Geom2d_BSplineCurve::SetPole
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch");
poles->SetValue (Index, P);
maxderivinvok = 0;
InvalidateCache();
}
//=======================================================================
@ -1140,7 +1128,6 @@ void Geom2d_BSplineCurve::SetWeight
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
@ -1149,11 +1136,11 @@ void Geom2d_BSplineCurve::SetWeight
//=======================================================================
void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt2d& P,
const Standard_Integer Index1,
const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole)
const gp_Pnt2d& 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) {
@ -1164,12 +1151,11 @@ void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0);
gp_Vec2d 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() ;
}
}
@ -1222,7 +1208,6 @@ MovePointAndTangent(const Standard_Real U,
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
InvalidateCache() ;
}
}
@ -1266,33 +1251,6 @@ void Geom2d_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break;
}
}
InvalidateCache() ;
}
//=======================================================================
//function : Invalidate the Cache
//purpose : as the name says
//=======================================================================
void Geom2d_BSplineCurve::InvalidateCache()
{
validcache = 0 ;
}
//=======================================================================
//function : check if the Cache is valid
//purpose : as the name says
//=======================================================================
Standard_Boolean Geom2d_BSplineCurve::IsCacheValid
(const Standard_Real U) const
{
//Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
Standard_Real aDelta = U - parametercache;
return ( validcache &&
(aDelta >= 0.0e0) &&
((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) );
}
//=======================================================================
@ -1315,83 +1273,3 @@ void Geom2d_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const
}
}
//=======================================================================
//function : Validate the Cache
//purpose : that is compute the cache so that it is valid
//=======================================================================
void Geom2d_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_HArray1OfPnt2d(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,7 @@
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_Mutex.hxx>
#include <Precision.hxx>
#define POLES (poles->Array1())
#define KNOTS (knots->Array1())
@ -183,36 +183,28 @@ Standard_Integer Geom2d_BSplineCurve::Degree () const
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
gp_Pnt2d& P) const
void Geom2d_BSplineCurve::D0(const Standard_Real U,
gp_Pnt2d& P) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_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(),
P) ;
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
weights->Array1(),
knots->Array1(), mults->Array1(),
P);
}
else {
BSplCLib::CacheD0(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P) ;
else
{
BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P);
}
}
@ -222,39 +214,29 @@ void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D1 (const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1) const
void Geom2d_BSplineCurve::D1(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_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 {
BSplCLib::CacheD1(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P,
V1) ;
else
{
BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1);
}
}
@ -263,42 +245,30 @@ void Geom2d_BSplineCurve::D1 (const Standard_Real U,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
gp_Pnt2d& P ,
gp_Vec2d& V1,
gp_Vec2d& V2 ) const
void Geom2d_BSplineCurve::D2(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1,
gp_Vec2d& V2) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_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()),
BSplCLib::NoWeights(),
P,
V1,
V2) ;
else
{
BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2);
}
}
@ -307,45 +277,31 @@ void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
//purpose :
//=======================================================================
void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
gp_Pnt2d& P ,
gp_Vec2d& V1,
gp_Vec2d& V2,
gp_Vec2d& V3 ) const
void Geom2d_BSplineCurve::D3(const Standard_Real U,
gp_Pnt2d& P,
gp_Vec2d& V1,
gp_Vec2d& V2,
gp_Vec2d& V3) const
{
Standard_Real NewU(U);
PeriodicNormalization(NewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_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 {
BSplCLib::CacheD3(NewU,
deg,
parametercache,
spanlenghtcache,
(cachepoles->Array1()),
BSplCLib::NoWeights(),
P,
V1,
V2,
V3) ;
else
{
BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P, V1, V2, V3);
}
}
@ -354,20 +310,20 @@ void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
//purpose :
//=======================================================================
gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U,
const Standard_Integer N ) const
gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N) const
{
gp_Vec2d V;
if ( rational ) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(),
FKNOTS,FMULTS,V);
weights->Array1(),
FKNOTS,FMULTS,V);
}
else {
else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
*((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V);
}
return V;
}
@ -440,6 +396,11 @@ void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1();
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const
{
return knots->Array1();
}
//=======================================================================
//function : KnotSequence
//purpose :
@ -452,6 +413,11 @@ void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1();
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//=======================================================================
//function : LastUKnotIndex
//purpose :
@ -676,6 +642,11 @@ void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1();
}
const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//=======================================================================
//function : NbKnots
//purpose :
@ -716,6 +687,11 @@ void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
P = poles->Array1();
}
const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const
{
return poles->Array1();
}
//=======================================================================
//function : StartPoint
//purpose :
@ -764,6 +740,13 @@ void Geom2d_BSplineCurve::Weights
}
}
const TColStd_Array1OfReal& Geom2d_BSplineCurve::Weights() const
{
if (IsRational())
return weights->Array1();
return BSplCLib::NoWeights();
}
//=======================================================================
//function : IsRational
//purpose :
@ -786,7 +769,6 @@ void Geom2d_BSplineCurve::Transform
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
InvalidateCache();
// maxderivinvok = 0;
}

View File

@ -23,6 +23,7 @@
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_Line.hxx>
@ -54,6 +55,14 @@ static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
static gp_Vec2d 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(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
//=======================================================================
//function : Copy
//purpose :
@ -211,163 +220,38 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP ) const
void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP) const
{
const Standard_Real aTol = gp::Resolution();
Vec2d vD1;
basisCurve->D1 (theU, theP, vD1);
Standard_Real Ndu = vD1.Magnitude();
if(Ndu <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
Standard_Boolean IsDirectionChange = Standard_False;
if(vD1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1);
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
Vec2d 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;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
Standard_Real aDirFactor = V.Dot(V1);
if(aDirFactor < 0.0)
vD1 = -V;
else
vD1 = V;
Ndu = vD1.Magnitude();
}//if(Ndu <= aTol)
if (Ndu <= aTol)
Geom2d_UndefinedValue::Raise("Exception: Undefined normal vector "
"because tangent vector has zero-magnitude!");
Standard_Real A = vD1.Y();
Standard_Real B = - vD1.X();
A = A * offsetValue/Ndu;
B = B * offsetValue/Ndu;
theP.SetCoord(theP.X() + A, theP.Y() + B);
}
CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) const
{
void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
const Standard_Real aTol = gp::Resolution();
Vec2d V2;
basisCurve->D2 (theU, P, theV1, V2);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
basisCurve->D2 (theU, theP, theV1, V2);
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
Vec2d 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;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d 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);
}
}//if(theV1.Magnitude() <= aTol)
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2);
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
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()) Geom2d_UndefinedDerivative::Raise();
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(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 (Vec2d(DNdir));
}
D0(theU, P);
CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1);
}
//=======================================================================
@ -376,8 +260,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) c
//=======================================================================
void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
Pnt2d& P,
Vec2d& theV1, Vec2d& V2) const
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
@ -388,124 +272,13 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
Vec2d V3;
basisCurve->D3 (theU, P, theV1, V2, V3);
const Standard_Real aTol = gp::Resolution();
basisCurve->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3);
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
Vec2d 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;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d 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);
}
}//if(V1.Magnitude() <= aTol)
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
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())
{
Geom2d_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 (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(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 (Vec2d(D2Ndir));
// V1 = P' (U)
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec2d(DNdir));
}
//P (U) :
D0(theU, P);
CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2);
}
@ -515,9 +288,9 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
//=======================================================================
void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
Pnt2d& P,
Vec2d& theV1, Vec2d& V2, Vec2d& V3) const {
Pnt2d& theP,
Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
@ -532,149 +305,16 @@ void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
// (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);
basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec2d V4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4);
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
Vec2d 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;
Pnt2d P1, P2;
basisCurve->D0(Min(theU, u),P1);
basisCurve->D0(Max(theU, u),P2);
Vec2d 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)
XY Ndir (theV1.Y(), -theV1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
XY D3Ndir (V4.Y(), -V4.X());
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())
{
//We try another computation but the stability is not very good
//dixit ISG.
if (R6 <= gp::Resolution())
Geom2d_UndefinedDerivative::Raise();
// V3 = P"' (U) :
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R2));
D3Ndir.Subtract (
(DNdir.Multiplied ((3.0 * offsetValue) * ((D2r/R2) + (Dr*Dr)/R4))));
D3Ndir.Add (Ndir.Multiplied (
(offsetValue * (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 (Vec2d(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 (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
theV1.Add (Vec2d(DNdir));
}
else
{
// Same computation as IICURV in EUCLID-IS because the stability is
// better.
// V3 = P"' (U) :
D3Ndir.Multiply (offsetValue/R);
D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R3));
D3Ndir.Subtract (DNdir.Multiplied (
((3.0 * offsetValue) * ((D2r/R3) + (Dr*Dr)/R5))) );
D3Ndir.Add (Ndir.Multiplied (
(offsetValue * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))));
if(IsDirectionChange)
V3=-V3;
V3.Add (Vec2d(D3Ndir));
// V2 = P" (U) :
D2Ndir.Multiply (offsetValue/R);
D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
D2Ndir.Subtract (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
theV1.Add (Vec2d(DNdir));
}
//P (U) :
D0(theU, P);
}
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange,
theP, theV1, theV2, theV3);
}
//=======================================================================
//function : DN
@ -709,10 +349,10 @@ Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1."
void Geom2d_OffsetCurve::Value (const Standard_Real theU,
Pnt2d& theP, Pnt2d& thePbasis,
Vec2d& theV1basis ) const
{
{
basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP);
}
}
//=======================================================================
@ -741,30 +381,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real U,
if (Index != 2) {
V2 = basisCurve->DN (U, Index);
}
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X());
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()) { Geom2d_UndefinedDerivative::Raise(); }
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue / R2);
V1.Add (Vec2d(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));
V1.Add (Vec2d(DNdir));
}
Ndir.Multiply (offsetValue/R);
Ndir.Add (Pbasis.XY());
P.SetXY (Ndir);
CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1);
}
@ -800,52 +418,8 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real U,
V2 = basisCurve->DN (U, Index);
V3 = basisCurve->DN (U, Index + 1);
}
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X());
XY D2Ndir (V3.Y(), -V3.X());
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()) { Geom2d_UndefinedDerivative::Raise(); }
// 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 (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply(R);
DNdir.Subtract (Ndir.Multiplied (Dr/R));
DNdir.Multiply (offsetValue/R2);
V1.Add (Vec2d(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.Subtract (Ndir.Multiplied (
offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
)
);
V2.Add (Vec2d(D2Ndir));
// V1 = P' (U) :
DNdir.Multiply (offsetValue/R);
DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
V1.Add (Vec2d(DNdir));
}
//P (U) :
Ndir.Multiply (offsetValue/R);
Ndir.Add (Pbasis.XY());
P.SetXY (Ndir);
CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2);
}
//=======================================================================
@ -961,3 +535,57 @@ GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const
{
return myBasisCurveContinuity;
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2,
gp_Vec2d& theD3, gp_Vec2d& 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
Vec2d 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;
Pnt2d P1, P2;
theCurve->D0(Min(theU, u),P1);
theCurve->D0(Max(theU, u),P2);
Vec2d V1(P1,P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec2d* 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

@ -27,7 +27,8 @@ uses
gp,
Standard,
TColStd,
TColgp
TColgp,
BSplCLib
is

View File

@ -33,7 +33,8 @@ uses Vec2d from gp,
BSplineCurve from Geom2d,
CurveType from GeomAbs,
Shape from GeomAbs,
HCurve2d from Adaptor2d
HCurve2d from Adaptor2d,
Cache from BSplCLib
raises NoSuchObject from Standard,
@ -123,19 +124,44 @@ is
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
ValueBSpline(me; U: Real) returns Pnt2d from gp
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
ValueOffset(me; U: Real) returns Pnt2d from gp
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D0 (me; U : Real; P : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
D0BSpline(me; theU : Real; theP : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
D0Offset(me; theU : Real; theP : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D1 (me; U : Real; P : out Pnt2d from gp ; V : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the curve with its
-- first derivative.
raises
DomainError from Standard
--- Purpose : Raised if the continuity of the current interval
-- is not C1.
is redefined static;
D1BSpline(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its derivative
is private;
D1Offset(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its derivative
is private;
D2 (me; U : Real; P : out Pnt2d from gp; V1, V2 : out Vec2d from gp)
--- Purpose :
@ -147,6 +173,16 @@ is
-- is not C2.
is redefined static;
D2BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first and second derivatives
is private;
D2Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first and second derivatives
is private;
D3 (me; U : Real; P : out Pnt2d from gp; V1, V2, V3 : out Vec2d from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
@ -156,6 +192,16 @@ is
--- Purpose : Raised if the continuity of the current interval
-- is not C3.
is redefined static;
D3BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first, second and third derivatives
is private;
D3Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first, second and third derivatives
is private;
DN (me; U : Real; N : Integer) returns Vec2d from gp
--- Purpose :
@ -169,6 +215,18 @@ is
--- Purpose : Raised if N < 1.
is redefined static;
DNBSpline(me; theU : Real; N : Integer) returns Vec2d from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
DNOffset(me; theU : Real; N : Integer) returns Vec2d from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
Resolution(me; Ruv :Real) returns Real
---Purpose : returns the parametric resolution
@ -243,6 +301,11 @@ is
load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real)
is private;
RebuildCache(me; theParameter : Real)
---Purpose: Rebuilds B-spline cache
-- \param theParameter the value on the knot axis which identifies the caching span
is static private;
fields
@ -250,6 +313,8 @@ fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve2d from Adaptor2d;
end Curve;

View File

@ -26,6 +26,7 @@
#include <Geom2dAdaptor_HCurve.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
@ -42,6 +43,9 @@
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <CSLib_Offset.hxx>
//#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
#include <Standard_OutOfRange.hxx>
@ -52,6 +56,17 @@
#define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
// Recalculate derivatives in the singular point
// Returns true is the direction of derivatives is changed
static Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
@ -197,6 +212,16 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C,
}
else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
// Create cache for B-spline
myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
{
myTypeCurve = GeomAbs_OtherCurve;
// Create nested adaptor for base curve
Handle(Geom2d_Curve) aBase = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve();
myOffsetBaseCurveAdaptor = new Geom2dAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
@ -218,7 +243,7 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
if (myTypeCurve == GeomAbs_BSplineCurve) {
return LocalContinuity(myFirst, myLast);
}
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape S =
(*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity();
switch(S){
@ -330,7 +355,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
}
}
}
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
@ -342,9 +367,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
Geom2dAdaptor_Curve C
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
myNbIntervals = C.NbIntervals(BaseS);
myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
}
return myNbIntervals;
@ -447,7 +470,7 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
}
}
}
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
@ -459,10 +482,8 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
Geom2dAdaptor_Curve C
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
myNbIntervals = C.NbIntervals(BaseS);
C.Intervals(T, BaseS);
myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
myOffsetBaseCurveAdaptor->Intervals(T, BaseS);
}
T( T.Lower() ) = myFirst;
@ -525,6 +546,17 @@ Standard_Real Geom2dAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
{
myCurveCache->BuildCache(theParameter, myBspl->Degree(),
myBspl->IsPeriodic(), myBspl->KnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@ -532,24 +564,65 @@ Standard_Real Geom2dAdaptor_Curve::Period() const
gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
return ValueBSpline(U);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
return ValueOffset(U);
return myCurve->Value(U);
}
//=======================================================================
//function : ValueBSpline
//purpose : Computes the point of parameter U on the B-spline curve
//=======================================================================
gp_Pnt2d Geom2dAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst)
{
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast)
{
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalValue(U, Ideb, Ifin);
return myBspl->LocalValue(theU, Ideb, Ifin);
}
else {
return myCurve->Value( U);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
gp_Pnt2d aRes;
myCurveCache->D0(theU, aRes);
return aRes;
}
return myCurve->Value(theU);
}
//=======================================================================
//function : ValueOffset
//purpose : Computes the point of parameter U on the offset curve
//=======================================================================
gp_Pnt2d Geom2dAdaptor_Curve::ValueOffset(const Standard_Real theU) const
{
gp_Pnt2d aP;
gp_Vec2d aD1;
myOffsetBaseCurveAdaptor->D1(theU, aP, aD1);
Standard_Boolean isDirectionChange = Standard_False;
const Standard_Real aTol = gp::Resolution();
if(aD1.SquareMagnitude() <= aTol)
isDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aD1);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D0(aP, aD1, anOffset, isDirectionChange, aP);
return aP;
}
//=======================================================================
@ -559,24 +632,59 @@ gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D0BSpline(U, P);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D0Offset(U, P);
return;
}
myCurve->D0(U, P);
}
//=======================================================================
//function : D0BSpline
//purpose : Computes the point of parameter theU on the B-spline curve
//=======================================================================
void Geom2dAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt2d& theP) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD0( U, Ideb, Ifin, P);
myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
}
else {
myCurve->D0(U, P);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D0(theU, theP);
return;
}
myCurve->D0(theU, theP);
}
//=======================================================================
//function : D0Offset
//purpose : Computes the point of parameter theU on the offset curve
//=======================================================================
void Geom2dAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt2d& theP) const
{
theP = ValueOffset(theU);
}
//=======================================================================
@ -584,27 +692,75 @@ void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
//purpose :
//=======================================================================
void Geom2dAdaptor_Curve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V) const
void Geom2dAdaptor_Curve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D1BSpline(U, P, V);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D1Offset(U, P, V);
return;
}
myCurve->D1(U, P, V);
}
//=======================================================================
//function : D1BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its derivative
//=======================================================================
void Geom2dAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD1( U, Ideb, Ifin, P, V);
}
else {
myCurve->D1( U, P, V);
myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
return;
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D1(theU, theP, theV);
return;
}
myCurve->D1(theU, theP, theV);
}
//=======================================================================
//function : D1Offset
//purpose : Computes the point of parameter theU on the offset curve and its derivative
//=======================================================================
void Geom2dAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
gp_Vec2d V2;
myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, V2);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, V2);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D1(theP, theV, V2, anOffset, IsDirectionChange, theP, theV);
}
//=======================================================================
@ -613,26 +769,78 @@ void Geom2dAdaptor_Curve::D1(const Standard_Real U,
//=======================================================================
void Geom2dAdaptor_Curve::D2(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D2BSpline(U, P, V1, V2);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D2Offset(U, P, V1, V2);
return;
}
myCurve->D2(U, P, V1, V2);
}
//=======================================================================
//function : D2BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its first and second derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
}
else {
myCurve->D2( U, P, V1, V2);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D2(theU, theP, theV1, theV2);
return;
}
myCurve->D2(theU, theP, theV1, theV2);
}
//=======================================================================
//function : D2Offset
//purpose : Computes the point of parameter theU on the offset curve and its first and second derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
gp_Vec2d V3;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D2(theP, theV1, theV2, V3, anOffset, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
@ -641,27 +849,86 @@ void Geom2dAdaptor_Curve::D2(const Standard_Real U,
//=======================================================================
void Geom2dAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V3) const
gp_Pnt2d& P, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V3) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
{
D3BSpline(U, P, V1, V2, V3);
return;
}
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
{
D3Offset(U, P, V1, V2, V3);
return;
}
myCurve->D3(U, P, V1, V2, V3);
}
//=======================================================================
//function : D3BSpline
//purpose : Computes the point of parameter theU on the B-spline curve and its 1st - 3rd derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D3BSpline(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
return;
}
else {
myCurve->D3( U, P, V1, V2, V3);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D3(theU, theP, theV1, theV2, theV3);
return;
}
myCurve->D3(theU, theP, theV1, theV2, theV3);
}
//=======================================================================
//function : D3Offset
//purpose : Computes the point of parameter theU on the offset curve and its 1st - 3rd derivatives
//=======================================================================
void Geom2dAdaptor_Curve::D3Offset(const Standard_Real theU, gp_Pnt2d& theP,
gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
//P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
// (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
Standard_Boolean IsDirectionChange = Standard_False;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
gp_Vec2d V4 = myOffsetBaseCurveAdaptor->DN (theU, 4);
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffset, IsDirectionChange,
theP, theV1, theV2, theV3);
}
//=======================================================================
@ -670,10 +937,21 @@ void Geom2dAdaptor_Curve::D3(const Standard_Real U,
//=======================================================================
gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const
const Standard_Integer N) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
return DNBSpline(U, N);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
return DNOffset(U, N);
return myCurve->DN(U, N);
}
gp_Vec2d Geom2dAdaptor_Curve::DNBSpline(const Standard_Real U,
const Standard_Integer N) const
{
if (U==myFirst || U==myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
@ -686,10 +964,32 @@ gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
}
else {
return myCurve->DN( U, N);
}
return myCurve->DN( U, N);
}
gp_Vec2d Geom2dAdaptor_Curve::DNOffset(const Standard_Real U,
const Standard_Integer N) const
{
gp_Pnt2d aPnt;
gp_Vec2d aVec, aVN;
switch (N)
{
case 1:
D1Offset(U, aPnt, aVN);
break;
case 2:
D2Offset(U, aPnt, aVec, aVN);
break;
case 3:
D3Offset(U, aPnt, aVec, aVec, aVN);
break;
default:
aVN = myCurve->DN(U, N);
}
return aVN;
}
//=======================================================================
@ -906,3 +1206,57 @@ Standard_Integer Geom2dAdaptor_Curve::NbSamples() const
{
return nbPoints(myCurve);
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative,
Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2,
gp_Vec2d& theD3, gp_Vec2d& theD4)
{
static const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False;
const Standard_Real anUinfium = theAdaptor->FirstParameter();
const Standard_Real anUsupremum = theAdaptor->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_Vec2d V;
do
{
V = theAdaptor->DN(theU, ++anIndex);
}
while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
Standard_Real u;
if(theU-anUinfium < aDelta)
u = theU+aDelta;
else
u = theU-aDelta;
gp_Pnt2d P1, P2;
theAdaptor->D0(Min(theU, u),P1);
theAdaptor->D0(Max(theU, u),P2);
gp_Vec2d V1(P1, P2);
IsDirectionChange = V.Dot(V1) < 0.0;
Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0;
theD1 = V * aSign;
gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4};
for (Standard_Integer i = 1; i < theMaxDerivative; i++)
*(aDeriv[i-1]) = theAdaptor->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@ -28,7 +28,9 @@ uses
TColStd,
Geom2dAdaptor,
TColgp,
Precision
Precision,
BSplCLib,
BSplSLib
is
class Curve;

View File

@ -33,7 +33,8 @@ uses Vec from gp,
BSplineCurve from Geom,
CurveType from GeomAbs,
Shape from GeomAbs,
HCurve from Adaptor3d
HCurve from Adaptor3d,
Cache from BSplCLib
raises NoSuchObject from Standard,
ConstructionError from Standard,
@ -129,10 +130,26 @@ is
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
ValueBSpline(me; U: Real) returns Pnt from gp
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
ValueOffset(me; U: Real) returns Pnt from gp
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D0 (me; U : Real; P : out Pnt from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
D0BSpline(me; theU : Real; theP : out Pnt from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
is private;
D0Offset(me; theU : Real; theP : out Pnt from gp)
--- Purpose : Computes the point of parameter U on the offset curve
is private;
D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp)
--- Purpose : Computes the point of parameter U on the curve
-- with its first derivative.
@ -142,6 +159,16 @@ is
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
D1BSpline(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its derivative
is private;
D1Offset(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its derivative
is private;
D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp)
--- Purpose :
@ -154,6 +181,16 @@ is
-- else the derivatives are computed on the basis curve.
is redefined static;
D2BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first and second derivatives
is private;
D2Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first and second derivatives
is private;
D3 (me; U : Real; P : out Pnt from gp; V1, V2, V3 : out Vec from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
@ -164,6 +201,16 @@ is
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
D3BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the B-spline curve
-- and its first, second and third derivatives
is private;
D3Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
--- Purpose : Computes the point of parameter U on the offset curve
-- and its first, second and third derivatives
is private;
DN (me; U : Real; N : Integer) returns Vec from gp
--- Purpose :
@ -179,6 +226,19 @@ is
is redefined static;
DNBSpline(me; theU : Real; N : Integer) returns Vec from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
DNOffset(me; theU : Real; N : Integer) returns Vec from gp
--- Purpose :
-- The returned vector gives the value of the derivative for the
-- order of derivation N.
is private;
Resolution(me; R3d :Real) returns Real
---Purpose : returns the parametric resolution
is redefined static;
@ -279,6 +339,11 @@ is
load(me : in out; C : Curve from Geom; UFirst,ULast : Real)
is private;
RebuildCache(me; theParameter : Real)
---Purpose: Rebuilds B-spline cache
-- \param theParameter the value on the knot axis which identifies the caching span
is static private;
fields
@ -286,6 +351,8 @@ fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve from Adaptor3d;
friends
class Surface from GeomAdaptor

View File

@ -26,6 +26,7 @@
#include <GeomAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
@ -48,10 +49,22 @@
#include <Standard_NullObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Geom_OffsetCurve.hxx>
#include <CSLib_Offset.hxx>
#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
static const int maxDerivOrder = 3;
static const Standard_Real MinStep = 1e-7;
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(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1,
gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative);
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
@ -155,6 +168,15 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C,
}
else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
// Create cache for B-spline
myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
myTypeCurve = GeomAbs_OtherCurve;
// Create nested adaptor for base curve
Handle(Geom_Curve) aBase = Handle(Geom_OffsetCurve)::DownCast(myCurve)->BasisCurve();
myOffsetBaseCurveAdaptor = new GeomAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
@ -510,6 +532,17 @@ Standard_Real GeomAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
{
myCurveCache->BuildCache(theParameter, myBspl->Degree(),
myBspl->IsPeriodic(), myBspl->KnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@ -517,22 +550,64 @@ Standard_Real GeomAdaptor_Curve::Period() const
gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
return ValueBSpline(U);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
return ValueOffset(U);
return myCurve->Value(U);
}
//=======================================================================
//function : ValueBSpline
//purpose :
//=======================================================================
gp_Pnt GeomAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalValue(U, Ideb, Ifin);
return myBspl->LocalValue(theU, Ideb, Ifin);
}
return myCurve->Value(U);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
gp_Pnt aRes;
myCurveCache->D0(theU, aRes);
return aRes;
}
return myCurve->Value(theU);
}
//=======================================================================
//function : ValueOffset
//purpose :
//=======================================================================
gp_Pnt GeomAdaptor_Curve::ValueOffset(const Standard_Real theU) const
{
gp_Pnt aP;
gp_Vec aV;
myOffsetBaseCurveAdaptor->D1(theU, aP, aV);
Standard_Boolean IsDirectionChange = Standard_False;
if(aV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aV);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D0(aP, aV, anOffsetDir, anOffsetVal, IsDirectionChange, aP);
return aP;
}
//=======================================================================
@ -542,24 +617,53 @@ gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
D0BSpline(U, P);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D0Offset(U, P);
else
myCurve->D0(U, P);
}
//=======================================================================
//function : D0BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt& theP) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD0( U, Ideb, Ifin, P);
myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
}
else {
myCurve->D0(U, P);
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D0(theU, theP);
return;
}
myCurve->D0(theU, theP);
}
//=======================================================================
//function : D0Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt& theP) const
{
theP = ValueOffset(theU);
}
//=======================================================================
@ -569,52 +673,133 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
D1BSpline(U, P, V);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D1Offset(U, P, V);
else
myCurve->D1(U, P, V);
}
//=======================================================================
//function : D1BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD1( U, Ideb, Ifin, P, V);
}
else {
myCurve->D1( U, P, V);
myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
return;
}
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D1(theU, theP, theV);
return;
}
myCurve->D1(theU, theP, theV);
}
//=======================================================================
//function : D1Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
{
gp_Vec aV2;
myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, aV2);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, aV2);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D1(theP, theV, aV2, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV);
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2(const Standard_Real U,
gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
D2BSpline(U, P, V1, V2);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D2Offset(U, P, V1, V2);
else
myCurve->D2(U, P, V1, V2);
}
//=======================================================================
//function : D2BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt& theP,
gp_Vec& theV1, gp_Vec& theV2) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
}
else {
myCurve->D2( U, P, V1, V2);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D2(theU, theP, theV1, theV2);
return;
}
myCurve->D2(theU, theP, theV1, theV2);
}
//=======================================================================
//function : D2Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt& theP,
gp_Vec& theV1, gp_Vec& theV2) const
{
gp_Vec V3;
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D2(theP, theV1, theV2, V3, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
@ -623,27 +808,71 @@ void GeomAdaptor_Curve::D2(const Standard_Real U,
//=======================================================================
void GeomAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt& P, gp_Vec& V1,
gp_Vec& V2, gp_Vec& V3) const
gp_Pnt& P, gp_Vec& V1,
gp_Vec& V2, gp_Vec& V3) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
D3BSpline(U, P, V1, V2, V3);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
D3Offset(U, P, V1, V2, V3);
else
myCurve->D3(U, P, V1, V2, V3);
}
//=======================================================================
//function : D3BSpline
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D3BSpline(const Standard_Real theU,
gp_Pnt& theP, gp_Vec& theV1,
gp_Vec& theV2, gp_Vec& theV3) const
{
if (theU == myFirst || theU == myLast)
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
if (U==myLast) {
if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
return;
}
else {
myCurve->D3( U, P, V1, V2, V3);
else if (!myCurveCache.IsNull()) // use cached B-spline data
{
if (!myCurveCache->IsCacheValid(theU))
RebuildCache(theU);
myCurveCache->D3(theU, theP, theV1, theV2, theV3);
return;
}
myCurve->D3(theU, theP, theV1, theV2, theV3);
}
//=======================================================================
//function : D3Offset
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D3Offset(const Standard_Real theU,
gp_Pnt& theP, gp_Vec& theV1,
gp_Vec& theV2, gp_Vec& theV3) const
{
myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
gp_Vec V4 = myOffsetBaseCurveAdaptor->DN(theU, 4);
Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
Standard_Real anOffsetVal = anOffC->Offset();
const gp_Dir& anOffsetDir = anOffC->Direction();
CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffsetDir, anOffsetVal, IsDirectionChange,
theP, theV1, theV2, theV3);
}
//=======================================================================
@ -652,10 +881,21 @@ void GeomAdaptor_Curve::D3(const Standard_Real U,
//=======================================================================
gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const
const Standard_Integer N) const
{
if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
(U==myFirst || U==myLast) ) {
if (myTypeCurve == GeomAbs_BSplineCurve)
return DNBSpline(U, N);
else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
return DNOffset(U, N);
return myCurve->DN(U, N);
}
gp_Vec GeomAdaptor_Curve::DNBSpline(const Standard_Real U,
const Standard_Integer N) const
{
if ((U==myFirst || U==myLast))
{
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
@ -668,10 +908,31 @@ gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
}
else {
return myCurve->DN( U, N);
}
return myCurve->DN( U, N);
}
gp_Vec GeomAdaptor_Curve::DNOffset(const Standard_Real U,
const Standard_Integer N) const
{
gp_Pnt aPnt;
gp_Vec aVec, aVN;
switch (N)
{
case 1:
D1Offset(U, aPnt, aVN);
break;
case 2:
D2Offset(U, aPnt, aVec, aVN);
break;
case 3:
D3Offset(U, aPnt, aVec, aVec, aVN);
break;
default:
aVN = myCurve->DN(U, N);
}
return aVN;
}
//=======================================================================
@ -857,3 +1118,56 @@ Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const
return *((Handle(Geom_BSplineCurve)*)&myCurve);
}
// ============= Auxiliary functions ===================
Standard_Boolean AdjustDerivative(const Handle(Adaptor3d_HCurve)& theAdaptor, 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 = theAdaptor->FirstParameter();
const Standard_Real anUsupremum = theAdaptor->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 = theAdaptor->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;
theAdaptor->D0(Min(theU, u), P1);
theAdaptor->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]) = theAdaptor->DN(theU, anIndex + i) * aSign;
return IsDirectionChange;
}

View File

@ -38,7 +38,8 @@ uses
Shape from GeomAbs,
Curve from GeomAdaptor,
HCurve from Adaptor3d,
HSurface from Adaptor3d
HSurface from Adaptor3d,
Cache from BSplSLib
raises
NoSuchObject from Standard,
@ -386,6 +387,12 @@ is
TolV : Real = 0.0)
is private;
RebuildCache(me; theU, theV : Real)
---Purpose: Rebuilds B-spline cache
-- \param theU first parameter to identify the span for caching
-- \param theV second parameter to identify the span for caching
is static private;
fields
mySurface : Surface from Geom;
@ -395,5 +402,6 @@ fields
myVFirst : Real from Standard;
myVLast : Real from Standard;
myTolU, myTolV : Real from Standard;
mySurfaceCache : Cache from BSplSLib;
end Surface;

View File

@ -51,6 +51,7 @@
#include <gp_Lin.hxx>
#include <gp_Trsf.hxx>
#include <BSplCLib.hxx>
#include <BSplSLib_Cache.hxx>
#include <Precision.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NullObject.hxx>
@ -131,7 +132,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_BezierSurface;
else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(),
UFirst,ULast,VFirst,VLast);
UFirst,ULast,VFirst,VLast);
}
else if ( TheType == STANDARD_TYPE(Geom_Plane))
mySurfaceType = GeomAbs_Plane;
@ -149,7 +150,12 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_SurfaceOfExtrusion;
else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
mySurfaceType = GeomAbs_BSplineSurface;
myBspl = *((Handle(Geom_BSplineSurface)*)&S);
myBspl = *((Handle(Geom_BSplineSurface)*)&mySurface);
// Create cache for B-spline
mySurfaceCache = new BSplSLib_Cache(
myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
mySurfaceType = GeomAbs_OffsetSurface;
@ -599,6 +605,19 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
return mySurface->VPeriod();
}
//=======================================================================
//function : RebuildCache
//purpose :
//=======================================================================
void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
const Standard_Real theV) const
{
mySurfaceCache->BuildCache(theU, theV,
myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
myBspl->Poles(), myBspl->Weights());
}
//=======================================================================
//function : Value
//purpose :
@ -607,6 +626,15 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
const Standard_Real V) const
{
if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
gp_Pnt P;
mySurfaceCache->D0(U, V, P);
return P;
}
return mySurface->Value(U,V);
}
@ -618,6 +646,14 @@ gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
void GeomAdaptor_Surface::D0(const Standard_Real U,
const Standard_Real V, gp_Pnt& P) const
{
if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D0(U, V, P);
return;
}
mySurface->D0(U,V,P);
}
@ -629,11 +665,11 @@ void GeomAdaptor_Surface::D0(const Standard_Real U,
void GeomAdaptor_Surface::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_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
@ -641,39 +677,42 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType) {
case GeomAbs_BSplineSurface:
{
if((USide==0)&&(VSide==0)){
myBspl->D1(u,v,P,D1U,D1V);
}
else {
if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
myBspl->LocalD1 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V);
else myBspl->D1(u,v,P,D1U,D1V);
}
break;
case GeomAbs_BSplineSurface:
if ((USide != 0 || VSide != 0) &&
IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
else if (!mySurfaceCache.IsNull())
{
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D1(U, V, P, D1U, D1V);
}
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D1(u,v,P,D1U,D1V);
else myExtSurf->LocalD1(u,v,USide,P,D1U,D1V);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D1 (u, v, P,D1U,D1V );
else myRevSurf->LocalD1 (u, v, VSide, P,D1U,D1V );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D1 (u, v,P,D1U,D1V );
else myOffSurf->LocalD1 (u, v, USide, VSide ,P,D1U,D1V );
break;
}
default :
mySurface->D1(u,v,P,D1U,D1V);
else
myBspl->D1(u, v, P, D1U, D1V);
break;
case GeomAbs_SurfaceOfExtrusion:
if (USide==0)
myExtSurf->D1(u, v, P, D1U, D1V);
else
myExtSurf->LocalD1(u, v, USide, P, D1U, D1V);
break;
case GeomAbs_SurfaceOfRevolution:
if (VSide==0)
myRevSurf->D1(u, v, P, D1U, D1V);
else
myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V);
break;
case GeomAbs_OffsetSurface:
if (USide==0 && VSide==0)
myOffSurf->D1(u, v, P, D1U, D1V);
else
myOffSurf->LocalD1(u, v, USide, VSide, P, D1U, D1V);
break;
default:
mySurface->D1(u, v, P, D1U, D1V);
}
}
@ -683,50 +722,56 @@ void GeomAdaptor_Surface::D1(const Standard_Real U,
//=======================================================================
void GeomAdaptor_Surface::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_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType)
switch(mySurfaceType) {
case GeomAbs_BSplineSurface:
if((USide != 0 || VSide != 0) &&
IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
else if (!mySurfaceCache.IsNull())
{
case GeomAbs_BSplineSurface:
if((USide==0)&&(VSide==0)) myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else{
if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
myBspl->LocalD2 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V,D2U,D2V,D2UV);
else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
}
break;
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
break;
}
default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;}
if (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
}
else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfExtrusion :
if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
break;
case GeomAbs_SurfaceOfRevolution :
if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
break;
case GeomAbs_OffsetSurface :
{
if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
break;
}
default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
break;}
}
}

View File

@ -958,13 +958,19 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
BS->EndPoint().XYZ().SquareModulus());
Standard_Real eps = Epsilon(aDist);
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
!BS->IsClosed() && !BS->IsPeriodic())
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
{
//force Closed()
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
BS->SetPole(1, aPm);
BS->SetPole(BS->NbPoles(), aPm);
// Avoid creating B-splines containing two coincident poles only
if (mbspc.Degree() == 1 && nbpoles == 2)
continue;
if (!BS->IsClosed() && !BS->IsPeriodic())
{
//force Closed()
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
BS->SetPole(1, aPm);
BS->SetPole(BS->NbPoles(), aPm);
}
}
sline.Append(BS);

View File

@ -1705,6 +1705,8 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface,
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
if (Abs(ww - 1.0) < EpsW)
ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
@ -1725,6 +1727,8 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface,
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
if (Abs(ww - 1.0) < EpsW)
ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}

View File

@ -679,20 +679,25 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
if( (aPoly1->DeflectionOverEstimation() > TolConf) ||
if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
(aPoly2->DeflectionOverEstimation() > TolConf))
{
const Standard_Real aDeflectionSum =
Max(aPoly1->DeflectionOverEstimation(), TolConf) +
Max(aPoly2->DeflectionOverEstimation(), TolConf);
aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
const Bnd_Box2d aB1 = aPoly1->Bounding(), aB2 = aPoly2->Bounding();
aPoly1->ComputeWithBox(C1, aB2);
aPoly2->ComputeWithBox(C2, aB1);
if (nbsamplesOnC2 > nbsamplesOnC1)
{
aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
}
else
{
aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
}
}
//----------------------------------------------------------------------

View File

@ -569,7 +569,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
Standard_Real rvalf = Sign(1.,Valf(1));
for(Standard_Integer i = 2; i <= aNbSamples; ++i)
{
D1->SamplePoint(i,s2d, s3d);
T->SamplePoint(i,s2d, s3d);
UVap(1)=s2d.X();
UVap(2)=s2d.Y();
Func.Value(UVap,Valf);

View File

@ -1986,37 +1986,20 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
const Standard_Real aTol = 1.0e-14;
Handle(Geom_Surface) aS1, aS2;
switch(theASurf1->GetType())
{
case GeomAbs_BezierSurface:
aS1 = theASurf1->Surface().Bezier();
break;
case GeomAbs_BSplineSurface:
aS1 = theASurf1->Surface().BSpline();
break;
default:
return Standard_True;
}
switch(theASurf2->GetType())
{
case GeomAbs_BezierSurface:
aS2 = theASurf2->Surface().Bezier();
break;
case GeomAbs_BSplineSurface:
aS2 = theASurf2->Surface().BSpline();
break;
default:
return Standard_True;
}
if (theASurf1->GetType() != GeomAbs_BezierSurface &&
theASurf1->GetType() != GeomAbs_BSplineSurface)
return Standard_True;
if (theASurf2->GetType() != GeomAbs_BezierSurface &&
theASurf2->GetType() != GeomAbs_BSplineSurface)
return Standard_True;
Standard_Boolean aStatus = Standard_False;
gp_Pnt aP1, aP2;
gp_Vec aD1u, aD1v, aD2U, aD2V;
aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v);
theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V);
Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
@ -2053,8 +2036,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
gp_Pnt aPt1, aPt2;
aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
@ -2078,8 +2061,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
}
else
{
aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v);
theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V);
gp_Vec aP12(aPt1, aPt2);
aGradFu = -aP12.Dot(aD1u);

View File

@ -122,10 +122,11 @@ Standard_Real ShapeAnalysis_Curve::Project(const Handle(Geom_Curve)& C3D,
Standard_Real uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf);
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end
gp_Pnt LowBound = C3D->Value(uMin);
gp_Pnt HigBound = C3D->Value(uMax);
gp_Pnt LowBound = GAC.Value(uMin);
gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D);
if (distmin <= prec) {
param = uMin;
@ -140,7 +141,6 @@ Standard_Real ShapeAnalysis_Curve::Project(const Handle(Geom_Curve)& C3D,
}
}
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost"
@ -403,10 +403,11 @@ Standard_Real ShapeAnalysis_Curve::NextProject(const Standard_Real paramPrev,
Standard_Real uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf);
Standard_Real distmin = Precision::Infinite();
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end
gp_Pnt LowBound = C3D->Value(uMin);
gp_Pnt HigBound = C3D->Value(uMax);
gp_Pnt LowBound = GAC.Value(uMin);
gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D);
if (distmin <= prec) {
param = uMin;
@ -421,7 +422,6 @@ Standard_Real ShapeAnalysis_Curve::NextProject(const Standard_Real paramPrev,
}
}
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost"
@ -1017,11 +1017,13 @@ Standard_Boolean ShapeAnalysis_Curve::GetSamplePoints (const Handle(Geom_Curve)&
Handle(Geom_TrimmedCurve) aC = Handle(Geom_TrimmedCurve)::DownCast(curve);
return GetSamplePoints(aC->BasisCurve(),first,last,seq);
}
GeomAdaptor_Curve GAC(curve);
Standard_Real step = ( last - first ) / (Standard_Real)( nbp - 1 );
Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step )
seq.Append(curve->Value(par));
seq.Append(curve->Value(last));
seq.Append(GAC.Value(par));
seq.Append(GAC.Value(last));
return Standard_True;
}
//=======================================================================
@ -1043,8 +1045,8 @@ Standard_Boolean ShapeAnalysis_Curve::GetSamplePoints (const Handle(Geom2d_Curve
Standard_Real step = ( last - first ) / (Standard_Real)( nbs - 1 );
Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step )
seq.Append(curve->Value(par));
seq.Append(curve->Value(last));
seq.Append(C.Value(par));
seq.Append(C.Value(last));
return Standard_True;
/*
Standard_Integer i;

View File

@ -1068,7 +1068,7 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu
// from 3d curve (but only if edge is SameParameter)
static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge,
const Handle(ShapeAnalysis_Surface) &surf,
const Handle(Geom2d_Curve) &Crv2d,
const Geom2dAdaptor_Curve &Crv2d,
const Standard_Real param )
{
if ( BRep_Tool::SameParameter ( edge ) ) {
@ -1078,7 +1078,8 @@ static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge,
if ( ! ConS.IsNull() )
return ConS->Value ( param ).Transformed ( L.Transformation() );
}
return surf->Value ( Crv2d->Value ( param ) );
gp_Pnt2d aP2d = Crv2d.Value(param);
return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
}
//=======================================================================
@ -1132,7 +1133,7 @@ Standard_Boolean ShapeAnalysis_Wire::CheckSelfIntersectingEdge (const Standard_I
const IntRes2d_Transition &Tr2 = IP.TransitionOfSecond();
if ( Tr1.PositionOnCurve() != IntRes2d_Middle &&
Tr2.PositionOnCurve() != IntRes2d_Middle ) continue;
gp_Pnt pint = GetPointOnEdge ( edge, mySurf, Crv, IP.ParamOnFirst() );
gp_Pnt pint = GetPointOnEdge ( edge, mySurf, AC, IP.ParamOnFirst() );
Standard_Real dist21 = pnt1.SquareDistance ( pint );
Standard_Real dist22 = pnt2.SquareDistance ( pint );
if ( dist21 > tol1 * tol1 && dist22 > tol2 * tol2 ) {
@ -1222,11 +1223,11 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges (const Standard_Inte
Standard_Real tolint = 1.0e-10;
//szv#4:S4163:12Mar99 warning
IntRes2d_Domain d1 ( Crv1->Value ( a1 ), a1, tolint,
Crv1->Value ( b1 ), b1, tolint );
IntRes2d_Domain d2 ( Crv2->Value ( a2 ), a2, tolint,
Crv2->Value ( b2 ), b2, tolint );
Geom2dAdaptor_Curve C1 ( Crv1 ), C2 ( Crv2 );
IntRes2d_Domain d1 ( C1.Value ( a1 ), a1, tolint,
C1.Value ( b1 ), b1, tolint );
IntRes2d_Domain d2 ( C2.Value ( a2 ), a2, tolint,
C2.Value ( b2 ), b2, tolint );
//:64 abv 25 Dec 97: Attention!
// Since Intersection algorithm is not symmetrical, for consistency with BRepCheck
@ -1282,8 +1283,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges (const Standard_Inte
param2-b2 > ::Precision::PConfusion() ) continue;
//:82 abv 21 Jan 98: point of intersection on Crv1 and Crv2 is different
gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) );
gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) );
gp_Pnt pint = 0.5 * ( pi1.XYZ() + pi2.XYZ() );
Standard_Real di1 = pi1.SquareDistance ( pnt );
Standard_Real di2 = pi2.SquareDistance ( pnt );
@ -1413,8 +1414,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges(const Standard_Integ
Tr2.PositionOnCurve() != IntRes2d_Middle ) continue;
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 );
gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 );
Standard_Boolean OK1 = Standard_False;
Standard_Boolean OK2 = Standard_False;
@ -1494,13 +1495,15 @@ Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num,
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False;
}
c2d->D1 ( b, p2d1, v1 );
Geom2dAdaptor_Curve anAdapt(c2d);
anAdapt.D1(b, p2d1, v1);
if ( E1.Orientation() == TopAbs_REVERSED ) v1.Reverse();
if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) {
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False;
}
c2d->D1 ( a, p2d2, v2 );
anAdapt.Load(c2d);
anAdapt.D1(a, p2d2, v2);
if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse();
v12 = p2d2.XY() - p2d1.XY();
myMax2d = v12.SquareMagnitude();

View File

@ -426,7 +426,7 @@ void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci)
Standard_Real wmid;
sac.Project(COnS,mid,preci,pnt,wmid,Standard_False);
wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period);
if(w1>w2) {
if(w1>=w2) {
if(w2 > wmid) myFirstParam -= period;
else if (w1 > wmid)
UpdateParam2d(theCurve2d);

View File

@ -1281,6 +1281,16 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
found = (staout != clas.Perform (unp1,Standard_False));
}
}
// Additional check of diagonal steps for toroidal surfaces
if (!found && uclosed && vclosed)
{
for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
{
unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY);
found = (staout != clas.Perform(unp1, Standard_False));
}
}
}
if(found) {
if(stb==TopAbs_IN) stb = TopAbs_OUT;

View File

@ -18,6 +18,8 @@
#include <BRepTools.hxx>
#include <Bnd_Box2d.hxx>
#include <BndLib_Add2dCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_BSplineCurve.hxx>
@ -68,7 +70,7 @@ ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReS
//=======================================================================
static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
const Handle(ShapeAnalysis_Surface) &surf,
const Handle(Geom2d_Curve) &Crv2d,
const Geom2dAdaptor_Curve &Crv2d,
const Standard_Real param )
{
if( BRep_Tool::SameParameter(edge) ) {
@ -78,7 +80,8 @@ static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
if( !ConS.IsNull() )
return ConS->Value(param).Transformed(L.Transformation());
}
return surf->Value(Crv2d->Value(param));
gp_Pnt2d aP2d = Crv2d.Value(param);
return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
}
@ -868,9 +871,9 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
Standard_Real tolint = 1.0e-10;
IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
Geom2dInt_GInter Inter;
Inter.Perform( C1, d1, C2, d2, tolint, tolint );
if(!Inter.IsDone()) continue;
@ -883,8 +886,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
Tr2.PositionOnCurve() == IntRes2d_Middle ) {
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
BRep_Builder B;
TopoDS_Vertex V;
Standard_Real tolV=0;
@ -1023,10 +1026,10 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
Standard_Real p12 = IPL.ParamOnFirst();
Standard_Real p22 = IPL.ParamOnSecond();
gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
// next string commented by skl 29.12.2004 for OCC7624
//if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
@ -1155,8 +1158,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
if( !IsModified1 && !IsModified2 ) {
Standard_Real param1 = (p11+p12)/2;
Standard_Real param2 = (p21+p22)/2;
gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
(Pnt10.Z()+Pnt20.Z())/2 );
dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
@ -1516,9 +1519,9 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
continue; //return Standard_False;gka 06.09.04
Standard_Real tolint = 1.0e-10;
IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
Geom2dInt_GInter Inter;
Inter.Perform( C1, d1, C2, d2, tolint, tolint );
if(!Inter.IsDone()) continue;
@ -1532,8 +1535,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
// create new vertex and split both edges
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
BRep_Builder B;
TopoDS_Vertex V;
@ -1597,10 +1600,10 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
Standard_Real p12 = IPL.ParamOnFirst();
Standard_Real p22 = IPL.ParamOnSecond();
gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
// analysis for edge1
TopoDS_Vertex V1 = sae.FirstVertex(edge1);
@ -1888,8 +1891,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires
(Pnt11.Z()+Pnt12.Z())/2 );
Standard_Real param1 = (p11+p12)/2;
Standard_Real param2 = (p21+p22)/2;
gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
Standard_Real tolV = Max(dist1,dist2);

View File

@ -3132,7 +3132,11 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
}
else
FixDummySeam(n1);
{
FixDummySeam(n1);
// The seam edge is removed from the list. So, need to step back to avoid missing of edge processing
i--;
}
i--;
if(!Context().IsNull()) //skl 07.03.2002 for OCC180

View File

@ -421,7 +421,8 @@ void StepToTopoDS_TranslateEdge::MakeFromCurve3D
TP->AddWarning(C3D,"Update of 3D-Parameters has failed");
//:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends
gp_Pnt pU1 = C1->Value ( U1 ), pU2 = C1->Value ( U2 );
GeomAdaptor_Curve aCA(C1);
gp_Pnt pU1 = aCA.Value ( U1 ), pU2 = aCA.Value ( U2 );
temp1 = pU1.Distance ( pv1 );
temp2 = pU2.Distance ( pv2 );
if ( temp1 > preci || temp2 > preci ) {

View File

@ -440,7 +440,8 @@ math_FunctionRoots::math_FunctionRoots(math_FunctionWithDerivative& F,
F.Value(x1,f1); f1-=K;
F.Value(x2,f2); f2-=K;
//-- printf("\n *************** RECHERCHE MINIMUM **********\n");
while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > 0)) {
Standard_Real tolX = 0.001 * NEpsX;
while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > tolX)) {
//-- printf("\n (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) ",
//-- x0,f0,x1,f1,x2,f2,x3,f3);
if(recherche_minimum) {

View File

@ -151,7 +151,7 @@ void math_TrigonometricFunctionRoots::Perform(const Standard_Real A,
InfiniteStatus = Standard_False;
Done = Standard_True;
Eps = 1.e-12;
Eps = 1.5e-12;
Depi = M_PI+M_PI;
if (InfBound <= RealFirst() && SupBound >= RealLast()) {

View File

@ -1,6 +1,5 @@
# Original bug : pro10658
# Date : 24mar98
puts "TODO #26080 ALL: Faulty shapes in variables faulty_1"
puts "TODO ALL Error : The area of the resulting shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b

View File

@ -1,5 +1,4 @@
# pro10658
puts "TODO #26080 ALL: Faulty shapes in variables faulty_1"
puts "TODO ALL Error : The area of the resulting shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b

View File

@ -18,7 +18,10 @@ compound result
repeat 21 {
plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i
bsection s_$i b f_$i
set bsres [bsection s_$i b f_$i]
if { [regexp {Error} $bsres] } {
puts "Error: bsection not done"
}
compound result s_$i result
set dist [expr $i * 100]
puts "OK Section:$dist"

View File

@ -8,7 +8,10 @@ set i 1
repeat 199 {
plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i
bsection s_$i a f_$i
set bsres [bsection s_$i a f_$i]
if { [regexp {Error} $bsres] } {
puts "Error: bsection not done"
}
compound result s_$i result
set dist [expr $i * 100]
puts "OK Section:$dist"

View File

@ -1,7 +1,7 @@
# test script on make volume operation
# cone cylinder plane
puts "TODO OCC26020 ALL: Error: bopcheck failed"
puts "TODO OCC26020 Windows: Error: bopcheck failed"
# planar face
plane pln_f1 27.577164466275352 -1038.2137499999999 27.577164466275359 0.70710678118654746 4.4408920985006262e-016 0.70710678118654768

View File

@ -30,7 +30,7 @@ set distance -0.1
catch { OFFSETSHAPE $distance {} $calcul $type }
set square 253.552
set square 253.902
set nb_v_good 2
set nb_e_good 3

View File

@ -30,7 +30,7 @@ set distance -0.1
catch { OFFSETSHAPE $distance {s_3} $calcul $type }
set square 502.411
set square 502.366
set nb_v_good 3
set nb_e_good 5

View File

@ -30,7 +30,7 @@ set distance -0.1
catch { OFFSETSHAPE $distance {s_2} $calcul $type }
set square 502.411
set square 502.366
set nb_v_good 3
set nb_e_good 5

View File

@ -30,7 +30,7 @@ set distance -0.1
catch { OFFSETSHAPE $distance {s_3 s_2} $calcul $type }
set square 489.812
set square 489.372
set nb_v_good 3
set nb_e_good 5

View File

@ -1,6 +1,6 @@
puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape"
puts "TODO OCC25925 ALL: result is not a topological shape"
puts "TODO OCC25925 ALL: TEST INCOMPLETE"
puts "TODO OCC24862 ALL: Error : Result shape is WRONG"
puts "TODO OCC24862 ALL: Error : The square of result shape is"
puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "============"
puts "OCC5805"

View File

@ -1,7 +1,6 @@
puts "TODO OCC25925 ALL: Tcl Exception: result is not a topological shape!!!"
puts "TODO OCC25925 ALL: ERROR. offsetperform operation not done"
puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape"
puts "TODO OCC25925 ALL: TEST INCOMPLETE"
puts "TODO OCC24862 ALL: Error : Result shape is WRONG"
puts "TODO OCC24862 ALL: Error : The square of result shape is"
puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "============"
puts "OCC5805"

View File

@ -7,8 +7,6 @@ puts ""
## After command sew in DRAW on attached shape free wires are disappeared.
####################################################
puts "TODO OCC25593 ALL: Faulty shapes in variables faulty_1 to faulty_4"
restore [locate_data_file OCC714.brep] a
checkshape a

View File

@ -21,7 +21,7 @@ vertex v2 x y z
distmini d v1 v2
regexp {([-0-9.+eE]+)} [dump d_val] full dist
set checkdist 2.54211497292521e-013
set checkdist 1.13686837721616e-013
if { [expr 1.*abs($checkdist - $dist)/$checkdist] > 0.1 } {
puts "Error : Distance is wrong"

View File

@ -10,12 +10,12 @@ pload QAcommands
set status 0
set info1 [OCC24303 4]
set info1 [OCC24303 5]
regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution
regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance
if { [info exists Sol4] } {
set info2 [dump Sol4]
if { [info exists Sol5] } {
set info2 [dump Sol5]
regexp {Center +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full CenterX CenterY
regexp {XAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full XAxisX XAxisY
regexp {YAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full YAxisX YAxisY

View File

@ -14,7 +14,7 @@ sewing result 0.1 a
checkmaxtol result 0.0076621571738049385
checknbshapes result -shell 1
checkfreebounds result 2
checkfreebounds result 0
set 2dviewer 1

View File

@ -20,15 +20,15 @@ compound vl v1l vnl vol vil result
set nbshapes_expected "
Number of shapes in shape
VERTEX : 169
EDGE : 85
VERTEX : 165
EDGE : 83
WIRE : 0
FACE : 0
SHELL : 0
SOLID : 0
COMPSOLID : 0
COMPOUND : 1
SHAPE : 255
SHAPE : 249
"
checknbshapes result -ref ${nbshapes_expected} -t -m "HLRToShape"

View File

@ -39,9 +39,9 @@ set deltaY [dval dvy1-dvy2]
set deltaZ [dval dvz1-dvz2]
set percent_max 0.1
set good_deltaX 4.4408920985006262e-015
set good_deltaY -4.6629367034256575e-015
set good_deltaZ -2.6645352591003757e-015
set good_deltaX -3.5527136788005009e-015
set good_deltaY -3.5527136788005009e-015
set good_deltaZ 8.8817841970012523e-016
set deltaX_percent [GetPercent ${deltaX} ${good_deltaX}]
puts "deltaX_percent = ${deltaX_percent}"

View File

@ -28,14 +28,14 @@ regexp {deflection +([-0-9.+eE]+)} $tri_info full defl
set env(os_type) $tcl_platform(platform)
if { [string compare $env(os_type) "windows"] != 0 } {
puts "OS = Linux"
set good_tri 520414
set good_nod 263938
set good_defl 0.0026800432954056617
set good_tri 615414
set good_nod 311438
set good_defl 0.0032657364637550075
} else {
puts "OS = Windows NT"
set good_tri 520414
set good_nod 263938
set good_defl 0.0026800432954056617
set good_tri 615414
set good_nod 311438
set good_defl 0.0032657364637550075
}
proc GetPercent {Value GoodValue} {

View File

@ -26,7 +26,7 @@ if [catch { igesbrep $filepath a * } res] {
checkmaxtol result 2.5472812372261969e-005
checknbshapes result -shell 13
checkfreebounds result 1249
checkfreebounds result 1247
}
set 2dviewer 0

View File

@ -1,5 +1,3 @@
puts "TODO OCC12345 ALL: Faulty OCC498: Wrong 3d point from offset surface by parameters"
puts "========="
puts " OCC498 "
puts "========="

View File

@ -25,16 +25,16 @@ set tol_abs 1.0e-05
set tol_rel 0.01
set expected_dmax 0.0013771610718045313
set expected_ufmax 0.890625
set expected_ufmax 0.953125
checkreal "dmax" ${dmax} ${expected_dmax} ${tol_abs} ${tol_rel}
checkreal "ufmax" ${ufmax} ${expected_ufmax} ${tol_abs} ${tol_rel}
set expected_ulmax 0.90625
set expected_ulmax 0.96875
if { ${ulmax} != ${expected_ulmax} } {
puts "Error : bad value of ulmax=${ulmax}"
}
set expected_i 69
set expected_i 73
if { ${i} != ${expected_i} } {
puts "Error : bad value of i=${i}"
}

View File

@ -1,6 +1,4 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: TPSTAT : Faulty"
set filename UKI60095.igs

View File

@ -11,7 +11,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) Summary = 18221 ( 18221 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 8213 ( 8213 )
TOLERANCE : MaxTol = 0.004034169186 ( 0.004034577888 ) AvgTol = 7.709492698e-006 ( 1.210857047e-005 )
LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 929 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1829 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1829 ) LayerLabels = 900 ( 1829 )
LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 930 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1830 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1830 ) LayerLabels = 900 ( 1830 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = YELLOW ( YELLOW )

View File

@ -8,10 +8,10 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 1091 ) Summary = 42 ( 1091 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22098 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10005 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22096 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10004 )
TOLERANCE : MaxTol = 0.5433123154 ( 0.5433122968 ) AvgTol = 0.002230678782 ( 0.002235663837 )
LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1450 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2488 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2488 ) LayerLabels = 1038 ( 2488 )
LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1449 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2487 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2487 ) LayerLabels = 1038 ( 2487 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 2 ( 2 )
COLORS : Colors = GREEN RED ( GREEN RED )

View File

@ -7,9 +7,9 @@ set filename CTS21655.igs
set ref_data {
DATA : Faulties = 0 ( 12 ) Warnings = 0 ( 1 ) Summary = 0 ( 13 )
TPSTAT : Faulties = 0 ( 28 ) Warnings = 116 ( 7 ) Summary = 116 ( 35 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 1 ) Solids = 0 ( 1 )
NBSHAPES : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) Summary = 15092 ( 7703 )
STATSHAPE : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6291 ( 3138 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 1 ) Solids = 0 ( 1 )
NBSHAPES : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) Summary = 15073 ( 7693 )
STATSHAPE : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6283 ( 3134 )
TOLERANCE : MaxTol = 0.2496383637 ( 0.2496258832 ) AvgTol = 0.00219239232 ( 0.004111699336 )
LABELS : N0Labels = 27 ( 27 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 27 ( 27 ) NameLabels = 27 ( 27 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )

View File

@ -1,18 +1,18 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR25923 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: Error : 2 differences with reference data found"
set filename FRA62468-1.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 427 ( 5255 ) Summary = 427 ( 5255 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 299 ( 5226 ) Summary = 299 ( 5226 )
CHECKSHAPE : Wires = 12 ( 20 ) Faces = 16 ( 18 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68354 ( 68418 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29043 ( 29075 )
TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01115315301 ( 0.0111584608 )
LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4437 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9895 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9829 ) LayerLabels = 5391 ( 9829 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68422 ( 68420 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29075 ( 29079 )
TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01114309412 ( 0.01115568387 )
LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4427 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9885 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9819 ) LayerLabels = 5391 ( 9819 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 CYAN1 GREEN ( BLACK BLUE1 CYAN1 GREEN )

View File

@ -1,19 +1,19 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: TPSTAT : Faulty"
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
set LinuxDiff 3
set filename PRO14319.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 2 ( 64 ) Summary = 2 ( 64 )
CHECKSHAPE : Wires = 1 ( 7 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7360 ( 7320 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3632 ( 3603 )
TOLERANCE : MaxTol = 0.3749733839 ( 0.3140268243 ) AvgTol = 0.002809949164 ( 0.0005120147149 )
LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 788 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 849 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 849 ) LayerLabels = 0 ( 0 )
TPSTAT : Faulties = 1 ( 0 ) Warnings = 3 ( 64 ) Summary = 4 ( 64 )
CHECKSHAPE : Wires = 3 ( 5 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7731 ( 7831 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3842 ( 3895 )
TOLERANCE : MaxTol = 0.3140268251 ( 0.3140268243 ) AvgTol = 0.0009762560334 ( 0.000488212708 )
LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 1080 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 1141 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 1141 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = CYAN1 GREEN WHITE ( CYAN1 GREEN WHITE )

View File

@ -1,7 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
set filename 12ls328.igs
set ref_data {

View File

@ -1,5 +1,4 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
set LinuxDiff 1

View File

@ -10,7 +10,7 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 444 ( 1005 ) Summary = 444 ( 1005 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50232 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50230 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) FreeWire = 119 ( 139 ) FreeEdge = 4488 ( 4487 ) SharedEdge = 24679 ( 24678 )
TOLERANCE : MaxTol = 1e-05 ( 0.06099237775 ) AvgTol = 3.184880431e-07 ( 1.621424764e-05 )
LABELS : N0Labels = 432 ( 432 ) N1Labels = 12 ( 845 ) N2Labels = 0 ( 0 ) TotalLabels = 444 ( 1277 ) NameLabels = 432 ( 687 ) ColorLabels = 320 ( 1277 ) LayerLabels = 320 ( 1277 )

View File

@ -1,17 +1,18 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 2
set filename brazo1.igs
set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 148 ( 478 ) Summary = 148 ( 478 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 139 ( 454 ) Summary = 139 ( 454 )
CHECKSHAPE : Wires = 6 ( 8 ) Faces = 6 ( 8 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4666 ( 4542 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2144 ( 2074 )
TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01125801875 ( 0.01225981249 )
LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 242 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 465 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 465 ) LayerLabels = 223 ( 465 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4710 ( 4574 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2166 ( 2092 )
TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01133191355 ( 0.01225911215 )
LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 256 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 479 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 479 ) LayerLabels = 223 ( 479 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 MAGENTA1 YELLOW ( BLUE1 MAGENTA1 YELLOW )

View File

@ -12,7 +12,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) Summary = 12751 ( 12759 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) FreeWire = 36 ( 36 ) FreeEdge = 232 ( 232 ) SharedEdge = 5541 ( 5545 )
TOLERANCE : MaxTol = 0.9845041621 ( 0.9845038147 ) AvgTol = 0.00992720939 ( 0.009919874447 )
LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1770 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2650 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2650 ) LayerLabels = 844 ( 2650 )
LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1784 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2664 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2664 ) LayerLabels = 844 ( 2664 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = BLACK ( BLACK )

View File

@ -7,10 +7,10 @@ set filename ims003.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 38 ( 183 ) Summary = 38 ( 183 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) Summary = 2511 ( 2510 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) FreeWire = 23 ( 23 ) FreeEdge = 331 ( 331 ) SharedEdge = 983 ( 983 )
TOLERANCE : MaxTol = 0.1829958579 ( 0.1829958769 ) AvgTol = 0.003259834421 ( 0.003329232309 )
TOLERANCE : MaxTol = 0.1830141575 ( 0.1830141765 ) AvgTol = 0.003295423033 ( 0.003364815075 )
LABELS : N0Labels = 412 ( 412 ) N1Labels = 2 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 414 ( 412 ) NameLabels = 412 ( 412 ) ColorLabels = 389 ( 410 ) LayerLabels = 389 ( 410 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 5 ( 5 )

View File

@ -1,18 +1,19 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR25923 ALL: STATSHAPE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 5
set filename BUC60743.igs
set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 )
TPSTAT : Faulties = 3 ( 59 ) Warnings = 2205 ( 4736 ) Summary = 2208 ( 4795 )
CHECKSHAPE : Wires = 7 ( 16 ) Faces = 6 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 2837 ) Summary = 45907 ( 39191 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19595 ( 16764 )
TOLERANCE : MaxTol = 3.742696236 ( 5.769095076 ) AvgTol = 0.01636161939 ( 0.01749445935 )
LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6319 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6330 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6319 ) LayerLabels = 2411 ( 5257 )
TPSTAT : Faulties = 3 ( 59 ) Warnings = 2203 ( 4655 ) Summary = 2206 ( 4714 )
CHECKSHAPE : Wires = 7 ( 17 ) Faces = 7 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 2837 ) Summary = 45927 ( 39202 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19607 ( 16774 )
TOLERANCE : MaxTol = 4.854604894 ( 5.769095076 ) AvgTol = 0.01628658326 ( 0.01747356296 )
LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6327 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6338 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6327 ) LayerLabels = 2411 ( 5258 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 RED YELLOW ( BLACK BLUE1 RED YELLOW )

View File

@ -10,10 +10,10 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 56 ( 12 ) Summary = 56 ( 12 )
CHECKSHAPE : Wires = 2 ( 1 ) Faces = 2 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25969 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10687 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25971 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10688 )
TOLERANCE : MaxTol = 0.9711309062 ( 0.9711309063 ) AvgTol = 0.01916076754 ( 0.01948753951 )
LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3205 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3455 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3449 ) LayerLabels = 0 ( 0 )
LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3204 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3454 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3448 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ( CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN )

View File

@ -5,8 +5,8 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 191 ) Summary = 88 ( 191 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7836 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3350 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7833 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3348 )
TOLERANCE : MaxTol = 0.7161069967 ( 0.7585238415 ) AvgTol = 0.006717667602 ( 0.006937200018 )
LABELS : N0Labels = 568 ( 568 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 570 ( 570 ) NameLabels = 568 ( 568 ) ColorLabels = 569 ( 569 ) LayerLabels = 569 ( 569 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )

View File

@ -1,19 +1,20 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR25923 ALL: NBSHAPES : Faulty"
#puts "TODO CR23096 ALL: Error : 1 differences with reference data found :"
puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: Error : 2 differences with reference data found"
set LinuxDiff 1
set filename FRA62468-2.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 349 ( 5016 ) Summary = 349 ( 5016 )
CHECKSHAPE : Wires = 12 ( 19 ) Faces = 12 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63090 ( 63144 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26766 ( 26793 )
TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01154225009 ( 0.01155173987 )
LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3844 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 9009 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8933 ) LayerLabels = 5086 ( 8933 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 253 ( 4993 ) Summary = 253 ( 4993 )
CHECKSHAPE : Wires = 8 ( 11 ) Faces = 8 ( 7 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63158 ( 63146 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26798 ( 26797 )
TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01153089031 ( 0.01154870945 )
LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3834 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 8999 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8923 ) LayerLabels = 5086 ( 8923 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 CYAN1 GREEN ( BLUE1 CYAN1 GREEN )

View File

@ -3,7 +3,7 @@ puts "TODO CR23096 ALL: TPSTAT : Faulty"
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set filename PRO10626.igs
@ -11,8 +11,8 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 2 ( 0 ) Warnings = 85 ( 295 ) Summary = 87 ( 295 )
CHECKSHAPE : Wires = 8 ( 13 ) Faces = 8 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5352 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2221 ( 2228 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5349 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2220 ( 2226 )
TOLERANCE : MaxTol = 4.547932063 ( 4.543567878 ) AvgTol = 0.03466358537 ( 0.03659099671 )
LABELS : N0Labels = 457 ( 457 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 457 ) NameLabels = 457 ( 457 ) ColorLabels = 451 ( 455 ) LayerLabels = 453 ( 457 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )

View File

@ -10,10 +10,10 @@ set ref_data {
DATA : Faulties = 0 ( 1 ) Warnings = 0 ( 0 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 650 ( 1843 ) Summary = 650 ( 1843 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17129 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7869 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17126 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7867 )
TOLERANCE : MaxTol = 1.089725986e-005 ( 1.089659651e-005 ) AvgTol = 1.975835144e-006 ( 9.652818162e-006 )
LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1400 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2093 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2093 ) LayerLabels = 692 ( 2093 )
LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1399 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2092 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2092 ) LayerLabels = 692 ( 2092 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 4 )
COLORS : Colors = CYAN1 WHITE YELLOW ( CYAN1 GREEN3 WHITE YELLOW )

View File

@ -14,7 +14,7 @@ TPSTAT : Faulties = 44 ( 0 ) Warnings = 169 ( 1291 ) Summary = 213 (
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) Summary = 8171 ( 8283 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) FreeWire = 108 ( 108 ) FreeEdge = 606 ( 606 ) SharedEdge = 3685 ( 3689 )
TOLERANCE : MaxTol = 5.750743843e+14 ( 4.784430882e+15 ) AvgTol = 2.722724827e+11 ( 2.206755414e+12 )
TOLERANCE : MaxTol = 2.113937626e+17 ( 2.113937968e+17 ) AvgTol = 9.737589861e+13 ( 9.762248147e+13 )
LABELS : N0Labels = 7 ( 7 ) N1Labels = 450 ( 2042 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 2049 ) NameLabels = 457 ( 698 ) ColorLabels = 450 ( 2043 ) LayerLabels = 449 ( 2042 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 7 ( 7 )

View File

@ -1,5 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: COLORS : Faulty"
puts "TODO CR25013 ALL: Error : 3 differences with reference data found"
@ -12,10 +13,10 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 3 ) Warnings = 274 ( 4465 ) Summary = 274 ( 4468 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39230 ( 39268 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17933 ( 17940 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39231 ( 39275 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17934 ( 17947 )
TOLERANCE : MaxTol = 4.337400808e+088 ( 8.082392835e+086 ) AvgTol = 2.040579288e+085 ( 5.099401401e+083 )
LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9638 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9644 ) NameLabels = 1649 ( 2890 ) ColorLabels = 1645 ( 9643 ) LayerLabels = 489 ( 3997 )
LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9621 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9627 ) NameLabels = 1649 ( 2891 ) ColorLabels = 1645 ( 9626 ) LayerLabels = 489 ( 3997 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 5 )
COLORS : Colors = BLUE1 CYAN1 GOLD3 GREEN ( BLUE1 CYAN1 GOLD3 GREEN YELLOW )

Some files were not shown because too many files have changed in this diff Show More