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.
#include <Standard_NotImplemented.hxx>
#include <Adaptor3d_TopolTool.ixx>
#include <Precision.hxx>
+#include <GeomAdaptor_Surface.hxx>
#include <gp_Cone.hxx>
#include <gp_Pnt.hxx>
Standard_Real tol = Max(0.01*aDefl2, 1.e-9);
Standard_Integer l;
+ // Calculations of B-spline values will be made using adaptor,
+ // because it caches the data for performance
+ GeomAdaptor_Surface aBSplAdaptor(aBS);
+
anUFlg(1) = Standard_True;
anUFlg(nbsu) = Standard_True;
//myNbSamplesU = 2;
}
t2 = anUPars(j);
- gp_Pnt p1 = aBS->Value(t2, t1);
+// gp_Pnt p1 = aBS->Value(t2, t1);
+ gp_Pnt p1 = aBSplAdaptor.Value(t2, t1);
for(k = j+2; k <= nbsu; ++k) {
t2 = anUPars(k);
- gp_Pnt p2 = aBS->Value(t2, t1);
+// gp_Pnt p2 = aBS->Value(t2, t1);
+ gp_Pnt p2 = aBSplAdaptor.Value(t2, t1);
//gce_MakeLin MkLin(p1, p2);
//const gp_Lin& lin = MkLin.Value();
break;
}
- gp_Pnt pp = aBS->Value(anUPars(l), t1);
+// gp_Pnt pp = aBS->Value(anUPars(l), t1);
+ gp_Pnt pp = aBSplAdaptor.Value(anUPars(l), t1);
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;
}
t2 = aVPars(j);
- gp_Pnt p1 = aBS->Value(t1, t2);
+// gp_Pnt p1 = aBS->Value(t1, t2);
+ gp_Pnt p1 = aBSplAdaptor.Value(t1, t2);
for(k = j+2; k <= nbsv; ++k) {
t2 = aVPars(k);
- gp_Pnt p2 = aBS->Value(t1, t2);
+// gp_Pnt p2 = aBS->Value(t1, t2);
+ gp_Pnt p2 = aBSplAdaptor.Value(t1, t2);
if(p1.SquareDistance(p2) <= tol) continue;
//gce_MakeLin MkLin(p1, p2);
break;
}
- gp_Pnt pp = aBS->Value(t1, aVPars(l));
+// gp_Pnt pp = aBS->Value(t1, aVPars(l));
+ gp_Pnt pp = aBSplAdaptor.Value(t1, aVPars(l));
Standard_Real d = lin.SquareDistance(pp);
if(d <= aDefl2) continue;
aTV1=aTV - dt;
}
//
- aC2D->D0 (aTV1, aPV1);
- aC2D->D0 (aTV, aPV);
+ aGAC2D.D0 (aTV1, aPV1);
+ aGAC2D.D0 (aTV, aPV);
//
aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
//
aTolInt=1.e-10;
//
BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol);
+ aGAC1.Load(aC2D, aT1, aT2);
//
aTV=BRep_Tool::Parameter (aV, aE, myFace);
- aC2D->D0(aTV, aPV);
+ aGAC1.D0(aTV, aPV);
//
aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
//
- aGAC1.Load(aC2D, aT1, aT2);
- aC2D->D0(aT1, aP1);
- aC2D->D0(aT2, aP2);
+ aGAC1.D0(aT1, aP1);
+ aGAC1.D0(aT2, aP2);
aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
//
for (i=0; i<2; ++i) {
}
//
aT=aT1max + aCf*dT;
- aC2D->D0(aT, aP);
+ aGAC1.D0(aT, aP);
gp_Vec2d aV2D(aPV, aP);
gp_Dir2d aDir2D(aV2D);
//
dU=-dU;
}
//
- aC2D->D0(aU, aP2D0);
+ aBAC2D.D0(aU, aP2D0);
for(i=2; i<=aNbS; i++) {
aU=aU1+(i-1)*dU;
- aC2D->D0(aU, aP2D1);
+ aBAC2D.D0(aU, aP2D1);
aP2D0.Coord(aX0, aY0);
aP2D1.Coord(aX1, aY1);
//
static
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
- const Handle(Geom_Surface)& aS,
+ const GeomAdaptor_Surface& aS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2);
aT=BRep_Tool::Parameter(aV, aE);
//
aC2D->D0(aT, aP2D);
- aS->D0(aP2D.X(), aP2D.Y(), aP);
+ aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD2=aPV.SquareDistance(aP);
if (aD2>aD2max) {
aD2max=aD2;
continue;
}
//
- aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
+ aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
if (aD2>aD2max) {
aD2max=aD2;
}
//=======================================================================
Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
const TopoDS_Face& aF,
- const Handle(Geom_Surface)& aS,
+ const GeomAdaptor_Surface& aGAS,
const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2)
{
}
//
aP2D = aPoint.Value();
- aS->D0(aP2D.X(), aP2D.Y(), aP);
+ aGAS.D0(aP2D.X(), aP2D.Y(), aP);
aD=aPV.SquareDistance(aP);
if (aD > aDist) {
aDist = 1.01 * aD;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
- Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast);
- aC3D->D0(aT, aPc);
+ GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
+ aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
- Handle(Geom_Curve) aC3D=aC.Curve();
- aC3D->D0(aT, aPc);
+ GeomAdaptor_Curve aCA( aC.Curve() );
+ aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
}
static
- void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
+ void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
const Standard_Real aPrm,
gp_Pnt2d& Pnt,
gp_Vec2d& aVec2d);
C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
if(C2d.IsNull())
continue;
+ Geom2dAdaptor_Curve aCA(C2d);
aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
- aPnt = C2d->Value(aParam);
+ aPnt = aCA.Value(aParam);
if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
continue;
- CurveDirForParameter(C2d, aParam, aPnt, aDer);
+ CurveDirForParameter(aCA, aParam, aPnt, aDer);
if (aVOrientation == anE.Orientation())
aDer.Reverse();
//function : CurveDirForParameter
//purpose :
//=======================================================================
-void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
- const Standard_Real aPrm,
- gp_Pnt2d& Pnt,
- gp_Vec2d& aVec2d)
+void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
+ const Standard_Real aPrm,
+ gp_Pnt2d& Pnt,
+ gp_Vec2d& aVec2d)
{
Standard_Real aTol=gp::Resolution();
Standard_Integer i;
- aC2d->D1(aPrm, Pnt, aVec2d);
+ aC2d.D1(aPrm, Pnt, aVec2d);
//
if (aVec2d.Magnitude() <= aTol) {
for (i = 2; i <= 100; i++){
- aVec2d = aC2d->DN(aPrm, i);
+ aVec2d = aC2d.DN(aPrm, i);
if (aVec2d.Magnitude() > aTol) {
- break;
+ break;
}
}
}
// otherwise preserve only one of its representations.
//----------------------------------------------------------
if (!BRep_Tool::Degenerated(E)) {
+ Standard_Real aParTol = 2.0 * Precision::PConfusion();
for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) ||
-
- Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) {
+ Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= aParTol) {
if(k+1 == TheVer.Length()) {
StoreInMap(TheVer(k), TheVer(k+1), MapVV);
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_HCurve.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomProjLib.hxx>
const Standard_Real theFirst,
const Standard_Real theLast)
:
- myCurve(theC3D),
- myPCurve(theC2D),
- mySurf(theSurf),
myFirst(theFirst),
myLast(theLast)
{
+ myCurve = new GeomAdaptor_HCurve(theC3D);
+ myPCurve = new Geom2dAdaptor_HCurve(theC2D);
+ mySurf = new GeomAdaptor_HSurface(theSurf);
}
//
virtual Standard_Integer NbVariables() const {
return ((myFirst <= theParam) && (theParam <= myLast));
}
- Handle(Geom_Curve) myCurve;
- Handle(Geom2d_Curve) myPCurve;
- Handle(Geom_Surface) mySurf;
+ Handle(GeomAdaptor_HCurve) myCurve;
+ Handle(Geom2dAdaptor_HCurve) myPCurve;
+ Handle(GeomAdaptor_HSurface) mySurf;
Standard_Real myFirst;
Standard_Real myLast;
};
Standard_Real cl = C->LastParameter();
Standard_Real epsilon = Precision::PConfusion();
Standard_Boolean periodic = C->IsPeriodic();
-
+ GeomAdaptor_Curve aCA(C);
TopoDS_Vertex V1,V2;
if (periodic) {
Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1);
Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2);
gp_Pnt P1,P2;
- if (!p1inf) P1 = C->Value(p1);
- if (!p2inf) P2 = C->Value(p2);
+ if (!p1inf) P1 = aCA.Value(p1);
+ if (!p2inf) P2 = aCA.Value(p2);
Standard_Real preci = BRepLib::Precision();
BRep_Builder B;
// check for closed curve
Standard_Boolean closed = Standard_False;
+ Standard_Boolean degenerated = Standard_False;
if (!p1inf && !p2inf)
closed = (P1.Distance(P2) <= preci);
V2 = V1;
else {
if (!V1.IsSame(V2)) {
- myError = BRepLib_DifferentPointsOnClosedCurve;
- return;
+ myError = BRepLib_DifferentPointsOnClosedCurve;
+ return;
}
else if (P1.Distance(BRep_Tool::Pnt(V1)) >
- Max(preci,BRep_Tool::Tolerance(V1))) {
- myError = BRepLib_DifferentPointsOnClosedCurve;
- return;
+ Max(preci,BRep_Tool::Tolerance(V1))) {
+ myError = BRepLib_DifferentPointsOnClosedCurve;
+ return;
+ }
+ else
+ {
+ gp_Pnt PM = aCA.Value((p1+p2)/2);
+ if (P1.Distance(PM) < preci)
+ degenerated = Standard_True;
}
}
}
B.Add(E,V2);
}
B.Range(E,p1,p2);
+ B.Degenerated(E, degenerated);
myError = BRepLib_EdgeDone;
Done();
is
+
+ imported transient class Cache;
imported EvaluatorFunction ;
-- If rational computes the homogeneous Taylor expension
-- for the numerator and stores it in CachePoles
+ BuildCache(theParameter : Real;
+ theSpanDomain : Real;
+ thePeriodicFlag : Boolean ;
+ theDegree : Integer;
+ theFlatKnots : Array1OfReal from TColStd ;
+ thePoles : Array1OfPnt from TColgp;
+ theWeights : Array1OfReal from TColStd ;
+ theCacheArray : in out Array2OfReal from TColStd) ;
+ ---Purpose: Perform the evaluation of the Taylor expansion
+ -- of the Bspline normalized between 0 and 1.
+ -- Structure of result optimized for BSplCLib_Cache.
+
+ BuildCache(theParameter : Real;
+ theSpanDomain : Real;
+ thePeriodicFlag : Boolean ;
+ theDegree : Integer;
+ theFlatKnots : Array1OfReal from TColStd ;
+ thePoles : Array1OfPnt2d from TColgp;
+ theWeights : Array1OfReal from TColStd ;
+ theCacheArray : in out Array2OfReal from TColStd) ;
+ ---Purpose: Perform the evaluation of the Taylor expansion
+ -- of the Bspline normalized between 0 and 1.
+ -- Structure of result optimized for BSplCLib_Cache.
+
PolesCoefficients(Poles : Array1OfPnt2d from TColgp;
CachePoles : in out Array1OfPnt2d from TColgp);
---Warning: To be used for Beziercurves ONLY!!!
-- all u1 and u0 in the domain of the curve f(u)
-- | u1 - u0 | < UTolerance and
-- we have |f (u1) - f (u0)| < Tolerance3D
+
end BSplCLib;
{
// replaced by simple dichotomy (RLE)
Ilc = XX.Lower();
+ if (XX.Length() <= 1) return;
const Standard_Real *px = &XX(Ilc);
px -= Ilc;
--- /dev/null
+// 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]);
+}
+
--- /dev/null
+// 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
// xab : 12-Mar-96 : added MovePointAndTangent
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_Array2OfReal.hxx>
#include <gp_Vec2d.hxx>
#include <Standard_ConstructionError.hxx>
#include <PLib.hxx>
}
}
+void BSplCLib::BuildCache(const Standard_Real theParameter,
+ const Standard_Real theSpanDomain,
+ const Standard_Boolean thePeriodicFlag,
+ const Standard_Integer theDegree,
+ const TColStd_Array1OfReal& theFlatKnots,
+ const Array1OfPoints& thePoles,
+ const TColStd_Array1OfReal& theWeights,
+ TColStd_Array2OfReal& theCacheArray)
+{
+ Standard_Real aParam = theParameter;
+ Standard_Integer anIndex = 0;
+ Standard_Integer aDimension;
+ Standard_Boolean isRational;
+
+ BSplCLib_DataContainer dc(theDegree);
+ PrepareEval(aParam,
+ anIndex,
+ aDimension,
+ isRational,
+ theDegree,
+ thePeriodicFlag,
+ thePoles,
+ theWeights,
+ theFlatKnots,
+ (BSplCLib::NoMults()),
+ dc);
+ //
+ // Watch out : PrepareEval checks if locally the Bspline is polynomial
+ // therefore rational flag could be set to False even if there are
+ // Weights. The Dimension is set accordingly.
+ //
+
+ Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the curve is locally polynomial
+ (&theWeights != NULL && !isRational) ? aDimension + 1 : aDimension;
+
+ BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles);
+
+ Standard_Real aCoeff = 1.0;
+ Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
+ Standard_Real* aPolyCoeffs = dc.poles;
+
+ for (Standard_Integer i = 0; i <= theDegree; i++)
+ {
+ for (Standard_Integer j = 0; j< aDimension; j++)
+ aCache[j] = aPolyCoeffs[j] * aCoeff;
+ aCoeff *= theSpanDomain / (i+1);
+ aPolyCoeffs += aDimension;
+ aCache += aDimension;
+ if (aCacheShift > aDimension)
+ {
+ aCache[0] = 0.0;
+ aCache++;
+ }
+ }
+
+ if (aCacheShift > aDimension)
+ theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
+}
+
//=======================================================================
//function : Interpolate
//purpose :
BSplCLib_BzSyntaxes.cxx
BSplCLib_CurveComputation.gxx
BSplCLib_EvaluatorFunction.hxx
-
+BSplCLib_Cache.hxx
+BSplCLib_Cache.cxx
is
+
+ imported transient class Cache;
imported EvaluatorFunction ;
---Purpose:
--
--
+ BuildCache(theU, theV : Real;
+ theUSpanDomain, theVSpanDomain : Real;
+ theUPeriodic, theVPeriodic : Boolean;
+ theUDegree, theVDegree : Integer;
+ theUIndex, theVIndex : Integer;
+ theUFlatKnots, theVFlatKnots : Array1OfReal from TColStd;
+ thePoles : Array2OfPnt from TColgp;
+ theWeights : Array2OfReal from TColStd;
+ theCacheArray : in out Array2OfReal from TColStd);
+ ---Purpose: Perform the evaluation of the Taylor expansion
+ -- of the Bspline normalized between 0 and 1.
+ -- Structure of result optimized for BSplSLib_Cache.
+
CacheD0(U,V : Real;
UDegree,VDegree : Integer;
UCacheParameter,VCacheParameter : Real;
}
}
+void BSplSLib::BuildCache(const Standard_Real theU,
+ const Standard_Real theV,
+ const Standard_Real theUSpanDomain,
+ const Standard_Real theVSpanDomain,
+ const Standard_Boolean theUPeriodicFlag,
+ const Standard_Boolean theVPeriodicFlag,
+ const Standard_Integer theUDegree,
+ const Standard_Integer theVDegree,
+ const Standard_Integer theUIndex,
+ const Standard_Integer theVIndex,
+ const TColStd_Array1OfReal& theUFlatKnots,
+ const TColStd_Array1OfReal& theVFlatKnots,
+ const TColgp_Array2OfPnt& thePoles,
+ const TColStd_Array2OfReal& theWeights,
+ TColStd_Array2OfReal& theCacheArray)
+{
+ Standard_Boolean flag_u_or_v;
+ Standard_Integer d1, d2;
+ Standard_Real u1, u2;
+ Standard_Boolean isRationalOnParam = (&theWeights != NULL);
+ Standard_Boolean isRational;
+
+ BSplSLib_DataContainer dc(theUDegree, theVDegree);
+ flag_u_or_v =
+ PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree,
+ isRationalOnParam, isRationalOnParam,
+ theUPeriodicFlag, theVPeriodicFlag,
+ thePoles, theWeights,
+ theUFlatKnots, theVFlatKnots,
+ (BSplCLib::NoMults()), (BSplCLib::NoMults()),
+ u1, u2, d1, d2, isRational, dc);
+
+ Standard_Integer d2p1 = d2 + 1;
+ Standard_Integer aDimension = isRational ? 4 : 3;
+ Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial
+ (isRationalOnParam && !isRational) ? aDimension + 1 : aDimension;
+
+ Standard_Real aDomains[2];
+ // aDomains[0] corresponds to variable with minimal degree
+ // aDomains[1] corresponds to variable with maximal degree
+ if (flag_u_or_v)
+ {
+ aDomains[0] = theUSpanDomain;
+ aDomains[1] = theVSpanDomain;
+ }
+ else
+ {
+ aDomains[0] = theVSpanDomain;
+ aDomains[1] = theUSpanDomain;
+ }
+
+ BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles);
+ for (Standard_Integer kk = 0; kk <= d1 ; kk++)
+ BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1));
+
+ Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
+ Standard_Real* aPolyCoeffs = dc.poles;
+
+ Standard_Real aFactors[2];
+ // aFactors[0] corresponds to variable with minimal degree
+ // aFactors[1] corresponds to variable with maximal degree
+ aFactors[1] = 1.0;
+ Standard_Integer aRow, aCol, i;
+ Standard_Real aCoeff;
+ for (aRow = 0; aRow <= d2; aRow++)
+ {
+ aFactors[0] = 1.0;
+ for (aCol = 0; aCol <= d1; aCol++)
+ {
+ aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension;
+ aCoeff = aFactors[0] * aFactors[1];
+ for (i = 0; i < aDimension; i++)
+ aCache[i] = aPolyCoeffs[i] * aCoeff;
+ aCache += aCacheShift;
+ aFactors[0] *= aDomains[0] / (aCol + 1);
+ }
+ aFactors[1] *= aDomains[1] / (aRow + 1);
+ }
+
+ // Fill the weights for the surface which is not locally polynomial
+ if (aCacheShift > aDimension)
+ {
+ aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
+ aCache += aCacheShift - 1;
+ for (aRow = 0; aRow <= d2; aRow++)
+ for (aCol = 0; aCol <= d1; aCol++)
+ {
+ *aCache = 0.0;
+ aCache += aCacheShift;
+ }
+ theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
+ }
+}
+
+
//=======================================================================
//function : CacheD0
//purpose : Evaluates the polynomial cache of the Bspline Curve
--- /dev/null
+// 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);
+}
+
--- /dev/null
+// 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
BSplSLib_BzSyntaxes.cxx
BSplSLib_EvaluatorFunction.hxx
-
+BSplSLib_Cache.hxx
+BSplSLib_Cache.cxx
// if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag;
}
else
- { Normal = gp_Dir (D1UvD1V); Status = Defined; }
+ {
+ // Firstly normalize tangent vectors D1U and D1V (this method is more stable)
+ gp_Dir aD1U(D1U);
+ gp_Dir aD1V(D1V);
+ Normal = gp_Dir(aD1U.Crossed(aD1V));
+ Status = Defined;
+ }
}
--- /dev/null
+// 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));
+}
+
--- /dev/null
+// 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
--- /dev/null
+CSLib_Offset.hxx
+CSLib_Offset.cxx
IntExtIsDone = IntExtIsDone || mydone;
}
mydone = IntExtIsDone;
+
+ // Additional checking if the point is on the first or last point of the curve and does not added yet
+ if (mydist1 < Precision::SquareConfusion() || mydist2 < Precision::SquareConfusion())
+ {
+ Standard_Boolean isFirstAdded = Standard_False;
+ Standard_Boolean isLastAdded = Standard_False;
+ Standard_Integer aNbPoints = mypoint.Length();
+ for (i = 1; i <= aNbPoints; i++)
+ {
+ U = mypoint.Value(i).Parameter();
+ if (Abs(U - myuinf) < mytolu)
+ isFirstAdded = Standard_True;
+ else if (Abs(myusup - U) < mytolu)
+ isLastAdded = Standard_True;
+ }
+ if (!isFirstAdded && mydist1 < Precision::SquareConfusion())
+ {
+ mySqDist.Prepend(mydist1);
+ myismin.Prepend(Standard_True);
+ mypoint.Prepend(ThePOnC(myuinf, Pf));
+ }
+ if (!isLastAdded && mydist2 < Precision::SquareConfusion())
+ {
+ mySqDist.Append(mydist2);
+ myismin.Append(Standard_True);
+ mypoint.Append(ThePOnC(myusup, Pl));
+ }
+ }
return;
}
}
Vec from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom,
- Shape from GeomAbs,
- Mutex from Standard
+ Shape from GeomAbs
raises ConstructionError from Standard,
---Purpose :
-- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real.
-
- IsCacheValid(me; Parameter : Real) returns Boolean
-
- ---Purpose :
- -- Tells whether the Cache is valid for the
- -- given parameter
- -- Warnings : the parameter must be normalized within
- -- the period if the curve is periodic. Otherwise
- -- the answer will be false
- --
- is static private;
Continuity (me) returns Shape from GeomAbs;
---Purpose :
raises DimensionError;
---Purpose :
-- Raised if the length of K is not equal to the number of knots.
+ Knots (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : returns the knot values of the B-spline curve;
+ -- Warning
+ -- A knot with a multiplicity greater than 1 is not
+ -- repeated in the knot table. The Multiplicity function
+ -- can be used to obtain the multiplicity of each knot.
+ ---C++ : return const &
+ is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
-- Standard_DimensionError if the array K is not of
-- the appropriate length.Returns the knots sequence.
raises DimensionError;
+ KnotSequence (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : returns the knots of the B-spline curve.
+ -- Knots with multiplicit greater than 1 are repeated
+ ---C++ : return const &
+ is static;
raises DimensionError;
---Purpose :
-- Raised if the length of M is not equal to NbKnots.
+ Multiplicities (me)
+ returns Array1OfInteger from TColStd
+ ---Purpose : returns the multiplicity of the knots of the curve.
+ ---C++ : return const &
+ is static;
NbKnots (me) returns Integer;
raises DimensionError;
---Purpose :
-- Raised if the length of P is not equal to the number of poles.
+ Poles (me)
+ returns Array1OfPnt from TColgp
+ ---Purpose : Returns the poles of the B-spline curve;
+ ---C++ : return const &
+ is static;
StartPoint (me) returns Pnt;
raises DimensionError;
---Purpose :
-- Raised if the length of W is not equal to NbPoles.
+ Weights (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the weights of the B-spline curve;
+ ---C++ : return const &
+ is static;
Copy (me) returns like me;
---Purpose: Creates a new object which is a copy of this BSpline curve.
-
- InvalidateCache(me : mutable)
- ---Purpose : Invalidates the cache. This has to be private
- -- this has to be private
- is static private;
UpdateKnots(me : mutable)
---Purpose : Recompute the flatknots, the knotsdistribution, the continuity.
is static private;
-
- ValidateCache(me : mutable ; Parameter : Real)
-
- is static private;
- ---Purpose : updates the cache and validates it
IsEqual(me; theOther : BSplineCurve from Geom;
thePreci : Real from Standard ) returns Boolean;
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
- cachepoles : HArray1OfPnt from TColgp;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1] see below
- cacheweights : HArray1OfReal from TColStd;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1] see below
- validcache : Integer;
- -- = 1 the cache is valid
- -- = 0 the cache is invalid
- parametercache : Real;
- -- Parameter at which the Taylor expension is stored in
- -- the cache
- spanlenghtcache : Real;
- -- Since the Taylor expansion is normalized in the
- -- cache to evaluate the cache one has to use
- -- (Parameter - parametercache) / nspanlenghtcache
- spanindexcache : Integer;
- -- the span for which the cache is valid if
- -- validcache is 1
-
- -- usefull to evaluate the parametric resolution
maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
- myMutex : Mutex from Standard;
- -- protected bspline-cache
end;
{
// check
- CheckCurveData (Poles,
- Knots,
- Mults,
- Degree,
- Periodic);
-
+ CheckCurveData(Poles,
+ Knots,
+ Mults,
+ Degree,
+ Periodic);
// copy arrays
mults->ChangeArray1() = Mults;
UpdateKnots();
- cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
- parametercache = 0.0e0 ;
- spanlenghtcache = 0.0e0 ;
- spanindexcache = 0 ;
-
}
//=======================================================================
// check
- CheckCurveData (Poles,
- Knots,
- Mults,
- Degree,
- Periodic);
+ CheckCurveData(Poles,
+ Knots,
+ Mults,
+ Degree,
+ Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom_BSplineCurve");
poles = new TColgp_HArray1OfPnt(1,Poles.Length());
poles->ChangeArray1() = Poles;
- cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1);
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
- cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
knots = new TColStd_HArray1OfReal(1,Knots.Length());
mults->ChangeArray1() = Mults;
UpdateKnots();
- parametercache = 0.0e0 ;
- spanlenghtcache = 0.0e0 ;
- spanindexcache = 0 ;
}
//=======================================================================
BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(),
NewU2,periodic,FromU1,ToU2,index2,U);
- if ( Abs(knots->Value(index2+1)-U) <= Eps)
+ if ( Abs(knots->Value(index2+1)-U) <= Eps || index2 == index1)
index2++;
Standard_Integer nbknots = index2 - index1 + 1;
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise();
poles->SetValue (Index, P);
maxderivinvok = 0;
- InvalidateCache() ;
}
//=======================================================================
rational = !weights.IsNull();
}
maxderivinvok = 0;
- InvalidateCache() ;
}
//=======================================================================
//=======================================================================
void Geom_BSplineCurve::MovePoint(const Standard_Real U,
- const gp_Pnt& P,
- const Standard_Integer Index1,
- const Standard_Integer Index2,
- Standard_Integer& FirstModifiedPole,
- Standard_Integer& LastmodifiedPole)
+ const gp_Pnt& P,
+ const Standard_Integer Index1,
+ const Standard_Integer Index2,
+ Standard_Integer& FirstModifiedPole,
+ Standard_Integer& LastmodifiedPole)
{
if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
D0(U, P0);
gp_Vec Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
- weights->Array1(), flatknots->Array1(),
- FirstModifiedPole, LastmodifiedPole, npoles);
+ weights->Array1(), flatknots->Array1(),
+ FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) {
poles->ChangeArray1() = npoles;
maxderivinvok = 0;
- InvalidateCache() ;
}
}
//purpose :
//=======================================================================
-void Geom_BSplineCurve::
-MovePointAndTangent(const Standard_Real U,
- const gp_Pnt& P,
- const gp_Vec& Tangent,
- const Standard_Real Tolerance,
- const Standard_Integer StartingCondition,
- const Standard_Integer EndingCondition,
- Standard_Integer& ErrorStatus)
+void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U,
+ const gp_Pnt& P,
+ const gp_Vec& Tangent,
+ const Standard_Real Tolerance,
+ const Standard_Integer StartingCondition,
+ const Standard_Integer EndingCondition,
+ Standard_Integer& ErrorStatus)
{
Standard_Integer ii ;
if (IsPeriodic()) {
delta_derivative) ;
gp_Vec delta(P0, P);
for (ii = 1 ; ii <= 3 ; ii++) {
- delta_derivative.SetCoord(ii,
- Tangent.Coord(ii)- delta_derivative.Coord(ii)) ;
+ delta_derivative.SetCoord(ii, Tangent.Coord(ii)-delta_derivative.Coord(ii));
}
BSplCLib::MovePointAndTangent(U,
- delta,
- delta_derivative,
- Tolerance,
- deg,
- rational,
- StartingCondition,
- EndingCondition,
- poles->Array1(),
- weights->Array1(),
- flatknots->Array1(),
- new_poles,
- ErrorStatus) ;
+ delta,
+ delta_derivative,
+ Tolerance,
+ deg,
+ rational,
+ StartingCondition,
+ EndingCondition,
+ poles->Array1(),
+ weights->Array1(),
+ flatknots->Array1(),
+ new_poles,
+ ErrorStatus) ;
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
- InvalidateCache() ;
}
}
rational = !weights.IsNull();
Standard_Integer MaxKnotMult = 0;
- BSplCLib::KnotAnalysis (deg,
- periodic,
- knots->Array1(),
- mults->Array1(),
- knotSet, MaxKnotMult);
+ BSplCLib::KnotAnalysis(deg,
+ periodic,
+ knots->Array1(),
+ mults->Array1(),
+ knotSet, MaxKnotMult);
if (knotSet == GeomAbs_Uniform && !periodic) {
flatknots = knots;
flatknots = new TColStd_HArray1OfReal
(1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic));
- BSplCLib::KnotSequence (knots->Array1(),
- mults->Array1(),
- deg,periodic,
- flatknots->ChangeArray1());
+ BSplCLib::KnotSequence(knots->Array1(),
+ mults->Array1(),
+ deg,periodic,
+ flatknots->ChangeArray1());
}
if (MaxKnotMult == 0) smooth = GeomAbs_CN;
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)) );
}
//=======================================================================
}
}
-//=======================================================================
-//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 ;
-}
-
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
-#include <Standard_Mutex.hxx>
#include <Precision.hxx>
#define POLES (poles->Array1())
void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if(!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD0(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- cachepoles->Array1(),
- cacheweights->Array1(),
+ BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
P);
}
- else
+ else
{
- BSplCLib::CacheD0(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- cachepoles->Array1(),
+ BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
P);
}
}
gp_Pnt& P,
gp_Vec& V1) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if(!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD1(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- cachepoles->Array1(),
- cacheweights->Array1(),
- P,
- V1);
+ BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1);
}
- else
+ else
{
- BSplCLib::CacheD1(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- cachepoles->Array1(),
+ BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
*((TColStd_Array1OfReal*) NULL),
- P,
- V1);
+ knots->Array1(), mults->Array1(),
+ P, V1);
}
}
gp_Vec& V1,
gp_Vec& V2) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if(!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD2(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P,
- V1,
- V2);
+ BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2);
}
- else {
- BSplCLib::CacheD2(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- *((TColStd_Array1OfReal*) NULL),
- P,
- V1,
- V2);
+ else
+ {
+ BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2);
}
}
gp_Vec& V2,
gp_Vec& V3) const
{
-
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if(!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD3(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P,
- V1,
- V2,
- V3) ;
+ BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2, V3);
}
- else
+ else
{
- BSplCLib::CacheD3(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- cachepoles->Array1(),
- *((TColStd_Array1OfReal*) NULL),
- P,
- V1,
- V2,
- V3) ;
+ BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2, V3);
}
}
//purpose :
//=======================================================================
-gp_Vec Geom_BSplineCurve::DN (const Standard_Real U,
- const Standard_Integer N ) const
+gp_Vec Geom_BSplineCurve::DN(const Standard_Real U,
+ const Standard_Integer N) const
{
gp_Vec V;
if (rational) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
- weights->Array1(),
- FKNOTS,FMULTS,V);
+ weights->Array1(),
+ FKNOTS,FMULTS,V);
}
else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
- *((TColStd_Array1OfReal*) NULL),
- FKNOTS,FMULTS,V);
+ *((TColStd_Array1OfReal*) NULL),
+ FKNOTS,FMULTS,V);
}
return V;
}
K = knots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const
+{
+ return knots->Array1();
+}
+
//=======================================================================
//function : KnotSequence
//purpose :
K = flatknots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const
+{
+ return flatknots->Array1();
+}
+
//=======================================================================
//function : LastUKnotIndex
//purpose :
M = mults->Array1();
}
+const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const
+{
+ return mults->Array1();
+}
+
//=======================================================================
//function : NbKnots
//purpose :
P = poles->Array1();
}
+const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const
+{
+ return poles->Array1();
+}
+
//=======================================================================
//function : StartPoint
//purpose :
}
}
+const TColStd_Array1OfReal& Geom_BSplineCurve::Weights() const
+{
+ if (IsRational())
+ return weights->Array1();
+ return BSplCLib::NoWeights();
+}
+
//=======================================================================
//function : IsRational
//purpose :
TColgp_Array1OfPnt & CPoles = poles->ChangeArray1();
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
- InvalidateCache() ;
maxderivinvok = 0;
}
BSplKnotDistribution from GeomAbs,
Curve from Geom,
Geometry from Geom,
- Shape from GeomAbs,
- Mutex from Standard
+ Shape from GeomAbs
raises ConstructionError from Standard,
DimensionError from Standard,
-- |1.0, 2.0, 0.5|
-- if Weights = |1.0, 2.0, 0.5| returns False
-- |1.0, 2.0, 0.5|
-
- IsCacheValid(me; UParameter, VParameter : Real) returns Boolean ;
-
- ---Purpose :
- -- Tells whether the Cache is valid for the
- -- given parameter
- -- Warnings : the parameter must be normalized within
- -- the period if the curve is periodic. Otherwise
- -- the answer will be false
- --
Bounds (me; U1, U2, V1, V2 : out Real);
---Purpose :
---Purpose :
-- Raised if the length of P in the U and V direction
-- is not equal to NbUpoles and NbVPoles.
+ Poles (me)
+ returns Array2OfPnt from TColgp
+ ---Purpose : Returns the poles of the B-spline surface.
+ ---C++ : return const &
+ is static;
UDegree (me) returns Integer;
---Purpose :
-- Raised if the length of Ku is not equal to the number of knots
-- in the U direction.
+ UKnots (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the knots in the U direction.
+ ---C++ : return const &
+ is static;
UKnotSequence (me; Ku : out Array1OfReal from TColStd)
raises DimensionError;
---Purpose :
-- Raised if the length of Ku is not equal to NbUPoles + UDegree + 1
+ UKnotSequence (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the uknots sequence.
+ -- In this sequence the knots with a multiplicity greater than 1
+ -- are repeated.
+ --- Example :
+ -- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
+ ---C++ : return const &
+ is static;
UMultiplicity (me; UIndex : Integer) returns Integer
---Purpose :
-- Raised if the length of Mu is not equal to the number of
-- knots in the U direction.
+ UMultiplicities (me)
+ returns Array1OfInteger from TColStd
+ ---Purpose : Returns the multiplicities of the knots in the U direction.
+ ---C++ : return const &
+ is static;
VDegree (me) returns Integer;
---Purpose :
-- Raised if the length of Kv is not equal to the number of
-- knots in the V direction.
+ VKnots (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the knots in the V direction.
+ ---C++ : return const &
+ is static;
VKnotSequence (me; Kv : out Array1OfReal from TColStd)
raises DimensionError;
---Purpose :
-- Raised if the length of Kv is not equal to NbVPoles + VDegree + 1
+ VKnotSequence (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the vknots sequence.
+ -- In this sequence the knots with a multiplicity greater than 1
+ -- are repeated.
+ --- Example :
+ -- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
+ ---C++ : return const &
+ is static;
VMultiplicity (me; VIndex : Integer) returns Integer
---Purpose :
-- Raised if the length of Mv is not equal to the number of
-- knots in the V direction.
+ VMultiplicities (me)
+ returns Array1OfInteger from TColStd
+ ---Purpose : Returns the multiplicities of the knots in the V direction.
+ ---C++ : return const &
+ is static;
Weight (me; UIndex, VIndex : Integer) returns Real
---Purpose :
-- Raised if the length of W in the U and V direction is
-- not equal to NbUPoles and NbVPoles.
+ Weights (me)
+ returns Array2OfReal from TColStd
+ ---Purpose : Returns the weights of the B-spline surface.
+ ---C++ : return const &
+ is static;
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
vknots : HArray1OfReal from TColStd;
umults : HArray1OfInteger from TColStd;
vmults : HArray1OfInteger from TColStd;
- -- Inplementation of the cache on surfaces
- cachepoles : HArray2OfPnt from TColgp;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1]x[0 1]. The Taylor expension of lower degree
- -- is stored as consecutive Pnt in the array that is
- -- if udeg <= vdeg than the array stores the following
- --
- -- (2,0) (3,0)
- -- (1,0) f (u0,v0) f (u0,v0)
- -- f (u0,v0) f (u0,v0) ------------- -----------
- -- 2 3!
- --
- -- (2,1) (3,1)
- -- (0,1) (1,1) f (u0,v0) f (u0,v0)
- -- f (u0,v0) f (u0,v0) ------------- -----------
- -- 2 3!
- --
- -- Otherwise it is stored in the following fashion
- --
- --
- -- (0,2) (0,3)
- -- (0,1) f (u0,v0) f (u0,v0)
- -- f (u0,v0) f (u0,v0) ------------- -----------
- -- 2 3!
- --
- -- (1,2) (1,3)
- -- (1,0) (1,1) f (u0,v0) f (u0,v0)
- -- f (u0,v0) f (u0,v0) ------------- -----------
- -- 2 3!
- --
- -- The size of the array is (1,Max degree) (1, Min degree)
- --
- cacheweights : HArray2OfReal from TColStd;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1]x[0 1]. The Taylor expension of lower degree
- -- is stored as consecutive Real in the array as explained above
- ucacheparameter : Real ;
- vcacheparameter : Real ;
- -- Parameters at which the Taylor expension is stored in
- -- the cache
- ucachespanlenght : Real ;
- vcachespanlenght : Real ;
- -- Since the Taylor expansion is normalized in the
- -- cache to evaluate the cache one has to use
- -- (UParameter - uparametercache) / ucachespanlenght
- -- (VParameter - vparametercache) / vcachespanlenght
- ucachespanindex : Integer ;
- vcachespanindex : Integer ;
- -- the span for which the cache is valid if
- -- validcache is 1
- validcache : Integer ;
-
- -- usefull to evaluate the parametric resolutions
- umaxderivinv : Real from Standard;
- vmaxderivinv : Real from Standard;
- maxderivinvok : Boolean from Standard;
-
- myMutex : Mutex from Standard;
- -- protected bsplinesurface-cache
-
+ umaxderivinv : Real from Standard;
+ vmaxderivinv : Real from Standard;
+ maxderivinvok : Boolean from Standard;
+
end;
maxderivinvok(0)
{
- Standard_Integer MinDegree,
- MaxDegree ;
// check
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
- MinDegree = Min(udeg,vdeg) ;
- MaxDegree = Max(udeg,vdeg) ;
- cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
- 1,MinDegree + 1) ;
-
- cacheweights.Nullify() ;
- ucacheparameter = 0.0e0 ;
- vcacheparameter = 0.0e0 ;
- ucachespanlenght = 1.0e0 ;
- vcachespanlenght = 1.0e0 ;
- ucachespanindex = 0 ;
- vcachespanindex = 0 ;
- validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
vdeg(VDegree),
maxderivinvok(0)
{
- Standard_Integer MinDegree,
- MaxDegree ;
// check weights
if (Weights.ColLength() != Poles.ColLength())
vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
vmults->ChangeArray1() = VMults;
- MinDegree = Min(udeg,vdeg) ;
- MaxDegree = Max(udeg,vdeg) ;
- cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
- 1,MinDegree + 1) ;
- if (urational || vrational) {
- cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1,
- 1,MinDegree + 1);
- }
- ucacheparameter = 0.0e0 ;
- vcacheparameter = 0.0e0 ;
- ucachespanlenght = 1.0e0 ;
- vcachespanlenght = 1.0e0 ;
- ucachespanindex = 0 ;
- vcachespanindex = 0 ;
- validcache = 0 ;
UpdateUKnots();
UpdateVKnots();
default : Usmooth = GeomAbs_C3; break;
}
}
-
- InvalidateCache() ;
}
//=======================================================================
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 : ValidateCache
-//purpose : function that validates the cache of the surface
-//=======================================================================
-
-void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter,
- const Standard_Real Vparameter)
-{
- Standard_Real NewParameter ;
- Standard_Integer LocalIndex = 0 ;
- Standard_Integer MinDegree,
- MaxDegree ;
- //
- // check if the degree did not change
- //
-
- MinDegree = Min(udeg,vdeg) ;
- MaxDegree = Max(udeg,vdeg) ;
- if (cachepoles->ColLength() < MaxDegree + 1 ||
- cachepoles->RowLength() < MinDegree + 1) {
- cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
- 1,MinDegree + 1);
- }
- //
- // Verif + poussee pour les poids
- //
- if (urational || vrational) {
- if (cacheweights.IsNull()) {
- cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
- 1,MinDegree + 1);
- }
- else {
- if (cacheweights->ColLength() < MaxDegree + 1 ||
- cacheweights->RowLength() < MinDegree + 1) {
- cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
- 1,MinDegree + 1);
- }
- }
- }
- else if (!cacheweights.IsNull())
- cacheweights.Nullify();
-
- BSplCLib::LocateParameter(udeg,
- (ufknots->Array1()),
- (BSplCLib::NoMults()),
- Uparameter,
- uperiodic,
- LocalIndex,
- NewParameter);
- ucachespanindex = LocalIndex ;
- if (Uparameter == ufknots->Value(LocalIndex + 1)) {
-
- LocalIndex += 1 ;
- ucacheparameter = ufknots->Value(LocalIndex) ;
- if (LocalIndex == ufknots->Upper() - udeg) {
- //
- // for the last span if the parameter is outside of
- // the domain of the curve than use the last knot
- // and normalize with the last span Still set the
- // cachespanindex to flatknots->Upper() - deg so that
- // the IsCacheValid will know for sure we are extending
- // the Bspline
- //
-
- ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ;
- }
- else {
- ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
- }
- }
- else {
- ucacheparameter = ufknots->Value(LocalIndex) ;
- ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
- }
-
- LocalIndex = 0 ;
- BSplCLib::LocateParameter(vdeg,
- (vfknots->Array1()),
- (BSplCLib::NoMults()),
- Vparameter,
- vperiodic,
- LocalIndex,
- NewParameter);
- vcachespanindex = LocalIndex ;
- if (Vparameter == vfknots->Value(LocalIndex + 1)) {
- LocalIndex += 1 ;
- vcacheparameter = vfknots->Value(LocalIndex) ;
- if (LocalIndex == vfknots->Upper() - vdeg) {
- //
- // for the last span if the parameter is outside of
- // the domain of the curve than use the last knot
- // and normalize with the last span Still set the
- // cachespanindex to flatknots->Upper() - deg so that
- // the IsCacheValid will know for sure we are extending
- // the Bspline
- //
-
- vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ;
- }
- else {
- vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
- }
- }
- else {
- vcacheparameter = vfknots->Value(LocalIndex) ;
- vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
- }
-
- Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
- uspanlenght_11 = ucachespanlenght/2,
- vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
- vspanlenght_11 = vcachespanlenght/2 ;
- if (urational || vrational) {
- BSplSLib::BuildCache(uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- uperiodic,
- vperiodic,
- udeg,
- vdeg,
- ucachespanindex,
- vcachespanindex,
- (ufknots->Array1()),
- (vfknots->Array1()),
- poles->Array2(),
- weights->Array2(),
- cachepoles->ChangeArray2(),
- cacheweights->ChangeArray2()) ;
- }
- else {
- BSplSLib::BuildCache(uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- uperiodic,
- vperiodic,
- udeg,
- vdeg,
- ucachespanindex,
- vcachespanindex,
- (ufknots->Array1()),
- (vfknots->Array1()),
- poles->Array2(),
- *((TColStd_Array2OfReal*) NULL),
- cachepoles->ChangeArray2(),
- *((TColStd_Array2OfReal*) NULL)) ;
- }
- validcache = 1 ;
-}
-
-//=======================================================================
-//function : IsCacheValid
-//purpose : function that checks for the validity of the cache of the
-// surface
-//=======================================================================
-Standard_Boolean Geom_BSplineSurface::IsCacheValid
-(const Standard_Real U,
- const Standard_Real V) const
-{
- //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
- Standard_Real aDeltaU = U - ucacheparameter;
- Standard_Real aDeltaV = V - vcacheparameter;
-
- return ( validcache &&
- (aDeltaU >= 0.0e0) &&
- ((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) &&
- (aDeltaV >= 0.0e0) &&
- ((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) );
-}
-
//=======================================================================
//function : SetWeight
//purpose :
}
Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
Rational(Weights, urational, vrational);
- InvalidateCache();
}
//=======================================================================
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
-
- InvalidateCache();
}
//=======================================================================
}
// Verifie si c'est rationnel
Rational(Weights, urational, vrational);
- InvalidateCache();
}
void Geom_BSplineSurface::D0(const Standard_Real U,
const Standard_Real V,
- gp_Pnt& P) const
-{
- Standard_Real new_u(U), new_v(V);
- PeriodicNormalization(new_u, new_v);
-
- Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
- Standard_Mutex::Sentry aSentry(MySurface->myMutex);
-
- if(!IsCacheValid(new_u, new_v))
- MySurface->ValidateCache(new_u, new_v);
-
- Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
- uspanlenght_11 = ucachespanlenght/2,
- vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
- vspanlenght_11 = vcachespanlenght/2 ;
- if (cacheweights.IsNull()) {
-
- BSplSLib::CacheD0(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- *((TColStd_Array2OfReal*) NULL),
- P) ;
- }
- else {
- BSplSLib::CacheD0(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- cacheweights->Array2(),
- P) ;
- }
+ gp_Pnt& P) const
+{
+ Standard_Real aNewU = U;
+ Standard_Real aNewV = V;
+ PeriodicNormalization(aNewU, aNewV);
+
+ BSplSLib::D0(aNewU,aNewV,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
+ udeg,vdeg,urational,vrational,uperiodic,vperiodic,
+ P);
}
//=======================================================================
void Geom_BSplineSurface::D1(const Standard_Real U,
const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V) const
+ gp_Pnt& P,
+ gp_Vec& D1U,
+ gp_Vec& D1V) const
{
- Standard_Real new_u(U), new_v(V);
- PeriodicNormalization(new_u, new_v);
+ Standard_Real aNewU = U;
+ Standard_Real aNewV = V;
+ PeriodicNormalization(aNewU, aNewV);
- Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
- Standard_Mutex::Sentry aSentry(MySurface->myMutex);
+ Standard_Integer uindex = 0, vindex = 0;
- if(!IsCacheValid(new_u, new_v))
- MySurface->ValidateCache(new_u, new_v);
+ BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
+ uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
- Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
- uspanlenght_11 = ucachespanlenght/2,
- vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
- vspanlenght_11 = vcachespanlenght/2 ;
+ BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
+ vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
- if (cacheweights.IsNull()) {
-
- BSplSLib::CacheD1(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- *((TColStd_Array2OfReal*) NULL),
- P,
- D1U,
- D1V) ;
- }
- else {
-
- BSplSLib::CacheD1(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- cacheweights->Array2(),
- P,
- D1U,
- D1V) ;
- }
+ BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
+ udeg,vdeg,urational,vrational,uperiodic,vperiodic,
+ P, D1U, D1V);
}
//=======================================================================
//=======================================================================
void Geom_BSplineSurface::D2 (const Standard_Real U,
- const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V,
- gp_Vec& D2U,
- gp_Vec& D2V,
- gp_Vec& D2UV) const
-{
- Standard_Real new_u(U), new_v(V);
- PeriodicNormalization(new_u, new_v);
-
- Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this;
- Standard_Mutex::Sentry aSentry(MySurface->myMutex);
-
- if(!IsCacheValid(new_u, new_v))
- MySurface->ValidateCache(new_u, new_v);
-
- Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
- uspanlenght_11 = ucachespanlenght/2,
- vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
- vspanlenght_11 = vcachespanlenght/2 ;
- if (cacheweights.IsNull()) {
- BSplSLib::CacheD2(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- *((TColStd_Array2OfReal*) NULL),
- P,
- D1U,
- D1V,
- D2U,
- D2UV,
- D2V);
- }
- else {
- BSplSLib::CacheD2(new_u,
- new_v,
- udeg,
- vdeg,
- uparameter_11,
- vparameter_11,
- uspanlenght_11,
- vspanlenght_11,
- cachepoles->Array2(),
- cacheweights->Array2(),
- P,
- D1U,
- D1V,
- D2U,
- D2UV,
- D2V);
- }
- }
+ const Standard_Real V,
+ gp_Pnt& P,
+ gp_Vec& D1U,
+ gp_Vec& D1V,
+ gp_Vec& D2U,
+ gp_Vec& D2V,
+ gp_Vec& D2UV) const
+{
+ Standard_Real aNewU = U;
+ Standard_Real aNewV = V;
+ PeriodicNormalization(aNewU, aNewV);
+
+ Standard_Integer uindex = 0, vindex = 0;
+
+ BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
+ uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
+
+ BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
+ vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
+
+ BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
+ udeg,vdeg,urational,vrational,uperiodic,vperiodic,
+ P, D1U, D1V, D2U, D2V, D2UV);
+}
//=======================================================================
//function : D3
P = poles->Array2();
}
+const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const
+{
+ return poles->Array2();
+}
+
//=======================================================================
//function : UIso
//purpose :
Ku = uknots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const
+{
+ return uknots->Array1();
+}
+
//=======================================================================
//function : VKnots
//purpose :
Kv = vknots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const
+{
+ return vknots->Array1();
+}
+
//=======================================================================
//function : UKnotSequence
//purpose :
Ku = ufknots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const
+{
+ return ufknots->Array1();
+}
+
//=======================================================================
//function : VKnotSequence
//purpose :
Kv = vfknots->Array1();
}
+const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const
+{
+ return vfknots->Array1();
+}
+
//=======================================================================
//function : UMultiplicity
//purpose :
Mu = umults->Array1();
}
+const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const
+{
+ return umults->Array1();
+}
+
//=======================================================================
//function : VIso
//purpose :
Mv = vmults->Array1();
}
+const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const
+{
+ return vmults->Array1();
+}
+
//=======================================================================
//function : Weight
//purpose :
W = weights->Array2();
}
+const TColStd_Array2OfReal& Geom_BSplineSurface::Weights() const
+{
+ if (urational || vrational)
+ return weights->Array2();
+ return BSplSLib::NoWeights();
+}
+
//=======================================================================
//function : Transform
//purpose :
VPoles (i, j).Transform (T);
}
}
-
- InvalidateCache();
}
//=======================================================================
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
}
-
- InvalidateCache();
}
//=======================================================================
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
}
-
- InvalidateCache();
}
//=======================================================================
const gp_Pnt& P)
{
poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
- InvalidateCache();
}
//=======================================================================
poles->ChangeArray2() = npoles;
}
maxderivinvok = 0;
- InvalidateCache() ;
}
//=======================================================================
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
+#include <CSLib_Offset.hxx>
typedef Geom_OffsetCurve OffsetCurve;
typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve);
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);
+
//=======================================================================
//purpose :
//=======================================================================
-void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& P, Vec& theV1, Vec& V2, Vec& V3)
-const {
-
-
+void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec& theV2, Vec& theV3) const
+{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
- const Standard_Real aTol = gp::Resolution();
-
Standard_Boolean IsDirectionChange = Standard_False;
- basisCurve->D3 (theU, P, theV1, V2, V3);
- Vec V4 = basisCurve->DN (theU, 4);
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = -basisCurve->DN (theU, anIndex + 1);
- V3 = -basisCurve->DN (theU, anIndex + 2);
- V4 = -basisCurve->DN (theU, anIndex + 3);
+ basisCurve->D3 (theU, theP, theV1, theV2, theV3);
+ Vec aV4 = basisCurve->DN (theU, 4);
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, aV4);
- IsDirectionChange = Standard_True;
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex + 1);
- V3 = basisCurve->DN (theU, anIndex + 2);
- V4 = basisCurve->DN (theU, anIndex + 3);
- }
- }//if(V1.Magnitude() <= aTol)
-
-
- XYZ OffsetDir = direction.XYZ();
- XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
- XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
- XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
- XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir);
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R2 * R;
- Standard_Real R4 = R2 * R2;
- Standard_Real R5 = R3 * R2;
- Standard_Real R6 = R3 * R3;
- Standard_Real R7 = R5 * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
- Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
- if (R7 <= gp::Resolution()) {
- if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
- // V3 = P"' (U) :
- D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2));
- D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4))));
- D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 -
- 15.0*Dr*Dr*Dr/R6 - D3r));
- D3Ndir.Multiply (offsetValue/R);
-
- if(IsDirectionChange)
- V3=-V3;
-
- V3.Add (Vec(D3Ndir));
-
- // V2 = P" (U) :
- Standard_Real R4 = R2 * R2;
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
- D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2)));
- D2Ndir.Multiply (offsetValue / R);
- V2.Add (Vec(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec(DNdir));
- }
- else {
- // V3 = P"' (U) :
- D3Ndir.Divide (R);
- D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3));
- D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5))));
- D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 -
- 15.0*Dr*Dr*Dr/R7 - D3r));
- D3Ndir.Multiply (offsetValue);
-
- if(IsDirectionChange)
- V3=-V3;
-
- V3.Add (Vec(D3Ndir));
-
- // V2 = P" (U) :
- D2Ndir.Divide (R);
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3));
- D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3)));
- D2Ndir.Multiply (offsetValue);
- V2.Add (Vec(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- theV1.Add (Vec(DNdir));
- }
- //P (U) :
- D0(theU,P);
+ CSLib_Offset::D3(theP, theV1, theV2, theV3, aV4, direction, offsetValue,
+ IsDirectionChange, theP, theV1, theV2, theV3);
}
void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP,
gp_Pnt& thePbasis, gp_Vec& theV1basis)const
- {
- const Standard_Real aTol = gp::Resolution();
+{
+ basisCurve->D1(theU, thePbasis, theV1basis);
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1basis.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, theV1basis);
- basisCurve->D1 (theU, thePbasis, theV1basis);
- Standard_Real Ndu = theV1basis.Magnitude();
-
- if(Ndu <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- gp_Vec V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- Ndu = V.Magnitude();
- }
- while((Ndu <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- gp_Pnt P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- gp_Vec V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- theV1basis = -V;
- else
- theV1basis = V;
-
- Ndu = theV1basis.Magnitude();
- }//if(Ndu <= aTol)
-
- XYZ Ndir = (theV1basis.XYZ()).Crossed (direction.XYZ());
- Standard_Real R = Ndir.Modulus();
- if (R <= gp::Resolution())
- Geom_UndefinedValue::Raise("Exception: Undefined normal vector "
- "because tangent vector has zero-magnitude!");
-
- Ndir.Multiply (offsetValue/R);
- Ndir.Add (thePbasis.XYZ());
- theP.SetXYZ(Ndir);
+ CSLib_Offset::D0(thePbasis, theV1basis, direction, offsetValue, IsDirectionChange, theP);
}
//=======================================================================
//=======================================================================
void Geom_OffsetCurve::D1 ( const Standard_Real theU,
- Pnt& P , Pnt& PBasis ,
- Vec& theV1, Vec& V1basis, Vec& V2basis) const {
+ Pnt& theP , Pnt& thePBasis ,
+ Vec& theV1, Vec& theV1basis, Vec& theV2basis) const {
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
- const Standard_Real aTol = gp::Resolution();
+ basisCurve->D2 (theU, thePBasis, theV1basis, theV2basis);
- basisCurve->D2 (theU, PBasis, V1basis, V2basis);
- theV1 = V1basis;
- Vec V2 = V2basis;
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1basis.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1basis, theV2basis);
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = - basisCurve->DN (theU, anIndex+1);
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex+1);
- }
-
- V2basis = V2;
- V1basis = theV1;
- }//if(theV1.Magnitude() <= aTol)
-
- XYZ OffsetDir = direction.XYZ();
- XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
- XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- if (R3 <= gp::Resolution()) {
- //We try another computation but the stability is not very good.
- if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec(DNdir));
- }
- else {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue * Dr/R3));
- theV1.Add (Vec(DNdir));
- }
- D0(theU,P);
+ CSLib_Offset::D1(thePBasis, theV1basis, theV2basis, direction, offsetValue, IsDirectionChange, theP, theV1);
}
//purpose :
//=======================================================================
-void Geom_OffsetCurve::D2 (const Standard_Real theU,
- Pnt& P , Pnt& PBasis ,
- Vec& theV1 , Vec& V2 ,
- Vec& V1basis, Vec& V2basis, Vec& V3basis) const {
-
+void Geom_OffsetCurve::D2 (const Standard_Real theU,
+ Pnt& theP, Pnt& thePBasis,
+ Vec& theV1, Vec& theV2,
+ Vec& theV1basis, Vec& theV2basis, Vec& theV3basis) const
+{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
// P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
- const Standard_Real aTol = gp::Resolution();
-
Standard_Boolean IsDirectionChange = Standard_False;
- basisCurve->D3 (theU, PBasis, V1basis, V2basis, V3basis);
+ basisCurve->D3 (theU, thePBasis, theV1basis, theV2basis, theV3basis);
- theV1 = V1basis;
- V2 = V2basis;
- Vec V3 = V3basis;
-
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = -basisCurve->DN (theU, anIndex+1);
- V3 = -basisCurve->DN (theU, anIndex + 2);
+ if(theV1basis.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1basis, theV2basis, theV3basis);
- IsDirectionChange = Standard_True;
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex+1);
- V3 = basisCurve->DN (theU, anIndex + 2);
- }
-
- V2basis = V2;
- V1basis = theV1;
- }//if(V1.Magnitude() <= aTol)
-
- XYZ OffsetDir = direction.XYZ();
- XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir);
- XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
- XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R2 * R;
- Standard_Real R4 = R2 * R2;
- Standard_Real R5 = R3 * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
-
- if (R5 <= gp::Resolution()) {
- //We try another computation but the stability is not very good
- //dixit ISG.
- if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
- // V2 = P" (U) :
- Standard_Real R4 = R2 * R2;
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
- D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
- D2Ndir.Multiply (offsetValue / R);
-
- if(IsDirectionChange)
- V2=-V2;
-
- V2.Add (Vec(D2Ndir));
-
- // V1 = P' (U) :
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec(DNdir));
- }
- else {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better.
- // V2 = P" (U) :
- D2Ndir.Multiply (offsetValue/R);
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
- D2Ndir.Add (Ndir.Multiplied (
- offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
- )
- );
-
- if(IsDirectionChange)
- V2=-V2;
-
- V2.Add (Vec(D2Ndir));
-
- // V1 = P' (U) :
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- theV1.Add (Vec(DNdir));
- }
- //P (U) :
- D0(theU,P);
+ CSLib_Offset::D2(thePBasis, theV1basis, theV2basis, theV3basis, direction, offsetValue,
+ IsDirectionChange, theP, theV1, theV2);
}
{
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;
+}
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
+
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
+
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
+ // If the point is placed on the axis of revolution then derivatives on U are undefined.
+ // Manually set them to zero.
+ if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
+ VcrossCQ.SetCoord(0.0, 0.0, 0.0);
+
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
Vec2d from gp,
BSplKnotDistribution from GeomAbs,
Geometry from Geom2d,
- Shape from GeomAbs,
- Mutex from Standard
+ Shape from GeomAbs
raises ConstructionError from Standard,
DimensionError from Standard,
-- Returns True if the weights are not identical.
-- The tolerance criterion is Epsilon of the class Real.
- IsCacheValid(me; Parameter : Real) returns Boolean
-
- ---Purpose :
- -- Tells whether the Cache is valid for the
- -- given parameter
- -- Warnings : the parameter must be normalized within
- -- the period if the curve is periodic. Otherwise
- -- the answer will be false
- --
- is static private;
-
Continuity (me) returns Shape from GeomAbs;
--- Purpose :
-- Returns the global continuity of the curve :
raises DimensionError;
--- Purpose :
-- Raised if the length of K is not equal to the number of knots.
+ Knots (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : returns the knot values of the B-spline curve;
+ ---C++ : return const &
+ is static;
KnotSequence (me; K : out Array1OfReal from TColStd)
raises DimensionError;
--- Purpose :
-- Raised if the length of K is not equal to NbPoles + Degree + 1
+ KnotSequence (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the knots sequence.
+ -- In this sequence the knots with a multiplicity greater than 1
+ -- are repeated.
+ -- Example :
+ -- K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
+ ---C++ : return const &
+ is static;
raises DimensionError;
--- Purpose :
-- Raised if the length of M is not equal to NbKnots.
+ Multiplicities (me)
+ returns Array1OfInteger from TColStd
+ ---Purpose : returns the multiplicity of the knots of the curve.
+ ---C++ : return const &
+ is static;
NbKnots (me) returns Integer;
raises DimensionError;
--- Purpose :
-- Raised if the length of P is not equal to the number of poles.
+ Poles (me)
+ returns Array1OfPnt2d from TColgp
+ ---Purpose : Returns the poles of the B-spline curve;
+ ---C++ : return const &
+ is static;
StartPoint (me) returns Pnt2d;
raises DimensionError;
--- Purpose :
-- Raised if the length of W is not equal to NbPoles.
+ Weights (me)
+ returns Array1OfReal from TColStd
+ ---Purpose : Returns the weights of the B-spline curve;
+ ---C++ : return const &
+ is static;
UpdateKnots(me : mutable)
---Purpose: Recompute the flatknots, the knotsdistribution, the continuity.
is static private;
-
- InvalidateCache(me : mutable)
- ---Purpose : Invalidates the cache. This has to be private this has to be private
- is static private;
- ValidateCache(me : mutable ; Parameter : Real)
-
- is static private;
- ---Purpose : updates the cache and validates it
-
fields
rational : Boolean;
flatknots : HArray1OfReal from TColStd;
knots : HArray1OfReal from TColStd;
mults : HArray1OfInteger from TColStd;
- cachepoles : HArray1OfPnt2d from TColgp;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1] see below
- cacheweights : HArray1OfReal from TColStd;
- -- Taylor expansion of the poles function, in homogeneous
- -- form if the curve is rational. The taylor expansion
- -- is normalized so that the span corresponds to
- -- [0 1] see below
- validcache : Integer;
- -- = 1 the cache is valid
- -- = 0 the cache is invalid
- parametercache : Real;
- -- Parameter at which the Taylor expension is stored in
- -- the cache
- spanlenghtcache : Real;
- -- Since the Taylor expansion is normalized in the
- -- cache to evaluate the cache one has to use
- -- (Parameter - refcache) * normcache
- spanindexcache : Integer;
- -- the span for which the cache is valid if
- -- validcache is 1
-
- -- usefull to evaluate the parametric resolution
maxderivinv : Real from Standard;
maxderivinvok : Boolean from Standard;
- myMutex : Mutex from Standard;
- -- protected bspline-cache
-
end;
{
// check
- CheckCurveData (Poles,
- Knots,
- Mults,
- Degree,
- Periodic);
-
+ CheckCurveData(Poles,
+ Knots,
+ Mults,
+ Degree,
+ Periodic);
// copy arrays
mults->ChangeArray1() = Mults;
UpdateKnots();
- cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
- parametercache = 0.0e0 ;
- spanlenghtcache = 0.0e0 ;
- spanindexcache = 0 ;
}
//=======================================================================
// check
- CheckCurveData (Poles,
- Knots,
- Mults,
- Degree,
- Periodic);
+ CheckCurveData(Poles,
+ Knots,
+ Mults,
+ Degree,
+ Periodic);
if (Weights.Length() != Poles.Length())
Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch");
poles = new TColgp_HArray1OfPnt2d(1,Poles.Length());
poles->ChangeArray1() = Poles;
- cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1);
if (rational) {
weights = new TColStd_HArray1OfReal(1,Weights.Length());
weights->ChangeArray1() = Weights;
- cacheweights = new TColStd_HArray1OfReal(1,Degree + 1);
}
knots = new TColStd_HArray1OfReal(1,Knots.Length());
mults->ChangeArray1() = Mults;
UpdateKnots();
-
- parametercache = 0.0e0 ;
- spanlenghtcache = 0.0e0 ;
- spanindexcache = 0 ;
}
//=======================================================================
if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch");
poles->SetValue (Index, P);
maxderivinvok = 0;
- InvalidateCache();
}
//=======================================================================
}
maxderivinvok = 0;
- InvalidateCache() ;
}
//=======================================================================
//=======================================================================
void Geom2d_BSplineCurve::MovePoint(const Standard_Real U,
- const gp_Pnt2d& P,
- const Standard_Integer Index1,
- const Standard_Integer Index2,
- Standard_Integer& FirstModifiedPole,
- Standard_Integer& LastmodifiedPole)
+ const gp_Pnt2d& P,
+ const Standard_Integer Index1,
+ const Standard_Integer Index2,
+ Standard_Integer& FirstModifiedPole,
+ Standard_Integer& LastmodifiedPole)
{
if (Index1 < 1 || Index1 > poles->Length() ||
Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) {
D0(U, P0);
gp_Vec2d Displ(P0, P);
BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(),
- weights->Array1(), flatknots->Array1(),
- FirstModifiedPole, LastmodifiedPole, npoles);
+ weights->Array1(), flatknots->Array1(),
+ FirstModifiedPole, LastmodifiedPole, npoles);
if (FirstModifiedPole) {
poles->ChangeArray1() = npoles;
maxderivinvok = 0;
- InvalidateCache() ;
}
}
if (!ErrorStatus) {
poles->ChangeArray1() = new_poles;
maxderivinvok = 0;
- InvalidateCache() ;
}
}
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)) );
}
//=======================================================================
}
}
-//=======================================================================
-//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 ;
-}
-
#include <Standard_OutOfRange.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_RangeError.hxx>
-#include <Standard_Mutex.hxx>
+#include <Precision.hxx>
#define POLES (poles->Array1())
#define KNOTS (knots->Array1())
//purpose :
//=======================================================================
-void Geom2d_BSplineCurve::D0 ( const Standard_Real U,
- gp_Pnt2d& P) const
+void Geom2d_BSplineCurve::D0(const Standard_Real U,
+ gp_Pnt2d& P) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if (!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD0(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P) ;
+ BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P);
}
- else {
- BSplCLib::CacheD0(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- BSplCLib::NoWeights(),
- P) ;
+ else
+ {
+ BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P);
}
}
//purpose :
//=======================================================================
-void Geom2d_BSplineCurve::D1 (const Standard_Real U,
- gp_Pnt2d& P,
- gp_Vec2d& V1) const
+void Geom2d_BSplineCurve::D1(const Standard_Real U,
+ gp_Pnt2d& P,
+ gp_Vec2d& V1) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if (!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD1(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P,
- V1) ;
+ BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1);
}
- else {
- BSplCLib::CacheD1(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- BSplCLib::NoWeights(),
- P,
- V1) ;
+ else
+ {
+ BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P, V1);
}
}
//purpose :
//=======================================================================
-void Geom2d_BSplineCurve::D2 (const Standard_Real U ,
- gp_Pnt2d& P ,
- gp_Vec2d& V1,
- gp_Vec2d& V2 ) const
+void Geom2d_BSplineCurve::D2(const Standard_Real U,
+ gp_Pnt2d& P,
+ gp_Vec2d& V1,
+ gp_Vec2d& V2) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if (!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD2(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P,
- V1,
- V2) ;
+ BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2);
}
- else {
- BSplCLib::CacheD2(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- BSplCLib::NoWeights(),
- P,
- V1,
- V2) ;
+ else
+ {
+ BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2);
}
}
//purpose :
//=======================================================================
-void Geom2d_BSplineCurve::D3 (const Standard_Real U ,
- gp_Pnt2d& P ,
- gp_Vec2d& V1,
- gp_Vec2d& V2,
- gp_Vec2d& V3 ) const
+void Geom2d_BSplineCurve::D3(const Standard_Real U,
+ gp_Pnt2d& P,
+ gp_Vec2d& V1,
+ gp_Vec2d& V2,
+ gp_Vec2d& V3) const
{
- Standard_Real NewU(U);
- PeriodicNormalization(NewU);
-
- Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this;
- Standard_Mutex::Sentry aSentry(MyCurve->myMutex);
-
- if (!IsCacheValid(NewU))
- MyCurve->ValidateCache(NewU);
-
- if(rational)
+ Standard_Integer aSpanIndex = 0;
+ Standard_Real aNewU(U);
+ PeriodicNormalization(aNewU);
+ BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU);
+ if (aNewU < knots->Value(aSpanIndex))
+ aSpanIndex--;
+ if (rational)
{
- BSplCLib::CacheD3(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- cacheweights->Array1(),
- P,
- V1,
- V2,
- V3) ;
+ BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
+ weights->Array1(),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2, V3);
}
- else {
- BSplCLib::CacheD3(NewU,
- deg,
- parametercache,
- spanlenghtcache,
- (cachepoles->Array1()),
- BSplCLib::NoWeights(),
- P,
- V1,
- V2,
- V3) ;
+ else
+ {
+ BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES,
+ *((TColStd_Array1OfReal*) NULL),
+ knots->Array1(), mults->Array1(),
+ P, V1, V2, V3);
}
}
//purpose :
//=======================================================================
-gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U,
- const Standard_Integer N ) const
+gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U,
+ const Standard_Integer N) const
{
gp_Vec2d V;
if ( rational ) {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
- weights->Array1(),
- FKNOTS,FMULTS,V);
+ weights->Array1(),
+ FKNOTS,FMULTS,V);
}
- else {
+ else {
BSplCLib::DN(U,N,0,deg,periodic,POLES,
- *((TColStd_Array1OfReal*) NULL),
- FKNOTS,FMULTS,V);
+ *((TColStd_Array1OfReal*) NULL),
+ FKNOTS,FMULTS,V);
}
return V;
}
K = knots->Array1();
}
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const
+{
+ return knots->Array1();
+}
+
//=======================================================================
//function : KnotSequence
//purpose :
K = flatknots->Array1();
}
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const
+{
+ return flatknots->Array1();
+}
+
//=======================================================================
//function : LastUKnotIndex
//purpose :
M = mults->Array1();
}
+const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const
+{
+ return mults->Array1();
+}
+
//=======================================================================
//function : NbKnots
//purpose :
P = poles->Array1();
}
+const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const
+{
+ return poles->Array1();
+}
+
//=======================================================================
//function : StartPoint
//purpose :
}
}
+const TColStd_Array1OfReal& Geom2d_BSplineCurve::Weights() const
+{
+ if (IsRational())
+ return weights->Array1();
+ return BSplCLib::NoWeights();
+}
+
//=======================================================================
//function : IsRational
//purpose :
for (Standard_Integer I = 1; I <= CPoles.Length(); I++)
CPoles (I).Transform (T);
- InvalidateCache();
// maxderivinvok = 0;
}
#include <Standard_ConstructionError.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_NotImplemented.hxx>
+#include <CSLib_Offset.hxx>
#include <Geom2d_UndefinedDerivative.hxx>
#include <Geom2d_UndefinedValue.hxx>
#include <Geom2d_Line.hxx>
static const Standard_Real MinStep = 1e-7;
static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
+static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
+
+// Recalculate derivatives in the singular point
+// Returns true if the direction of derivatives is changed
+static Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative,
+ Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
+ gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
+
//=======================================================================
//function : Copy
//purpose :
//purpose :
//=======================================================================
-void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
- Pnt2d& theP ) const
+void Geom2d_OffsetCurve::D0 (const Standard_Real theU,
+ Pnt2d& theP) const
{
- const Standard_Real aTol = gp::Resolution();
-
Vec2d vD1;
-
basisCurve->D1 (theU, theP, vD1);
- Standard_Real Ndu = vD1.Magnitude();
- if(Ndu <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec2d V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- Ndu = V.Magnitude();
- }
- while((Ndu <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt2d P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec2d V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- vD1 = -V;
- else
- vD1 = V;
-
- Ndu = vD1.Magnitude();
- }//if(Ndu <= aTol)
-
- if (Ndu <= aTol)
- Geom2d_UndefinedValue::Raise("Exception: Undefined normal vector "
- "because tangent vector has zero-magnitude!");
-
- Standard_Real A = vD1.Y();
- Standard_Real B = - vD1.X();
- A = A * offsetValue/Ndu;
- B = B * offsetValue/Ndu;
- theP.SetCoord(theP.X() + A, theP.Y() + B);
- }
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(vD1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1);
+
+ CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP);
+}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
-void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) const
- {
+void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1) const
+{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
- const Standard_Real aTol = gp::Resolution();
-
Vec2d V2;
- basisCurve->D2 (theU, P, theV1, V2);
-
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec2d V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt2d P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec2d V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = - basisCurve->DN (theU, anIndex+1);
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex+1);
- }
- }//if(theV1.Magnitude() <= aTol)
-
- XY Ndir (theV1.Y(), -theV1.X());
- XY DNdir (V2.Y(), -V2.X());
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- if (R3 <= gp::Resolution()) {
- //We try another computation but the stability is not very good.
- if (R2 <= gp::Resolution()) Geom2d_UndefinedDerivative::Raise();
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec2d(DNdir));
- }
- else {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- theV1.Add (Vec2d(DNdir));
- }
+ basisCurve->D2 (theU, theP, theV1, V2);
- D0(theU, P);
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2);
+
+ CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1);
}
//=======================================================================
//=======================================================================
void Geom2d_OffsetCurve::D2 (const Standard_Real theU,
- Pnt2d& P,
- Vec2d& theV1, Vec2d& V2) const
+ Pnt2d& theP,
+ Vec2d& theV1, Vec2d& theV2) const
{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
Vec2d V3;
- basisCurve->D3 (theU, P, theV1, V2, V3);
-
- const Standard_Real aTol = gp::Resolution();
+ basisCurve->D3 (theU, theP, theV1, theV2, V3);
Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3);
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec2d V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt2d P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec2d V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = -basisCurve->DN (theU, anIndex+1);
- V3 = -basisCurve->DN (theU, anIndex + 2);
-
- IsDirectionChange = Standard_True;
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex+1);
- V3 = basisCurve->DN (theU, anIndex + 2);
- }
- }//if(V1.Magnitude() <= aTol)
-
- XY Ndir (theV1.Y(), -theV1.X());
- XY DNdir (V2.Y(), -V2.X());
- XY D2Ndir (V3.Y(), -V3.X());
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R2 * R;
- Standard_Real R4 = R2 * R2;
- Standard_Real R5 = R3 * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
- if (R5 <= gp::Resolution())
- {
- //We try another computation but the stability is not very good
- //dixit ISG.
- if (R4 <= gp::Resolution())
- {
- Geom2d_UndefinedDerivative::Raise();
- }
- // V2 = P" (U) :
- Standard_Real R4 = R2 * R2;
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
- D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
- D2Ndir.Multiply (offsetValue / R);
-
- if(IsDirectionChange)
- V2=-V2;
-
- V2.Add (Vec2d(D2Ndir));
-
- // V1 = P' (U) :
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec2d(DNdir));
- }
- else
- {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better.
- // V2 = P" (U) :
- D2Ndir.Multiply (offsetValue/R);
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
- D2Ndir.Add (Ndir.Multiplied
- (offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
-
- if(IsDirectionChange)
- V2=-V2;
-
- V2.Add (Vec2d(D2Ndir));
-
- // V1 = P' (U)
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- theV1.Add (Vec2d(DNdir));
- }
-
- //P (U) :
- D0(theU, P);
+ CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
void Geom2d_OffsetCurve::D3 (const Standard_Real theU,
- Pnt2d& P,
- Vec2d& theV1, Vec2d& V2, Vec2d& V3) const {
-
+ Pnt2d& theP,
+ Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const
+{
// P(u) = p(u) + Offset * Ndir / R
// with R = || p' ^ Z|| and Ndir = P' ^ Z
// (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
// (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
- const Standard_Real aTol = gp::Resolution();
+ basisCurve->D3 (theU, theP, theV1, theV2, theV3);
+ Vec2d V4 = basisCurve->DN (theU, 4);
Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4);
- basisCurve->D3 (theU, P, theV1, V2, V3);
- Vec2d V4 = basisCurve->DN (theU, 4);
-
- if(theV1.Magnitude() <= aTol)
- {
- const Standard_Real anUinfium = basisCurve->FirstParameter();
- const Standard_Real anUsupremum = basisCurve->LastParameter();
-
- const Standard_Real DivisionFactor = 1.e-3;
- Standard_Real du;
- if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
- du = 0.0;
- else
- du = anUsupremum-anUinfium;
-
- const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
-//Derivative is approximated by Taylor-series
-
- Standard_Integer anIndex = 1; //Derivative order
- Vec2d V;
-
- do
- {
- V = basisCurve->DN(theU,++anIndex);
- }
- while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder);
-
- Standard_Real u;
-
- if(theU-anUinfium < aDelta)
- u = theU+aDelta;
- else
- u = theU-aDelta;
-
- Pnt2d P1, P2;
- basisCurve->D0(Min(theU, u),P1);
- basisCurve->D0(Max(theU, u),P2);
-
- Vec2d V1(P1,P2);
- Standard_Real aDirFactor = V.Dot(V1);
-
- if(aDirFactor < 0.0)
- {
- theV1 = -V;
- V2 = -basisCurve->DN (theU, anIndex + 1);
- V3 = -basisCurve->DN (theU, anIndex + 2);
- V4 = -basisCurve->DN (theU, anIndex + 3);
-
- IsDirectionChange = Standard_True;
- }
- else
- {
- theV1 = V;
- V2 = basisCurve->DN (theU, anIndex + 1);
- V3 = basisCurve->DN (theU, anIndex + 2);
- V4 = basisCurve->DN (theU, anIndex + 3);
- }
- }//if(V1.Magnitude() <= aTol)
-
- XY Ndir (theV1.Y(), -theV1.X());
- XY DNdir (V2.Y(), -V2.X());
- XY D2Ndir (V3.Y(), -V3.X());
- XY D3Ndir (V4.Y(), -V4.X());
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R2 * R;
- Standard_Real R4 = R2 * R2;
- Standard_Real R5 = R3 * R2;
- Standard_Real R6 = R3 * R3;
- Standard_Real R7 = R5 * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
- Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
-
- if (R7 <= gp::Resolution())
- {
- //We try another computation but the stability is not very good
- //dixit ISG.
-
- if (R6 <= gp::Resolution())
- Geom2d_UndefinedDerivative::Raise();
-
- // V3 = P"' (U) :
- D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R2));
- D3Ndir.Subtract (
- (DNdir.Multiplied ((3.0 * offsetValue) * ((D2r/R2) + (Dr*Dr)/R4))));
- D3Ndir.Add (Ndir.Multiplied (
- (offsetValue * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r))));
- D3Ndir.Multiply (offsetValue/R);
-
- if(IsDirectionChange)
- V3=-V3;
-
- V3.Add (Vec2d(D3Ndir));
-
-
- // V2 = P" (U) :
- Standard_Real R4 = R2 * R2;
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
- D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
- D2Ndir.Multiply (offsetValue / R);
- V2.Add (Vec2d(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- theV1.Add (Vec2d(DNdir));
- }
- else
- {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better.
- // V3 = P"' (U) :
- D3Ndir.Multiply (offsetValue/R);
- D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R3));
- D3Ndir.Subtract (DNdir.Multiplied (
- ((3.0 * offsetValue) * ((D2r/R3) + (Dr*Dr)/R5))) );
- D3Ndir.Add (Ndir.Multiplied (
- (offsetValue * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))));
-
- if(IsDirectionChange)
- V3=-V3;
-
- V3.Add (Vec2d(D3Ndir));
-
- // V2 = P" (U) :
- D2Ndir.Multiply (offsetValue/R);
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
- D2Ndir.Subtract (Ndir.Multiplied (
- offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
- V2.Add (Vec2d(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- theV1.Add (Vec2d(DNdir));
- }
- //P (U) :
- D0(theU, P);
- }
+ CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange,
+ theP, theV1, theV2, theV3);
+}
//=======================================================================
//function : DN
void Geom2d_OffsetCurve::Value (const Standard_Real theU,
Pnt2d& theP, Pnt2d& thePbasis,
Vec2d& theV1basis ) const
- {
+{
basisCurve->D1(theU, thePbasis, theV1basis);
D0(theU,theP);
- }
+}
//=======================================================================
if (Index != 2) {
V2 = basisCurve->DN (U, Index);
}
- XY Ndir (V1.Y(), -V1.X());
- XY DNdir (V2.Y(), -V2.X());
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- if (R3 <= gp::Resolution()) {
- //We try another computation but the stability is not very good.
- if (R2 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue / R2);
- V1.Add (Vec2d(DNdir));
- }
- else {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- V1.Add (Vec2d(DNdir));
- }
- Ndir.Multiply (offsetValue/R);
- Ndir.Add (Pbasis.XY());
- P.SetXY (Ndir);
+
+ CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1);
}
V2 = basisCurve->DN (U, Index);
V3 = basisCurve->DN (U, Index + 1);
}
- XY Ndir (V1.Y(), -V1.X());
- XY DNdir (V2.Y(), -V2.X());
- XY D2Ndir (V3.Y(), -V3.X());
- Standard_Real R2 = Ndir.SquareModulus();
- Standard_Real R = Sqrt (R2);
- Standard_Real R3 = R2 * R;
- Standard_Real R4 = R2 * R2;
- Standard_Real R5 = R3 * R2;
- Standard_Real Dr = Ndir.Dot (DNdir);
- Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
- if (R5 <= gp::Resolution()) {
- //We try another computation but the stability is not very good
- //dixit ISG.
- if (R4 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
- // V2 = P" (U) :
- Standard_Real R4 = R2 * R2;
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
- D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
- D2Ndir.Multiply (offsetValue / R);
- V2.Add (Vec2d(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply(R);
- DNdir.Subtract (Ndir.Multiplied (Dr/R));
- DNdir.Multiply (offsetValue/R2);
- V1.Add (Vec2d(DNdir));
- }
- else {
- // Same computation as IICURV in EUCLID-IS because the stability is
- // better.
- // V2 = P" (U) :
- D2Ndir.Multiply (offsetValue/R);
- D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
- D2Ndir.Subtract (Ndir.Multiplied (
- offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
- )
- );
- V2.Add (Vec2d(D2Ndir));
- // V1 = P' (U) :
- DNdir.Multiply (offsetValue/R);
- DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
- V1.Add (Vec2d(DNdir));
- }
- //P (U) :
- Ndir.Multiply (offsetValue/R);
- Ndir.Add (Pbasis.XY());
- P.SetXY (Ndir);
+
+ CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2);
}
//=======================================================================
{
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;
+}
gp,
Standard,
TColStd,
- TColgp
+ TColgp,
+ BSplCLib
is
BSplineCurve from Geom2d,
CurveType from GeomAbs,
Shape from GeomAbs,
- HCurve2d from Adaptor2d
+ HCurve2d from Adaptor2d,
+ Cache from BSplCLib
raises NoSuchObject from Standard,
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
+ ValueBSpline(me; U: Real) returns Pnt2d from gp
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ is private;
+
+ ValueOffset(me; U: Real) returns Pnt2d from gp
+ --- Purpose : Computes the point of parameter U on the offset curve
+ is private;
+
D0 (me; U : Real; P : out Pnt2d from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
+ D0BSpline(me; theU : Real; theP : out Pnt2d from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ is private;
+
+ D0Offset(me; theU : Real; theP : out Pnt2d from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ is private;
+
D1 (me; U : Real; P : out Pnt2d from gp ; V : out Vec2d from gp)
--- Purpose : Computes the point of parameter U on the curve with its
-- first derivative.
-
raises
DomainError from Standard
--- Purpose : Raised if the continuity of the current interval
-- is not C1.
is redefined static;
+
+ D1BSpline(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its derivative
+ is private;
+
+ D1Offset(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its derivative
+ is private;
D2 (me; U : Real; P : out Pnt2d from gp; V1, V2 : out Vec2d from gp)
--- Purpose :
-- is not C2.
is redefined static;
+ D2BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its first and second derivatives
+ is private;
+
+ D2Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its first and second derivatives
+ is private;
+
D3 (me; U : Real; P : out Pnt2d from gp; V1, V2, V3 : out Vec2d from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
--- Purpose : Raised if the continuity of the current interval
-- is not C3.
is redefined static;
+
+ D3BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its first, second and third derivatives
+ is private;
+
+ D3Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its first, second and third derivatives
+ is private;
DN (me; U : Real; N : Integer) returns Vec2d from gp
--- Purpose :
--- Purpose : Raised if N < 1.
is redefined static;
+ DNBSpline(me; theU : Real; N : Integer) returns Vec2d from gp
+ --- Purpose :
+ -- The returned vector gives the value of the derivative for the
+ -- order of derivation N.
+ is private;
+
+ DNOffset(me; theU : Real; N : Integer) returns Vec2d from gp
+ --- Purpose :
+ -- The returned vector gives the value of the derivative for the
+ -- order of derivation N.
+ is private;
+
Resolution(me; Ruv :Real) returns Real
---Purpose : returns the parametric resolution
load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real)
is private;
+
+ RebuildCache(me; theParameter : Real)
+ ---Purpose: Rebuilds B-spline cache
+ -- \param theParameter the value on the knot axis which identifies the caching span
+ is static private;
fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
+ myCurveCache : Cache from BSplCLib;
+ myOffsetBaseCurveAdaptor : HCurve2d from Adaptor2d;
end Curve;
#include <Geom2dAdaptor_HCurve.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <BSplCLib.hxx>
+#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_Hyperbola.hxx>
+#include <Geom2d_UndefinedValue.hxx>
+#include <Geom2d_UndefinedDerivative.hxx>
+#include <CSLib_Offset.hxx>
//#include <Geom2dConvert_BSplineCurveKnotSplitting.hxx>
#include <Standard_OutOfRange.hxx>
#define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
+static const int maxDerivOrder = 3;
+static const Standard_Real MinStep = 1e-7;
+
+static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
+
+// Recalculate derivatives in the singular point
+// Returns true is the direction of derivatives is changed
+static Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative,
+ Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative,
+ gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative);
+
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
}
else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
+ // Create cache for B-spline
+ myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
+ myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
+ }
+ else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
+ {
+ myTypeCurve = GeomAbs_OtherCurve;
+ // Create nested adaptor for base curve
+ Handle(Geom2d_Curve) aBase = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve();
+ myOffsetBaseCurveAdaptor = new Geom2dAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
if (myTypeCurve == GeomAbs_BSplineCurve) {
return LocalContinuity(myFirst, myLast);
}
- else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape S =
(*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity();
switch(S){
}
}
}
- else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
- Geom2dAdaptor_Curve C
- ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
- myNbIntervals = C.NbIntervals(BaseS);
+ myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
}
return myNbIntervals;
}
}
}
- else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){
GeomAbs_Shape BaseS=GeomAbs_C0;
switch(S){
case GeomAbs_G1:
case GeomAbs_C2: BaseS = GeomAbs_C3; break;
default: BaseS = GeomAbs_CN;
}
- Geom2dAdaptor_Curve C
- ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve());
- myNbIntervals = C.NbIntervals(BaseS);
- C.Intervals(T, BaseS);
+ myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS);
+ myOffsetBaseCurveAdaptor->Intervals(T, BaseS);
}
T( T.Lower() ) = myFirst;
return myCurve->LastParameter() - myCurve->FirstParameter();
}
+//=======================================================================
+//function : RebuildCache
+//purpose :
+//=======================================================================
+void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
+{
+ myCurveCache->BuildCache(theParameter, myBspl->Degree(),
+ myBspl->IsPeriodic(), myBspl->KnotSequence(),
+ myBspl->Poles(), myBspl->Weights());
+}
+
//=======================================================================
//function : Value
//purpose :
gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ return ValueBSpline(U);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
+ return ValueOffset(U);
+
+ return myCurve->Value(U);
+}
+
+//=======================================================================
+//function : ValueBSpline
+//purpose : Computes the point of parameter U on the B-spline curve
+//=======================================================================
+gp_Pnt2d Geom2dAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst)
+ {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast)
+ {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- return myBspl->LocalValue(U, Ideb, Ifin);
+ return myBspl->LocalValue(theU, Ideb, Ifin);
}
- else {
- return myCurve->Value( U);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ gp_Pnt2d aRes;
+ myCurveCache->D0(theU, aRes);
+ return aRes;
}
+ return myCurve->Value(theU);
+}
+
+//=======================================================================
+//function : ValueOffset
+//purpose : Computes the point of parameter U on the offset curve
+//=======================================================================
+gp_Pnt2d Geom2dAdaptor_Curve::ValueOffset(const Standard_Real theU) const
+{
+ gp_Pnt2d aP;
+ gp_Vec2d aD1;
+ myOffsetBaseCurveAdaptor->D1(theU, aP, aD1);
+ Standard_Boolean isDirectionChange = Standard_False;
+ const Standard_Real aTol = gp::Resolution();
+ if(aD1.SquareMagnitude() <= aTol)
+ isDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aD1);
+
+ Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
+ CSLib_Offset::D0(aP, aD1, anOffset, isDirectionChange, aP);
+ return aP;
}
//=======================================================================
void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ {
+ D0BSpline(U, P);
+ return;
+ }
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
+ {
+ D0Offset(U, P);
+ return;
+ }
+
+ myCurve->D0(U, P);
+}
+
+//=======================================================================
+//function : D0BSpline
+//purpose : Computes the point of parameter theU on the B-spline curve
+//=======================================================================
+void Geom2dAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt2d& theP) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD0( U, Ideb, Ifin, P);
+ myBspl->LocalD0(theU, Ideb, Ifin, theP);
+ return;
}
- else {
- myCurve->D0(U, P);
- }
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D0(theU, theP);
+ return;
+ }
+ myCurve->D0(theU, theP);
+}
+
+//=======================================================================
+//function : D0Offset
+//purpose : Computes the point of parameter theU on the offset curve
+//=======================================================================
+void Geom2dAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt2d& theP) const
+{
+ theP = ValueOffset(theU);
}
//=======================================================================
//purpose :
//=======================================================================
-void Geom2dAdaptor_Curve::D1(const Standard_Real U,
- gp_Pnt2d& P, gp_Vec2d& V) const
+void Geom2dAdaptor_Curve::D1(const Standard_Real U,
+ gp_Pnt2d& P, gp_Vec2d& V) const
+{
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ {
+ 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 ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD1( U, Ideb, Ifin, P, V);
- }
- else {
- myCurve->D1( U, P, V);
+ myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
+ return;
}
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D1(theU, theP, theV);
+ return;
+ }
+ myCurve->D1(theU, theP, theV);
+}
+
+//=======================================================================
+//function : D1Offset
+//purpose : Computes the point of parameter theU on the offset curve and its derivative
+//=======================================================================
+void Geom2dAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const
+{
+ // P(u) = p(u) + Offset * Ndir / R
+ // with R = || p' ^ Z|| and Ndir = P' ^ Z
+
+ // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
+
+ gp_Vec2d V2;
+ myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, V2);
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, V2);
+
+ Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
+ CSLib_Offset::D1(theP, theV, V2, anOffset, IsDirectionChange, theP, theV);
}
//=======================================================================
//=======================================================================
void Geom2dAdaptor_Curve::D2(const Standard_Real U,
- gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
+ gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ {
+ D2BSpline(U, P, V1, V2);
+ return;
+ }
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
+ {
+ D2Offset(U, P, V1, V2);
+ return;
+ }
+
+ myCurve->D2(U, P, V1, V2);
+}
+
+//=======================================================================
+//function : D2BSpline
+//purpose : Computes the point of parameter theU on the B-spline curve and its first and second derivatives
+//=======================================================================
+void Geom2dAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt2d& theP,
+ gp_Vec2d& theV1, gp_Vec2d& theV2) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
+ myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
+ return;
}
- else {
- myCurve->D2( U, P, V1, V2);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D2(theU, theP, theV1, theV2);
+ return;
}
+ myCurve->D2(theU, theP, theV1, theV2);
+}
+//=======================================================================
+//function : D2Offset
+//purpose : Computes the point of parameter theU on the offset curve and its first and second derivatives
+//=======================================================================
+void Geom2dAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt2d& theP,
+ gp_Vec2d& theV1, gp_Vec2d& theV2) const
+{
+ // P(u) = p(u) + Offset * Ndir / R
+ // with R = || p' ^ Z|| and Ndir = P' ^ Z
+
+ // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
+
+ // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
+ // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
+
+ gp_Vec2d V3;
+ myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
+
+ Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
+ CSLib_Offset::D2(theP, theV1, theV2, V3, anOffset, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
//=======================================================================
void Geom2dAdaptor_Curve::D3(const Standard_Real U,
- gp_Pnt2d& P, gp_Vec2d& V1,
- gp_Vec2d& V2, gp_Vec2d& V3) const
+ gp_Pnt2d& P, gp_Vec2d& V1,
+ gp_Vec2d& V2, gp_Vec2d& V3) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ {
+ D3BSpline(U, P, V1, V2, V3);
+ return;
+ }
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
+ {
+ D3Offset(U, P, V1, V2, V3);
+ return;
+ }
+
+ myCurve->D3(U, P, V1, V2, V3);
+}
+
+//=======================================================================
+//function : D3BSpline
+//purpose : Computes the point of parameter theU on the B-spline curve and its 1st - 3rd derivatives
+//=======================================================================
+void Geom2dAdaptor_Curve::D3BSpline(const Standard_Real theU, gp_Pnt2d& theP,
+ gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
+ myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
+ return;
}
- else {
- myCurve->D3( U, P, V1, V2, V3);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D3(theU, theP, theV1, theV2, theV3);
+ return;
}
+ myCurve->D3(theU, theP, theV1, theV2, theV3);
+}
+//=======================================================================
+//function : D3Offset
+//purpose : Computes the point of parameter theU on the offset curve and its 1st - 3rd derivatives
+//=======================================================================
+void Geom2dAdaptor_Curve::D3Offset(const Standard_Real theU, gp_Pnt2d& theP,
+ gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const
+{
+ // P(u) = p(u) + Offset * Ndir / R
+ // with R = || p' ^ Z|| and Ndir = P' ^ Z
+
+ // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
+
+ // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
+ // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
+
+ //P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
+ // (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
+ // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
+ // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+
+ myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
+ gp_Vec2d V4 = myOffsetBaseCurveAdaptor->DN (theU, 4);
+
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
+
+ Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset();
+ CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffset, IsDirectionChange,
+ theP, theV1, theV2, theV3);
}
//=======================================================================
//=======================================================================
gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U,
- const Standard_Integer N) const
+ const Standard_Integer N) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ return DNBSpline(U, N);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve))
+ return DNOffset(U, N);
+
+ return myCurve->DN(U, N);
+}
+
+gp_Vec2d Geom2dAdaptor_Curve::DNBSpline(const Standard_Real U,
+ const Standard_Integer N) const
+{
+ if (U==myFirst || U==myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
- }
- else {
- return myCurve->DN( U, N);
}
+
+ return myCurve->DN( U, N);
+}
+
+gp_Vec2d Geom2dAdaptor_Curve::DNOffset(const Standard_Real U,
+ const Standard_Integer N) const
+{
+ gp_Pnt2d aPnt;
+ gp_Vec2d aVec, aVN;
+
+ switch (N)
+ {
+ case 1:
+ D1Offset(U, aPnt, aVN);
+ break;
+ case 2:
+ D2Offset(U, aPnt, aVec, aVN);
+ break;
+ case 3:
+ D3Offset(U, aPnt, aVec, aVec, aVN);
+ break;
+ default:
+ aVN = myCurve->DN(U, N);
+ }
+ return aVN;
}
//=======================================================================
{
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;
+}
TColStd,
Geom2dAdaptor,
TColgp,
- Precision
+ Precision,
+ BSplCLib,
+ BSplSLib
is
class Curve;
BSplineCurve from Geom,
CurveType from GeomAbs,
Shape from GeomAbs,
- HCurve from Adaptor3d
+ HCurve from Adaptor3d,
+ Cache from BSplCLib
raises NoSuchObject from Standard,
ConstructionError from Standard,
--- Purpose : Computes the point of parameter U on the curve
is redefined static;
+ ValueBSpline(me; U: Real) returns Pnt from gp
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ is private;
+
+ ValueOffset(me; U: Real) returns Pnt from gp
+ --- Purpose : Computes the point of parameter U on the offset curve
+ is private;
+
D0 (me; U : Real; P : out Pnt from gp)
--- Purpose : Computes the point of parameter U.
is redefined static;
+ D0BSpline(me; theU : Real; theP : out Pnt from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ is private;
+
+ D0Offset(me; theU : Real; theP : out Pnt from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ is private;
+
D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp)
--- Purpose : Computes the point of parameter U on the curve
-- with its first derivative.
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
+
+ D1BSpline(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its derivative
+ is private;
+
+ D1Offset(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its derivative
+ is private;
D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp)
--- Purpose :
-- else the derivatives are computed on the basis curve.
is redefined static;
+ D2BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its first and second derivatives
+ is private;
+
+ D2Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its first and second derivatives
+ is private;
+
D3 (me; U : Real; P : out Pnt from gp; V1, V2, V3 : out Vec from gp)
--- Purpose :
-- Returns the point P of parameter U, the first, the second
-- derivatives are computed on the current interval.
-- else the derivatives are computed on the basis curve.
is redefined static;
+
+ D3BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the B-spline curve
+ -- and its first, second and third derivatives
+ is private;
+
+ D3Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp)
+ --- Purpose : Computes the point of parameter U on the offset curve
+ -- and its first, second and third derivatives
+ is private;
DN (me; U : Real; N : Integer) returns Vec from gp
--- Purpose :
is redefined static;
+ DNBSpline(me; theU : Real; N : Integer) returns Vec from gp
+ --- Purpose :
+ -- The returned vector gives the value of the derivative for the
+ -- order of derivation N.
+ is private;
+
+ DNOffset(me; theU : Real; N : Integer) returns Vec from gp
+ --- Purpose :
+ -- The returned vector gives the value of the derivative for the
+ -- order of derivation N.
+ is private;
+
+
Resolution(me; R3d :Real) returns Real
---Purpose : returns the parametric resolution
is redefined static;
load(me : in out; C : Curve from Geom; UFirst,ULast : Real)
is private;
+
+ RebuildCache(me; theParameter : Real)
+ ---Purpose: Rebuilds B-spline cache
+ -- \param theParameter the value on the knot axis which identifies the caching span
+ is static private;
fields
myTypeCurve : CurveType from GeomAbs ;
myFirst : Real from Standard ;
myLast : Real from Standard;
+ myCurveCache : Cache from BSplCLib;
+ myOffsetBaseCurveAdaptor : HCurve from Adaptor3d;
friends
class Surface from GeomAdaptor
#include <GeomAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <BSplCLib.hxx>
+#include <BSplCLib_Cache.hxx>
#include <GeomAbs_Shape.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_NullObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Geom_OffsetCurve.hxx>
+#include <CSLib_Offset.hxx>
#define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve))
#define PosTol Precision::PConfusion()/2
+static const int maxDerivOrder = 3;
+static const Standard_Real MinStep = 1e-7;
+
+static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative
+// Recalculate derivatives in the singular point
+// Returns true if the direction of derivatives is changed
+static Standard_Boolean AdjustDerivative(
+ const Handle(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1,
+ gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative);
+
+
//=======================================================================
//function : LocalContinuity
//purpose : Computes the Continuity of a BSplineCurve
}
else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) {
myTypeCurve = GeomAbs_BSplineCurve;
+ // Create cache for B-spline
+ myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(),
+ myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights());
+ }
+ else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) {
+ myTypeCurve = GeomAbs_OtherCurve;
+ // Create nested adaptor for base curve
+ Handle(Geom_Curve) aBase = Handle(Geom_OffsetCurve)::DownCast(myCurve)->BasisCurve();
+ myOffsetBaseCurveAdaptor = new GeomAdaptor_HCurve(aBase);
}
else {
myTypeCurve = GeomAbs_OtherCurve;
return myCurve->LastParameter() - myCurve->FirstParameter();
}
+//=======================================================================
+//function : RebuildCache
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const
+{
+ myCurveCache->BuildCache(theParameter, myBspl->Degree(),
+ myBspl->IsPeriodic(), myBspl->KnotSequence(),
+ myBspl->Poles(), myBspl->Weights());
+}
+
//=======================================================================
//function : Value
//purpose :
gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ return ValueBSpline(U);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
+ return ValueOffset(U);
+ return myCurve->Value(U);
+}
+
+//=======================================================================
+//function : ValueBSpline
+//purpose :
+//=======================================================================
+gp_Pnt GeomAdaptor_Curve::ValueBSpline(const Standard_Real theU) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- return myBspl->LocalValue(U, Ideb, Ifin);
+ return myBspl->LocalValue(theU, Ideb, Ifin);
}
- return myCurve->Value(U);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ gp_Pnt aRes;
+ myCurveCache->D0(theU, aRes);
+ return aRes;
+ }
+ return myCurve->Value(theU);
+}
+
+//=======================================================================
+//function : ValueOffset
+//purpose :
+//=======================================================================
+gp_Pnt GeomAdaptor_Curve::ValueOffset(const Standard_Real theU) const
+{
+ gp_Pnt aP;
+ gp_Vec aV;
+ myOffsetBaseCurveAdaptor->D1(theU, aP, aV);
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(aV.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aV);
+
+ Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
+ Standard_Real anOffsetVal = anOffC->Offset();
+ const gp_Dir& anOffsetDir = anOffC->Direction();
+
+ CSLib_Offset::D0(aP, aV, anOffsetDir, anOffsetVal, IsDirectionChange, aP);
+ return aP;
}
//=======================================================================
void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ D0BSpline(U, P);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
+ D0Offset(U, P);
+ else
+ myCurve->D0(U, P);
+}
+
+//=======================================================================
+//function : D0BSpline
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt& theP) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD0( U, Ideb, Ifin, P);
+ myBspl->LocalD0(theU, Ideb, Ifin, theP);
+ return;
}
- else {
- myCurve->D0(U, P);
- }
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D0(theU, theP);
+ return;
+ }
+ myCurve->D0(theU, theP);
+}
+
+//=======================================================================
+//function : D0Offset
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt& theP) const
+{
+ theP = ValueOffset(theU);
}
//=======================================================================
void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ D1BSpline(U, P, V);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
+ D1Offset(U, P, V);
+ else
+ myCurve->D1(U, P, V);
+}
+
+//=======================================================================
+//function : D1BSpline
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD1( U, Ideb, Ifin, P, V);
- }
- else {
- myCurve->D1( U, P, V);
+ myBspl->LocalD1(theU, Ideb, Ifin, theP, theV);
+ return;
}
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D1(theU, theP, theV);
+ return;
+ }
+ myCurve->D1(theU, theP, theV);
}
+//=======================================================================
+//function : D1Offset
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const
+{
+ gp_Vec aV2;
+ myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, aV2);
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, aV2);
+
+ Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
+ Standard_Real anOffsetVal = anOffC->Offset();
+ const gp_Dir& anOffsetDir = anOffC->Direction();
+ CSLib_Offset::D1(theP, theV, aV2, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV);
+}
+
+
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void GeomAdaptor_Curve::D2(const Standard_Real U,
- gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
+ gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const
+{
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ 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 ( (myTypeCurve == GeomAbs_BSplineCurve)&&
- (U==myFirst || U==myLast) ) {
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2);
+ myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2);
+ return;
}
- else {
- myCurve->D2( U, P, V1, V2);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D2(theU, theP, theV1, theV2);
+ return;
}
+ myCurve->D2(theU, theP, theV1, theV2);
+}
+
+//=======================================================================
+//function : D2Offset
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt& theP,
+ gp_Vec& theV1, gp_Vec& theV2) const
+{
+ gp_Vec V3;
+ myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3);
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3);
+
+ Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
+ Standard_Real anOffsetVal = anOffC->Offset();
+ const gp_Dir& anOffsetDir = anOffC->Direction();
+ CSLib_Offset::D2(theP, theV1, theV2, V3, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV1, theV2);
}
//=======================================================================
//=======================================================================
void GeomAdaptor_Curve::D3(const Standard_Real U,
- gp_Pnt& P, gp_Vec& V1,
- gp_Vec& V2, gp_Vec& V3) const
+ gp_Pnt& P, gp_Vec& V1,
+ gp_Vec& V2, gp_Vec& V3) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ D3BSpline(U, P, V1, V2, V3);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
+ D3Offset(U, P, V1, V2, V3);
+ else
+ myCurve->D3(U, P, V1, V2, V3);
+}
+
+//=======================================================================
+//function : D3BSpline
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D3BSpline(const Standard_Real theU,
+ gp_Pnt& theP, gp_Vec& theV1,
+ gp_Vec& theV2, gp_Vec& theV3) const
+{
+ if (theU == myFirst || theU == myLast)
+ {
Standard_Integer Ideb = 0, Ifin = 0;
- if (U==myFirst) {
+ if (theU == myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb<1) Ideb=1;
if (Ideb>=Ifin) Ifin = Ideb+1;
}
- if (U==myLast) {
+ if (theU == myLast) {
myBspl->LocateU(myLast, PosTol, Ideb, Ifin);
if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots();
if (Ideb>=Ifin) Ideb = Ifin-1;
}
- myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3);
+ myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3);
+ return;
}
- else {
- myCurve->D3( U, P, V1, V2, V3);
+ else if (!myCurveCache.IsNull()) // use cached B-spline data
+ {
+ if (!myCurveCache->IsCacheValid(theU))
+ RebuildCache(theU);
+ myCurveCache->D3(theU, theP, theV1, theV2, theV3);
+ return;
}
+ myCurve->D3(theU, theP, theV1, theV2, theV3);
+}
+
+//=======================================================================
+//function : D3Offset
+//purpose :
+//=======================================================================
+void GeomAdaptor_Curve::D3Offset(const Standard_Real theU,
+ gp_Pnt& theP, gp_Vec& theV1,
+ gp_Vec& theV2, gp_Vec& theV3) const
+{
+ myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3);
+ gp_Vec V4 = myOffsetBaseCurveAdaptor->DN(theU, 4);
+
+ Standard_Boolean IsDirectionChange = Standard_False;
+ if(theV1.SquareMagnitude() <= gp::Resolution())
+ IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4);
+
+ Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve);
+ Standard_Real anOffsetVal = anOffC->Offset();
+ const gp_Dir& anOffsetDir = anOffC->Direction();
+ CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffsetDir, anOffsetVal, IsDirectionChange,
+ theP, theV1, theV2, theV3);
}
//=======================================================================
//=======================================================================
gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
- const Standard_Integer N) const
+ const Standard_Integer N) const
+{
+ if (myTypeCurve == GeomAbs_BSplineCurve)
+ return DNBSpline(U, N);
+ else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
+ return DNOffset(U, N);
+
+ return myCurve->DN(U, N);
+}
+
+gp_Vec GeomAdaptor_Curve::DNBSpline(const Standard_Real U,
+ const Standard_Integer N) const
{
- if ( (myTypeCurve == GeomAbs_BSplineCurve) &&
- (U==myFirst || U==myLast) ) {
+ if ((U==myFirst || U==myLast))
+ {
Standard_Integer Ideb = 0, Ifin = 0;
if (U==myFirst) {
myBspl->LocateU(myFirst, PosTol, Ideb, Ifin);
if (Ideb>=Ifin) Ideb = Ifin-1;
}
return myBspl->LocalDN( U, Ideb, Ifin, N);
- }
- else {
- return myCurve->DN( U, N);
}
+ return myCurve->DN( U, N);
+}
+
+gp_Vec GeomAdaptor_Curve::DNOffset(const Standard_Real U,
+ const Standard_Integer N) const
+{
+ gp_Pnt aPnt;
+ gp_Vec aVec, aVN;
+
+ switch (N)
+ {
+ case 1:
+ D1Offset(U, aPnt, aVN);
+ break;
+ case 2:
+ D2Offset(U, aPnt, aVec, aVN);
+ break;
+ case 3:
+ D3Offset(U, aPnt, aVec, aVec, aVN);
+ break;
+ default:
+ aVN = myCurve->DN(U, N);
+ }
+ return aVN;
}
//=======================================================================
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;
+}
Shape from GeomAbs,
Curve from GeomAdaptor,
HCurve from Adaptor3d,
- HSurface from Adaptor3d
+ HSurface from Adaptor3d,
+ Cache from BSplSLib
raises
NoSuchObject from Standard,
TolV : Real = 0.0)
is private;
+ RebuildCache(me; theU, theV : Real)
+ ---Purpose: Rebuilds B-spline cache
+ -- \param theU first parameter to identify the span for caching
+ -- \param theV second parameter to identify the span for caching
+ is static private;
+
fields
mySurface : Surface from Geom;
myVFirst : Real from Standard;
myVLast : Real from Standard;
myTolU, myTolV : Real from Standard;
+ mySurfaceCache : Cache from BSplSLib;
end Surface;
#include <gp_Lin.hxx>
#include <gp_Trsf.hxx>
#include <BSplCLib.hxx>
+#include <BSplSLib_Cache.hxx>
#include <Precision.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NullObject.hxx>
mySurfaceType = GeomAbs_BezierSurface;
else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(),
- UFirst,ULast,VFirst,VLast);
+ UFirst,ULast,VFirst,VLast);
}
else if ( TheType == STANDARD_TYPE(Geom_Plane))
mySurfaceType = GeomAbs_Plane;
mySurfaceType = GeomAbs_SurfaceOfExtrusion;
else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) {
mySurfaceType = GeomAbs_BSplineSurface;
- myBspl = *((Handle(Geom_BSplineSurface)*)&S);
+ myBspl = *((Handle(Geom_BSplineSurface)*)&mySurface);
+ // Create cache for B-spline
+ mySurfaceCache = new BSplSLib_Cache(
+ myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
+ myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
+ myBspl->Poles(), myBspl->Weights());
}
else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface))
mySurfaceType = GeomAbs_OffsetSurface;
return mySurface->VPeriod();
}
+//=======================================================================
+//function : RebuildCache
+//purpose :
+//=======================================================================
+void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU,
+ const Standard_Real theV) const
+{
+ mySurfaceCache->BuildCache(theU, theV,
+ myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(),
+ myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(),
+ myBspl->Poles(), myBspl->Weights());
+}
+
//=======================================================================
//function : Value
//purpose :
gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U,
const Standard_Real V) const
{
+ if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
+ {
+ if (!mySurfaceCache->IsCacheValid(U, V))
+ RebuildCache(U, V);
+ gp_Pnt P;
+ mySurfaceCache->D0(U, V, P);
+ return P;
+ }
+
return mySurface->Value(U,V);
}
void GeomAdaptor_Surface::D0(const Standard_Real U,
const Standard_Real V, gp_Pnt& P) const
{
+ if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull())
+ {
+ if (!mySurfaceCache->IsCacheValid(U, V))
+ RebuildCache(U, V);
+ mySurfaceCache->D0(U, V, P);
+ return;
+ }
+
mySurface->D0(U,V,P);
}
void GeomAdaptor_Surface::D1(const Standard_Real U,
const Standard_Real V,
- gp_Pnt& P,
- gp_Vec& D1U,
- gp_Vec& D1V ) const
+ gp_Pnt& P,
+ gp_Vec& D1U,
+ gp_Vec& D1V ) const
{
- Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
+ Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
switch(mySurfaceType) {
- case GeomAbs_BSplineSurface:
- {
- if((USide==0)&&(VSide==0)){
- myBspl->D1(u,v,P,D1U,D1V);
- }
- else {
- if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
- myBspl->LocalD1 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V);
- else myBspl->D1(u,v,P,D1U,D1V);
- }
- break;
+ case GeomAbs_BSplineSurface:
+ if ((USide != 0 || VSide != 0) &&
+ IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
+ myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V);
+ else if (!mySurfaceCache.IsNull())
+ {
+ if (!mySurfaceCache->IsCacheValid(U, V))
+ RebuildCache(U, V);
+ mySurfaceCache->D1(U, V, P, D1U, D1V);
}
-
- case GeomAbs_SurfaceOfExtrusion :
-
- if(USide==0) myExtSurf->D1(u,v,P,D1U,D1V);
- else myExtSurf->LocalD1(u,v,USide,P,D1U,D1V);
- break;
-
- case GeomAbs_SurfaceOfRevolution :
-
- if(VSide==0) myRevSurf->D1 (u, v, P,D1U,D1V );
- else myRevSurf->LocalD1 (u, v, VSide, P,D1U,D1V );
- break;
-
- case GeomAbs_OffsetSurface :
- {
- if((USide==0)&&(VSide==0)) myOffSurf->D1 (u, v,P,D1U,D1V );
- else myOffSurf->LocalD1 (u, v, USide, VSide ,P,D1U,D1V );
- break;
- }
- default :
- mySurface->D1(u,v,P,D1U,D1V);
+ else
+ myBspl->D1(u, v, P, D1U, D1V);
+ break;
+
+ case GeomAbs_SurfaceOfExtrusion:
+ if (USide==0)
+ myExtSurf->D1(u, v, P, D1U, D1V);
+ else
+ myExtSurf->LocalD1(u, v, USide, P, D1U, D1V);
+ break;
+
+ case GeomAbs_SurfaceOfRevolution:
+ if (VSide==0)
+ myRevSurf->D1(u, v, P, D1U, D1V);
+ else
+ myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V);
+ break;
+
+ case GeomAbs_OffsetSurface:
+ if (USide==0 && VSide==0)
+ myOffSurf->D1(u, v, P, D1U, D1V);
+ else
+ myOffSurf->LocalD1(u, v, USide, VSide, P, D1U, D1V);
+ break;
+ default:
+ mySurface->D1(u, v, P, D1U, D1V);
}
}
//=======================================================================
void GeomAdaptor_Surface::D2(const Standard_Real U,
- const Standard_Real V, gp_Pnt& P,
- gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U,
- gp_Vec& D2V, gp_Vec& D2UV) const
+ const Standard_Real V,
+ gp_Pnt& P,
+ gp_Vec& D1U,
+ gp_Vec& D1V,
+ gp_Vec& D2U,
+ gp_Vec& D2V,
+ gp_Vec& D2UV) const
{
- Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0;
+ Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0;
Standard_Real u = U, v = V;
if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;}
else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;}
if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;}
else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;}
- switch(mySurfaceType)
+ switch(mySurfaceType) {
+ case GeomAbs_BSplineSurface:
+ if((USide != 0 || VSide != 0) &&
+ IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide))
+ myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV);
+ else if (!mySurfaceCache.IsNull())
{
- case GeomAbs_BSplineSurface:
-
- if((USide==0)&&(VSide==0)) myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
- else{
- if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide))
- myBspl->LocalD2 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V,D2U,D2V,D2UV);
- else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
- }
- break;
-
- case GeomAbs_SurfaceOfExtrusion :
-
- if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
- else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
- break;
-
- case GeomAbs_SurfaceOfRevolution :
-
- if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
- else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
- break;
-
- case GeomAbs_OffsetSurface :
- {
- if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
- else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
- break;
- }
- default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
- break;}
+ if (!mySurfaceCache->IsCacheValid(U, V))
+ RebuildCache(U, V);
+ mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV);
}
+ else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
+ break;
+
+ case GeomAbs_SurfaceOfExtrusion :
+
+ if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
+ else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV);
+ break;
+
+ case GeomAbs_SurfaceOfRevolution :
+
+ if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV );
+ else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV );
+ break;
+
+ case GeomAbs_OffsetSurface :
+ {
+ if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV );
+ else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV );
+ break;
+ }
+ default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV);
+ break;}
+ }
}
Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(),
BS->EndPoint().XYZ().SquareModulus());
Standard_Real eps = Epsilon(aDist);
- if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps &&
- !BS->IsClosed() && !BS->IsPeriodic())
+ if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps)
{
- //force Closed()
- gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
- BS->SetPole(1, aPm);
- BS->SetPole(BS->NbPoles(), aPm);
+ // Avoid creating B-splines containing two coincident poles only
+ if (mbspc.Degree() == 1 && nbpoles == 2)
+ continue;
+
+ if (!BS->IsClosed() && !BS->IsPeriodic())
+ {
+ //force Closed()
+ gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.);
+ BS->SetPole(1, aPm);
+ BS->SetPole(BS->NbPoles(), aPm);
+ }
}
sline.Append(BS);
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
+ if (Abs(ww - 1.0) < EpsW)
+ ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
NewP(ii,jj).SetCoord(3,PRes(indice+2));
if (rational) {
ww = PRes(indice+3);
+ if (Abs(ww - 1.0) < EpsW)
+ ww = 1.0;
if (ww < EpsW) {
NullWeight = Standard_True;
}
aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
- if( (aPoly1->DeflectionOverEstimation() > TolConf) ||
+ if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
(aPoly2->DeflectionOverEstimation() > TolConf))
{
const Standard_Real aDeflectionSum =
Max(aPoly1->DeflectionOverEstimation(), TolConf) +
Max(aPoly2->DeflectionOverEstimation(), TolConf);
- aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
- aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
-
- const Bnd_Box2d aB1 = aPoly1->Bounding(), aB2 = aPoly2->Bounding();
-
- aPoly1->ComputeWithBox(C1, aB2);
- aPoly2->ComputeWithBox(C2, aB1);
+ if (nbsamplesOnC2 > nbsamplesOnC1)
+ {
+ aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
+ aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
+ aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
+ }
+ else
+ {
+ aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
+ aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
+ aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
+ }
}
//----------------------------------------------------------------------
Standard_Real rvalf = Sign(1.,Valf(1));
for(Standard_Integer i = 2; i <= aNbSamples; ++i)
{
- D1->SamplePoint(i,s2d, s3d);
+ T->SamplePoint(i,s2d, s3d);
UVap(1)=s2d.X();
UVap(2)=s2d.Y();
Func.Value(UVap,Valf);
const Standard_Real aTol = 1.0e-14;
Handle(Geom_Surface) aS1, aS2;
- switch(theASurf1->GetType())
- {
- case GeomAbs_BezierSurface:
- aS1 = theASurf1->Surface().Bezier();
- break;
- case GeomAbs_BSplineSurface:
- aS1 = theASurf1->Surface().BSpline();
- break;
- default:
- return Standard_True;
- }
-
- switch(theASurf2->GetType())
- {
- case GeomAbs_BezierSurface:
- aS2 = theASurf2->Surface().Bezier();
- break;
- case GeomAbs_BSplineSurface:
- aS2 = theASurf2->Surface().BSpline();
- break;
- default:
- return Standard_True;
- }
+ if (theASurf1->GetType() != GeomAbs_BezierSurface &&
+ theASurf1->GetType() != GeomAbs_BSplineSurface)
+ return Standard_True;
+ if (theASurf2->GetType() != GeomAbs_BezierSurface &&
+ theASurf2->GetType() != GeomAbs_BSplineSurface)
+ return Standard_True;
Standard_Boolean aStatus = Standard_False;
gp_Pnt aP1, aP2;
gp_Vec aD1u, aD1v, aD2U, aD2V;
- aS1->D1(theU1, theV1, aP1, aD1u, aD1v);
- aS2->D1(theU2, theV2, aP2, aD2U, aD2V);
+ theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v);
+ theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V);
Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
gp_Pnt aPt1, aPt2;
- aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
- aS2->D1(aParU, aParV, aPt2, aD2U, aD2V);
+ theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v);
+ theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V);
Standard_Real aSQDist = aPt1.SquareDistance(aPt2);
}
else
{
- aS1->D1(theU1, theV1, aPt1, aD1u, aD1v);
- aS2->D1(theU2, theV2, aPt2, aD2U, aD2V);
+ theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v);
+ theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V);
gp_Vec aP12(aPt1, aPt2);
aGradFu = -aP12.Dot(aD1u);
Standard_Real uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf);
+ GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end
- gp_Pnt LowBound = C3D->Value(uMin);
- gp_Pnt HigBound = C3D->Value(uMax);
+ gp_Pnt LowBound = GAC.Value(uMin);
+ gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D);
if (distmin <= prec) {
param = uMin;
}
}
- GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost"
Standard_Real uMin = (cf < cl ? cf : cl);
Standard_Real uMax = (cf < cl ? cl : cf);
Standard_Real distmin = Precision::Infinite();
+ GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end
- gp_Pnt LowBound = C3D->Value(uMin);
- gp_Pnt HigBound = C3D->Value(uMax);
+ gp_Pnt LowBound = GAC.Value(uMin);
+ gp_Pnt HigBound = GAC.Value(uMax);
distmin = LowBound.Distance(P3D);
if (distmin <= prec) {
param = uMin;
}
}
- GeomAdaptor_Curve GAC(C3D, uMin, uMax);
if (!C3D->IsClosed()) {
//modified by rln on 16/12/97 after CSR# PRO11641 entity 20767
//the VIso was not closed (according to C3D->IsClosed()) while it "almost"
Handle(Geom_TrimmedCurve) aC = Handle(Geom_TrimmedCurve)::DownCast(curve);
return GetSamplePoints(aC->BasisCurve(),first,last,seq);
}
+
+ GeomAdaptor_Curve GAC(curve);
Standard_Real step = ( last - first ) / (Standard_Real)( nbp - 1 );
Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step )
- seq.Append(curve->Value(par));
- seq.Append(curve->Value(last));
+ seq.Append(GAC.Value(par));
+ seq.Append(GAC.Value(last));
return Standard_True;
}
//=======================================================================
Standard_Real step = ( last - first ) / (Standard_Real)( nbs - 1 );
Standard_Real par = first, stop = last - 0.5 * step;
for ( ; par < stop; par += step )
- seq.Append(curve->Value(par));
- seq.Append(curve->Value(last));
+ seq.Append(C.Value(par));
+ seq.Append(C.Value(last));
return Standard_True;
/*
Standard_Integer i;
// from 3d curve (but only if edge is SameParameter)
static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge,
const Handle(ShapeAnalysis_Surface) &surf,
- const Handle(Geom2d_Curve) &Crv2d,
+ const Geom2dAdaptor_Curve &Crv2d,
const Standard_Real param )
{
if ( BRep_Tool::SameParameter ( edge ) ) {
if ( ! ConS.IsNull() )
return ConS->Value ( param ).Transformed ( L.Transformation() );
}
- return surf->Value ( Crv2d->Value ( param ) );
+ gp_Pnt2d aP2d = Crv2d.Value(param);
+ return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
}
//=======================================================================
const IntRes2d_Transition &Tr2 = IP.TransitionOfSecond();
if ( Tr1.PositionOnCurve() != IntRes2d_Middle &&
Tr2.PositionOnCurve() != IntRes2d_Middle ) continue;
- gp_Pnt pint = GetPointOnEdge ( edge, mySurf, Crv, IP.ParamOnFirst() );
+ gp_Pnt pint = GetPointOnEdge ( edge, mySurf, AC, IP.ParamOnFirst() );
Standard_Real dist21 = pnt1.SquareDistance ( pint );
Standard_Real dist22 = pnt2.SquareDistance ( pint );
if ( dist21 > tol1 * tol1 && dist22 > tol2 * tol2 ) {
Standard_Real tolint = 1.0e-10;
//szv#4:S4163:12Mar99 warning
- IntRes2d_Domain d1 ( Crv1->Value ( a1 ), a1, tolint,
- Crv1->Value ( b1 ), b1, tolint );
- IntRes2d_Domain d2 ( Crv2->Value ( a2 ), a2, tolint,
- Crv2->Value ( b2 ), b2, tolint );
Geom2dAdaptor_Curve C1 ( Crv1 ), C2 ( Crv2 );
+ IntRes2d_Domain d1 ( C1.Value ( a1 ), a1, tolint,
+ C1.Value ( b1 ), b1, tolint );
+ IntRes2d_Domain d2 ( C2.Value ( a2 ), a2, tolint,
+ C2.Value ( b2 ), b2, tolint );
//:64 abv 25 Dec 97: Attention!
// Since Intersection algorithm is not symmetrical, for consistency with BRepCheck
param2-b2 > ::Precision::PConfusion() ) continue;
//:82 abv 21 Jan 98: point of intersection on Crv1 and Crv2 is different
- gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
- gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) );
+ gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
+ gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) );
gp_Pnt pint = 0.5 * ( pi1.XYZ() + pi2.XYZ() );
Standard_Real di1 = pi1.SquareDistance ( pnt );
Standard_Real di2 = pi2.SquareDistance ( pnt );
Tr2.PositionOnCurve() != IntRes2d_Middle ) continue;
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
- gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
- gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 );
+ gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) );
+ gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 );
Standard_Boolean OK1 = Standard_False;
Standard_Boolean OK2 = Standard_False;
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False;
}
- c2d->D1 ( b, p2d1, v1 );
+ Geom2dAdaptor_Curve anAdapt(c2d);
+ anAdapt.D1(b, p2d1, v1);
if ( E1.Orientation() == TopAbs_REVERSED ) v1.Reverse();
if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) {
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
return Standard_False;
}
- c2d->D1 ( a, p2d2, v2 );
+ anAdapt.Load(c2d);
+ anAdapt.D1(a, p2d2, v2);
if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse();
v12 = p2d2.XY() - p2d1.XY();
myMax2d = v12.SquareMagnitude();
Standard_Real wmid;
sac.Project(COnS,mid,preci,pnt,wmid,Standard_False);
wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period);
- if(w1>w2) {
+ if(w1>=w2) {
if(w2 > wmid) myFirstParam -= period;
else if (w1 > wmid)
UpdateParam2d(theCurve2d);
found = (staout != clas.Perform (unp1,Standard_False));
}
}
+ // Additional check of diagonal steps for toroidal surfaces
+ if (!found && uclosed && vclosed)
+ {
+ for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
+ for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
+ {
+ unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY);
+ found = (staout != clas.Perform(unp1, Standard_False));
+ }
+ }
}
if(found) {
if(stb==TopAbs_IN) stb = TopAbs_OUT;
#include <BRepTools.hxx>
#include <Bnd_Box2d.hxx>
#include <BndLib_Add2dCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_BSplineCurve.hxx>
//=======================================================================
static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge,
const Handle(ShapeAnalysis_Surface) &surf,
- const Handle(Geom2d_Curve) &Crv2d,
+ const Geom2dAdaptor_Curve &Crv2d,
const Standard_Real param )
{
if( BRep_Tool::SameParameter(edge) ) {
if( !ConS.IsNull() )
return ConS->Value(param).Transformed(L.Transformation());
}
- return surf->Value(Crv2d->Value(param));
+ gp_Pnt2d aP2d = Crv2d.Value(param);
+ return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y());
}
if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False;
if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False;
Standard_Real tolint = 1.0e-10;
- IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
- IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
+ IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
+ IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
Geom2dInt_GInter Inter;
Inter.Perform( C1, d1, C2, d2, tolint, tolint );
if(!Inter.IsDone()) continue;
Tr2.PositionOnCurve() == IntRes2d_Middle ) {
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
- gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
- gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
+ gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
+ gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
BRep_Builder B;
TopoDS_Vertex V;
Standard_Real tolV=0;
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
Standard_Real p12 = IPL.ParamOnFirst();
Standard_Real p22 = IPL.ParamOnSecond();
- gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
- gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
- gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
- gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
+ gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
+ gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
+ gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
+ gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
// next string commented by skl 29.12.2004 for OCC7624
//if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue;
if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue;
if( !IsModified1 && !IsModified2 ) {
Standard_Real param1 = (p11+p12)/2;
Standard_Real param2 = (p21+p22)/2;
- gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
- gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
+ gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
+ gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2,
(Pnt10.Z()+Pnt20.Z())/2 );
dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0));
if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) )
continue; //return Standard_False;gka 06.09.04
Standard_Real tolint = 1.0e-10;
- IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint);
- IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint);
Geom2dAdaptor_Curve C1(Crv1), C2(Crv2);
+ IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint);
+ IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint);
Geom2dInt_GInter Inter;
Inter.Perform( C1, d1, C2, d2, tolint, tolint );
if(!Inter.IsDone()) continue;
// create new vertex and split both edges
Standard_Real param1 = IP.ParamOnFirst();
Standard_Real param2 = IP.ParamOnSecond();
- gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1);
- gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2);
+ gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1);
+ gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2);
gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
BRep_Builder B;
TopoDS_Vertex V;
IntRes2d_IntersectionPoint IPL = IS.LastPoint();
Standard_Real p12 = IPL.ParamOnFirst();
Standard_Real p22 = IPL.ParamOnSecond();
- gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11);
- gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12);
- gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21);
- gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22);
+ gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11);
+ gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12);
+ gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21);
+ gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22);
// analysis for edge1
TopoDS_Vertex V1 = sae.FirstVertex(edge1);
(Pnt11.Z()+Pnt12.Z())/2 );
Standard_Real param1 = (p11+p12)/2;
Standard_Real param2 = (p21+p22)/2;
- gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1);
- gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2);
+ gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1);
+ gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2);
dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10));
dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10));
Standard_Real tolV = Max(dist1,dist2);
myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
}
else
- FixDummySeam(n1);
+ {
+ FixDummySeam(n1);
+ // The seam edge is removed from the list. So, need to step back to avoid missing of edge processing
+ i--;
+ }
i--;
if(!Context().IsNull()) //skl 07.03.2002 for OCC180
TP->AddWarning(C3D,"Update of 3D-Parameters has failed");
//:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends
- gp_Pnt pU1 = C1->Value ( U1 ), pU2 = C1->Value ( U2 );
+ GeomAdaptor_Curve aCA(C1);
+ gp_Pnt pU1 = aCA.Value ( U1 ), pU2 = aCA.Value ( U2 );
temp1 = pU1.Distance ( pv1 );
temp2 = pU2.Distance ( pv2 );
if ( temp1 > preci || temp2 > preci ) {
F.Value(x1,f1); f1-=K;
F.Value(x2,f2); f2-=K;
//-- printf("\n *************** RECHERCHE MINIMUM **********\n");
- while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > 0)) {
+ Standard_Real tolX = 0.001 * NEpsX;
+ while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > tolX)) {
//-- printf("\n (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) ",
//-- x0,f0,x1,f1,x2,f2,x3,f3);
if(recherche_minimum) {
InfiniteStatus = Standard_False;
Done = Standard_True;
- Eps = 1.e-12;
+ Eps = 1.5e-12;
Depi = M_PI+M_PI;
if (InfBound <= RealFirst() && SupBound >= RealLast()) {
# Original bug : pro10658
# Date : 24mar98
-puts "TODO #26080 ALL: Faulty shapes in variables faulty_1"
puts "TODO ALL Error : The area of the resulting shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b
# pro10658
-puts "TODO #26080 ALL: Faulty shapes in variables faulty_1"
puts "TODO ALL Error : The area of the resulting shape is"
restore [locate_data_file CTO900_pro10658a.rle] a
restore [locate_data_file pro10658b.rle] b
repeat 21 {
plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i
- bsection s_$i b f_$i
+ set bsres [bsection s_$i b f_$i]
+ if { [regexp {Error} $bsres] } {
+ puts "Error: bsection not done"
+ }
compound result s_$i result
set dist [expr $i * 100]
puts "OK Section:$dist"
repeat 199 {
plane p_$i 0 $i*100 0 0 1 0
mkface f_$i p_$i
- bsection s_$i a f_$i
+ set bsres [bsection s_$i a f_$i]
+ if { [regexp {Error} $bsres] } {
+ puts "Error: bsection not done"
+ }
compound result s_$i result
set dist [expr $i * 100]
puts "OK Section:$dist"
# test script on make volume operation
# cone cylinder plane
-puts "TODO OCC26020 ALL: Error: bopcheck failed"
+puts "TODO OCC26020 Windows: Error: bopcheck failed"
# planar face
plane pln_f1 27.577164466275352 -1038.2137499999999 27.577164466275359 0.70710678118654746 4.4408920985006262e-016 0.70710678118654768
catch { OFFSETSHAPE $distance {} $calcul $type }
-set square 253.552
+set square 253.902
set nb_v_good 2
set nb_e_good 3
catch { OFFSETSHAPE $distance {s_3} $calcul $type }
-set square 502.411
+set square 502.366
set nb_v_good 3
set nb_e_good 5
catch { OFFSETSHAPE $distance {s_2} $calcul $type }
-set square 502.411
+set square 502.366
set nb_v_good 3
set nb_e_good 5
catch { OFFSETSHAPE $distance {s_3 s_2} $calcul $type }
-set square 489.812
+set square 489.372
set nb_v_good 3
set nb_e_good 5
-puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape"
-puts "TODO OCC25925 ALL: result is not a topological shape"
-puts "TODO OCC25925 ALL: TEST INCOMPLETE"
+puts "TODO OCC24862 ALL: Error : Result shape is WRONG"
+puts "TODO OCC24862 ALL: Error : The square of result shape is"
+puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "============"
puts "OCC5805"
-puts "TODO OCC25925 ALL: Tcl Exception: result is not a topological shape!!!"
-puts "TODO OCC25925 ALL: ERROR. offsetperform operation not done"
-puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape"
-puts "TODO OCC25925 ALL: TEST INCOMPLETE"
+puts "TODO OCC24862 ALL: Error : Result shape is WRONG"
+puts "TODO OCC24862 ALL: Error : The square of result shape is"
+puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "============"
puts "OCC5805"
## After command sew in DRAW on attached shape free wires are disappeared.
####################################################
-puts "TODO OCC25593 ALL: Faulty shapes in variables faulty_1 to faulty_4"
-
restore [locate_data_file OCC714.brep] a
checkshape a
distmini d v1 v2
regexp {([-0-9.+eE]+)} [dump d_val] full dist
-set checkdist 2.54211497292521e-013
+set checkdist 1.13686837721616e-013
if { [expr 1.*abs($checkdist - $dist)/$checkdist] > 0.1 } {
puts "Error : Distance is wrong"
set status 0
-set info1 [OCC24303 4]
+set info1 [OCC24303 5]
regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution
regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance
-if { [info exists Sol4] } {
- set info2 [dump Sol4]
+if { [info exists Sol5] } {
+ set info2 [dump Sol5]
regexp {Center +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full CenterX CenterY
regexp {XAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full XAxisX XAxisY
regexp {YAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full YAxisX YAxisY
checkmaxtol result 0.0076621571738049385
checknbshapes result -shell 1
-checkfreebounds result 2
+checkfreebounds result 0
set 2dviewer 1
set nbshapes_expected "
Number of shapes in shape
- VERTEX : 169
- EDGE : 85
+ VERTEX : 165
+ EDGE : 83
WIRE : 0
FACE : 0
SHELL : 0
SOLID : 0
COMPSOLID : 0
COMPOUND : 1
- SHAPE : 255
+ SHAPE : 249
"
checknbshapes result -ref ${nbshapes_expected} -t -m "HLRToShape"
set deltaZ [dval dvz1-dvz2]
set percent_max 0.1
-set good_deltaX 4.4408920985006262e-015
-set good_deltaY -4.6629367034256575e-015
-set good_deltaZ -2.6645352591003757e-015
+set good_deltaX -3.5527136788005009e-015
+set good_deltaY -3.5527136788005009e-015
+set good_deltaZ 8.8817841970012523e-016
set deltaX_percent [GetPercent ${deltaX} ${good_deltaX}]
puts "deltaX_percent = ${deltaX_percent}"
set env(os_type) $tcl_platform(platform)
if { [string compare $env(os_type) "windows"] != 0 } {
puts "OS = Linux"
- set good_tri 520414
- set good_nod 263938
- set good_defl 0.0026800432954056617
+ set good_tri 615414
+ set good_nod 311438
+ set good_defl 0.0032657364637550075
} else {
puts "OS = Windows NT"
- set good_tri 520414
- set good_nod 263938
- set good_defl 0.0026800432954056617
+ set good_tri 615414
+ set good_nod 311438
+ set good_defl 0.0032657364637550075
}
proc GetPercent {Value GoodValue} {
checkmaxtol result 2.5472812372261969e-005
checknbshapes result -shell 13
- checkfreebounds result 1249
+ checkfreebounds result 1247
}
set 2dviewer 0
-puts "TODO OCC12345 ALL: Faulty OCC498: Wrong 3d point from offset surface by parameters"
-
puts "========="
puts " OCC498 "
puts "========="
set tol_rel 0.01
set expected_dmax 0.0013771610718045313
-set expected_ufmax 0.890625
+set expected_ufmax 0.953125
checkreal "dmax" ${dmax} ${expected_dmax} ${tol_abs} ${tol_rel}
checkreal "ufmax" ${ufmax} ${expected_ufmax} ${tol_abs} ${tol_rel}
-set expected_ulmax 0.90625
+set expected_ulmax 0.96875
if { ${ulmax} != ${expected_ulmax} } {
puts "Error : bad value of ulmax=${ulmax}"
}
-set expected_i 69
+set expected_i 73
if { ${i} != ${expected_i} } {
puts "Error : bad value of i=${i}"
}
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR23096 ALL: TPSTAT : Faulty"
-
set filename UKI60095.igs
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) Summary = 18221 ( 18221 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 8213 ( 8213 )
TOLERANCE : MaxTol = 0.004034169186 ( 0.004034577888 ) AvgTol = 7.709492698e-006 ( 1.210857047e-005 )
-LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 929 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1829 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1829 ) LayerLabels = 900 ( 1829 )
+LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 930 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1830 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1830 ) LayerLabels = 900 ( 1830 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = YELLOW ( YELLOW )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 1091 ) Summary = 42 ( 1091 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22098 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10005 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22096 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10004 )
TOLERANCE : MaxTol = 0.5433123154 ( 0.5433122968 ) AvgTol = 0.002230678782 ( 0.002235663837 )
-LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1450 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2488 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2488 ) LayerLabels = 1038 ( 2488 )
+LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1449 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2487 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2487 ) LayerLabels = 1038 ( 2487 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 2 ( 2 )
COLORS : Colors = GREEN RED ( GREEN RED )
set ref_data {
DATA : Faulties = 0 ( 12 ) Warnings = 0 ( 1 ) Summary = 0 ( 13 )
TPSTAT : Faulties = 0 ( 28 ) Warnings = 116 ( 7 ) Summary = 116 ( 35 )
-CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 1 ) Solids = 0 ( 1 )
-NBSHAPES : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) Summary = 15092 ( 7703 )
-STATSHAPE : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6291 ( 3138 )
+CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 1 ) Solids = 0 ( 1 )
+NBSHAPES : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) Summary = 15073 ( 7693 )
+STATSHAPE : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6283 ( 3134 )
TOLERANCE : MaxTol = 0.2496383637 ( 0.2496258832 ) AvgTol = 0.00219239232 ( 0.004111699336 )
LABELS : N0Labels = 27 ( 27 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 27 ( 27 ) NameLabels = 27 ( 27 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR25923 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
-
+puts "TODO CR23096 ALL: NBSHAPES : Faulty"
+puts "TODO CR23096 ALL: Error : 2 differences with reference data found"
set filename FRA62468-1.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
-TPSTAT : Faulties = 0 ( 0 ) Warnings = 427 ( 5255 ) Summary = 427 ( 5255 )
+TPSTAT : Faulties = 0 ( 0 ) Warnings = 299 ( 5226 ) Summary = 299 ( 5226 )
CHECKSHAPE : Wires = 12 ( 20 ) Faces = 16 ( 18 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68354 ( 68418 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29043 ( 29075 )
-TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01115315301 ( 0.0111584608 )
-LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4437 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9895 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9829 ) LayerLabels = 5391 ( 9829 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68422 ( 68420 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29075 ( 29079 )
+TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01114309412 ( 0.01115568387 )
+LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4427 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9885 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9819 ) LayerLabels = 5391 ( 9819 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 CYAN1 GREEN ( BLACK BLUE1 CYAN1 GREEN )
# !!!! This file is generated automatically, do not edit manually! See end script
+puts "TODO CR23096 ALL: TPSTAT : Faulty"
+puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
-puts "TODO CR23096 ALL: TOLERANCE : Faulty"
-
set LinuxDiff 3
set filename PRO14319.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
-TPSTAT : Faulties = 0 ( 0 ) Warnings = 2 ( 64 ) Summary = 2 ( 64 )
-CHECKSHAPE : Wires = 1 ( 7 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7360 ( 7320 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3632 ( 3603 )
-TOLERANCE : MaxTol = 0.3749733839 ( 0.3140268243 ) AvgTol = 0.002809949164 ( 0.0005120147149 )
-LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 788 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 849 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 849 ) LayerLabels = 0 ( 0 )
+TPSTAT : Faulties = 1 ( 0 ) Warnings = 3 ( 64 ) Summary = 4 ( 64 )
+CHECKSHAPE : Wires = 3 ( 5 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7731 ( 7831 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3842 ( 3895 )
+TOLERANCE : MaxTol = 0.3140268251 ( 0.3140268243 ) AvgTol = 0.0009762560334 ( 0.000488212708 )
+LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 1080 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 1141 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 1141 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = CYAN1 GREEN WHITE ( CYAN1 GREEN WHITE )
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
-
set filename 12ls328.igs
set ref_data {
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
set LinuxDiff 1
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 444 ( 1005 ) Summary = 444 ( 1005 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50232 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50230 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) FreeWire = 119 ( 139 ) FreeEdge = 4488 ( 4487 ) SharedEdge = 24679 ( 24678 )
TOLERANCE : MaxTol = 1e-05 ( 0.06099237775 ) AvgTol = 3.184880431e-07 ( 1.621424764e-05 )
LABELS : N0Labels = 432 ( 432 ) N1Labels = 12 ( 845 ) N2Labels = 0 ( 0 ) TotalLabels = 444 ( 1277 ) NameLabels = 432 ( 687 ) ColorLabels = 320 ( 1277 ) LayerLabels = 320 ( 1277 )
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
+puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 2
set filename brazo1.igs
set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 )
-TPSTAT : Faulties = 0 ( 0 ) Warnings = 148 ( 478 ) Summary = 148 ( 478 )
+TPSTAT : Faulties = 0 ( 0 ) Warnings = 139 ( 454 ) Summary = 139 ( 454 )
CHECKSHAPE : Wires = 6 ( 8 ) Faces = 6 ( 8 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4666 ( 4542 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2144 ( 2074 )
-TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01125801875 ( 0.01225981249 )
-LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 242 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 465 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 465 ) LayerLabels = 223 ( 465 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4710 ( 4574 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2166 ( 2092 )
+TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01133191355 ( 0.01225911215 )
+LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 256 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 479 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 479 ) LayerLabels = 223 ( 479 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 MAGENTA1 YELLOW ( BLUE1 MAGENTA1 YELLOW )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) Summary = 12751 ( 12759 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) FreeWire = 36 ( 36 ) FreeEdge = 232 ( 232 ) SharedEdge = 5541 ( 5545 )
TOLERANCE : MaxTol = 0.9845041621 ( 0.9845038147 ) AvgTol = 0.00992720939 ( 0.009919874447 )
-LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1770 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2650 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2650 ) LayerLabels = 844 ( 2650 )
+LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1784 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2664 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2664 ) LayerLabels = 844 ( 2664 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 )
COLORS : Colors = BLACK ( BLACK )
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 38 ( 183 ) Summary = 38 ( 183 )
-CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) Summary = 2511 ( 2510 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) FreeWire = 23 ( 23 ) FreeEdge = 331 ( 331 ) SharedEdge = 983 ( 983 )
-TOLERANCE : MaxTol = 0.1829958579 ( 0.1829958769 ) AvgTol = 0.003259834421 ( 0.003329232309 )
+TOLERANCE : MaxTol = 0.1830141575 ( 0.1830141765 ) AvgTol = 0.003295423033 ( 0.003364815075 )
LABELS : N0Labels = 412 ( 412 ) N1Labels = 2 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 414 ( 412 ) NameLabels = 412 ( 412 ) ColorLabels = 389 ( 410 ) LayerLabels = 389 ( 410 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 5 ( 5 )
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR25923 ALL: STATSHAPE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
+puts "TODO CR23096 ALL: STATSHAPE : Faulty"
+puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 5
set filename BUC60743.igs
set ref_data {
DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 )
-TPSTAT : Faulties = 3 ( 59 ) Warnings = 2205 ( 4736 ) Summary = 2208 ( 4795 )
-CHECKSHAPE : Wires = 7 ( 16 ) Faces = 6 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 2837 ) Summary = 45907 ( 39191 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19595 ( 16764 )
-TOLERANCE : MaxTol = 3.742696236 ( 5.769095076 ) AvgTol = 0.01636161939 ( 0.01749445935 )
-LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6319 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6330 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6319 ) LayerLabels = 2411 ( 5257 )
+TPSTAT : Faulties = 3 ( 59 ) Warnings = 2203 ( 4655 ) Summary = 2206 ( 4714 )
+CHECKSHAPE : Wires = 7 ( 17 ) Faces = 7 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 2837 ) Summary = 45927 ( 39202 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19607 ( 16774 )
+TOLERANCE : MaxTol = 4.854604894 ( 5.769095076 ) AvgTol = 0.01628658326 ( 0.01747356296 )
+LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6327 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6338 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6327 ) LayerLabels = 2411 ( 5258 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = BLACK BLUE1 RED YELLOW ( BLACK BLUE1 RED YELLOW )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 56 ( 12 ) Summary = 56 ( 12 )
CHECKSHAPE : Wires = 2 ( 1 ) Faces = 2 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25969 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10687 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25971 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10688 )
TOLERANCE : MaxTol = 0.9711309062 ( 0.9711309063 ) AvgTol = 0.01916076754 ( 0.01948753951 )
-LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3205 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3455 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3449 ) LayerLabels = 0 ( 0 )
+LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3204 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3454 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3448 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 4 )
COLORS : Colors = CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ( CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 191 ) Summary = 88 ( 191 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7836 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3350 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7833 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3348 )
TOLERANCE : MaxTol = 0.7161069967 ( 0.7585238415 ) AvgTol = 0.006717667602 ( 0.006937200018 )
LABELS : N0Labels = 568 ( 568 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 570 ( 570 ) NameLabels = 568 ( 568 ) ColorLabels = 569 ( 569 ) LayerLabels = 569 ( 569 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR23096 ALL: LABELS : Faulty"
-puts "TODO CR25923 ALL: NBSHAPES : Faulty"
-#puts "TODO CR23096 ALL: Error : 1 differences with reference data found :"
+puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
+puts "TODO CR23096 ALL: LABELS : Faulty"
+puts "TODO CR23096 ALL: NBSHAPES : Faulty"
+puts "TODO CR23096 ALL: Error : 2 differences with reference data found"
set LinuxDiff 1
set filename FRA62468-2.igs
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
-TPSTAT : Faulties = 0 ( 0 ) Warnings = 349 ( 5016 ) Summary = 349 ( 5016 )
-CHECKSHAPE : Wires = 12 ( 19 ) Faces = 12 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63090 ( 63144 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26766 ( 26793 )
-TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01154225009 ( 0.01155173987 )
-LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3844 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 9009 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8933 ) LayerLabels = 5086 ( 8933 )
+TPSTAT : Faulties = 0 ( 0 ) Warnings = 253 ( 4993 ) Summary = 253 ( 4993 )
+CHECKSHAPE : Wires = 8 ( 11 ) Faces = 8 ( 7 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63158 ( 63146 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26798 ( 26797 )
+TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01153089031 ( 0.01154870945 )
+LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3834 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 8999 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8923 ) LayerLabels = 5086 ( 8923 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 3 )
COLORS : Colors = BLUE1 CYAN1 GREEN ( BLUE1 CYAN1 GREEN )
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
-
+puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set filename PRO10626.igs
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 2 ( 0 ) Warnings = 85 ( 295 ) Summary = 87 ( 295 )
CHECKSHAPE : Wires = 8 ( 13 ) Faces = 8 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5352 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2221 ( 2228 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5349 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2220 ( 2226 )
TOLERANCE : MaxTol = 4.547932063 ( 4.543567878 ) AvgTol = 0.03466358537 ( 0.03659099671 )
LABELS : N0Labels = 457 ( 457 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 457 ) NameLabels = 457 ( 457 ) ColorLabels = 451 ( 455 ) LayerLabels = 453 ( 457 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
DATA : Faulties = 0 ( 1 ) Warnings = 0 ( 0 ) Summary = 0 ( 1 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 650 ( 1843 ) Summary = 650 ( 1843 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17129 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7869 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17126 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7867 )
TOLERANCE : MaxTol = 1.089725986e-005 ( 1.089659651e-005 ) AvgTol = 1.975835144e-006 ( 9.652818162e-006 )
-LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1400 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2093 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2093 ) LayerLabels = 692 ( 2093 )
+LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1399 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2092 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2092 ) LayerLabels = 692 ( 2092 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 3 ( 4 )
COLORS : Colors = CYAN1 WHITE YELLOW ( CYAN1 GREEN3 WHITE YELLOW )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) Summary = 8171 ( 8283 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) FreeWire = 108 ( 108 ) FreeEdge = 606 ( 606 ) SharedEdge = 3685 ( 3689 )
-TOLERANCE : MaxTol = 5.750743843e+14 ( 4.784430882e+15 ) AvgTol = 2.722724827e+11 ( 2.206755414e+12 )
+TOLERANCE : MaxTol = 2.113937626e+17 ( 2.113937968e+17 ) AvgTol = 9.737589861e+13 ( 9.762248147e+13 )
LABELS : N0Labels = 7 ( 7 ) N1Labels = 450 ( 2042 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 2049 ) NameLabels = 457 ( 698 ) ColorLabels = 450 ( 2043 ) LayerLabels = 449 ( 2042 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 7 ( 7 )
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: NBSHAPES : Faulty"
+puts "TODO CR23096 ALL: TOLERANCE : Faulty"
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: COLORS : Faulty"
puts "TODO CR25013 ALL: Error : 3 differences with reference data found"
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 3 ) Warnings = 274 ( 4465 ) Summary = 274 ( 4468 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39230 ( 39268 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17933 ( 17940 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39231 ( 39275 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17934 ( 17947 )
TOLERANCE : MaxTol = 4.337400808e+088 ( 8.082392835e+086 ) AvgTol = 2.040579288e+085 ( 5.099401401e+083 )
-LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9638 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9644 ) NameLabels = 1649 ( 2890 ) ColorLabels = 1645 ( 9643 ) LayerLabels = 489 ( 3997 )
+LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9621 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9627 ) NameLabels = 1649 ( 2891 ) ColorLabels = 1645 ( 9626 ) LayerLabels = 489 ( 3997 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 4 ( 5 )
COLORS : Colors = BLUE1 CYAN1 GOLD3 GREEN ( BLUE1 CYAN1 GOLD3 GREEN YELLOW )
set ref_data {
DATA : Faulties = 2 ( 0 ) Warnings = 0 ( 0 ) Summary = 2 ( 0 )
TPSTAT : Faulties = 4 ( 33 ) Warnings = 125 ( 319 ) Summary = 129 ( 352 )
-CHECKSHAPE : Wires = 1 ( 1 ) Faces = 2 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 420 ( 159 ) Summary = 7849 ( 4452 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 420 ( 419 ) FreeWire = 66 ( 114 ) FreeEdge = 430 ( 430 ) SharedEdge = 3347 ( 1892 )
+CHECKSHAPE : Wires = 1 ( 1 ) Faces = 3 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 421 ( 159 ) Summary = 7850 ( 4452 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 421 ( 419 ) FreeWire = 66 ( 114 ) FreeEdge = 430 ( 430 ) SharedEdge = 3347 ( 1892 )
TOLERANCE : MaxTol = 3.181671051 ( 2716.882548 ) AvgTol = 0.008547757257 ( 3.678737151 )
-LABELS : N0Labels = 3 ( 3 ) N1Labels = 325 ( 1833 ) N2Labels = 0 ( 0 ) TotalLabels = 328 ( 1836 ) NameLabels = 328 ( 424 ) ColorLabels = 325 ( 1833 ) LayerLabels = 193 ( 1568 )
+LABELS : N0Labels = 3 ( 3 ) N1Labels = 325 ( 1831 ) N2Labels = 0 ( 0 ) TotalLabels = 328 ( 1834 ) NameLabels = 328 ( 425 ) ColorLabels = 325 ( 1831 ) LayerLabels = 193 ( 1566 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 6 ( 7 )
COLORS : Colors = GREEN MATRABLUE RED RED4 WHITE YELLOW ( GREEN MAGENTA1 MATRABLUE RED RED4 WHITE YELLOW )
puts "TODO CR23096 ALL: LABELS : Faulty"
puts "TODO CR23096 ALL: COLORS : Faulty"
puts "TODO CR23096 ALL: LAYERS : Faulty"
-puts "TODO CR25013 ALL: Error : 4 differences with reference data found"
+puts "TODO CR25013 ALL: Error : 3 differences with reference data found"
set filename BUC40132.igs
set filename 1stpunch-mcsrfs.igs
set ref_data {
-DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 2792 ) Summary = 0 ( 2792 )
-TPSTAT : Faulties = 0 ( 0 ) Warnings = 885 ( 1953 ) Summary = 885 ( 1953 )
-CHECKSHAPE : Wires = 6 ( 5 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1223 ( 1223 ) Summary = 68998 ( 68973 )
+DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 )
+TPSTAT : Faulties = 0 ( 0 ) Warnings = 885 ( 1951 ) Summary = 885 ( 1951 )
+CHECKSHAPE : Wires = 6 ( 4 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1223 ( 1223 ) Summary = 68996 ( 68971 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1223 ( 1223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 33290 ( 33278 )
-TOLERANCE : MaxTol = 0.2461173132 ( 0.001436622896 ) AvgTol = 1.137529899e-005 ( 9.779578952e-006 )
+TOLERANCE : MaxTol = 0.002714431471 ( 0.001436622896 ) AvgTol = 1.636929841e-006 ( 9.67254762e-006 )
LABELS : N0Labels = 1215 ( 1215 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1215 ( 1215 ) NameLabels = 1215 ( 1215 ) ColorLabels = 0 ( 0 ) LayerLabels = 1207 ( 1215 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 58 ) Summary = 42 ( 58 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) Summary = 579 ( 530 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) Summary = 579 ( 529 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 220 ( 218 )
TOLERANCE : MaxTol = 0.003591433268 ( 0.006121716429 ) AvgTol = 0.0002657130942 ( 0.0004625449099 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 6 ( 6 ) Summary = 6 ( 6 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 39 ( 0 ) Face = 39 ( 39 ) Summary = 492 ( 456 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 39 ( 0 ) Face = 39 ( 39 ) Summary = 492 ( 455 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 39 ( 0 ) Face = 39 ( 39 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 193 ( 192 )
TOLERANCE : MaxTol = 0.003673630603 ( 0.003673630602 ) AvgTol = 0.0002911716538 ( 0.0002911716555 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 5 ( 10 ) Summary = 5 ( 10 )
-CHECKSHAPE : Wires = 1 ( 1 ) Faces = 1 ( 1 ) Shells = 0 ( 2 ) Solids = 0 ( 0 )
+CHECKSHAPE : Wires = 0 ( 1 ) Faces = 0 ( 2 ) Shells = 0 ( 2 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 51 ( 2 ) Face = 51 ( 48 ) Summary = 584 ( 569 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 51 ( 2 ) Face = 51 ( 48 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 220 ( 218 )
TOLERANCE : MaxTol = 0.4289319668 ( 0.007688098235 ) AvgTol = 0.0122902841 ( 0.0002401295385 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 2 ) Warnings = 19 ( 27 ) Summary = 19 ( 29 )
CHECKSHAPE : Wires = 2 ( 3 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) Summary = 151 ( 151 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 59 ( 60 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) Summary = 149 ( 149 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 57 ( 58 )
TOLERANCE : MaxTol = 1562.051497 ( 1562.051497 ) AvgTol = 192.5735494 ( 206.7634854 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
set ref_data {
DATA : Faulties = 0 ( 3 ) Warnings = 0 ( 2 ) Summary = 0 ( 5 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 11 ( 9 ) Summary = 11 ( 9 )
-CHECKSHAPE : Wires = 1 ( 0 ) Faces = 1 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 99 ( 99 ) Summary = 655 ( 656 )
-STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 99 ( 99 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 266 ( 266 )
+CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 99 ( 99 ) Summary = 654 ( 656 )
+STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 99 ( 99 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 265 ( 266 )
TOLERANCE : MaxTol = 3.000180002 ( 3.000180002 ) AvgTol = 0.1203601833 ( 0.1203606739 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 3 ( 3 ) NameLabels = 1 ( 1 ) ColorLabels = 2 ( 2 ) LayerLabels = 2 ( 2 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
CHECKSHAPE : Wires = 1 ( 0 ) Faces = 1 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 257 ( 257 ) Summary = 1770 ( 1770 )
STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 257 ( 257 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 746 ( 746 )
-TOLERANCE : MaxTol = 0.477874439 ( 0.477874439 ) AvgTol = 0.005726825808 ( 0.007088060753 )
+TOLERANCE : MaxTol = 0.477874439 ( 3.60548709 ) AvgTol = 0.005726825988 ( 0.01506499669 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 1 ( 1 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 1 ( 1 )
# !!!! This file is generated automatically, do not edit manually! See end script
puts "TODO CR23096 ALL: LABELS : Faulty"
-puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
-
-
set filename PRO20364.stp
# !!!! 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 CR23096 ALL: NBSHAPES : Faulty"
+set LinuxDiff 3
set filename r76sy.stp
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 1 ( 4 ) Warnings = 68 ( 103 ) Summary = 69 ( 107 )
-CHECKSHAPE : Wires = 2 ( 0 ) Faces = 2 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 23 ( 23 ) Shell = 47 ( 47 ) Face = 194 ( 194 ) Summary = 1352 ( 1357 )
-STATSHAPE : Solid = 23 ( 23 ) Shell = 47 ( 47 ) Face = 194 ( 194 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 504 ( 504 )
+CHECKSHAPE : Wires = 1 ( 0 ) Faces = 1 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 23 ( 23 ) Shell = 47 ( 47 ) Face = 194 ( 194 ) Summary = 1350 ( 1357 )
+STATSHAPE : Solid = 23 ( 23 ) Shell = 47 ( 47 ) Face = 194 ( 194 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 502 ( 504 )
TOLERANCE : MaxTol = 0.0205434719 ( 0.0293421419 ) AvgTol = 0.0005065999101 ( 0.00138068504 )
LABELS : N0Labels = 3 ( 3 ) N1Labels = 69 ( 67 ) N2Labels = 0 ( 0 ) TotalLabels = 72 ( 70 ) NameLabels = 5 ( 5 ) ColorLabels = 47 ( 45 ) LayerLabels = 43 ( 45 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
CHECKSHAPE : Wires = 1 ( 0 ) Faces = 1 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 55 ( 54 ) Summary = 329 ( 314 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 55 ( 54 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 139 ( 130 )
-TOLERANCE : MaxTol = 43.63397635 ( 0.004765335881 ) AvgTol = 0.9413185963 ( 0.0005744934329 )
+TOLERANCE : MaxTol = 43.63397625 ( 0.004765335881 ) AvgTol = 1.059548993 ( 0.0005744934329 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 53 ( 54 ) N2Labels = 0 ( 0 ) TotalLabels = 54 ( 55 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 53 ( 54 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 0 ( 0 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 1 ( 1 ) Solids = 1 ( 1 )
NBSHAPES : Solid = 4 ( 4 ) Shell = 4 ( 4 ) Face = 40 ( 40 ) Summary = 263 ( 263 )
STATSHAPE : Solid = 4 ( 4 ) Shell = 4 ( 4 ) Face = 40 ( 40 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 98 ( 98 )
-TOLERANCE : MaxTol = 0.7226608412 ( 0.7227160437 ) AvgTol = 0.04200651748 ( 0.04200775508 )
+TOLERANCE : MaxTol = 0.7571968817 ( 0.757178949 ) AvgTol = 0.04326711711 ( 0.04326805656 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 4 ( 4 ) N2Labels = 0 ( 0 ) TotalLabels = 5 ( 5 ) NameLabels = 1 ( 1 ) ColorLabels = 4 ( 4 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 2 ( 2 )
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR23096 ALL: TPSTAT : Faulty"
set filename id_exhaust-B.stp
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 31 ( 28 ) Summary = 31 ( 28 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) Summary = 2005 ( 2003 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 841 ( 839 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) Summary = 2004 ( 2003 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 840 ( 839 )
TOLERANCE : MaxTol = 0.007356791914 ( 0.009485808595 ) AvgTol = 0.0003528568313 ( 0.001207996284 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 1 ( 1 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 39 ( 6 ) Summary = 39 ( 6 )
CHECKSHAPE : Wires = 64 ( 48 ) Faces = 64 ( 48 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 15 ( 16 ) Shell = 17 ( 17 ) Face = 367 ( 366 ) Summary = 2505 ( 2495 )
+NBSHAPES : Solid = 15 ( 16 ) Shell = 17 ( 17 ) Face = 367 ( 366 ) Summary = 2506 ( 2495 )
STATSHAPE : Solid = 71 ( 79 ) Shell = 87 ( 87 ) Face = 2740 ( 2732 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 1064 ( 1057 )
TOLERANCE : MaxTol = 4.389003466 ( 5.153790881 ) AvgTol = 0.05707355423 ( 0.06633632879 )
LABELS : N0Labels = 10 ( 10 ) N1Labels = 32 ( 32 ) N2Labels = 0 ( 0 ) TotalLabels = 42 ( 42 ) NameLabels = 22 ( 22 ) ColorLabels = 22 ( 22 ) LayerLabels = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 31 ( 28 ) Summary = 31 ( 28 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) Summary = 2006 ( 2004 )
-STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 841 ( 839 )
+NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) Summary = 2005 ( 2004 )
+STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 357 ( 357 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 840 ( 839 )
TOLERANCE : MaxTol = 0.007356791914 ( 0.009485808595 ) AvgTol = 0.0003528126958 ( 0.001207999522 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 2 ) Warnings = 2 ( 28 ) Summary = 2 ( 30 )
CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 416 ( 415 ) Summary = 2779 ( 2761 )
-STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 416 ( 415 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 1195 ( 1179 )
-TOLERANCE : MaxTol = 9511.663612 ( 0.9492387908 ) AvgTol = 22.86226785 ( 0.0392704055 )
+NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 416 ( 415 ) Summary = 2778 ( 2760 )
+STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 416 ( 415 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 1194 ( 1178 )
+TOLERANCE : MaxTol = 9036.639612 ( 0.9492387908 ) AvgTol = 21.72114525 ( 0.03925492632 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 28 ( 28 ) N2Labels = 0 ( 0 ) TotalLabels = 29 ( 29 ) NameLabels = 1 ( 1 ) ColorLabels = 29 ( 29 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 1 ( 1 ) Volume = 1 ( 1 ) Area = 1 ( 1 )
NCOLORS : NColors = 2 ( 2 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 2 ( 24 ) Summary = 2 ( 24 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 415 ( 415 ) Summary = 2770 ( 2755 )
-STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 415 ( 415 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 1191 ( 1176 )
+NBSHAPES : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 415 ( 415 ) Summary = 2769 ( 2754 )
+STATSHAPE : Solid = 1 ( 1 ) Shell = 1 ( 1 ) Face = 415 ( 415 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 1190 ( 1175 )
TOLERANCE : MaxTol = 0.09895712553 ( 0.9492387908 ) AvgTol = 0.01303492802 ( 0.03965300183 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 28 ( 28 ) N2Labels = 0 ( 0 ) TotalLabels = 29 ( 29 ) NameLabels = 1 ( 1 ) ColorLabels = 29 ( 29 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 1 ( 1 ) Volume = 1 ( 1 ) Area = 1 ( 1 )
DATA : Faulties = 0 ( 9 ) Warnings = 0 ( 0 ) Summary = 0 ( 9 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 77 ( 39 ) Summary = 77 ( 39 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 11 ( 11 ) Shell = 13 ( 13 ) Face = 270 ( 270 ) Summary = 1653 ( 1646 )
-STATSHAPE : Solid = 11 ( 11 ) Shell = 13 ( 13 ) Face = 270 ( 270 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 642 ( 640 )
+NBSHAPES : Solid = 10 ( 10 ) Shell = 12 ( 12 ) Face = 269 ( 269 ) Summary = 1638 ( 1636 )
+STATSHAPE : Solid = 10 ( 10 ) Shell = 12 ( 12 ) Face = 269 ( 269 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 636 ( 636 )
TOLERANCE : MaxTol = 0.01008857123 ( 0.01008857108 ) AvgTol = 0.0003104589496 ( 0.0003616303196 )
LABELS : N0Labels = 3 ( 3 ) N1Labels = 2 ( 3 ) N2Labels = 0 ( 1 ) TotalLabels = 5 ( 7 ) NameLabels = 5 ( 5 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 322 ( 148 ) Summary = 322 ( 148 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 797 ( 797 ) Face = 797 ( 797 ) Summary = 11928 ( 11928 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 797 ( 797 ) Face = 797 ( 797 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 4821 ( 4821 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 797 ( 797 ) Face = 797 ( 797 ) Summary = 11927 ( 11927 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 797 ( 797 ) Face = 797 ( 797 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 4820 ( 4820 )
TOLERANCE : MaxTol = 0.03846819732 ( 0.0394709482 ) AvgTol = 0.0008687242138 ( 0.002865279517 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 47 ( 41 ) Summary = 47 ( 41 )
-CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
+CHECKSHAPE : Wires = 0 ( 1 ) Faces = 1 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 209 ( 129 ) Face = 209 ( 209 ) Summary = 3032 ( 2883 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 209 ( 129 ) Face = 209 ( 209 ) FreeWire = 0 ( 1 ) FreeEdge = 67 ( 67 ) SharedEdge = 1152 ( 1150 )
TOLERANCE : MaxTol = 0.3035246255 ( 0.3035246024 ) AvgTol = 0.001361092422 ( 0.003604130581 )
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR25593 ALL: CHECKSHAPE : Faulty"
set filename trj7_pm5-hc-214.stp
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 167 ( 910 ) Summary = 167 ( 910 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 0 ( 0 ) Shell = 2823 ( 0 ) Face = 2823 ( 2823 ) Summary = 35044 ( 32219 )
-STATSHAPE : Solid = 0 ( 0 ) Shell = 3347 ( 0 ) Face = 3347 ( 3347 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 13235 ( 13233 )
+NBSHAPES : Solid = 0 ( 0 ) Shell = 2823 ( 0 ) Face = 2823 ( 2823 ) Summary = 35042 ( 32218 )
+STATSHAPE : Solid = 0 ( 0 ) Shell = 3347 ( 0 ) Face = 3347 ( 3347 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 13234 ( 13233 )
TOLERANCE : MaxTol = 0.07507769847 ( 0.07507769847 ) AvgTol = 0.0002646721739 ( 0.002834192939 )
LABELS : N0Labels = 37 ( 37 ) N1Labels = 76 ( 76 ) N2Labels = 0 ( 0 ) TotalLabels = 113 ( 113 ) NameLabels = 113 ( 113 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
# !!!! This file is generated automatically, do not edit manually! See end script
+puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR25593 ALL: Error : 3 differences with reference data found :"
-puts "TODO CR25593 ALL: TPSTAT : Faulty"
set LinuxDiff 1
set LinuxFaulties {CHECKSHAPE}
# !!!! This file is generated automatically, do not edit manually! See end script
-puts "TODO CR25593 ALL: CHECKSHAPE : Faulty"
-
# No checkape error on WNT in 64-bit only (after 22598 and issue 25797 was registered for that)
+puts "TODO CR23096 Linux: CHECKSHAPE : Faulty"
set filename trj6_pm4-hc-214.stp
puts "TODO CR23096 ALL: TPSTAT : Faulty"
puts "TODO CR23096 ALL: CHECKSHAPE : Faulty"
puts "TODO CR23096 ALL: STATSHAPE : Faulty"
-puts "TODO CR25013 ALL: Error : 4 differences with reference data found"
+puts "TODO CR23096 ALL: Error : 3 differences with reference data found"
set LinuxDiff 3
set filename Z8M6SAT.stp
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
-TPSTAT : Faulties = 11 ( 0 ) Warnings = 946 ( 3166 ) Summary = 957 ( 3166 )
-CHECKSHAPE : Wires = 51 ( 42 ) Faces = 51 ( 45 ) Shells = 0 ( 4 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 28 ( 28 ) Shell = 772 ( 32 ) Face = 3242 ( 3241 ) Summary = 29515 ( 28693 )
-STATSHAPE : Solid = 28 ( 28 ) Shell = 772 ( 32 ) Face = 3242 ( 3241 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 12667 ( 12612 )
-TOLERANCE : MaxTol = 15.00001475 ( 20.46526799 ) AvgTol = 0.03158606342 ( 0.03807479444 )
+TPSTAT : Faulties = 7 ( 0 ) Warnings = 956 ( 3168 ) Summary = 963 ( 3168 )
+CHECKSHAPE : Wires = 50 ( 41 ) Faces = 49 ( 45 ) Shells = 0 ( 4 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 28 ( 28 ) Shell = 772 ( 32 ) Face = 3242 ( 3241 ) Summary = 29459 ( 28673 )
+STATSHAPE : Solid = 28 ( 28 ) Shell = 772 ( 32 ) Face = 3242 ( 3241 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 12632 ( 12599 )
+TOLERANCE : MaxTol = 15.00300076 ( 20.46526799 ) AvgTol = 0.0281001785 ( 0.03853100147 )
LABELS : N0Labels = 3 ( 3 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 5 ( 5 ) NameLabels = 5 ( 5 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 0 ( 0 )
# !!!! This file is generated automatically, do not edit manually! See end script
+
set filename Z8INV5.stp
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 114 ( 619 ) Summary = 114 ( 619 )
-CHECKSHAPE : Wires = 16 ( 17 ) Faces = 18 ( 19 ) Shells = 1 ( 1 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 22 ( 22 ) Shell = 24 ( 24 ) Face = 1520 ( 1520 ) Summary = 11216 ( 11206 )
-STATSHAPE : Solid = 22 ( 22 ) Shell = 24 ( 24 ) Face = 1520 ( 1520 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 4787 ( 4781 )
-TOLERANCE : MaxTol = 12.54913924 ( 7.159520237 ) AvgTol = 0.04320092698 ( 0.0322263844 )
+CHECKSHAPE : Wires = 17 ( 17 ) Faces = 18 ( 19 ) Shells = 1 ( 1 ) Solids = 0 ( 0 )
+NBSHAPES : Solid = 22 ( 22 ) Shell = 24 ( 24 ) Face = 1520 ( 1520 ) Summary = 11210 ( 11195 )
+STATSHAPE : Solid = 22 ( 22 ) Shell = 24 ( 24 ) Face = 1520 ( 1520 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 4784 ( 4774 )
+TOLERANCE : MaxTol = 7.33063502 ( 7.159520237 ) AvgTol = 0.03499829069 ( 0.03222638333 )
LABELS : N0Labels = 25 ( 25 ) N1Labels = 23 ( 23 ) N2Labels = 0 ( 0 ) TotalLabels = 48 ( 48 ) NameLabels = 48 ( 48 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 0 ( 0 )
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 70 ) Summary = 88 ( 70 )
CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
-NBSHAPES : Solid = 37 ( 37 ) Shell = 58 ( 58 ) Face = 2694 ( 2694 ) Summary = 15919 ( 15919 )
-STATSHAPE : Solid = 81 ( 81 ) Shell = 104 ( 104 ) Face = 3190 ( 3190 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6451 ( 6451 )
+NBSHAPES : Solid = 37 ( 37 ) Shell = 58 ( 58 ) Face = 2694 ( 2694 ) Summary = 15918 ( 15918 )
+STATSHAPE : Solid = 81 ( 81 ) Shell = 104 ( 104 ) Face = 3190 ( 3190 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6450 ( 6450 )
TOLERANCE : MaxTol = 0.07893772536 ( 0.07893770763 ) AvgTol = 0.00122544179 ( 0.00660493083 )
LABELS : N0Labels = 37 ( 37 ) N1Labels = 76 ( 76 ) N2Labels = 0 ( 0 ) TotalLabels = 113 ( 113 ) NameLabels = 113 ( 113 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
-puts "TODO OCC25593 ALL: Faulty shapes in variables faulty_1 to faulty_4 "
-
restore [locate_data_file wrong_checkshape_2.brep] a
-puts "TODO OCC24035 ALL: Faulty shapes in variables faulty_1 to faulty_"
restore [locate_data_file wrong_checkshape_2.brep] a
-puts "TODO OCC23068 ALL: Error : big tolerance of shape result"
-puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to faulty_2"
-puts "TODO OCC23068 ALL: Error : The resulting shape is WRONG"
+puts "TODO OCC24682 ALL: Error: Offset is not done."
+puts "TODO OCC24682 ALL: Error : The offset cannot be built."
restore [locate_data_file offset_wire_041.brep] s
-puts "TODO OCC24255 ALL: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO OCC24682 ALL: Error: Offset is not done."
+puts "TODO OCC24682 ALL: Error : The offset cannot be built."
restore [locate_data_file offset_wire_059.brep] s
-#puts "TODO OCC23068 ALL: Error : big tolerance of shape result"
-#puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to faulty_2"
+puts "TODO OCC23068 ALL: Error : big tolerance of shape result"
+puts "TODO OCC23068 ALL: Faulty shapes in variables faulty_1 to faulty_2"
#puts "TODO OCC24255 ALL: An exception was caught"
-puts "TODO OCC24255 ALL: Error: Offset is not done."
-puts "TODO OCC24255 ALL: Error : The offset cannot be built."
+#puts "TODO OCC24255 ALL: Error: Offset is not done."
+#puts "TODO OCC24255 ALL: Error : The offset cannot be built."
#puts "TODO OCC23068 ALL: Error : The resulting shape is WRONG"
restore [locate_data_file offset_wire_041.brep] s
set length 3536.16
-set nbsh_v 622
-set nbsh_e 622
+set nbsh_v 621
+set nbsh_e 621
set nbsh_w 1
restore [locate_data_file offset_wire_059.brep] s
set length 347.204
-set nbsh_v 583
-set nbsh_e 583
+set nbsh_v 582
+set nbsh_e 582
set nbsh_w 1
restore [locate_data_file offset_wire_059.brep] s
set length 555.502
-set nbsh_v 573
-set nbsh_e 573
+set nbsh_v 574
+set nbsh_e 574
set nbsh_w 1