1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +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 <Standard_NotImplemented.hxx>
#include <Adaptor3d_TopolTool.ixx> #include <Adaptor3d_TopolTool.ixx>
#include <Precision.hxx> #include <Precision.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <gp_Cone.hxx> #include <gp_Cone.hxx>
#include <gp_Pnt.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_Real tol = Max(0.01*aDefl2, 1.e-9);
Standard_Integer l; 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(1) = Standard_True;
anUFlg(nbsu) = Standard_True; anUFlg(nbsu) = Standard_True;
//myNbSamplesU = 2; //myNbSamplesU = 2;
@ -1095,10 +1100,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
} }
t2 = anUPars(j); 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) { for(k = j+2; k <= nbsu; ++k) {
t2 = anUPars(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); //gce_MakeLin MkLin(p1, p2);
//const gp_Lin& lin = MkLin.Value(); //const gp_Lin& lin = MkLin.Value();
@ -1113,7 +1120,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break; 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); Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue; if(d <= aDefl2) continue;
@ -1180,10 +1188,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
} }
t2 = aVPars(j); 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) { for(k = j+2; k <= nbsv; ++k) {
t2 = aVPars(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; if(p1.SquareDistance(p2) <= tol) continue;
//gce_MakeLin MkLin(p1, p2); //gce_MakeLin MkLin(p1, p2);
@ -1197,7 +1207,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl,
break; 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); Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue; if(d <= aDefl2) continue;

View File

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

View File

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

View File

@ -111,7 +111,7 @@ static
static static
Standard_Real IntersectCurves2d(const gp_Pnt& aPV, Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const Handle(Geom_Surface)& aS, const GeomAdaptor_Surface& aS,
const TopoDS_Edge& aE1, const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2); const TopoDS_Edge& aE2);
@ -558,7 +558,7 @@ void CorrectWires(const TopoDS_Face& aFx)
aT=BRep_Tool::Parameter(aV, aE); aT=BRep_Tool::Parameter(aV, aE);
// //
aC2D->D0(aT, aP2D); aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP); aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP); aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) { if (aD2>aD2max) {
aD2max=aD2; aD2max=aD2;
@ -586,7 +586,7 @@ void CorrectWires(const TopoDS_Face& aFx)
continue; continue;
} }
// //
aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1); aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
if (aD2>aD2max) { if (aD2>aD2max) {
aD2max=aD2; aD2max=aD2;
} }
@ -606,7 +606,7 @@ void CorrectWires(const TopoDS_Face& aFx)
//======================================================================= //=======================================================================
Standard_Real IntersectCurves2d(const gp_Pnt& aPV, Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const Handle(Geom_Surface)& aS, const GeomAdaptor_Surface& aGAS,
const TopoDS_Edge& aE1, const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2) const TopoDS_Edge& aE2)
{ {
@ -650,7 +650,7 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
} }
// //
aP2D = aPoint.Value(); aP2D = aPoint.Value();
aS->D0(aP2D.X(), aP2D.Y(), aP); aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD=aPV.SquareDistance(aP); aD=aPV.SquareDistance(aP);
if (aD > aDist) { if (aD > aDist) {
aDist = 1.01 * aD; 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); gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV); aTolV=BRep_Tool::Tolerance(aV);
Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast); GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
aC3D->D0(aT, aPc); aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc); aDist=aPv.Distance(aPc);
if (aDist>aTolV) { if (aDist>aTolV) {
BRep_Builder BB; BRep_Builder BB;
@ -97,8 +97,8 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
gp_Pnt aPv=BRep_Tool::Pnt(aV); gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV); aTolV=BRep_Tool::Tolerance(aV);
Handle(Geom_Curve) aC3D=aC.Curve(); GeomAdaptor_Curve aCA( aC.Curve() );
aC3D->D0(aT, aPc); aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc); aDist=aPv.Distance(aPc);
if (aDist>aTolV) { if (aDist>aTolV) {
BRep_Builder BB; BRep_Builder BB;

View File

@ -108,7 +108,7 @@ inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
} }
static static
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d, void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm, const Standard_Real aPrm,
gp_Pnt2d& Pnt, gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d); gp_Vec2d& aVec2d);
@ -1653,14 +1653,15 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam); C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
if(C2d.IsNull()) if(C2d.IsNull())
continue; continue;
Geom2dAdaptor_Curve aCA(C2d);
aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam; aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
aPnt = C2d->Value(aParam); aPnt = aCA.Value(aParam);
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False)) if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
continue; continue;
CurveDirForParameter(C2d, aParam, aPnt, aDer); CurveDirForParameter(aCA, aParam, aPnt, aDer);
if (aVOrientation == anE.Orientation()) if (aVOrientation == anE.Orientation())
aDer.Reverse(); aDer.Reverse();
@ -1753,21 +1754,21 @@ void ChoixUV(const TopoDS_Vertex& theVertex,
//function : CurveDirForParameter //function : CurveDirForParameter
//purpose : //purpose :
//======================================================================= //=======================================================================
void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d, void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm, const Standard_Real aPrm,
gp_Pnt2d& Pnt, gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d) gp_Vec2d& aVec2d)
{ {
Standard_Real aTol=gp::Resolution(); Standard_Real aTol=gp::Resolution();
Standard_Integer i; Standard_Integer i;
aC2d->D1(aPrm, Pnt, aVec2d); aC2d.D1(aPrm, Pnt, aVec2d);
// //
if (aVec2d.Magnitude() <= aTol) { if (aVec2d.Magnitude() <= aTol) {
for (i = 2; i <= 100; i++){ for (i = 2; i <= 100; i++){
aVec2d = aC2d->DN(aPrm, i); aVec2d = aC2d.DN(aPrm, i);
if (aVec2d.Magnitude() > aTol) { 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. // otherwise preserve only one of its representations.
//---------------------------------------------------------- //----------------------------------------------------------
if (!BRep_Tool::Degenerated(E)) { if (!BRep_Tool::Degenerated(E)) {
Standard_Real aParTol = 2.0 * Precision::PConfusion();
for (Standard_Integer k = 1; k < TheVer.Length(); k ++) { for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) || if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) ||
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= aParTol) {
Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) {
if(k+1 == TheVer.Length()) { if(k+1 == TheVer.Length()) {
StoreInMap(TheVer(k), TheVer(k+1), MapVV); StoreInMap(TheVer(k), TheVer(k+1), MapVV);

View File

@ -26,6 +26,7 @@
#include <GeomAdaptor_HSurface.hxx> #include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_HCurve.hxx> #include <GeomAdaptor_HCurve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomProjLib.hxx> #include <GeomProjLib.hxx>
@ -56,12 +57,12 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
const Standard_Real theFirst, const Standard_Real theFirst,
const Standard_Real theLast) const Standard_Real theLast)
: :
myCurve(theC3D),
myPCurve(theC2D),
mySurf(theSurf),
myFirst(theFirst), myFirst(theFirst),
myLast(theLast) myLast(theLast)
{ {
myCurve = new GeomAdaptor_HCurve(theC3D);
myPCurve = new Geom2dAdaptor_HCurve(theC2D);
mySurf = new GeomAdaptor_HSurface(theSurf);
} }
// //
virtual Standard_Integer NbVariables() const { virtual Standard_Integer NbVariables() const {
@ -160,9 +161,9 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc :
return ((myFirst <= theParam) && (theParam <= myLast)); return ((myFirst <= theParam) && (theParam <= myLast));
} }
Handle(Geom_Curve) myCurve; Handle(GeomAdaptor_HCurve) myCurve;
Handle(Geom2d_Curve) myPCurve; Handle(Geom2dAdaptor_HCurve) myPCurve;
Handle(Geom_Surface) mySurf; Handle(GeomAdaptor_HSurface) mySurf;
Standard_Real myFirst; Standard_Real myFirst;
Standard_Real myLast; 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 cl = C->LastParameter();
Standard_Real epsilon = Precision::PConfusion(); Standard_Real epsilon = Precision::PConfusion();
Standard_Boolean periodic = C->IsPeriodic(); Standard_Boolean periodic = C->IsPeriodic();
GeomAdaptor_Curve aCA(C);
TopoDS_Vertex V1,V2; TopoDS_Vertex V1,V2;
if (periodic) { if (periodic) {
@ -813,14 +813,15 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1); Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2); Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
gp_Pnt P1,P2; gp_Pnt P1,P2;
if (!p1inf) P1 = C->Value(p1); if (!p1inf) P1 = aCA.Value(p1);
if (!p2inf) P2 = C->Value(p2); if (!p2inf) P2 = aCA.Value(p2);
Standard_Real preci = BRepLib::Precision(); Standard_Real preci = BRepLib::Precision();
BRep_Builder B; BRep_Builder B;
// check for closed curve // check for closed curve
Standard_Boolean closed = Standard_False; Standard_Boolean closed = Standard_False;
Standard_Boolean degenerated = Standard_False;
if (!p1inf && !p2inf) if (!p1inf && !p2inf)
closed = (P1.Distance(P2) <= preci); closed = (P1.Distance(P2) <= preci);
@ -836,13 +837,19 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC,
V2 = V1; V2 = V1;
else { else {
if (!V1.IsSame(V2)) { if (!V1.IsSame(V2)) {
myError = BRepLib_DifferentPointsOnClosedCurve; myError = BRepLib_DifferentPointsOnClosedCurve;
return; return;
} }
else if (P1.Distance(BRep_Tool::Pnt(V1)) > else if (P1.Distance(BRep_Tool::Pnt(V1)) >
Max(preci,BRep_Tool::Tolerance(V1))) { Max(preci,BRep_Tool::Tolerance(V1))) {
myError = BRepLib_DifferentPointsOnClosedCurve; myError = BRepLib_DifferentPointsOnClosedCurve;
return; 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.Add(E,V2);
} }
B.Range(E,p1,p2); B.Range(E,p1,p2);
B.Degenerated(E, degenerated);
myError = BRepLib_EdgeDone; myError = BRepLib_EdgeDone;
Done(); Done();

View File

@ -104,6 +104,8 @@ uses TColStd, gp, TColgp, math, GeomAbs
is is
imported transient class Cache;
imported EvaluatorFunction ; imported EvaluatorFunction ;
@ -2063,6 +2065,30 @@ is
-- If rational computes the homogeneous Taylor expension -- If rational computes the homogeneous Taylor expension
-- for the numerator and stores it in CachePoles -- 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; PolesCoefficients(Poles : Array1OfPnt2d from TColgp;
CachePoles : in out Array1OfPnt2d from TColgp); CachePoles : in out Array1OfPnt2d from TColgp);
---Warning: To be used for Beziercurves ONLY!!! ---Warning: To be used for Beziercurves ONLY!!!
@ -2454,6 +2480,7 @@ is
-- all u1 and u0 in the domain of the curve f(u) -- all u1 and u0 in the domain of the curve f(u)
-- | u1 - u0 | < UTolerance and -- | u1 - u0 | < UTolerance and
-- we have |f (u1) - f (u0)| < Tolerance3D -- we have |f (u1) - f (u0)| < Tolerance3D
end BSplCLib; end BSplCLib;

View File

@ -73,6 +73,7 @@ void BSplCLib::Hunt (const Array1OfReal& XX,
{ {
// replaced by simple dichotomy (RLE) // replaced by simple dichotomy (RLE)
Ilc = XX.Lower(); Ilc = XX.Lower();
if (XX.Length() <= 1) return;
const Standard_Real *px = &XX(Ilc); const Standard_Real *px = &XX(Ilc);
px -= 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 // xab : 12-Mar-96 : added MovePointAndTangent
#include <TColStd_Array1OfInteger.hxx> #include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <gp_Vec2d.hxx> #include <gp_Vec2d.hxx>
#include <Standard_ConstructionError.hxx> #include <Standard_ConstructionError.hxx>
#include <PLib.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 //function : Interpolate
//purpose : //purpose :

View File

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

View File

@ -71,6 +71,8 @@ uses TColStd, gp, TColgp
is is
imported transient class Cache;
imported EvaluatorFunction ; imported EvaluatorFunction ;
---Purpose: ---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; CacheD0(U,V : Real;
UDegree,VDegree : Integer; UDegree,VDegree : Integer;
UCacheParameter,VCacheParameter : Real; 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 //function : CacheD0
//purpose : Evaluates the polynomial cache of the Bspline Curve //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_BzSyntaxes.cxx
BSplSLib_EvaluatorFunction.hxx 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; // if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag;
} }
else 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; IntExtIsDone = IntExtIsDone || mydone;
} }
mydone = IntExtIsDone; 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; return;
} }
} }

View File

@ -120,8 +120,7 @@ uses Array1OfInteger from TColStd,
Vec from gp, Vec from gp,
BSplKnotDistribution from GeomAbs, BSplKnotDistribution from GeomAbs,
Geometry from Geom, Geometry from Geom,
Shape from GeomAbs, Shape from GeomAbs
Mutex from Standard
raises ConstructionError from Standard, raises ConstructionError from Standard,
@ -590,17 +589,6 @@ is
---Purpose : ---Purpose :
-- Returns True if the weights are not identical. -- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real. -- 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; Continuity (me) returns Shape from GeomAbs;
---Purpose : ---Purpose :
@ -789,6 +777,15 @@ is
raises DimensionError; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of K is not equal to the number of knots. -- 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) KnotSequence (me; K : out Array1OfReal from TColStd)
@ -845,6 +842,12 @@ is
-- Standard_DimensionError if the array K is not of -- Standard_DimensionError if the array K is not of
-- the appropriate length.Returns the knots sequence. -- the appropriate length.Returns the knots sequence.
raises DimensionError; 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; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of M is not equal to NbKnots. -- 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; NbKnots (me) returns Integer;
@ -933,6 +941,11 @@ is
raises DimensionError; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of P is not equal to the number of poles. -- 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; StartPoint (me) returns Pnt;
@ -954,6 +967,11 @@ is
raises DimensionError; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of W is not equal to NbPoles. -- 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; Copy (me) returns like me;
---Purpose: Creates a new object which is a copy of this BSpline curve. ---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) UpdateKnots(me : mutable)
---Purpose : Recompute the flatknots, the knotsdistribution, the continuity. ---Purpose : Recompute the flatknots, the knotsdistribution, the continuity.
is static private; is static private;
ValidateCache(me : mutable ; Parameter : Real)
is static private;
---Purpose : updates the cache and validates it
IsEqual(me; theOther : BSplineCurve from Geom; IsEqual(me; theOther : BSplineCurve from Geom;
thePreci : Real from Standard ) returns Boolean; thePreci : Real from Standard ) returns Boolean;
@ -1015,34 +1023,7 @@ fields
flatknots : HArray1OfReal from TColStd; flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd; knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger 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; maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard; maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bspline-cache
end; end;

View File

@ -125,12 +125,11 @@ Geom_BSplineCurve::Geom_BSplineCurve
{ {
// check // check
CheckCurveData (Poles, CheckCurveData(Poles,
Knots, Knots,
Mults, Mults,
Degree, Degree,
Periodic); Periodic);
// copy arrays // copy arrays
@ -145,11 +144,6 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults; mults->ChangeArray1() = Mults;
UpdateKnots(); 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 // check
CheckCurveData (Poles, CheckCurveData(Poles,
Knots, Knots,
Mults, Mults,
Degree, Degree,
Periodic); Periodic);
if (Weights.Length() != Poles.Length()) if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom_BSplineCurve"); Standard_ConstructionError::Raise("Geom_BSplineCurve");
@ -197,11 +191,9 @@ Geom_BSplineCurve::Geom_BSplineCurve
poles = new TColgp_HArray1OfPnt(1,Poles.Length()); poles = new TColgp_HArray1OfPnt(1,Poles.Length());
poles->ChangeArray1() = Poles; poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
if (rational) { if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length()); weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights; weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
} }
knots = new TColStd_HArray1OfReal(1,Knots.Length()); knots = new TColStd_HArray1OfReal(1,Knots.Length());
@ -211,9 +203,6 @@ Geom_BSplineCurve::Geom_BSplineCurve
mults->ChangeArray1() = Mults; mults->ChangeArray1() = Mults;
UpdateKnots(); 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(), BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
NewU2,periodic,FromU1,ToU2,index2,U); 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++; index2++;
Standard_Integer nbknots = index2 - index1 + 1; Standard_Integer nbknots = index2 - index1 + 1;
@ -974,7 +963,6 @@ void Geom_BSplineCurve::SetPole
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise(); if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise();
poles->SetValue (Index, P); poles->SetValue (Index, P);
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
//======================================================================= //=======================================================================
@ -1023,7 +1011,6 @@ void Geom_BSplineCurve::SetWeight
rational = !weights.IsNull(); rational = !weights.IsNull();
} }
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
//======================================================================= //=======================================================================
@ -1032,11 +1019,11 @@ void Geom_BSplineCurve::SetWeight
//======================================================================= //=======================================================================
void Geom_BSplineCurve::MovePoint(const Standard_Real U, void Geom_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt& P, const gp_Pnt& P,
const Standard_Integer Index1, const Standard_Integer Index1,
const Standard_Integer Index2, const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole, Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole) Standard_Integer& LastmodifiedPole)
{ {
if (Index1 < 1 || Index1 > poles->Length() || if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) { Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
@ -1047,12 +1034,11 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0); D0(U, P0);
gp_Vec Displ(P0, P); gp_Vec Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(), BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
weights->Array1(), flatknots->Array1(), weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles); FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) { if (FirstModifiedPole) {
poles->ChangeArray1() = npoles; poles->ChangeArray1() = npoles;
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
} }
@ -1061,14 +1047,13 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U,
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom_BSplineCurve:: void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U,
MovePointAndTangent(const Standard_Real U, const gp_Pnt& P,
const gp_Pnt& P, const gp_Vec& Tangent,
const gp_Vec& Tangent, const Standard_Real Tolerance,
const Standard_Real Tolerance, const Standard_Integer StartingCondition,
const Standard_Integer StartingCondition, const Standard_Integer EndingCondition,
const Standard_Integer EndingCondition, Standard_Integer& ErrorStatus)
Standard_Integer& ErrorStatus)
{ {
Standard_Integer ii ; Standard_Integer ii ;
if (IsPeriodic()) { if (IsPeriodic()) {
@ -1086,26 +1071,24 @@ MovePointAndTangent(const Standard_Real U,
delta_derivative) ; delta_derivative) ;
gp_Vec delta(P0, P); gp_Vec delta(P0, P);
for (ii = 1 ; ii <= 3 ; ii++) { for (ii = 1 ; ii <= 3 ; ii++) {
delta_derivative.SetCoord(ii, delta_derivative.SetCoord(ii, Tangent.Coord(ii)-delta_derivative.Coord(ii));
Tangent.Coord(ii)- delta_derivative.Coord(ii)) ;
} }
BSplCLib::MovePointAndTangent(U, BSplCLib::MovePointAndTangent(U,
delta, delta,
delta_derivative, delta_derivative,
Tolerance, Tolerance,
deg, deg,
rational, rational,
StartingCondition, StartingCondition,
EndingCondition, EndingCondition,
poles->Array1(), poles->Array1(),
weights->Array1(), weights->Array1(),
flatknots->Array1(), flatknots->Array1(),
new_poles, new_poles,
ErrorStatus) ; ErrorStatus) ;
if (!ErrorStatus) { if (!ErrorStatus) {
poles->ChangeArray1() = new_poles; poles->ChangeArray1() = new_poles;
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
} }
@ -1119,11 +1102,11 @@ void Geom_BSplineCurve::UpdateKnots()
rational = !weights.IsNull(); rational = !weights.IsNull();
Standard_Integer MaxKnotMult = 0; Standard_Integer MaxKnotMult = 0;
BSplCLib::KnotAnalysis (deg, BSplCLib::KnotAnalysis(deg,
periodic, periodic,
knots->Array1(), knots->Array1(),
mults->Array1(), mults->Array1(),
knotSet, MaxKnotMult); knotSet, MaxKnotMult);
if (knotSet == GeomAbs_Uniform && !periodic) { if (knotSet == GeomAbs_Uniform && !periodic) {
flatknots = knots; flatknots = knots;
@ -1132,10 +1115,10 @@ void Geom_BSplineCurve::UpdateKnots()
flatknots = new TColStd_HArray1OfReal flatknots = new TColStd_HArray1OfReal
(1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic)); (1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
BSplCLib::KnotSequence (knots->Array1(), BSplCLib::KnotSequence(knots->Array1(),
mults->Array1(), mults->Array1(),
deg,periodic, deg,periodic,
flatknots->ChangeArray1()); flatknots->ChangeArray1());
} }
if (MaxKnotMult == 0) smooth = GeomAbs_CN; if (MaxKnotMult == 0) smooth = GeomAbs_CN;
@ -1148,36 +1131,6 @@ void Geom_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break; 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_OutOfRange.hxx>
#include <Standard_DomainError.hxx> #include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx> #include <Standard_RangeError.hxx>
#include <Standard_Mutex.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#define POLES (poles->Array1()) #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 void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if(!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD0(NewU, BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache,
cachepoles->Array1(),
cacheweights->Array1(),
P); P);
} }
else else
{ {
BSplCLib::CacheD0(NewU, BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL), *((TColStd_Array1OfReal*) NULL),
knots->Array1(), mults->Array1(),
P); P);
} }
} }
@ -221,36 +211,25 @@ void Geom_BSplineCurve::D1 (const Standard_Real U,
gp_Pnt& P, gp_Pnt& P,
gp_Vec& V1) const gp_Vec& V1) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if(!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD1(NewU, BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1);
cachepoles->Array1(),
cacheweights->Array1(),
P,
V1);
} }
else else
{ {
BSplCLib::CacheD1(NewU, BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
deg,
parametercache,
spanlenghtcache,
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL), *((TColStd_Array1OfReal*) NULL),
P, knots->Array1(), mults->Array1(),
V1); P, V1);
} }
} }
@ -264,37 +243,25 @@ void Geom_BSplineCurve::D2(const Standard_Real U,
gp_Vec& V1, gp_Vec& V1,
gp_Vec& V2) const gp_Vec& V2) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if(!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD2(NewU, BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1, V2);
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2);
} }
else { else
BSplCLib::CacheD2(NewU, {
deg, BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
parametercache, *((TColStd_Array1OfReal*) NULL),
spanlenghtcache, knots->Array1(), mults->Array1(),
(cachepoles->Array1()), P, V1, V2);
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2);
} }
} }
@ -309,41 +276,25 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
gp_Vec& V2, gp_Vec& V2,
gp_Vec& V3) const gp_Vec& V3) const
{ {
Standard_Integer aSpanIndex = 0;
Standard_Real NewU(U); Standard_Real aNewU(U);
PeriodicNormalization(NewU); PeriodicNormalization(aNewU);
BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; if (aNewU < knots->Value(aSpanIndex))
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); aSpanIndex--;
if (rational)
if(!IsCacheValid(NewU))
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD3(NewU, BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1, V2, V3);
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2,
V3) ;
} }
else else
{ {
BSplCLib::CacheD3(NewU, BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
deg, *((TColStd_Array1OfReal*) NULL),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1, V2, V3);
cachepoles->Array1(),
*((TColStd_Array1OfReal*) NULL),
P,
V1,
V2,
V3) ;
} }
} }
@ -352,19 +303,19 @@ void Geom_BSplineCurve::D3(const Standard_Real U,
//purpose : //purpose :
//======================================================================= //=======================================================================
gp_Vec Geom_BSplineCurve::DN (const Standard_Real U, gp_Vec Geom_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N ) const const Standard_Integer N) const
{ {
gp_Vec V; gp_Vec V;
if (rational) { if (rational) {
BSplCLib::DN(U,N,0,deg,periodic,POLES, BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(), weights->Array1(),
FKNOTS,FMULTS,V); FKNOTS,FMULTS,V);
} }
else { else {
BSplCLib::DN(U,N,0,deg,periodic,POLES, BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL), *((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V); FKNOTS,FMULTS,V);
} }
return V; return V;
} }
@ -437,6 +388,11 @@ void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1(); K = knots->Array1();
} }
const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
{
return knots->Array1();
}
//======================================================================= //=======================================================================
//function : KnotSequence //function : KnotSequence
//purpose : //purpose :
@ -449,6 +405,11 @@ void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1(); K = flatknots->Array1();
} }
const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//======================================================================= //=======================================================================
//function : LastUKnotIndex //function : LastUKnotIndex
//purpose : //purpose :
@ -668,6 +629,11 @@ void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1(); M = mults->Array1();
} }
const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//======================================================================= //=======================================================================
//function : NbKnots //function : NbKnots
//purpose : //purpose :
@ -708,6 +674,11 @@ void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const
P = poles->Array1(); P = poles->Array1();
} }
const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
{
return poles->Array1();
}
//======================================================================= //=======================================================================
//function : StartPoint //function : StartPoint
//purpose : //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 //function : IsRational
//purpose : //purpose :
@ -778,7 +756,6 @@ void Geom_BSplineCurve::Transform
TColgp_Array1OfPnt & CPoles = poles->ChangeArray1(); TColgp_Array1OfPnt & CPoles = poles->ChangeArray1();
for (Standard_Integer I = 1; I <= CPoles.Length(); I++) for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T); CPoles (I).Transform (T);
InvalidateCache() ;
maxderivinvok = 0; maxderivinvok = 0;
} }

View File

@ -147,8 +147,7 @@ uses Array1OfInteger from TColStd,
BSplKnotDistribution from GeomAbs, BSplKnotDistribution from GeomAbs,
Curve from Geom, Curve from Geom,
Geometry from Geom, Geometry from Geom,
Shape from GeomAbs, Shape from GeomAbs
Mutex from Standard
raises ConstructionError from Standard, raises ConstructionError from Standard,
DimensionError from Standard, DimensionError from Standard,
@ -919,16 +918,6 @@ is
-- |1.0, 2.0, 0.5| -- |1.0, 2.0, 0.5|
-- if Weights = |1.0, 2.0, 0.5| returns False -- if Weights = |1.0, 2.0, 0.5| returns False
-- |1.0, 2.0, 0.5| -- |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); Bounds (me; U1, U2, V1, V2 : out Real);
---Purpose : ---Purpose :
@ -1017,6 +1006,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of P in the U and V direction -- Raised if the length of P in the U and V direction
-- is not equal to NbUpoles and NbVPoles. -- 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; UDegree (me) returns Integer;
@ -1055,6 +1049,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of Ku is not equal to the number of knots -- Raised if the length of Ku is not equal to the number of knots
-- in the U direction. -- 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) UKnotSequence (me; Ku : out Array1OfReal from TColStd)
@ -1066,6 +1065,15 @@ is
raises DimensionError; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of Ku is not equal to NbUPoles + UDegree + 1 -- 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 UMultiplicity (me; UIndex : Integer) returns Integer
@ -1083,6 +1091,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of Mu is not equal to the number of -- Raised if the length of Mu is not equal to the number of
-- knots in the U direction. -- 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; VDegree (me) returns Integer;
@ -1120,6 +1133,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of Kv is not equal to the number of -- Raised if the length of Kv is not equal to the number of
-- knots in the V direction. -- 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) VKnotSequence (me; Kv : out Array1OfReal from TColStd)
@ -1131,6 +1149,15 @@ is
raises DimensionError; raises DimensionError;
---Purpose : ---Purpose :
-- Raised if the length of Kv is not equal to NbVPoles + VDegree + 1 -- 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 VMultiplicity (me; VIndex : Integer) returns Integer
@ -1148,6 +1175,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of Mv is not equal to the number of -- Raised if the length of Mv is not equal to the number of
-- knots in the V direction. -- 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 Weight (me; UIndex, VIndex : Integer) returns Real
@ -1164,6 +1196,11 @@ is
---Purpose : ---Purpose :
-- Raised if the length of W in the U and V direction is -- Raised if the length of W in the U and V direction is
-- not equal to NbUPoles and NbVPoles. -- 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; 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 fields
@ -1420,68 +1447,8 @@ fields
vknots : HArray1OfReal from TColStd; vknots : HArray1OfReal from TColStd;
umults : HArray1OfInteger from TColStd; umults : HArray1OfInteger from TColStd;
vmults : HArray1OfInteger from TColStd; vmults : HArray1OfInteger from TColStd;
-- Inplementation of the cache on surfaces umaxderivinv : Real from Standard;
cachepoles : HArray2OfPnt from TColgp; vmaxderivinv : Real from Standard;
-- Taylor expansion of the poles function, in homogeneous maxderivinvok : Boolean from Standard;
-- 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
end; end;

View File

@ -165,8 +165,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
maxderivinvok(0) maxderivinvok(0)
{ {
Standard_Integer MinDegree,
MaxDegree ;
// check // check
@ -196,19 +194,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length()); vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults; 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(); UpdateUKnots();
UpdateVKnots(); UpdateVKnots();
@ -238,8 +223,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vdeg(VDegree), vdeg(VDegree),
maxderivinvok(0) maxderivinvok(0)
{ {
Standard_Integer MinDegree,
MaxDegree ;
// check weights // check weights
if (Weights.ColLength() != Poles.ColLength()) if (Weights.ColLength() != Poles.ColLength())
@ -289,21 +272,6 @@ Geom_BSplineSurface::Geom_BSplineSurface
vmults = new TColStd_HArray1OfInteger (1,VMults.Length()); vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults; 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(); UpdateUKnots();
UpdateVKnots(); UpdateVKnots();
@ -1258,8 +1226,6 @@ void Geom_BSplineSurface::UpdateUKnots()
default : Usmooth = GeomAbs_C3; break; default : Usmooth = GeomAbs_C3; break;
} }
} }
InvalidateCache() ;
} }
//======================================================================= //=======================================================================
@ -1298,18 +1264,8 @@ void Geom_BSplineSurface::UpdateVKnots()
default : Vsmooth = GeomAbs_C3; break; 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 //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 //function : SetWeight
//purpose : //purpose :
@ -1550,7 +1335,6 @@ void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
} }
Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight; Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
Rational(Weights, urational, vrational); Rational(Weights, urational, vrational);
InvalidateCache();
} }
//======================================================================= //=======================================================================
@ -1583,8 +1367,6 @@ void Geom_BSplineSurface::SetWeightCol
} }
// Verifie si c'est rationnel // Verifie si c'est rationnel
Rational(Weights, urational, vrational); Rational(Weights, urational, vrational);
InvalidateCache();
} }
//======================================================================= //=======================================================================
@ -1619,6 +1401,5 @@ void Geom_BSplineSurface::SetWeightRow
} }
// Verifie si c'est rationnel // Verifie si c'est rationnel
Rational(Weights, urational, vrational); Rational(Weights, urational, vrational);
InvalidateCache();
} }

View File

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

View File

@ -39,6 +39,7 @@
#include <Standard_ConstructionError.hxx> #include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx> #include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx> #include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
typedef Geom_OffsetCurve OffsetCurve; typedef Geom_OffsetCurve OffsetCurve;
typedef Handle(Geom_OffsetCurve) Handle(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 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 : //purpose :
//======================================================================= //=======================================================================
void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& P, Vec& theV1, Vec& V2, Vec& V3) void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec& theV2, Vec& theV3) const
const { {
// P(u) = p(u) + Offset * Ndir / R // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) // 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 + // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * 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; Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, P, theV1, V2, V3); basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Vec V4 = basisCurve->DN (theU, 4); Vec aV4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol) if(theV1.SquareMagnitude() <= gp::Resolution())
{ IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, aV4);
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3; CSLib_Offset::D3(theP, theV1, theV2, theV3, aV4, direction, offsetValue,
Standard_Real du; IsDirectionChange, theP, theV1, theV2, theV3);
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);
} }
@ -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, void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
gp_Pnt& thePbasis, gp_Vec& theV1basis)const 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); CSLib_Offset::D0(thePbasis, theV1basis, direction, offsetValue, IsDirectionChange, theP);
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);
} }
//======================================================================= //=======================================================================
@ -578,96 +407,21 @@ void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
//======================================================================= //=======================================================================
void Geom_OffsetCurve::D1 ( const Standard_Real theU, void Geom_OffsetCurve::D1 ( const Standard_Real theU,
Pnt& P , Pnt& PBasis , Pnt& theP , Pnt& thePBasis ,
Vec& theV1, Vec& V1basis, Vec& V2basis) const { Vec& theV1, Vec& theV1basis, Vec& theV2basis) const {
// P(u) = p(u) + Offset * Ndir / R // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) // 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**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); Standard_Boolean IsDirectionChange = Standard_False;
theV1 = V1basis; if(theV1basis.SquareMagnitude() <= gp::Resolution())
Vec V2 = V2basis; IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1basis, theV2basis);
if(theV1.Magnitude() <= aTol) CSLib_Offset::D1(thePBasis, theV1basis, theV2basis, direction, offsetValue, IsDirectionChange, theP, theV1);
{
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);
} }
@ -676,11 +430,11 @@ void Geom_OffsetCurve::D1 ( const Standard_Real theU,
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom_OffsetCurve::D2 (const Standard_Real theU, void Geom_OffsetCurve::D2 (const Standard_Real theU,
Pnt& P , Pnt& PBasis , Pnt& theP, Pnt& thePBasis,
Vec& theV1 , Vec& V2 , Vec& theV1, Vec& theV2,
Vec& V1basis, Vec& V2basis, Vec& V3basis) const { Vec& theV1basis, Vec& theV2basis, Vec& theV3basis) const
{
// P(u) = p(u) + Offset * Ndir / R // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) // 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) + // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2))) // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False; Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, PBasis, V1basis, V2basis, V3basis); basisCurve->D3 (theU, thePBasis, theV1basis, theV2basis, theV3basis);
theV1 = V1basis; if(theV1basis.SquareMagnitude() <= gp::Resolution())
V2 = V2basis; IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1basis, theV2basis, theV3basis);
Vec V3 = V3basis;
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3; CSLib_Offset::D2(thePBasis, theV1basis, theV2basis, theV3basis, direction, offsetValue,
Standard_Real du; IsDirectionChange, theP, theV1, theV2);
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);
} }
@ -929,3 +569,57 @@ GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const
{ {
return myBasisCurveContinuity; 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 XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
@ -463,6 +467,10 @@ void Geom_SurfaceOfRevolution::D2
XYZ Vdir = direction.XYZ(); //Vdir XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
@ -558,6 +566,10 @@ void Geom_SurfaceOfRevolution::D3
XYZ Vdir = direction.XYZ(); //Vdir XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(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 XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')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 XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir 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 XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^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 VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''') XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')

View File

@ -124,8 +124,7 @@ uses Array1OfInteger from TColStd,
Vec2d from gp, Vec2d from gp,
BSplKnotDistribution from GeomAbs, BSplKnotDistribution from GeomAbs,
Geometry from Geom2d, Geometry from Geom2d,
Shape from GeomAbs, Shape from GeomAbs
Mutex from Standard
raises ConstructionError from Standard, raises ConstructionError from Standard,
DimensionError from Standard, DimensionError from Standard,
@ -642,17 +641,6 @@ is
-- Returns True if the weights are not identical. -- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real. -- 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; Continuity (me) returns Shape from GeomAbs;
--- Purpose : --- Purpose :
-- Returns the global continuity of the curve : -- Returns the global continuity of the curve :
@ -843,6 +831,11 @@ is
raises DimensionError; raises DimensionError;
--- Purpose : --- Purpose :
-- Raised if the length of K is not equal to the number of knots. -- 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) KnotSequence (me; K : out Array1OfReal from TColStd)
@ -854,6 +847,15 @@ is
raises DimensionError; raises DimensionError;
--- Purpose : --- Purpose :
-- Raised if the length of K is not equal to NbPoles + Degree + 1 -- 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; raises DimensionError;
--- Purpose : --- Purpose :
-- Raised if the length of M is not equal to NbKnots. -- 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; NbKnots (me) returns Integer;
@ -942,6 +949,11 @@ is
raises DimensionError; raises DimensionError;
--- Purpose : --- Purpose :
-- Raised if the length of P is not equal to the number of poles. -- 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; StartPoint (me) returns Pnt2d;
@ -963,6 +975,11 @@ is
raises DimensionError; raises DimensionError;
--- Purpose : --- Purpose :
-- Raised if the length of W is not equal to NbPoles. -- 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) UpdateKnots(me : mutable)
---Purpose: Recompute the flatknots, the knotsdistribution, the continuity. ---Purpose: Recompute the flatknots, the knotsdistribution, the continuity.
is static private; 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 fields
rational : Boolean; rational : Boolean;
@ -1019,35 +1027,7 @@ fields
flatknots : HArray1OfReal from TColStd; flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd; knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger 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; maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard; maxderivinvok : Boolean from Standard;
myMutex : Mutex from Standard;
-- protected bspline-cache
end; end;

View File

@ -123,12 +123,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
{ {
// check // check
CheckCurveData (Poles, CheckCurveData(Poles,
Knots, Knots,
Mults, Mults,
Degree, Degree,
Periodic); Periodic);
// copy arrays // copy arrays
@ -142,10 +141,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults; mults->ChangeArray1() = Mults;
UpdateKnots(); 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 // check
CheckCurveData (Poles, CheckCurveData(Poles,
Knots, Knots,
Mults, Mults,
Degree, Degree,
Periodic); Periodic);
if (Weights.Length() != Poles.Length()) if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch"); 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 = new TColgp_HArray1OfPnt2d(1,Poles.Length());
poles->ChangeArray1() = Poles; poles->ChangeArray1() = Poles;
cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
if (rational) { if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length()); weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights; weights->ChangeArray1() = Weights;
cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
} }
knots = new TColStd_HArray1OfReal(1,Knots.Length()); knots = new TColStd_HArray1OfReal(1,Knots.Length());
@ -206,10 +199,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve
mults->ChangeArray1() = Mults; mults->ChangeArray1() = Mults;
UpdateKnots(); 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"); if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch");
poles->SetValue (Index, P); poles->SetValue (Index, P);
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache();
} }
//======================================================================= //=======================================================================
@ -1140,7 +1128,6 @@ void Geom2d_BSplineCurve::SetWeight
} }
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
//======================================================================= //=======================================================================
@ -1149,11 +1136,11 @@ void Geom2d_BSplineCurve::SetWeight
//======================================================================= //=======================================================================
void Geom2d_BSplineCurve::MovePoint(const Standard_Real U, void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
const gp_Pnt2d& P, const gp_Pnt2d& P,
const Standard_Integer Index1, const Standard_Integer Index1,
const Standard_Integer Index2, const Standard_Integer Index2,
Standard_Integer& FirstModifiedPole, Standard_Integer& FirstModifiedPole,
Standard_Integer& LastmodifiedPole) Standard_Integer& LastmodifiedPole)
{ {
if (Index1 < 1 || Index1 > poles->Length() || if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) { Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
@ -1164,12 +1151,11 @@ void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
D0(U, P0); D0(U, P0);
gp_Vec2d Displ(P0, P); gp_Vec2d Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(), BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
weights->Array1(), flatknots->Array1(), weights->Array1(), flatknots->Array1(),
FirstModifiedPole, LastmodifiedPole, npoles); FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) { if (FirstModifiedPole) {
poles->ChangeArray1() = npoles; poles->ChangeArray1() = npoles;
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
} }
@ -1222,7 +1208,6 @@ MovePointAndTangent(const Standard_Real U,
if (!ErrorStatus) { if (!ErrorStatus) {
poles->ChangeArray1() = new_poles; poles->ChangeArray1() = new_poles;
maxderivinvok = 0; maxderivinvok = 0;
InvalidateCache() ;
} }
} }
@ -1266,33 +1251,6 @@ void Geom2d_BSplineCurve::UpdateKnots()
default : smooth = GeomAbs_C3; break; 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_OutOfRange.hxx>
#include <Standard_DomainError.hxx> #include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx> #include <Standard_RangeError.hxx>
#include <Standard_Mutex.hxx> #include <Precision.hxx>
#define POLES (poles->Array1()) #define POLES (poles->Array1())
#define KNOTS (knots->Array1()) #define KNOTS (knots->Array1())
@ -183,36 +183,28 @@ Standard_Integer Geom2d_BSplineCurve::Degree () const
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom2d_BSplineCurve::D0 ( const Standard_Real U, void Geom2d_BSplineCurve::D0(const Standard_Real U,
gp_Pnt2d& P) const gp_Pnt2d& P) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD0(NewU, BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P);
(cachepoles->Array1()),
cacheweights->Array1(),
P) ;
} }
else { else
BSplCLib::CacheD0(NewU, {
deg, BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
parametercache, *((TColStd_Array1OfReal*) NULL),
spanlenghtcache, knots->Array1(), mults->Array1(),
(cachepoles->Array1()), P);
BSplCLib::NoWeights(),
P) ;
} }
} }
@ -222,39 +214,29 @@ void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom2d_BSplineCurve::D1 (const Standard_Real U, void Geom2d_BSplineCurve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Pnt2d& P,
gp_Vec2d& V1) const gp_Vec2d& V1) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD1(NewU, BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1);
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1) ;
} }
else { else
BSplCLib::CacheD1(NewU, {
deg, BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
parametercache, *((TColStd_Array1OfReal*) NULL),
spanlenghtcache, knots->Array1(), mults->Array1(),
(cachepoles->Array1()), P, V1);
BSplCLib::NoWeights(),
P,
V1) ;
} }
} }
@ -263,42 +245,30 @@ void Geom2d_BSplineCurve::D1 (const Standard_Real U,
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom2d_BSplineCurve::D2 (const Standard_Real U , void Geom2d_BSplineCurve::D2(const Standard_Real U,
gp_Pnt2d& P , gp_Pnt2d& P,
gp_Vec2d& V1, gp_Vec2d& V1,
gp_Vec2d& V2 ) const gp_Vec2d& V2) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD2(NewU, BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1, V2);
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2) ;
} }
else { else
BSplCLib::CacheD2(NewU, {
deg, BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
parametercache, *((TColStd_Array1OfReal*) NULL),
spanlenghtcache, knots->Array1(), mults->Array1(),
(cachepoles->Array1()), P, V1, V2);
BSplCLib::NoWeights(),
P,
V1,
V2) ;
} }
} }
@ -307,45 +277,31 @@ void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom2d_BSplineCurve::D3 (const Standard_Real U , void Geom2d_BSplineCurve::D3(const Standard_Real U,
gp_Pnt2d& P , gp_Pnt2d& P,
gp_Vec2d& V1, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V2,
gp_Vec2d& V3 ) const gp_Vec2d& V3) const
{ {
Standard_Real NewU(U); Standard_Integer aSpanIndex = 0;
PeriodicNormalization(NewU); Standard_Real aNewU(U);
PeriodicNormalization(aNewU);
Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
Standard_Mutex::Sentry aSentry(MyCurve->myMutex); if (aNewU < knots->Value(aSpanIndex))
aSpanIndex--;
if (!IsCacheValid(NewU)) if (rational)
MyCurve->ValidateCache(NewU);
if(rational)
{ {
BSplCLib::CacheD3(NewU, BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
deg, weights->Array1(),
parametercache, knots->Array1(), mults->Array1(),
spanlenghtcache, P, V1, V2, V3);
(cachepoles->Array1()),
cacheweights->Array1(),
P,
V1,
V2,
V3) ;
} }
else { else
BSplCLib::CacheD3(NewU, {
deg, BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
parametercache, *((TColStd_Array1OfReal*) NULL),
spanlenghtcache, knots->Array1(), mults->Array1(),
(cachepoles->Array1()), P, V1, V2, V3);
BSplCLib::NoWeights(),
P,
V1,
V2,
V3) ;
} }
} }
@ -354,20 +310,20 @@ void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
//purpose : //purpose :
//======================================================================= //=======================================================================
gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U, gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U,
const Standard_Integer N ) const const Standard_Integer N) const
{ {
gp_Vec2d V; gp_Vec2d V;
if ( rational ) { if ( rational ) {
BSplCLib::DN(U,N,0,deg,periodic,POLES, BSplCLib::DN(U,N,0,deg,periodic,POLES,
weights->Array1(), weights->Array1(),
FKNOTS,FMULTS,V); FKNOTS,FMULTS,V);
} }
else { else {
BSplCLib::DN(U,N,0,deg,periodic,POLES, BSplCLib::DN(U,N,0,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL), *((TColStd_Array1OfReal*) NULL),
FKNOTS,FMULTS,V); FKNOTS,FMULTS,V);
} }
return V; return V;
} }
@ -440,6 +396,11 @@ void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const
K = knots->Array1(); K = knots->Array1();
} }
const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const
{
return knots->Array1();
}
//======================================================================= //=======================================================================
//function : KnotSequence //function : KnotSequence
//purpose : //purpose :
@ -452,6 +413,11 @@ void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const
K = flatknots->Array1(); K = flatknots->Array1();
} }
const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const
{
return flatknots->Array1();
}
//======================================================================= //=======================================================================
//function : LastUKnotIndex //function : LastUKnotIndex
//purpose : //purpose :
@ -676,6 +642,11 @@ void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const
M = mults->Array1(); M = mults->Array1();
} }
const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const
{
return mults->Array1();
}
//======================================================================= //=======================================================================
//function : NbKnots //function : NbKnots
//purpose : //purpose :
@ -716,6 +687,11 @@ void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const
P = poles->Array1(); P = poles->Array1();
} }
const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const
{
return poles->Array1();
}
//======================================================================= //=======================================================================
//function : StartPoint //function : StartPoint
//purpose : //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 //function : IsRational
//purpose : //purpose :
@ -786,7 +769,6 @@ void Geom2d_BSplineCurve::Transform
for (Standard_Integer I = 1; I <= CPoles.Length(); I++) for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T); CPoles (I).Transform (T);
InvalidateCache();
// maxderivinvok = 0; // maxderivinvok = 0;
} }

View File

@ -23,6 +23,7 @@
#include <Standard_ConstructionError.hxx> #include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx> #include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx> #include <Standard_NotImplemented.hxx>
#include <CSLib_Offset.hxx>
#include <Geom2d_UndefinedDerivative.hxx> #include <Geom2d_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx> #include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_Line.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 MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); 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 //function : Copy
//purpose : //purpose :
@ -211,163 +220,38 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
//purpose : //purpose :
//======================================================================= //=======================================================================
void Geom2d_OffsetCurve::D0 (const Standard_Real theU, void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
Pnt2d& theP ) const Pnt2d& theP) const
{ {
const Standard_Real aTol = gp::Resolution();
Vec2d vD1; Vec2d vD1;
basisCurve->D1 (theU, theP, vD1); basisCurve->D1 (theU, theP, vD1);
Standard_Real Ndu = vD1.Magnitude();
if(Ndu <= aTol) Standard_Boolean IsDirectionChange = Standard_False;
{ if(vD1.SquareMagnitude() <= gp::Resolution())
const Standard_Real anUinfium = basisCurve->FirstParameter(); IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1);
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3; CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP);
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);
}
//======================================================================= //=======================================================================
//function : D1 //function : D1
//purpose : //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 // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z // 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**2) * (DNdir/DU * R - Ndir * (DR/R))
const Standard_Real aTol = gp::Resolution();
Vec2d V2; Vec2d V2;
basisCurve->D2 (theU, P, theV1, V2); basisCurve->D2 (theU, theP, theV1, V2);
if(theV1.Magnitude() <= aTol)
{
const Standard_Real anUinfium = basisCurve->FirstParameter();
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3; Standard_Boolean IsDirectionChange = Standard_False;
Standard_Real du; if(theV1.SquareMagnitude() <= gp::Resolution())
if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2);
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)
XY Ndir (theV1.Y(), -theV1.X()); CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1);
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);
} }
//======================================================================= //=======================================================================
@ -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, void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
Pnt2d& P, Pnt2d& theP,
Vec2d& theV1, Vec2d& V2) const Vec2d& theV1, Vec2d& theV2) const
{ {
// P(u) = p(u) + Offset * Ndir / R // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z // 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))) // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
Vec2d V3; Vec2d V3;
basisCurve->D3 (theU, P, theV1, V2, V3); basisCurve->D3 (theU, theP, theV1, theV2, V3);
const Standard_Real aTol = gp::Resolution();
Standard_Boolean IsDirectionChange = Standard_False; Standard_Boolean IsDirectionChange = Standard_False;
if(theV1.SquareMagnitude() <= gp::Resolution())
IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3);
if(theV1.Magnitude() <= aTol) CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2);
{
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);
} }
@ -515,9 +288,9 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
//======================================================================= //=======================================================================
void Geom2d_OffsetCurve::D3 (const Standard_Real theU, void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
Pnt2d& P, Pnt2d& theP,
Vec2d& theV1, Vec2d& V2, Vec2d& V3) const { Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const
{
// P(u) = p(u) + Offset * Ndir / R // P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z // 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 + // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
const Standard_Real aTol = gp::Resolution(); basisCurve->D3 (theU, theP, theV1, theV2, theV3);
Standard_Boolean IsDirectionChange = Standard_False;
basisCurve->D3 (theU, P, theV1, V2, V3);
Vec2d V4 = basisCurve->DN (theU, 4); Vec2d V4 = basisCurve->DN (theU, 4);
if(theV1.Magnitude() <= aTol) Standard_Boolean IsDirectionChange = Standard_False;
{ if(theV1.SquareMagnitude() <= gp::Resolution())
const Standard_Real anUinfium = basisCurve->FirstParameter(); IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4);
const Standard_Real anUsupremum = basisCurve->LastParameter();
const Standard_Real DivisionFactor = 1.e-3; CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange,
Standard_Real du; theP, theV1, theV2, theV3);
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);
}
//======================================================================= //=======================================================================
//function : DN //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, void Geom2d_OffsetCurve::Value (const Standard_Real theU,
Pnt2d& theP, Pnt2d& thePbasis, Pnt2d& theP, Pnt2d& thePbasis,
Vec2d& theV1basis ) const Vec2d& theV1basis ) const
{ {
basisCurve->D1(theU, thePbasis, theV1basis); basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP); D0(theU,theP);
} }
//======================================================================= //=======================================================================
@ -741,30 +381,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real U,
if (Index != 2) { if (Index != 2) {
V2 = basisCurve->DN (U, Index); V2 = basisCurve->DN (U, Index);
} }
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X()); CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1);
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);
} }
@ -800,52 +418,8 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real U,
V2 = basisCurve->DN (U, Index); V2 = basisCurve->DN (U, Index);
V3 = basisCurve->DN (U, Index + 1); V3 = basisCurve->DN (U, Index + 1);
} }
XY Ndir (V1.Y(), -V1.X());
XY DNdir (V2.Y(), -V2.X()); CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2);
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);
} }
//======================================================================= //=======================================================================
@ -961,3 +535,57 @@ GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const
{ {
return myBasisCurveContinuity; 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, gp,
Standard, Standard,
TColStd, TColStd,
TColgp TColgp,
BSplCLib
is is

View File

@ -33,7 +33,8 @@ uses Vec2d from gp,
BSplineCurve from Geom2d, BSplineCurve from Geom2d,
CurveType from GeomAbs, CurveType from GeomAbs,
Shape from GeomAbs, Shape from GeomAbs,
HCurve2d from Adaptor2d HCurve2d from Adaptor2d,
Cache from BSplCLib
raises NoSuchObject from Standard, raises NoSuchObject from Standard,
@ -123,19 +124,44 @@ is
--- Purpose : Computes the point of parameter U on the curve --- Purpose : Computes the point of parameter U on the curve
is redefined static; 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) D0 (me; U : Real; P : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U. --- Purpose : Computes the point of parameter U.
is redefined static; 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) 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 --- Purpose : Computes the point of parameter U on the curve with its
-- first derivative. -- first derivative.
raises raises
DomainError from Standard DomainError from Standard
--- Purpose : Raised if the continuity of the current interval --- Purpose : Raised if the continuity of the current interval
-- is not C1. -- is not C1.
is redefined static; 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) D2 (me; U : Real; P : out Pnt2d from gp; V1, V2 : out Vec2d from gp)
--- Purpose : --- Purpose :
@ -147,6 +173,16 @@ is
-- is not C2. -- is not C2.
is redefined static; 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) D3 (me; U : Real; P : out Pnt2d from gp; V1, V2, V3 : out Vec2d from gp)
--- Purpose : --- Purpose :
-- Returns the point P of parameter U, the first, the second -- 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 --- Purpose : Raised if the continuity of the current interval
-- is not C3. -- is not C3.
is redefined static; 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 DN (me; U : Real; N : Integer) returns Vec2d from gp
--- Purpose : --- Purpose :
@ -169,6 +215,18 @@ is
--- Purpose : Raised if N < 1. --- Purpose : Raised if N < 1.
is redefined static; 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 Resolution(me; Ruv :Real) returns Real
---Purpose : returns the parametric resolution ---Purpose : returns the parametric resolution
@ -243,6 +301,11 @@ is
load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real) load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real)
is private; 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 fields
@ -250,6 +313,8 @@ fields
myTypeCurve : CurveType from GeomAbs ; myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ; myFirst : Real from Standard ;
myLast : Real from Standard; myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve2d from Adaptor2d;
end Curve; end Curve;

View File

@ -26,6 +26,7 @@
#include <Geom2dAdaptor_HCurve.hxx> #include <Geom2dAdaptor_HCurve.hxx>
#include <Adaptor2d_HCurve2d.hxx> #include <Adaptor2d_HCurve2d.hxx>
#include <BSplCLib.hxx> #include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx> #include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt2d.hxx> #include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
@ -42,6 +43,9 @@
#include <Geom2d_Ellipse.hxx> #include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx> #include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx> #include <Geom2d_Hyperbola.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <CSLib_Offset.hxx>
//#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx> //#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
#include <Standard_OutOfRange.hxx> #include <Standard_OutOfRange.hxx>
@ -52,6 +56,17 @@
#define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve)) #define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2 #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 //function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve //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)) { else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
myTypeCurve = GeomAbs_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 { else {
myTypeCurve = GeomAbs_OtherCurve; myTypeCurve = GeomAbs_OtherCurve;
@ -218,7 +243,7 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const
if (myTypeCurve == GeomAbs_BSplineCurve) { if (myTypeCurve == GeomAbs_BSplineCurve) {
return LocalContinuity(myFirst, myLast); return LocalContinuity(myFirst, myLast);
} }
else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape S = GeomAbs_Shape S =
(*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity();
switch(S){ 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; GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){ switch(S){
case GeomAbs_G1: case GeomAbs_G1:
@ -342,9 +367,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const
case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN; default: BaseS = GeomAbs_CN;
} }
Geom2dAdaptor_Curve C myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
myNbIntervals = C.NbIntervals(BaseS);
} }
return myNbIntervals; 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; GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){ switch(S){
case GeomAbs_G1: case GeomAbs_G1:
@ -459,10 +482,8 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T,
case GeomAbs_C2: BaseS = GeomAbs_C3; break; case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN; default: BaseS = GeomAbs_CN;
} }
Geom2dAdaptor_Curve C myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()); myOffsetBaseCurveAdaptor->Intervals(T, BaseS);
myNbIntervals = C.NbIntervals(BaseS);
C.Intervals(T, BaseS);
} }
T( T.Lower() ) = myFirst; T( T.Lower() ) = myFirst;
@ -525,6 +546,17 @@ Standard_Real Geom2dAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter(); 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 //function : Value
//purpose : //purpose :
@ -532,24 +564,65 @@ Standard_Real Geom2dAdaptor_Curve::Period() const
gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst)
{
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast)
{
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
return myBspl->LocalValue(U, Ideb, Ifin); return myBspl->LocalValue(theU, Ideb, Ifin);
} }
else { else if (!myCurveCache.IsNull()) // use cached B-spline data
return myCurve->Value( U); {
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 void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { {
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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD0( U, Ideb, Ifin, P); myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
} }
else { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D0(U, P); {
} 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 : //purpose :
//======================================================================= //=======================================================================
void Geom2dAdaptor_Curve::D1(const Standard_Real U, void Geom2dAdaptor_Curve::D1(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V) const gp_Pnt2d& P, gp_Vec2d& V) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { {
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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD1( U, Ideb, Ifin, P, V); myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
} return;
else {
myCurve->D1( U, P, V);
} }
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, 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)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { {
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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2); myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
} }
else { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D2( U, P, V1, V2); {
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, void Geom2dAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt2d& P, gp_Vec2d& V1, gp_Pnt2d& P, gp_Vec2d& V1,
gp_Vec2d& V2, gp_Vec2d& V3) const gp_Vec2d& V2, gp_Vec2d& V3) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve) && if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { {
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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; 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 { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D3( U, P, V1, V2, V3); {
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, gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const const Standard_Integer N) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve) && if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); 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; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
return myBspl->LocalDN( U, Ideb, Ifin, N); 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); 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, TColStd,
Geom2dAdaptor, Geom2dAdaptor,
TColgp, TColgp,
Precision Precision,
BSplCLib,
BSplSLib
is is
class Curve; class Curve;

View File

@ -33,7 +33,8 @@ uses Vec from gp,
BSplineCurve from Geom, BSplineCurve from Geom,
CurveType from GeomAbs, CurveType from GeomAbs,
Shape from GeomAbs, Shape from GeomAbs,
HCurve from Adaptor3d HCurve from Adaptor3d,
Cache from BSplCLib
raises NoSuchObject from Standard, raises NoSuchObject from Standard,
ConstructionError from Standard, ConstructionError from Standard,
@ -129,10 +130,26 @@ is
--- Purpose : Computes the point of parameter U on the curve --- Purpose : Computes the point of parameter U on the curve
is redefined static; 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) D0 (me; U : Real; P : out Pnt from gp)
--- Purpose : Computes the point of parameter U. --- Purpose : Computes the point of parameter U.
is redefined static; 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) D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp)
--- Purpose : Computes the point of parameter U on the curve --- Purpose : Computes the point of parameter U on the curve
-- with its first derivative. -- with its first derivative.
@ -142,6 +159,16 @@ is
-- derivatives are computed on the current interval. -- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve. -- else the derivatives are computed on the basis curve.
is redefined static; 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) D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp)
--- Purpose : --- Purpose :
@ -154,6 +181,16 @@ is
-- else the derivatives are computed on the basis curve. -- else the derivatives are computed on the basis curve.
is redefined static; 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) D3 (me; U : Real; P : out Pnt from gp; V1, V2, V3 : out Vec from gp)
--- Purpose : --- Purpose :
-- Returns the point P of parameter U, the first, the second -- Returns the point P of parameter U, the first, the second
@ -164,6 +201,16 @@ is
-- derivatives are computed on the current interval. -- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve. -- else the derivatives are computed on the basis curve.
is redefined static; 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 DN (me; U : Real; N : Integer) returns Vec from gp
--- Purpose : --- Purpose :
@ -179,6 +226,19 @@ is
is redefined static; 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 Resolution(me; R3d :Real) returns Real
---Purpose : returns the parametric resolution ---Purpose : returns the parametric resolution
is redefined static; is redefined static;
@ -279,6 +339,11 @@ is
load(me : in out; C : Curve from Geom; UFirst,ULast : Real) load(me : in out; C : Curve from Geom; UFirst,ULast : Real)
is private; 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 fields
@ -286,6 +351,8 @@ fields
myTypeCurve : CurveType from GeomAbs ; myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ; myFirst : Real from Standard ;
myLast : Real from Standard; myLast : Real from Standard;
myCurveCache : Cache from BSplCLib;
myOffsetBaseCurveAdaptor : HCurve from Adaptor3d;
friends friends
class Surface from GeomAdaptor class Surface from GeomAdaptor

View File

@ -26,6 +26,7 @@
#include <GeomAdaptor_HCurve.hxx> #include <GeomAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurve.hxx> #include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx> #include <BSplCLib.hxx>
#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx> #include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt.hxx> #include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
@ -48,10 +49,22 @@
#include <Standard_NullObject.hxx> #include <Standard_NullObject.hxx>
#include <Standard_NotImplemented.hxx> #include <Standard_NotImplemented.hxx>
#include <Geom_OffsetCurve.hxx> #include <Geom_OffsetCurve.hxx>
#include <CSLib_Offset.hxx>
#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve)) #define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2 #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 //function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve //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)) { else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
myTypeCurve = GeomAbs_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 { else {
myTypeCurve = GeomAbs_OtherCurve; myTypeCurve = GeomAbs_OtherCurve;
@ -510,6 +532,17 @@ Standard_Real GeomAdaptor_Curve::Period() const
return myCurve->LastParameter() - myCurve->FirstParameter(); 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 //function : Value
//purpose : //purpose :
@ -517,22 +550,64 @@ Standard_Real GeomAdaptor_Curve::Period() const
gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; 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 void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD0( U, Ideb, Ifin, P); myBspl->LocalD0(theU, Ideb, Ifin, theP);
return;
} }
else { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D0(U, P); {
} 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 void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD1( U, Ideb, Ifin, P, V); myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
} return;
else {
myCurve->D1( U, P, V);
} }
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 //function : D2
//purpose : //purpose :
//======================================================================= //=======================================================================
void GeomAdaptor_Curve::D2(const Standard_Real U, 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)&& if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2); myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
return;
} }
else { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D2( U, P, V1, V2); {
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, void GeomAdaptor_Curve::D3(const Standard_Real U,
gp_Pnt& P, gp_Vec& V1, gp_Pnt& P, gp_Vec& V1,
gp_Vec& V2, gp_Vec& V3) const gp_Vec& V2, gp_Vec& V3) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve) && if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1; if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1; if (Ideb>=Ifin) Ifin = Ideb+1;
} }
if (U==myLast) { if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin); myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1; 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 { else if (!myCurveCache.IsNull()) // use cached B-spline data
myCurve->D3( U, P, V1, V2, V3); {
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, gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
const Standard_Integer N) const const Standard_Integer N) const
{ {
if ( (myTypeCurve == GeomAbs_BSplineCurve) && if (myTypeCurve == GeomAbs_BSplineCurve)
(U==myFirst || U==myLast) ) { 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; Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) { if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); 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; if (Ideb>=Ifin) Ideb = Ifin-1;
} }
return myBspl->LocalDN( U, Ideb, Ifin, N); 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); 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, Shape from GeomAbs,
Curve from GeomAdaptor, Curve from GeomAdaptor,
HCurve from Adaptor3d, HCurve from Adaptor3d,
HSurface from Adaptor3d HSurface from Adaptor3d,
Cache from BSplSLib
raises raises
NoSuchObject from Standard, NoSuchObject from Standard,
@ -386,6 +387,12 @@ is
TolV : Real = 0.0) TolV : Real = 0.0)
is private; 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 fields
mySurface : Surface from Geom; mySurface : Surface from Geom;
@ -395,5 +402,6 @@ fields
myVFirst : Real from Standard; myVFirst : Real from Standard;
myVLast : Real from Standard; myVLast : Real from Standard;
myTolU, myTolV : Real from Standard; myTolU, myTolV : Real from Standard;
mySurfaceCache : Cache from BSplSLib;
end Surface; end Surface;

View File

@ -51,6 +51,7 @@
#include <gp_Lin.hxx> #include <gp_Lin.hxx>
#include <gp_Trsf.hxx> #include <gp_Trsf.hxx>
#include <BSplCLib.hxx> #include <BSplCLib.hxx>
#include <BSplSLib_Cache.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <Standard_NoSuchObject.hxx> #include <Standard_NoSuchObject.hxx>
#include <Standard_NullObject.hxx> #include <Standard_NullObject.hxx>
@ -131,7 +132,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_BezierSurface; mySurfaceType = GeomAbs_BezierSurface;
else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(), Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(),
UFirst,ULast,VFirst,VLast); UFirst,ULast,VFirst,VLast);
} }
else if ( TheType == STANDARD_TYPE(Geom_Plane)) else if ( TheType == STANDARD_TYPE(Geom_Plane))
mySurfaceType = GeomAbs_Plane; mySurfaceType = GeomAbs_Plane;
@ -149,7 +150,12 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S,
mySurfaceType = GeomAbs_SurfaceOfExtrusion; mySurfaceType = GeomAbs_SurfaceOfExtrusion;
else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) { else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
mySurfaceType = GeomAbs_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)) else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
mySurfaceType = GeomAbs_OffsetSurface; mySurfaceType = GeomAbs_OffsetSurface;
@ -599,6 +605,19 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
return mySurface->VPeriod(); 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 //function : Value
//purpose : //purpose :
@ -607,6 +626,15 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const
gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U, gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
const Standard_Real V) const 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); 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, void GeomAdaptor_Surface::D0(const Standard_Real U,
const Standard_Real V, gp_Pnt& P) const 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); 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, void GeomAdaptor_Surface::D1(const Standard_Real U,
const Standard_Real V, const Standard_Real V,
gp_Pnt& P, gp_Pnt& P,
gp_Vec& D1U, gp_Vec& D1U,
gp_Vec& D1V ) const 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; Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} 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;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType) { switch(mySurfaceType) {
case GeomAbs_BSplineSurface: case GeomAbs_BSplineSurface:
{ if ((USide != 0 || VSide != 0) &&
if((USide==0)&&(VSide==0)){ IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
myBspl->D1(u,v,P,D1U,D1V); myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
} else if (!mySurfaceCache.IsNull())
else { {
if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide)) if (!mySurfaceCache->IsCacheValid(U, V))
myBspl->LocalD1 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V); RebuildCache(U, V);
else myBspl->D1(u,v,P,D1U,D1V); mySurfaceCache->D1(U, V, P, D1U, D1V);
}
break;
} }
else
case GeomAbs_SurfaceOfExtrusion : myBspl->D1(u, v, P, D1U, D1V);
break;
if(USide==0) myExtSurf->D1(u,v,P,D1U,D1V);
else myExtSurf->LocalD1(u,v,USide,P,D1U,D1V); case GeomAbs_SurfaceOfExtrusion:
break; if (USide==0)
myExtSurf->D1(u, v, P, D1U, D1V);
case GeomAbs_SurfaceOfRevolution : else
myExtSurf->LocalD1(u, v, USide, P, D1U, D1V);
if(VSide==0) myRevSurf->D1 (u, v, P,D1U,D1V ); break;
else myRevSurf->LocalD1 (u, v, VSide, P,D1U,D1V );
break; case GeomAbs_SurfaceOfRevolution:
if (VSide==0)
case GeomAbs_OffsetSurface : myRevSurf->D1(u, v, P, D1U, D1V);
{ else
if((USide==0)&&(VSide==0)) myOffSurf->D1 (u, v,P,D1U,D1V ); myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V);
else myOffSurf->LocalD1 (u, v, USide, VSide ,P,D1U,D1V ); break;
break;
} case GeomAbs_OffsetSurface:
default : if (USide==0 && VSide==0)
mySurface->D1(u,v,P,D1U,D1V); 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, void GeomAdaptor_Surface::D2(const Standard_Real U,
const Standard_Real V, gp_Pnt& P, const Standard_Real V,
gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Pnt& P,
gp_Vec& D2V, gp_Vec& D2UV) const 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; Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} 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 (!mySurfaceCache->IsCacheValid(U, V))
RebuildCache(U, V);
if((USide==0)&&(VSide==0)) myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); mySurfaceCache->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;}
} }
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(), Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
BS->EndPoint().XYZ().SquareModulus()); BS->EndPoint().XYZ().SquareModulus());
Standard_Real eps = Epsilon(aDist); Standard_Real eps = Epsilon(aDist);
if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps && if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
!BS->IsClosed() && !BS->IsPeriodic())
{ {
//force Closed() // Avoid creating B-splines containing two coincident poles only
gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.); if (mbspc.Degree() == 1 && nbpoles == 2)
BS->SetPole(1, aPm); continue;
BS->SetPole(BS->NbPoles(), aPm);
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); sline.Append(BS);

View File

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

View File

@ -679,20 +679,25 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol), aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol); aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
if( (aPoly1->DeflectionOverEstimation() > TolConf) || if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
(aPoly2->DeflectionOverEstimation() > TolConf)) (aPoly2->DeflectionOverEstimation() > TolConf))
{ {
const Standard_Real aDeflectionSum = const Standard_Real aDeflectionSum =
Max(aPoly1->DeflectionOverEstimation(), TolConf) + Max(aPoly1->DeflectionOverEstimation(), TolConf) +
Max(aPoly2->DeflectionOverEstimation(), TolConf); Max(aPoly2->DeflectionOverEstimation(), TolConf);
aPoly2->SetDeflectionOverEstimation(aDeflectionSum); if (nbsamplesOnC2 > nbsamplesOnC1)
aPoly1->SetDeflectionOverEstimation(aDeflectionSum); {
aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
const Bnd_Box2d aB1 = aPoly1->Bounding(), aB2 = aPoly2->Bounding(); aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
aPoly1->ComputeWithBox(C1, aB2); }
aPoly2->ComputeWithBox(C2, aB1); 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)); Standard_Real rvalf = Sign(1.,Valf(1));
for(Standard_Integer i = 2; i <= aNbSamples; ++i) for(Standard_Integer i = 2; i <= aNbSamples; ++i)
{ {
D1->SamplePoint(i,s2d, s3d); T->SamplePoint(i,s2d, s3d);
UVap(1)=s2d.X(); UVap(1)=s2d.X();
UVap(2)=s2d.Y(); UVap(2)=s2d.Y();
Func.Value(UVap,Valf); Func.Value(UVap,Valf);

View File

@ -1986,37 +1986,20 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
const Standard_Real aTol = 1.0e-14; const Standard_Real aTol = 1.0e-14;
Handle(Geom_Surface) aS1, aS2; Handle(Geom_Surface) aS1, aS2;
switch(theASurf1->GetType()) if (theASurf1->GetType() != GeomAbs_BezierSurface &&
{ theASurf1->GetType() != GeomAbs_BSplineSurface)
case GeomAbs_BezierSurface: return Standard_True;
aS1 = theASurf1->Surface().Bezier(); if (theASurf2->GetType() != GeomAbs_BezierSurface &&
break; theASurf2->GetType() != GeomAbs_BSplineSurface)
case GeomAbs_BSplineSurface: return Standard_True;
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;
}
Standard_Boolean aStatus = Standard_False; Standard_Boolean aStatus = Standard_False;
gp_Pnt aP1, aP2; gp_Pnt aP1, aP2;
gp_Vec aD1u, aD1v, aD2U, aD2V; gp_Vec aD1u, aD1v, aD2U, aD2V;
aS1->D1(theU1, theV1, aP1, aD1u, aD1v); theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v);
aS2->D1(theU2, theV2, aP2, aD2U, aD2V); theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V);
Standard_Real aSQDistPrev = aP1.SquareDistance(aP2); Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
@ -2053,8 +2036,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
gp_Pnt aPt1, aPt2; gp_Pnt aPt1, aPt2;
aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v); theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
aS2->D1(aParU, aParV, aPt2, aD2U, aD2V); theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
Standard_Real aSQDist = aPt1.SquareDistance(aPt2); Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
@ -2078,8 +2061,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
} }
else else
{ {
aS1->D1(theU1, theV1, aPt1, aD1u, aD1v); theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v);
aS2->D1(theU2, theV2, aPt2, aD2U, aD2V); theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V);
gp_Vec aP12(aPt1, aPt2); gp_Vec aP12(aPt1, aPt2);
aGradFu = -aP12.Dot(aD1u); 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 uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf); Standard_Real uMax = (cf < cl ? cl : cf);
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { 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 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 LowBound = GAC.Value(uMin);
gp_Pnt HigBound = C3D->Value(uMax); gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D); distmin = LowBound.Distance(P3D);
if (distmin <= prec) { if (distmin <= prec) {
param = uMin; 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()) { if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767 //modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost" //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 uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf); Standard_Real uMax = (cf < cl ? cl : cf);
Standard_Real distmin = Precision::Infinite(); Standard_Real distmin = Precision::Infinite();
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { 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 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 LowBound = GAC.Value(uMin);
gp_Pnt HigBound = C3D->Value(uMax); gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D); distmin = LowBound.Distance(P3D);
if (distmin <= prec) { if (distmin <= prec) {
param = uMin; param = uMin;
@ -421,7 +422,6 @@ Standard_Real ShapeAnalysis_Curve::NextProject(const Standard_Real paramPrev,
} }
} }
GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (!C3D->IsClosed()) { if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767 //modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost" //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); Handle(Geom_TrimmedCurve) aC = Handle(Geom_TrimmedCurve)::DownCast(curve);
return GetSamplePoints(aC->BasisCurve(),first,last,seq); return GetSamplePoints(aC->BasisCurve(),first,last,seq);
} }
GeomAdaptor_Curve GAC(curve);
Standard_Real step = ( last - first ) / (Standard_Real)( nbp - 1 ); Standard_Real step = ( last - first ) / (Standard_Real)( nbp - 1 );
Standard_Real par = first, stop = last - 0.5 * step; Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step ) for ( ; par < stop; par += step )
seq.Append(curve->Value(par)); seq.Append(GAC.Value(par));
seq.Append(curve->Value(last)); seq.Append(GAC.Value(last));
return Standard_True; 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 step = ( last - first ) / (Standard_Real)( nbs - 1 );
Standard_Real par = first, stop = last - 0.5 * step; Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step ) for ( ; par < stop; par += step )
seq.Append(curve->Value(par)); seq.Append(C.Value(par));
seq.Append(curve->Value(last)); seq.Append(C.Value(last));
return Standard_True; return Standard_True;
/* /*
Standard_Integer i; 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) // from 3d curve (but only if edge is SameParameter)
static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge, static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge,
const Handle(ShapeAnalysis_Surface) &surf, const Handle(ShapeAnalysis_Surface) &surf,
const Handle(Geom2d_Curve) &Crv2d, const Geom2dAdaptor_Curve &Crv2d,
const Standard_Real param ) const Standard_Real param )
{ {
if ( BRep_Tool::SameParameter ( edge ) ) { if ( BRep_Tool::SameParameter ( edge ) ) {
@ -1078,7 +1078,8 @@ static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge,
if ( ! ConS.IsNull() ) if ( ! ConS.IsNull() )
return ConS->Value ( param ).Transformed ( L.Transformation() ); 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(); const IntRes2d_Transition &Tr2 = IP.TransitionOfSecond();
if ( Tr1.PositionOnCurve() != IntRes2d_Middle && if ( Tr1.PositionOnCurve() != IntRes2d_Middle &&
Tr2.PositionOnCurve() != IntRes2d_Middle ) continue; 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 dist21 = pnt1.SquareDistance ( pint );
Standard_Real dist22 = pnt2.SquareDistance ( pint ); Standard_Real dist22 = pnt2.SquareDistance ( pint );
if ( dist21 > tol1 * tol1 && dist22 > tol2 * tol2 ) { 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; Standard_Real tolint = 1.0e-10;
//szv#4:S4163:12Mar99 warning //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 ); 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! //:64 abv 25 Dec 97: Attention!
// Since Intersection algorithm is not symmetrical, for consistency with BRepCheck // 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; param2-b2 > ::Precision::PConfusion() ) continue;
//:82 abv 21 Jan 98: point of intersection on Crv1 and Crv2 is different //: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 pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) ); gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) );
gp_Pnt pint = 0.5 * ( pi1.XYZ() + pi2.XYZ() ); gp_Pnt pint = 0.5 * ( pi1.XYZ() + pi2.XYZ() );
Standard_Real di1 = pi1.SquareDistance ( pnt ); Standard_Real di1 = pi1.SquareDistance ( pnt );
Standard_Real di2 = pi2.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; Tr2.PositionOnCurve() != IntRes2d_Middle ) continue;
Standard_Real param1 = IP.ParamOnFirst(); Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond(); Standard_Real param2 = IP.ParamOnSecond();
gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) ); gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 );
Standard_Boolean OK1 = Standard_False; Standard_Boolean OK1 = Standard_False;
Standard_Boolean OK2 = 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); myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False; 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 ( E1.Orientation() == TopAbs_REVERSED ) v1.Reverse();
if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) { if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) {
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False; return Standard_False;
} }
c2d->D1 ( a, p2d2, v2 ); anAdapt.Load(c2d);
anAdapt.D1(a, p2d2, v2);
if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse(); if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse();
v12 = p2d2.XY() - p2d1.XY(); v12 = p2d2.XY() - p2d1.XY();
myMax2d = v12.SquareMagnitude(); myMax2d = v12.SquareMagnitude();

View File

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

View File

@ -1281,6 +1281,16 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
found = (staout != clas.Perform (unp1,Standard_False)); 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(found) {
if(stb==TopAbs_IN) stb = TopAbs_OUT; if(stb==TopAbs_IN) stb = TopAbs_OUT;

View File

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

View File

@ -3132,7 +3132,11 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges()
myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
} }
else 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--; i--;
if(!Context().IsNull()) //skl 07.03.2002 for OCC180 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"); TP->AddWarning(C3D,"Update of 3D-Parameters has failed");
//:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends //: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 ); temp1 = pU1.Distance ( pv1 );
temp2 = pU2.Distance ( pv2 ); temp2 = pU2.Distance ( pv2 );
if ( temp1 > preci || temp2 > preci ) { 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(x1,f1); f1-=K;
F.Value(x2,f2); f2-=K; F.Value(x2,f2); f2-=K;
//-- printf("\n *************** RECHERCHE MINIMUM **********\n"); //-- 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) ", //-- 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); //-- x0,f0,x1,f1,x2,f2,x3,f3);
if(recherche_minimum) { if(recherche_minimum) {

View File

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

View File

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

View File

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

View File

@ -18,7 +18,10 @@ compound result
repeat 21 { repeat 21 {
plane p_$i 0 $i*100 0 0 1 0 plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i 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 compound result s_$i result
set dist [expr $i * 100] set dist [expr $i * 100]
puts "OK Section:$dist" puts "OK Section:$dist"

View File

@ -8,7 +8,10 @@ set i 1
repeat 199 { repeat 199 {
plane p_$i 0 $i*100 0 0 1 0 plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i 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 compound result s_$i result
set dist [expr $i * 100] set dist [expr $i * 100]
puts "OK Section:$dist" puts "OK Section:$dist"

View File

@ -1,7 +1,7 @@
# test script on make volume operation # test script on make volume operation
# cone cylinder plane # cone cylinder plane
puts "TODO OCC26020 ALL: Error: bopcheck failed" puts "TODO OCC26020 Windows: Error: bopcheck failed"
# planar face # planar face
plane pln_f1 27.577164466275352 -1038.2137499999999 27.577164466275359 0.70710678118654746 4.4408920985006262e-016 0.70710678118654768 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 } catch { OFFSETSHAPE $distance {} $calcul $type }
set square 253.552 set square 253.902
set nb_v_good 2 set nb_v_good 2
set nb_e_good 3 set nb_e_good 3

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,8 +7,6 @@ puts ""
## After command sew in DRAW on attached shape free wires are disappeared. ## 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 restore [locate_data_file OCC714.brep] a
checkshape a checkshape a

View File

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

View File

@ -10,12 +10,12 @@ pload QAcommands
set status 0 set status 0
set info1 [OCC24303 4] set info1 [OCC24303 5]
regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution
regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance
if { [info exists Sol4] } { if { [info exists Sol5] } {
set info2 [dump Sol4] set info2 [dump Sol5]
regexp {Center +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full CenterX CenterY 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 {XAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full XAxisX XAxisY
regexp {YAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full YAxisX YAxisY 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 checkmaxtol result 0.0076621571738049385
checknbshapes result -shell 1 checknbshapes result -shell 1
checkfreebounds result 2 checkfreebounds result 0
set 2dviewer 1 set 2dviewer 1

View File

@ -20,15 +20,15 @@ compound vl v1l vnl vol vil result
set nbshapes_expected " set nbshapes_expected "
Number of shapes in shape Number of shapes in shape
VERTEX : 169 VERTEX : 165
EDGE : 85 EDGE : 83
WIRE : 0 WIRE : 0
FACE : 0 FACE : 0
SHELL : 0 SHELL : 0
SOLID : 0 SOLID : 0
COMPSOLID : 0 COMPSOLID : 0
COMPOUND : 1 COMPOUND : 1
SHAPE : 255 SHAPE : 249
" "
checknbshapes result -ref ${nbshapes_expected} -t -m "HLRToShape" 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 deltaZ [dval dvz1-dvz2]
set percent_max 0.1 set percent_max 0.1
set good_deltaX 4.4408920985006262e-015 set good_deltaX -3.5527136788005009e-015
set good_deltaY -4.6629367034256575e-015 set good_deltaY -3.5527136788005009e-015
set good_deltaZ -2.6645352591003757e-015 set good_deltaZ 8.8817841970012523e-016
set deltaX_percent [GetPercent ${deltaX} ${good_deltaX}] set deltaX_percent [GetPercent ${deltaX} ${good_deltaX}]
puts "deltaX_percent = ${deltaX_percent}" 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) set env(os_type) $tcl_platform(platform)
if { [string compare $env(os_type) "windows"] != 0 } { if { [string compare $env(os_type) "windows"] != 0 } {
puts "OS = Linux" puts "OS = Linux"
set good_tri 520414 set good_tri 615414
set good_nod 263938 set good_nod 311438
set good_defl 0.0026800432954056617 set good_defl 0.0032657364637550075
} else { } else {
puts "OS = Windows NT" puts "OS = Windows NT"
set good_tri 520414 set good_tri 615414
set good_nod 263938 set good_nod 311438
set good_defl 0.0026800432954056617 set good_defl 0.0032657364637550075
} }
proc GetPercent {Value GoodValue} { proc GetPercent {Value GoodValue} {

View File

@ -26,7 +26,7 @@ if [catch { igesbrep $filepath a * } res] {
checkmaxtol result 2.5472812372261969e-005 checkmaxtol result 2.5472812372261969e-005
checknbshapes result -shell 13 checknbshapes result -shell 13
checkfreebounds result 1249 checkfreebounds result 1247
} }
set 2dviewer 0 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 "========="
puts " OCC498 " puts " OCC498 "
puts "=========" puts "========="

View File

@ -25,16 +25,16 @@ set tol_abs 1.0e-05
set tol_rel 0.01 set tol_rel 0.01
set expected_dmax 0.0013771610718045313 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 "dmax" ${dmax} ${expected_dmax} ${tol_abs} ${tol_rel}
checkreal "ufmax" ${ufmax} ${expected_ufmax} ${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} } { if { ${ulmax} != ${expected_ulmax} } {
puts "Error : bad value of ulmax=${ulmax}" puts "Error : bad value of ulmax=${ulmax}"
} }
set expected_i 69 set expected_i 73
if { ${i} != ${expected_i} } { if { ${i} != ${expected_i} } {
puts "Error : bad value of i=${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 # !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: TPSTAT : Faulty"
set filename UKI60095.igs 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 ) 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 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 ) NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = YELLOW ( YELLOW ) COLORS : Colors = YELLOW ( YELLOW )

View File

@ -8,10 +8,10 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 1091 ) Summary = 42 ( 1091 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 1091 ) Summary = 42 ( 1091 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 ( 10005 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 2 ( 2 ) NCOLORS : NColors = 2 ( 2 )
COLORS : Colors = GREEN RED ( GREEN RED ) COLORS : Colors = GREEN RED ( GREEN RED )

View File

@ -7,9 +7,9 @@ set filename CTS21655.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 12 ) Warnings = 0 ( 1 ) Summary = 0 ( 13 ) DATA : Faulties = 0 ( 12 ) Warnings = 0 ( 1 ) Summary = 0 ( 13 )
TPSTAT : Faulties = 0 ( 28 ) Warnings = 116 ( 7 ) Summary = 116 ( 35 ) TPSTAT : Faulties = 0 ( 28 ) Warnings = 116 ( 7 ) Summary = 116 ( 35 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 1 ) Solids = 0 ( 1 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 1 ) Solids = 0 ( 1 )
NBSHAPES : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) Summary = 15092 ( 7703 ) NBSHAPES : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) Summary = 15073 ( 7693 )
STATSHAPE : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6291 ( 3138 ) 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 ) 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 ) 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 ) 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 # !!!! 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: 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 filename FRA62468-1.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) 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 ) 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 ) 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 = 29043 ( 29075 ) 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.01115315301 ( 0.0111584608 ) TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01114309412 ( 0.01115568387 )
LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4437 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9895 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9829 ) LayerLabels = 5391 ( 9829 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 ) NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 CYAN1 GREEN ( BLACK BLUE1 CYAN1 GREEN ) 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 # !!!! 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: LABELS : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
set LinuxDiff 3 set LinuxDiff 3
set filename PRO14319.igs set filename PRO14319.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 2 ( 64 ) Summary = 2 ( 64 ) TPSTAT : Faulties = 1 ( 0 ) Warnings = 3 ( 64 ) Summary = 4 ( 64 )
CHECKSHAPE : Wires = 1 ( 7 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) CHECKSHAPE : Wires = 3 ( 5 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7360 ( 7320 ) 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 = 3632 ( 3603 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3842 ( 3895 )
TOLERANCE : MaxTol = 0.3749733839 ( 0.3140268243 ) AvgTol = 0.002809949164 ( 0.0005120147149 ) TOLERANCE : MaxTol = 0.3140268251 ( 0.3140268243 ) AvgTol = 0.0009762560334 ( 0.000488212708 )
LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 788 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 849 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 849 ) LayerLabels = 0 ( 0 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 ) NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = CYAN1 GREEN WHITE ( CYAN1 GREEN WHITE ) 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 # !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty"
set filename 12ls328.igs set filename 12ls328.igs
set ref_data { set ref_data {

View File

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

View File

@ -10,7 +10,7 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 444 ( 1005 ) Summary = 444 ( 1005 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 444 ( 1005 ) Summary = 444 ( 1005 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 ) 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 ) 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 # !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 2 set LinuxDiff 2
set filename brazo1.igs set filename brazo1.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 ) 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 ) 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 ) 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 = 2144 ( 2074 ) 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.01125801875 ( 0.01225981249 ) TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01133191355 ( 0.01225911215 )
LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 242 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 465 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 465 ) LayerLabels = 223 ( 465 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 ) NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 MAGENTA1 YELLOW ( BLUE1 MAGENTA1 YELLOW ) 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 ) 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 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 ) NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = BLACK ( BLACK ) COLORS : Colors = BLACK ( BLACK )

View File

@ -7,10 +7,10 @@ set filename ims003.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 38 ( 183 ) Summary = 38 ( 183 ) 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 ) 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 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 5 ( 5 ) NCOLORS : NColors = 5 ( 5 )

View File

@ -1,18 +1,19 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! 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: LABELS : Faulty"
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 5 set LinuxDiff 5
set filename BUC60743.igs set filename BUC60743.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 ) DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 )
TPSTAT : Faulties = 3 ( 59 ) Warnings = 2205 ( 4736 ) Summary = 2208 ( 4795 ) TPSTAT : Faulties = 3 ( 59 ) Warnings = 2203 ( 4655 ) Summary = 2206 ( 4714 )
CHECKSHAPE : Wires = 7 ( 16 ) Faces = 6 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) CHECKSHAPE : Wires = 7 ( 17 ) Faces = 7 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 2837 ) Summary = 45907 ( 39191 ) NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 2837 ) Summary = 45927 ( 39202 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19595 ( 16764 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19607 ( 16774 )
TOLERANCE : MaxTol = 3.742696236 ( 5.769095076 ) AvgTol = 0.01636161939 ( 0.01749445935 ) TOLERANCE : MaxTol = 4.854604894 ( 5.769095076 ) AvgTol = 0.01628658326 ( 0.01747356296 )
LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6319 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6330 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6319 ) LayerLabels = 2411 ( 5257 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 ) NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 RED YELLOW ( BLACK BLUE1 RED YELLOW ) 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 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 56 ( 12 ) Summary = 56 ( 12 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 56 ( 12 ) Summary = 56 ( 12 )
CHECKSHAPE : Wires = 2 ( 1 ) Faces = 2 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 ( 10687 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 ) NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ( CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ) 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 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 191 ) Summary = 88 ( 191 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 191 ) Summary = 88 ( 191 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 ( 3350 ) 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 ) 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 ) 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 ) 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 # !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
puts "TODO CR25923 ALL: NBSHAPES : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty"
#puts "TODO CR23096 ALL: Error : 1 differences with reference data found :" puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: Error : 2 differences with reference data found"
set LinuxDiff 1 set LinuxDiff 1
set filename FRA62468-2.igs set filename FRA62468-2.igs
set ref_data { set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 349 ( 5016 ) Summary = 349 ( 5016 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 253 ( 4993 ) Summary = 253 ( 4993 )
CHECKSHAPE : Wires = 12 ( 19 ) Faces = 12 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) CHECKSHAPE : Wires = 8 ( 11 ) Faces = 8 ( 7 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63090 ( 63144 ) 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 = 26766 ( 26793 ) 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.01154225009 ( 0.01155173987 ) TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01153089031 ( 0.01154870945 )
LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3844 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 9009 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8933 ) LayerLabels = 5086 ( 8933 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 ) NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 CYAN1 GREEN ( BLUE1 CYAN1 GREEN ) 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: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty" puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set filename PRO10626.igs set filename PRO10626.igs
@ -11,8 +11,8 @@ set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 2 ( 0 ) Warnings = 85 ( 295 ) Summary = 87 ( 295 ) TPSTAT : Faulties = 2 ( 0 ) Warnings = 85 ( 295 ) Summary = 87 ( 295 )
CHECKSHAPE : Wires = 8 ( 13 ) Faces = 8 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 = 2221 ( 2228 ) 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 ) 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 ) 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 ) 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 ) DATA : Faulties = 0 ( 1 ) Warnings = 0 ( 0 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 650 ( 1843 ) Summary = 650 ( 1843 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 650 ( 1843 ) Summary = 650 ( 1843 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 ( 7869 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 4 ) NCOLORS : NColors = 3 ( 4 )
COLORS : Colors = CYAN1 WHITE YELLOW ( CYAN1 GREEN3 WHITE YELLOW ) 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 ) 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 ) 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 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 7 ( 7 ) NCOLORS : NColors = 7 ( 7 )

View File

@ -1,5 +1,6 @@
# !!!! This file is generated automatically, do not edit manually! See end script # !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: NBSHAPES : Faulty" puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: COLORS : Faulty" puts "TODO CR23096 ALL: COLORS : Faulty"
puts "TODO CR25013 ALL: Error : 3 differences with reference data found" 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 ) DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 3 ) Warnings = 274 ( 4465 ) Summary = 274 ( 4468 ) TPSTAT : Faulties = 0 ( 3 ) Warnings = 274 ( 4465 ) Summary = 274 ( 4468 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) 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 ) 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 = 17933 ( 17940 ) 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 ) 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 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 5 ) NCOLORS : NColors = 4 ( 5 )
COLORS : Colors = BLUE1 CYAN1 GOLD3 GREEN ( BLUE1 CYAN1 GOLD3 GREEN YELLOW ) 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