From 94f71cad33414ee106f5980abbdfa61621f8b22a Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 28 May 2015 13:36:57 +0300 Subject: [PATCH] 0024682: Move out B-spline cache from curves and surfaces to dedicated classes BSplCLib_Cache and BSplSLib_Cache 1. B-spline cache was moved into separated classes: BSplCLib_Cache for 2D and 3D curves and BSplSLib_Cache for surfaces. 2. The cache is used now in corresponding adaptor classes (Geom2dAdaptor_Curve, GeomAdaptor_Curve and GeomAdaptor_Surface) when the curve or surface is a B-spline. 3. Algorithms were changed to use adaptors for B-spline calculations instead of curves or surfaces. 4. Precised calculation of derivatives of surface of revolution is implemented for the points of surface placed on the axis of revolution (Geom_SurfaceOfRevolution.cxx) 5. Small modifications are made to adjust algorithms to new behavior of B-spline calculation. 6. Test cases were modified according to the modern behavior. 7. Changes in BOPAlgo_WireSplitter, BOPTools_AlgoTools, BRepLib_CheckCurveOnSurface and ShapeAnalysis_Wire to use adaptors instead of geometric entities 8. Allow Geom2dAdaptor and GeomAdaptor in case of offset curve to use corresponding adaptor for basis curve Modification of test-cases according to the new behavior. --- src/Adaptor3d/Adaptor3d_TopolTool.cxx | 23 +- src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx | 14 +- src/BOPTools/BOPTools_AlgoTools.cxx | 4 +- src/BOPTools/BOPTools_AlgoTools_1.cxx | 10 +- src/BOPTools/BOPTools_AlgoTools_2.cxx | 8 +- src/BRepCheck/BRepCheck_Wire.cxx | 21 +- src/BRepFill/BRepFill_OffsetWire.cxx | 4 +- src/BRepLib/BRepLib_CheckCurveOnSurface.cxx | 13 +- src/BRepLib/BRepLib_MakeEdge.cxx | 24 +- src/BSplCLib/BSplCLib.cdl | 27 + src/BSplCLib/BSplCLib.cxx | 1 + src/BSplCLib/BSplCLib_Cache.cxx | 362 +++++++++++ src/BSplCLib/BSplCLib_Cache.hxx | 182 ++++++ src/BSplCLib/BSplCLib_CurveComputation.gxx | 60 ++ src/BSplCLib/FILES | 3 +- src/BSplSLib/BSplSLib.cdl | 15 + src/BSplSLib/BSplSLib.cxx | 95 +++ src/BSplSLib/BSplSLib_Cache.cxx | 407 +++++++++++++ src/BSplSLib/BSplSLib_Cache.hxx | 161 +++++ src/BSplSLib/FILES | 3 +- src/CSLib/CSLib.cxx | 8 +- src/CSLib/CSLib_Offset.cxx | 470 +++++++++++++++ src/CSLib/CSLib_Offset.hxx | 190 ++++++ src/CSLib/FILES | 2 + src/Extrema/Extrema_GExtPC.gxx | 28 + src/Geom/Geom_BSplineCurve.cdl | 81 +-- src/Geom/Geom_BSplineCurve.cxx | 221 ++----- src/Geom/Geom_BSplineCurve_1.cxx | 211 +++---- src/Geom/Geom_BSplineSurface.cdl | 139 ++--- src/Geom/Geom_BSplineSurface.cxx | 219 ------- src/Geom/Geom_BSplineSurface_1.cxx | 230 +++---- src/Geom/Geom_OffsetCurve.cxx | 492 +++------------ src/Geom/Geom_SurfaceOfRevolution.cxx | 27 + src/Geom2d/Geom2d_BSplineCurve.cdl | 80 +-- src/Geom2d/Geom2d_BSplineCurve.cxx | 156 +---- src/Geom2d/Geom2d_BSplineCurve_1.cxx | 252 ++++---- src/Geom2d/Geom2d_OffsetCurve.cxx | 570 +++--------------- src/Geom2dAdaptor/Geom2dAdaptor.cdl | 3 +- src/Geom2dAdaptor/Geom2dAdaptor_Curve.cdl | 69 ++- src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx | 470 +++++++++++++-- src/GeomAdaptor/GeomAdaptor.cdl | 4 +- src/GeomAdaptor/GeomAdaptor_Curve.cdl | 69 ++- src/GeomAdaptor/GeomAdaptor_Curve.cxx | 404 +++++++++++-- src/GeomAdaptor/GeomAdaptor_Surface.cdl | 10 +- src/GeomAdaptor/GeomAdaptor_Surface.cxx | 191 +++--- src/GeomInt/GeomInt_IntSS_1.cxx | 18 +- src/GeomLib/GeomLib.cxx | 4 + src/IntCurve/IntCurve_IntPolyPolyGen.gxx | 21 +- src/IntPatch/IntPatch_ImpPrmIntersection.cxx | 2 +- src/IntWalk/IntWalk_PWalking.cxx | 41 +- src/ShapeAnalysis/ShapeAnalysis_Curve.cxx | 22 +- src/ShapeAnalysis/ShapeAnalysis_Wire.cxx | 29 +- src/ShapeFix/ShapeFix_EdgeProjAux.cxx | 2 +- src/ShapeFix/ShapeFix_Face.cxx | 10 + src/ShapeFix/ShapeFix_IntersectionTool.cxx | 47 +- src/ShapeFix/ShapeFix_Wire.cxx | 6 +- .../StepToTopoDS_TranslateEdge.cxx | 3 +- src/math/math_FunctionRoots.cxx | 3 +- src/math/math_TrigonometricFunctionRoots.cxx | 2 +- tests/boolean/bfuse_complex/F5 | 1 - tests/boolean/bfuse_complex/Q2 | 1 - tests/boolean/bsection/M9 | 5 +- tests/boolean/bsection/N4 | 5 +- tests/boolean/volumemaker/F8 | 2 +- tests/bugs/modalg_2/bug5805_21 | 2 +- tests/bugs/modalg_2/bug5805_22 | 2 +- tests/bugs/modalg_2/bug5805_23 | 2 +- tests/bugs/modalg_2/bug5805_24 | 2 +- tests/bugs/modalg_2/bug5805_41 | 6 +- tests/bugs/modalg_2/bug5805_43 | 7 +- tests/bugs/modalg_4/bug714 | 2 - tests/bugs/modalg_5/bug24200 | 2 +- tests/bugs/modalg_5/bug24303 | 6 +- tests/bugs/modalg_5/bug25175 | 2 +- tests/bugs/modalg_6/bug25908 | 6 +- tests/bugs/moddata_1/bug16119 | 6 +- tests/bugs/moddata_1/bug22759 | 12 +- tests/bugs/moddata_2/bug36 | 2 +- tests/bugs/moddata_2/bug498 | 2 - tests/bugs/moddata_3/bug25207 | 6 +- tests/de/iges_1/F9 | 2 - tests/de/iges_1/J2 | 2 +- tests/de/iges_1/J3 | 6 +- tests/de/iges_1/J9 | 6 +- tests/de/iges_1/K3 | 14 +- tests/de/iges_1/L8 | 16 +- tests/de/iges_1/M7 | 1 - tests/de/iges_1/O3 | 1 - tests/de/iges_1/O4 | 2 +- tests/de/iges_1/P5 | 11 +- tests/de/iges_1/P7 | 2 +- tests/de/iges_1/P9 | 4 +- tests/de/iges_1/R8 | 15 +- tests/de/iges_2/A9 | 6 +- tests/de/iges_2/B6 | 4 +- tests/de/iges_2/B8 | 19 +- tests/de/iges_2/C2 | 6 +- tests/de/iges_2/D8 | 6 +- tests/de/iges_2/F1 | 2 +- tests/de/iges_2/H9 | 7 +- tests/de/iges_3/A2 | 8 +- tests/de/iges_3/A4 | 2 +- tests/de/iges_3/B2 | 10 +- tests/de/step_1/A3 | 2 +- tests/de/step_1/D9 | 2 +- tests/de/step_1/G9 | 2 +- tests/de/step_1/J6 | 4 +- tests/de/step_1/J8 | 6 +- tests/de/step_2/B5 | 2 +- tests/de/step_2/B6 | 3 - tests/de/step_2/E7 | 8 +- tests/de/step_2/F4 | 2 +- tests/de/step_2/M4 | 2 +- tests/de/step_2/N8 | 1 - tests/de/step_2/R2 | 4 +- tests/de/step_2/S1 | 2 +- tests/de/step_2/T1 | 4 +- tests/de/step_2/T9 | 6 +- tests/de/step_2/U8 | 4 +- tests/de/step_2/Y5 | 4 +- tests/de/step_3/A4 | 4 +- tests/de/step_3/A8 | 2 +- tests/de/step_3/A9 | 1 - tests/de/step_3/B9 | 4 +- tests/de/step_3/C5 | 1 + tests/de/step_3/D3 | 2 - tests/de/step_3/D8 | 3 +- tests/de/step_3/E6 | 12 +- tests/de/step_5/A1 | 9 +- tests/de/step_5/A4 | 4 +- tests/heal/split_angle/F2 | 2 - tests/heal/split_closed_faces/G5 | 1 - tests/offset/wire_closed_inside_0_005/D1 | 5 +- tests/offset/wire_closed_inside_0_075/E8 | 3 +- tests/offset/wire_closed_outside_0_005/D1 | 12 +- tests/offset/wire_closed_outside_0_005/E8 | 4 +- tests/offset/wire_closed_outside_0_075/E8 | 4 +- 137 files changed, 4104 insertions(+), 2503 deletions(-) create mode 100644 src/BSplCLib/BSplCLib_Cache.cxx create mode 100644 src/BSplCLib/BSplCLib_Cache.hxx create mode 100644 src/BSplSLib/BSplSLib_Cache.cxx create mode 100644 src/BSplSLib/BSplSLib_Cache.hxx create mode 100644 src/CSLib/CSLib_Offset.cxx create mode 100644 src/CSLib/CSLib_Offset.hxx create mode 100644 src/CSLib/FILES diff --git a/src/Adaptor3d/Adaptor3d_TopolTool.cxx b/src/Adaptor3d/Adaptor3d_TopolTool.cxx index cdecee8848..deed6c2a1b 100644 --- a/src/Adaptor3d/Adaptor3d_TopolTool.cxx +++ b/src/Adaptor3d/Adaptor3d_TopolTool.cxx @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -1080,6 +1081,10 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl, Standard_Real tol = Max(0.01*aDefl2, 1.e-9); Standard_Integer l; + // Calculations of B-spline values will be made using adaptor, + // because it caches the data for performance + GeomAdaptor_Surface aBSplAdaptor(aBS); + anUFlg(1) = Standard_True; anUFlg(nbsu) = Standard_True; //myNbSamplesU = 2; @@ -1095,10 +1100,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl, } t2 = anUPars(j); - gp_Pnt p1 = aBS->Value(t2, t1); +// gp_Pnt p1 = aBS->Value(t2, t1); + gp_Pnt p1 = aBSplAdaptor.Value(t2, t1); for(k = j+2; k <= nbsu; ++k) { t2 = anUPars(k); - gp_Pnt p2 = aBS->Value(t2, t1); +// gp_Pnt p2 = aBS->Value(t2, t1); + gp_Pnt p2 = aBSplAdaptor.Value(t2, t1); //gce_MakeLin MkLin(p1, p2); //const gp_Lin& lin = MkLin.Value(); @@ -1113,7 +1120,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl, break; } - gp_Pnt pp = aBS->Value(anUPars(l), t1); +// gp_Pnt pp = aBS->Value(anUPars(l), t1); + gp_Pnt pp = aBSplAdaptor.Value(anUPars(l), t1); Standard_Real d = lin.SquareDistance(pp); if(d <= aDefl2) continue; @@ -1180,10 +1188,12 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl, } t2 = aVPars(j); - gp_Pnt p1 = aBS->Value(t1, t2); +// gp_Pnt p1 = aBS->Value(t1, t2); + gp_Pnt p1 = aBSplAdaptor.Value(t1, t2); for(k = j+2; k <= nbsv; ++k) { t2 = aVPars(k); - gp_Pnt p2 = aBS->Value(t1, t2); +// gp_Pnt p2 = aBS->Value(t1, t2); + gp_Pnt p2 = aBSplAdaptor.Value(t1, t2); if(p1.SquareDistance(p2) <= tol) continue; //gce_MakeLin MkLin(p1, p2); @@ -1197,7 +1207,8 @@ void Adaptor3d_TopolTool::BSplSamplePnts(const Standard_Real theDefl, break; } - gp_Pnt pp = aBS->Value(t1, aVPars(l)); +// gp_Pnt pp = aBS->Value(t1, aVPars(l)); + gp_Pnt pp = aBSplAdaptor.Value(t1, aVPars(l)); Standard_Real d = lin.SquareDistance(pp); if(d <= aDefl2) continue; diff --git a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx index 34408661d9..7e6d9fcc98 100644 --- a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx +++ b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx @@ -762,8 +762,8 @@ Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo) aTV1=aTV - dt; } // - aC2D->D0 (aTV1, aPV1); - aC2D->D0 (aTV, aPV); + aGAC2D.D0 (aTV1, aPV1); + aGAC2D.D0 (aTV, aPV); // aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1); // @@ -1017,15 +1017,15 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV, aTolInt=1.e-10; // BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol); + aGAC1.Load(aC2D, aT1, aT2); // aTV=BRep_Tool::Parameter (aV, aE, myFace); - aC2D->D0(aTV, aPV); + aGAC1.D0(aTV, aPV); // aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1; // - aGAC1.Load(aC2D, aT1, aT2); - aC2D->D0(aT1, aP1); - aC2D->D0(aT2, aP2); + aGAC1.D0(aT1, aP1); + aGAC1.D0(aT2, aP2); aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt); // for (i=0; i<2; ++i) { @@ -1066,7 +1066,7 @@ Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV, } // aT=aT1max + aCf*dT; - aC2D->D0(aT, aP); + aGAC1.D0(aT, aP); gp_Vec2d aV2D(aPV, aP); gp_Dir2d aDir2D(aV2D); // diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 1ed5095b27..85d1e8a5a1 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -1281,10 +1281,10 @@ Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW, dU=-dU; } // - aC2D->D0(aU, aP2D0); + aBAC2D.D0(aU, aP2D0); for(i=2; i<=aNbS; i++) { aU=aU1+(i-1)*dU; - aC2D->D0(aU, aP2D1); + aBAC2D.D0(aU, aP2D1); aP2D0.Coord(aX0, aY0); aP2D1.Coord(aX1, aY1); // diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx index 1bfcdfc332..10efe77184 100644 --- a/src/BOPTools/BOPTools_AlgoTools_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx @@ -111,7 +111,7 @@ static static Standard_Real IntersectCurves2d(const gp_Pnt& aPV, const TopoDS_Face& aF, - const Handle(Geom_Surface)& aS, + const GeomAdaptor_Surface& aS, const TopoDS_Edge& aE1, const TopoDS_Edge& aE2); @@ -558,7 +558,7 @@ void CorrectWires(const TopoDS_Face& aFx) aT=BRep_Tool::Parameter(aV, aE); // aC2D->D0(aT, aP2D); - aS->D0(aP2D.X(), aP2D.Y(), aP); + aGAS.D0(aP2D.X(), aP2D.Y(), aP); aD2=aPV.SquareDistance(aP); if (aD2>aD2max) { aD2max=aD2; @@ -586,7 +586,7 @@ void CorrectWires(const TopoDS_Face& aFx) continue; } // - aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1); + aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1); if (aD2>aD2max) { aD2max=aD2; } @@ -606,7 +606,7 @@ void CorrectWires(const TopoDS_Face& aFx) //======================================================================= Standard_Real IntersectCurves2d(const gp_Pnt& aPV, const TopoDS_Face& aF, - const Handle(Geom_Surface)& aS, + const GeomAdaptor_Surface& aGAS, const TopoDS_Edge& aE1, const TopoDS_Edge& aE2) { @@ -650,7 +650,7 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV, } // aP2D = aPoint.Value(); - aS->D0(aP2D.X(), aP2D.Y(), aP); + aGAS.D0(aP2D.X(), aP2D.Y(), aP); aD=aPV.SquareDistance(aP); if (aD > aDist) { aDist = 1.01 * aD; diff --git a/src/BOPTools/BOPTools_AlgoTools_2.cxx b/src/BOPTools/BOPTools_AlgoTools_2.cxx index 78e6181631..19003d5c10 100644 --- a/src/BOPTools/BOPTools_AlgoTools_2.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_2.cxx @@ -74,8 +74,8 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE, gp_Pnt aPv=BRep_Tool::Pnt(aV); aTolV=BRep_Tool::Tolerance(aV); - Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aE, aFirst, aLast); - aC3D->D0(aT, aPc); + GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) ); + aCA.D0(aT, aPc); aDist=aPv.Distance(aPc); if (aDist>aTolV) { BRep_Builder BB; @@ -97,8 +97,8 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC, gp_Pnt aPv=BRep_Tool::Pnt(aV); aTolV=BRep_Tool::Tolerance(aV); - Handle(Geom_Curve) aC3D=aC.Curve(); - aC3D->D0(aT, aPc); + GeomAdaptor_Curve aCA( aC.Curve() ); + aCA.D0(aT, aPc); aDist=aPv.Distance(aPc); if (aDist>aTolV) { BRep_Builder BB; diff --git a/src/BRepCheck/BRepCheck_Wire.cxx b/src/BRepCheck/BRepCheck_Wire.cxx index e59fae7429..e07e896de5 100644 --- a/src/BRepCheck/BRepCheck_Wire.cxx +++ b/src/BRepCheck/BRepCheck_Wire.cxx @@ -108,7 +108,7 @@ inline Standard_Boolean IsOriented(const TopoDS_Shape& S) } static - void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d, + void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d, const Standard_Real aPrm, gp_Pnt2d& Pnt, gp_Vec2d& aVec2d); @@ -1653,14 +1653,15 @@ void ChoixUV(const TopoDS_Vertex& theVertex, C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam); if(C2d.IsNull()) continue; + Geom2dAdaptor_Curve aCA(C2d); aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam; - aPnt = C2d->Value(aParam); + aPnt = aCA.Value(aParam); if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False)) continue; - CurveDirForParameter(C2d, aParam, aPnt, aDer); + CurveDirForParameter(aCA, aParam, aPnt, aDer); if (aVOrientation == anE.Orientation()) aDer.Reverse(); @@ -1753,21 +1754,21 @@ void ChoixUV(const TopoDS_Vertex& theVertex, //function : CurveDirForParameter //purpose : //======================================================================= -void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d, - const Standard_Real aPrm, - gp_Pnt2d& Pnt, - gp_Vec2d& aVec2d) +void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d, + const Standard_Real aPrm, + gp_Pnt2d& Pnt, + gp_Vec2d& aVec2d) { Standard_Real aTol=gp::Resolution(); Standard_Integer i; - aC2d->D1(aPrm, Pnt, aVec2d); + aC2d.D1(aPrm, Pnt, aVec2d); // if (aVec2d.Magnitude() <= aTol) { for (i = 2; i <= 100; i++){ - aVec2d = aC2d->DN(aPrm, i); + aVec2d = aC2d.DN(aPrm, i); if (aVec2d.Magnitude() > aTol) { - break; + break; } } } diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx index 5d216732b8..926c880dc0 100644 --- a/src/BRepFill/BRepFill_OffsetWire.cxx +++ b/src/BRepFill/BRepFill_OffsetWire.cxx @@ -2232,10 +2232,10 @@ void TrimEdge (const TopoDS_Edge& E, // otherwise preserve only one of its representations. //---------------------------------------------------------- if (!BRep_Tool::Degenerated(E)) { + Standard_Real aParTol = 2.0 * Precision::PConfusion(); for (Standard_Integer k = 1; k < TheVer.Length(); k ++) { if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) || - - Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) { + Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= aParTol) { if(k+1 == TheVer.Length()) { StoreInMap(TheVer(k), TheVer(k+1), MapVV); diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx index d8556a4178..321995977e 100644 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx +++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx @@ -26,6 +26,7 @@ #include #include +#include #include @@ -56,12 +57,12 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc : const Standard_Real theFirst, const Standard_Real theLast) : - myCurve(theC3D), - myPCurve(theC2D), - mySurf(theSurf), myFirst(theFirst), myLast(theLast) { + myCurve = new GeomAdaptor_HCurve(theC3D); + myPCurve = new Geom2dAdaptor_HCurve(theC2D); + mySurf = new GeomAdaptor_HSurface(theSurf); } // virtual Standard_Integer NbVariables() const { @@ -160,9 +161,9 @@ class BRepLib_CheckCurveOnSurface_GlobOptFunc : return ((myFirst <= theParam) && (theParam <= myLast)); } - Handle(Geom_Curve) myCurve; - Handle(Geom2d_Curve) myPCurve; - Handle(Geom_Surface) mySurf; + Handle(GeomAdaptor_HCurve) myCurve; + Handle(Geom2dAdaptor_HCurve) myPCurve; + Handle(GeomAdaptor_HSurface) mySurf; Standard_Real myFirst; Standard_Real myLast; }; diff --git a/src/BRepLib/BRepLib_MakeEdge.cxx b/src/BRepLib/BRepLib_MakeEdge.cxx index 74e99407ac..13fc409092 100644 --- a/src/BRepLib/BRepLib_MakeEdge.cxx +++ b/src/BRepLib/BRepLib_MakeEdge.cxx @@ -773,7 +773,7 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC, Standard_Real cl = C->LastParameter(); Standard_Real epsilon = Precision::PConfusion(); Standard_Boolean periodic = C->IsPeriodic(); - + GeomAdaptor_Curve aCA(C); TopoDS_Vertex V1,V2; if (periodic) { @@ -813,14 +813,15 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC, Standard_Boolean p1inf = Precision::IsNegativeInfinite(p1); Standard_Boolean p2inf = Precision::IsPositiveInfinite(p2); gp_Pnt P1,P2; - if (!p1inf) P1 = C->Value(p1); - if (!p2inf) P2 = C->Value(p2); + if (!p1inf) P1 = aCA.Value(p1); + if (!p2inf) P2 = aCA.Value(p2); Standard_Real preci = BRepLib::Precision(); BRep_Builder B; // check for closed curve Standard_Boolean closed = Standard_False; + Standard_Boolean degenerated = Standard_False; if (!p1inf && !p2inf) closed = (P1.Distance(P2) <= preci); @@ -836,13 +837,19 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC, V2 = V1; else { if (!V1.IsSame(V2)) { - myError = BRepLib_DifferentPointsOnClosedCurve; - return; + myError = BRepLib_DifferentPointsOnClosedCurve; + return; } else if (P1.Distance(BRep_Tool::Pnt(V1)) > - Max(preci,BRep_Tool::Tolerance(V1))) { - myError = BRepLib_DifferentPointsOnClosedCurve; - return; + Max(preci,BRep_Tool::Tolerance(V1))) { + myError = BRepLib_DifferentPointsOnClosedCurve; + return; + } + else + { + gp_Pnt PM = aCA.Value((p1+p2)/2); + if (P1.Distance(PM) < preci) + degenerated = Standard_True; } } } @@ -898,6 +905,7 @@ void BRepLib_MakeEdge::Init(const Handle(Geom_Curve)& CC, B.Add(E,V2); } B.Range(E,p1,p2); + B.Degenerated(E, degenerated); myError = BRepLib_EdgeDone; Done(); diff --git a/src/BSplCLib/BSplCLib.cdl b/src/BSplCLib/BSplCLib.cdl index 70f49b7475..e489b04fec 100644 --- a/src/BSplCLib/BSplCLib.cdl +++ b/src/BSplCLib/BSplCLib.cdl @@ -104,6 +104,8 @@ uses TColStd, gp, TColgp, math, GeomAbs is + + imported transient class Cache; imported EvaluatorFunction ; @@ -2063,6 +2065,30 @@ is -- If rational computes the homogeneous Taylor expension -- for the numerator and stores it in CachePoles + BuildCache(theParameter : Real; + theSpanDomain : Real; + thePeriodicFlag : Boolean ; + theDegree : Integer; + theFlatKnots : Array1OfReal from TColStd ; + thePoles : Array1OfPnt from TColgp; + theWeights : Array1OfReal from TColStd ; + theCacheArray : in out Array2OfReal from TColStd) ; + ---Purpose: Perform the evaluation of the Taylor expansion + -- of the Bspline normalized between 0 and 1. + -- Structure of result optimized for BSplCLib_Cache. + + BuildCache(theParameter : Real; + theSpanDomain : Real; + thePeriodicFlag : Boolean ; + theDegree : Integer; + theFlatKnots : Array1OfReal from TColStd ; + thePoles : Array1OfPnt2d from TColgp; + theWeights : Array1OfReal from TColStd ; + theCacheArray : in out Array2OfReal from TColStd) ; + ---Purpose: Perform the evaluation of the Taylor expansion + -- of the Bspline normalized between 0 and 1. + -- Structure of result optimized for BSplCLib_Cache. + PolesCoefficients(Poles : Array1OfPnt2d from TColgp; CachePoles : in out Array1OfPnt2d from TColgp); ---Warning: To be used for Beziercurves ONLY!!! @@ -2454,6 +2480,7 @@ is -- all u1 and u0 in the domain of the curve f(u) -- | u1 - u0 | < UTolerance and -- we have |f (u1) - f (u0)| < Tolerance3D + end BSplCLib; diff --git a/src/BSplCLib/BSplCLib.cxx b/src/BSplCLib/BSplCLib.cxx index 0357c7e31d..c87c5b76c8 100644 --- a/src/BSplCLib/BSplCLib.cxx +++ b/src/BSplCLib/BSplCLib.cxx @@ -73,6 +73,7 @@ void BSplCLib::Hunt (const Array1OfReal& XX, { // replaced by simple dichotomy (RLE) Ilc = XX.Lower(); + if (XX.Length() <= 1) return; const Standard_Real *px = &XX(Ilc); px -= Ilc; diff --git a/src/BSplCLib/BSplCLib_Cache.cxx b/src/BSplCLib/BSplCLib_Cache.cxx new file mode 100644 index 0000000000..4a4ce5a497 --- /dev/null +++ b/src/BSplCLib/BSplCLib_Cache.cxx @@ -0,0 +1,362 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#include + +#include +#include +#include +#include + +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]); +} + diff --git a/src/BSplCLib/BSplCLib_Cache.hxx b/src/BSplCLib/BSplCLib_Cache.hxx new file mode 100644 index 0000000000..05a3c86232 --- /dev/null +++ b/src/BSplCLib/BSplCLib_Cache.hxx @@ -0,0 +1,182 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BSplCLib_Cache_Headerfile +#define _BSplCLib_Cache_Headerfile + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +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 diff --git a/src/BSplCLib/BSplCLib_CurveComputation.gxx b/src/BSplCLib/BSplCLib_CurveComputation.gxx index e71b4e06f9..f35fdd5f27 100644 --- a/src/BSplCLib/BSplCLib_CurveComputation.gxx +++ b/src/BSplCLib/BSplCLib_CurveComputation.gxx @@ -19,6 +19,7 @@ // xab : 12-Mar-96 : added MovePointAndTangent #include #include +#include #include #include #include @@ -1089,6 +1090,65 @@ void BSplCLib::BuildCache } } +void BSplCLib::BuildCache(const Standard_Real theParameter, + const Standard_Real theSpanDomain, + const Standard_Boolean thePeriodicFlag, + const Standard_Integer theDegree, + const TColStd_Array1OfReal& theFlatKnots, + const Array1OfPoints& thePoles, + const TColStd_Array1OfReal& theWeights, + TColStd_Array2OfReal& theCacheArray) +{ + Standard_Real aParam = theParameter; + Standard_Integer anIndex = 0; + Standard_Integer aDimension; + Standard_Boolean isRational; + + BSplCLib_DataContainer dc(theDegree); + PrepareEval(aParam, + anIndex, + aDimension, + isRational, + theDegree, + thePeriodicFlag, + thePoles, + theWeights, + theFlatKnots, + (BSplCLib::NoMults()), + dc); + // + // Watch out : PrepareEval checks if locally the Bspline is polynomial + // therefore rational flag could be set to False even if there are + // Weights. The Dimension is set accordingly. + // + + Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the curve is locally polynomial + (&theWeights != NULL && !isRational) ? aDimension + 1 : aDimension; + + BSplCLib::Bohm(aParam, theDegree, theDegree, *dc.knots, aDimension, *dc.poles); + + Standard_Real aCoeff = 1.0; + Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol())); + Standard_Real* aPolyCoeffs = dc.poles; + + for (Standard_Integer i = 0; i <= theDegree; i++) + { + for (Standard_Integer j = 0; j< aDimension; j++) + aCache[j] = aPolyCoeffs[j] * aCoeff; + aCoeff *= theSpanDomain / (i+1); + aPolyCoeffs += aDimension; + aCache += aDimension; + if (aCacheShift > aDimension) + { + aCache[0] = 0.0; + aCache++; + } + } + + if (aCacheShift > aDimension) + theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0); +} + //======================================================================= //function : Interpolate //purpose : diff --git a/src/BSplCLib/FILES b/src/BSplCLib/FILES index ed982fe172..e6705be4b6 100755 --- a/src/BSplCLib/FILES +++ b/src/BSplCLib/FILES @@ -4,4 +4,5 @@ BSplCLib_3.cxx BSplCLib_BzSyntaxes.cxx BSplCLib_CurveComputation.gxx BSplCLib_EvaluatorFunction.hxx - +BSplCLib_Cache.hxx +BSplCLib_Cache.cxx diff --git a/src/BSplSLib/BSplSLib.cdl b/src/BSplSLib/BSplSLib.cdl index 73c053de83..b413650fd5 100644 --- a/src/BSplSLib/BSplSLib.cdl +++ b/src/BSplSLib/BSplSLib.cdl @@ -71,6 +71,8 @@ uses TColStd, gp, TColgp is + + imported transient class Cache; imported EvaluatorFunction ; ---Purpose: @@ -465,6 +467,19 @@ is -- -- + BuildCache(theU, theV : Real; + theUSpanDomain, theVSpanDomain : Real; + theUPeriodic, theVPeriodic : Boolean; + theUDegree, theVDegree : Integer; + theUIndex, theVIndex : Integer; + theUFlatKnots, theVFlatKnots : Array1OfReal from TColStd; + thePoles : Array2OfPnt from TColgp; + theWeights : Array2OfReal from TColStd; + theCacheArray : in out Array2OfReal from TColStd); + ---Purpose: Perform the evaluation of the Taylor expansion + -- of the Bspline normalized between 0 and 1. + -- Structure of result optimized for BSplSLib_Cache. + CacheD0(U,V : Real; UDegree,VDegree : Integer; UCacheParameter,VCacheParameter : Real; diff --git a/src/BSplSLib/BSplSLib.cxx b/src/BSplSLib/BSplSLib.cxx index 5ad633ccf4..813d6ae4c4 100644 --- a/src/BSplSLib/BSplSLib.cxx +++ b/src/BSplSLib/BSplSLib.cxx @@ -2043,6 +2043,101 @@ void BSplSLib::BuildCache } } +void BSplSLib::BuildCache(const Standard_Real theU, + const Standard_Real theV, + const Standard_Real theUSpanDomain, + const Standard_Real theVSpanDomain, + const Standard_Boolean theUPeriodicFlag, + const Standard_Boolean theVPeriodicFlag, + const Standard_Integer theUDegree, + const Standard_Integer theVDegree, + const Standard_Integer theUIndex, + const Standard_Integer theVIndex, + const TColStd_Array1OfReal& theUFlatKnots, + const TColStd_Array1OfReal& theVFlatKnots, + const TColgp_Array2OfPnt& thePoles, + const TColStd_Array2OfReal& theWeights, + TColStd_Array2OfReal& theCacheArray) +{ + Standard_Boolean flag_u_or_v; + Standard_Integer d1, d2; + Standard_Real u1, u2; + Standard_Boolean isRationalOnParam = (&theWeights != NULL); + Standard_Boolean isRational; + + BSplSLib_DataContainer dc(theUDegree, theVDegree); + flag_u_or_v = + PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree, + isRationalOnParam, isRationalOnParam, + theUPeriodicFlag, theVPeriodicFlag, + thePoles, theWeights, + theUFlatKnots, theVFlatKnots, + (BSplCLib::NoMults()), (BSplCLib::NoMults()), + u1, u2, d1, d2, isRational, dc); + + Standard_Integer d2p1 = d2 + 1; + Standard_Integer aDimension = isRational ? 4 : 3; + Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial + (isRationalOnParam && !isRational) ? aDimension + 1 : aDimension; + + Standard_Real aDomains[2]; + // aDomains[0] corresponds to variable with minimal degree + // aDomains[1] corresponds to variable with maximal degree + if (flag_u_or_v) + { + aDomains[0] = theUSpanDomain; + aDomains[1] = theVSpanDomain; + } + else + { + aDomains[0] = theVSpanDomain; + aDomains[1] = theUSpanDomain; + } + + BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles); + for (Standard_Integer kk = 0; kk <= d1 ; kk++) + BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1)); + + Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol())); + Standard_Real* aPolyCoeffs = dc.poles; + + Standard_Real aFactors[2]; + // aFactors[0] corresponds to variable with minimal degree + // aFactors[1] corresponds to variable with maximal degree + aFactors[1] = 1.0; + Standard_Integer aRow, aCol, i; + Standard_Real aCoeff; + for (aRow = 0; aRow <= d2; aRow++) + { + aFactors[0] = 1.0; + for (aCol = 0; aCol <= d1; aCol++) + { + aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension; + aCoeff = aFactors[0] * aFactors[1]; + for (i = 0; i < aDimension; i++) + aCache[i] = aPolyCoeffs[i] * aCoeff; + aCache += aCacheShift; + aFactors[0] *= aDomains[0] / (aCol + 1); + } + aFactors[1] *= aDomains[1] / (aRow + 1); + } + + // Fill the weights for the surface which is not locally polynomial + if (aCacheShift > aDimension) + { + aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol())); + aCache += aCacheShift - 1; + for (aRow = 0; aRow <= d2; aRow++) + for (aCol = 0; aCol <= d1; aCol++) + { + *aCache = 0.0; + aCache += aCacheShift; + } + theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0); + } +} + + //======================================================================= //function : CacheD0 //purpose : Evaluates the polynomial cache of the Bspline Curve diff --git a/src/BSplSLib/BSplSLib_Cache.cxx b/src/BSplSLib/BSplSLib_Cache.cxx new file mode 100644 index 0000000000..dbc8e4198b --- /dev/null +++ b/src/BSplSLib/BSplSLib_Cache.cxx @@ -0,0 +1,407 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include + +#include + +#include +#include +#include +#include + +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 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 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 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); +} + diff --git a/src/BSplSLib/BSplSLib_Cache.hxx b/src/BSplSLib/BSplSLib_Cache.hxx new file mode 100644 index 0000000000..819635006a --- /dev/null +++ b/src/BSplSLib/BSplSLib_Cache.hxx @@ -0,0 +1,161 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BSplSLib_Cache_Headerfile +#define _BSplSLib_Cache_Headerfile + +#include +#include +#include +#include + +#include +#include + +#include +#include + +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 diff --git a/src/BSplSLib/FILES b/src/BSplSLib/FILES index 05cf83cd2f..8781c3d3db 100755 --- a/src/BSplSLib/FILES +++ b/src/BSplSLib/FILES @@ -1,3 +1,4 @@ BSplSLib_BzSyntaxes.cxx BSplSLib_EvaluatorFunction.hxx - +BSplSLib_Cache.hxx +BSplSLib_Cache.cxx diff --git a/src/CSLib/CSLib.cxx b/src/CSLib/CSLib.cxx index 77c35067db..f2f341470a 100644 --- a/src/CSLib/CSLib.cxx +++ b/src/CSLib/CSLib.cxx @@ -165,7 +165,13 @@ gp_Dir& Normal // if (D1UMag <= MagTol || D1VMag <= MagTol && NMag > MagTol) MagTol = 2* NMag; } else - { Normal = gp_Dir (D1UvD1V); Status = Defined; } + { + // Firstly normalize tangent vectors D1U and D1V (this method is more stable) + gp_Dir aD1U(D1U); + gp_Dir aD1V(D1V); + Normal = gp_Dir(aD1U.Crossed(aD1V)); + Status = Defined; + } } diff --git a/src/CSLib/CSLib_Offset.cxx b/src/CSLib/CSLib_Offset.cxx new file mode 100644 index 0000000000..7dc972987f --- /dev/null +++ b/src/CSLib/CSLib_Offset.cxx @@ -0,0 +1,470 @@ +// Copyright (c) 2015-... OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +#include +#include +#include +#include + +#include + + +// ========== 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)); +} + diff --git a/src/CSLib/CSLib_Offset.hxx b/src/CSLib/CSLib_Offset.hxx new file mode 100644 index 0000000000..277dfdc6d8 --- /dev/null +++ b/src/CSLib/CSLib_Offset.hxx @@ -0,0 +1,190 @@ +// Copyright (c) 2015-... OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _CSLib_Offset_Headerfile +#define _CSLib_Offset_Headerfile + +#include +#include +#include +#include +#include +#include + +/** \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 diff --git a/src/CSLib/FILES b/src/CSLib/FILES new file mode 100644 index 0000000000..c41651007a --- /dev/null +++ b/src/CSLib/FILES @@ -0,0 +1,2 @@ +CSLib_Offset.hxx +CSLib_Offset.cxx diff --git a/src/Extrema/Extrema_GExtPC.gxx b/src/Extrema/Extrema_GExtPC.gxx index 5828922412..5a0d0bf69c 100644 --- a/src/Extrema/Extrema_GExtPC.gxx +++ b/src/Extrema/Extrema_GExtPC.gxx @@ -146,6 +146,34 @@ void Extrema_GExtPC::Perform(const ThePoint& P) IntExtIsDone = IntExtIsDone || mydone; } mydone = IntExtIsDone; + + // Additional checking if the point is on the first or last point of the curve and does not added yet + if (mydist1 < Precision::SquareConfusion() || mydist2 < Precision::SquareConfusion()) + { + Standard_Boolean isFirstAdded = Standard_False; + Standard_Boolean isLastAdded = Standard_False; + Standard_Integer aNbPoints = mypoint.Length(); + for (i = 1; i <= aNbPoints; i++) + { + U = mypoint.Value(i).Parameter(); + if (Abs(U - myuinf) < mytolu) + isFirstAdded = Standard_True; + else if (Abs(myusup - U) < mytolu) + isLastAdded = Standard_True; + } + if (!isFirstAdded && mydist1 < Precision::SquareConfusion()) + { + mySqDist.Prepend(mydist1); + myismin.Prepend(Standard_True); + mypoint.Prepend(ThePOnC(myuinf, Pf)); + } + if (!isLastAdded && mydist2 < Precision::SquareConfusion()) + { + mySqDist.Append(mydist2); + myismin.Append(Standard_True); + mypoint.Append(ThePOnC(myusup, Pl)); + } + } return; } } diff --git a/src/Geom/Geom_BSplineCurve.cdl b/src/Geom/Geom_BSplineCurve.cdl index 40ba005ce4..e428bf8af9 100644 --- a/src/Geom/Geom_BSplineCurve.cdl +++ b/src/Geom/Geom_BSplineCurve.cdl @@ -120,8 +120,7 @@ uses Array1OfInteger from TColStd, Vec from gp, BSplKnotDistribution from GeomAbs, Geometry from Geom, - Shape from GeomAbs, - Mutex from Standard + Shape from GeomAbs raises ConstructionError from Standard, @@ -590,17 +589,6 @@ is ---Purpose : -- Returns True if the weights are not identical. -- The tolerance criterion is Epsilon of the class Real. - - IsCacheValid(me; Parameter : Real) returns Boolean - - ---Purpose : - -- Tells whether the Cache is valid for the - -- given parameter - -- Warnings : the parameter must be normalized within - -- the period if the curve is periodic. Otherwise - -- the answer will be false - -- - is static private; Continuity (me) returns Shape from GeomAbs; ---Purpose : @@ -789,6 +777,15 @@ is raises DimensionError; ---Purpose : -- Raised if the length of K is not equal to the number of knots. + Knots (me) + returns Array1OfReal from TColStd + ---Purpose : returns the knot values of the B-spline curve; + -- Warning + -- A knot with a multiplicity greater than 1 is not + -- repeated in the knot table. The Multiplicity function + -- can be used to obtain the multiplicity of each knot. + ---C++ : return const & + is static; KnotSequence (me; K : out Array1OfReal from TColStd) @@ -845,6 +842,12 @@ is -- Standard_DimensionError if the array K is not of -- the appropriate length.Returns the knots sequence. raises DimensionError; + KnotSequence (me) + returns Array1OfReal from TColStd + ---Purpose : returns the knots of the B-spline curve. + -- Knots with multiplicit greater than 1 are repeated + ---C++ : return const & + is static; @@ -910,6 +913,11 @@ is raises DimensionError; ---Purpose : -- Raised if the length of M is not equal to NbKnots. + Multiplicities (me) + returns Array1OfInteger from TColStd + ---Purpose : returns the multiplicity of the knots of the curve. + ---C++ : return const & + is static; NbKnots (me) returns Integer; @@ -933,6 +941,11 @@ is raises DimensionError; ---Purpose : -- Raised if the length of P is not equal to the number of poles. + Poles (me) + returns Array1OfPnt from TColgp + ---Purpose : Returns the poles of the B-spline curve; + ---C++ : return const & + is static; StartPoint (me) returns Pnt; @@ -954,6 +967,11 @@ is raises DimensionError; ---Purpose : -- Raised if the length of W is not equal to NbPoles. + Weights (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the weights of the B-spline curve; + ---C++ : return const & + is static; @@ -981,20 +999,10 @@ is Copy (me) returns like me; ---Purpose: Creates a new object which is a copy of this BSpline curve. - - InvalidateCache(me : mutable) - ---Purpose : Invalidates the cache. This has to be private - -- this has to be private - is static private; UpdateKnots(me : mutable) ---Purpose : Recompute the flatknots, the knotsdistribution, the continuity. is static private; - - ValidateCache(me : mutable ; Parameter : Real) - - is static private; - ---Purpose : updates the cache and validates it IsEqual(me; theOther : BSplineCurve from Geom; thePreci : Real from Standard ) returns Boolean; @@ -1015,34 +1023,7 @@ fields flatknots : HArray1OfReal from TColStd; knots : HArray1OfReal from TColStd; mults : HArray1OfInteger from TColStd; - cachepoles : HArray1OfPnt from TColgp; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1] see below - cacheweights : HArray1OfReal from TColStd; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1] see below - validcache : Integer; - -- = 1 the cache is valid - -- = 0 the cache is invalid - parametercache : Real; - -- Parameter at which the Taylor expension is stored in - -- the cache - spanlenghtcache : Real; - -- Since the Taylor expansion is normalized in the - -- cache to evaluate the cache one has to use - -- (Parameter - parametercache) / nspanlenghtcache - spanindexcache : Integer; - -- the span for which the cache is valid if - -- validcache is 1 - - -- usefull to evaluate the parametric resolution maxderivinv : Real from Standard; maxderivinvok : Boolean from Standard; - myMutex : Mutex from Standard; - -- protected bspline-cache end; diff --git a/src/Geom/Geom_BSplineCurve.cxx b/src/Geom/Geom_BSplineCurve.cxx index 01a3a06394..876f373c14 100644 --- a/src/Geom/Geom_BSplineCurve.cxx +++ b/src/Geom/Geom_BSplineCurve.cxx @@ -125,12 +125,11 @@ Geom_BSplineCurve::Geom_BSplineCurve { // check - CheckCurveData (Poles, - Knots, - Mults, - Degree, - Periodic); - + CheckCurveData(Poles, + Knots, + Mults, + Degree, + Periodic); // copy arrays @@ -145,11 +144,6 @@ Geom_BSplineCurve::Geom_BSplineCurve mults->ChangeArray1() = Mults; UpdateKnots(); - cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1); - parametercache = 0.0e0 ; - spanlenghtcache = 0.0e0 ; - spanindexcache = 0 ; - } //======================================================================= @@ -174,11 +168,11 @@ Geom_BSplineCurve::Geom_BSplineCurve // check - CheckCurveData (Poles, - Knots, - Mults, - Degree, - Periodic); + CheckCurveData(Poles, + Knots, + Mults, + Degree, + Periodic); if (Weights.Length() != Poles.Length()) Standard_ConstructionError::Raise("Geom_BSplineCurve"); @@ -197,11 +191,9 @@ Geom_BSplineCurve::Geom_BSplineCurve poles = new TColgp_HArray1OfPnt(1,Poles.Length()); poles->ChangeArray1() = Poles; - cachepoles = new TColgp_HArray1OfPnt(1,Degree + 1); if (rational) { weights = new TColStd_HArray1OfReal(1,Weights.Length()); weights->ChangeArray1() = Weights; - cacheweights = new TColStd_HArray1OfReal(1,Degree + 1); } knots = new TColStd_HArray1OfReal(1,Knots.Length()); @@ -211,9 +203,6 @@ Geom_BSplineCurve::Geom_BSplineCurve mults->ChangeArray1() = Mults; UpdateKnots(); - parametercache = 0.0e0 ; - spanlenghtcache = 0.0e0 ; - spanindexcache = 0 ; } //======================================================================= @@ -598,7 +587,7 @@ void Geom_BSplineCurve::Segment(const Standard_Real U1, BSplCLib::LocateParameter(deg,knots->Array1(),mults->Array1(), NewU2,periodic,FromU1,ToU2,index2,U); - if ( Abs(knots->Value(index2+1)-U) <= Eps) + if ( Abs(knots->Value(index2+1)-U) <= Eps || index2 == index1) index2++; Standard_Integer nbknots = index2 - index1 + 1; @@ -974,7 +963,6 @@ void Geom_BSplineCurve::SetPole if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise(); poles->SetValue (Index, P); maxderivinvok = 0; - InvalidateCache() ; } //======================================================================= @@ -1023,7 +1011,6 @@ void Geom_BSplineCurve::SetWeight rational = !weights.IsNull(); } maxderivinvok = 0; - InvalidateCache() ; } //======================================================================= @@ -1032,11 +1019,11 @@ void Geom_BSplineCurve::SetWeight //======================================================================= void Geom_BSplineCurve::MovePoint(const Standard_Real U, - const gp_Pnt& P, - const Standard_Integer Index1, - const Standard_Integer Index2, - Standard_Integer& FirstModifiedPole, - Standard_Integer& LastmodifiedPole) + const gp_Pnt& P, + const Standard_Integer Index1, + const Standard_Integer Index2, + Standard_Integer& FirstModifiedPole, + Standard_Integer& LastmodifiedPole) { if (Index1 < 1 || Index1 > poles->Length() || Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) { @@ -1047,12 +1034,11 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U, D0(U, P0); gp_Vec Displ(P0, P); BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(), - weights->Array1(), flatknots->Array1(), - FirstModifiedPole, LastmodifiedPole, npoles); + weights->Array1(), flatknots->Array1(), + FirstModifiedPole, LastmodifiedPole, npoles); if (FirstModifiedPole) { poles->ChangeArray1() = npoles; maxderivinvok = 0; - InvalidateCache() ; } } @@ -1061,14 +1047,13 @@ void Geom_BSplineCurve::MovePoint(const Standard_Real U, //purpose : //======================================================================= -void Geom_BSplineCurve:: -MovePointAndTangent(const Standard_Real U, - const gp_Pnt& P, - const gp_Vec& Tangent, - const Standard_Real Tolerance, - const Standard_Integer StartingCondition, - const Standard_Integer EndingCondition, - Standard_Integer& ErrorStatus) +void Geom_BSplineCurve::MovePointAndTangent(const Standard_Real U, + const gp_Pnt& P, + const gp_Vec& Tangent, + const Standard_Real Tolerance, + const Standard_Integer StartingCondition, + const Standard_Integer EndingCondition, + Standard_Integer& ErrorStatus) { Standard_Integer ii ; if (IsPeriodic()) { @@ -1086,26 +1071,24 @@ MovePointAndTangent(const Standard_Real U, delta_derivative) ; gp_Vec delta(P0, P); for (ii = 1 ; ii <= 3 ; ii++) { - delta_derivative.SetCoord(ii, - Tangent.Coord(ii)- delta_derivative.Coord(ii)) ; + delta_derivative.SetCoord(ii, Tangent.Coord(ii)-delta_derivative.Coord(ii)); } BSplCLib::MovePointAndTangent(U, - delta, - delta_derivative, - Tolerance, - deg, - rational, - StartingCondition, - EndingCondition, - poles->Array1(), - weights->Array1(), - flatknots->Array1(), - new_poles, - ErrorStatus) ; + delta, + delta_derivative, + Tolerance, + deg, + rational, + StartingCondition, + EndingCondition, + poles->Array1(), + weights->Array1(), + flatknots->Array1(), + new_poles, + ErrorStatus) ; if (!ErrorStatus) { poles->ChangeArray1() = new_poles; maxderivinvok = 0; - InvalidateCache() ; } } @@ -1119,11 +1102,11 @@ void Geom_BSplineCurve::UpdateKnots() rational = !weights.IsNull(); Standard_Integer MaxKnotMult = 0; - BSplCLib::KnotAnalysis (deg, - periodic, - knots->Array1(), - mults->Array1(), - knotSet, MaxKnotMult); + BSplCLib::KnotAnalysis(deg, + periodic, + knots->Array1(), + mults->Array1(), + knotSet, MaxKnotMult); if (knotSet == GeomAbs_Uniform && !periodic) { flatknots = knots; @@ -1132,10 +1115,10 @@ void Geom_BSplineCurve::UpdateKnots() flatknots = new TColStd_HArray1OfReal (1, BSplCLib::KnotSequenceLength(mults->Array1(),deg,periodic)); - BSplCLib::KnotSequence (knots->Array1(), - mults->Array1(), - deg,periodic, - flatknots->ChangeArray1()); + BSplCLib::KnotSequence(knots->Array1(), + mults->Array1(), + deg,periodic, + flatknots->ChangeArray1()); } if (MaxKnotMult == 0) smooth = GeomAbs_CN; @@ -1148,36 +1131,6 @@ void Geom_BSplineCurve::UpdateKnots() default : smooth = GeomAbs_C3; break; } } - InvalidateCache() ; -} - -//======================================================================= -//function : Invalidate the Cache -//purpose : as the name says -//======================================================================= - -void Geom_BSplineCurve::InvalidateCache() -{ - validcache = 0 ; -} - -//======================================================================= -//function : check if the Cache is valid -//purpose : as the name says -//======================================================================= - -Standard_Boolean Geom_BSplineCurve::IsCacheValid -(const Standard_Real U) const -{ - //Roman Lygin 26.12.08, performance improvements - //1. avoided using NewParameter = (U - parametercache) / spanlenghtcache - //to check against [0, 1), as division is CPU consuming - //2. minimized use of if, as branching is also CPU consuming - Standard_Real aDelta = U - parametercache; - - return ( validcache && - (aDelta >= 0.0e0) && - ((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) ); } //======================================================================= @@ -1200,83 +1153,3 @@ void Geom_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const } } -//======================================================================= -//function : Validate the Cache -//purpose : that is compute the cache so that it is valid -//======================================================================= - -void Geom_BSplineCurve::ValidateCache(const Standard_Real Parameter) -{ - Standard_Real NewParameter ; - Standard_Integer LocalIndex = 0 ; - // - // check if the degree did not change - // - if (cachepoles->Upper() < deg + 1) - cachepoles = new TColgp_HArray1OfPnt(1,deg + 1); - if (rational) - { - if (cacheweights.IsNull() || cacheweights->Upper() < deg + 1) - cacheweights = new TColStd_HArray1OfReal(1,deg + 1); - } - else if (!cacheweights.IsNull()) - cacheweights.Nullify(); - - BSplCLib::LocateParameter(deg, - (flatknots->Array1()), - (BSplCLib::NoMults()), - Parameter, - periodic, - LocalIndex, - NewParameter); - spanindexcache = LocalIndex ; - if (Parameter == flatknots->Value(LocalIndex + 1)) { - - LocalIndex += 1 ; - parametercache = flatknots->Value(LocalIndex) ; - if (LocalIndex == flatknots->Upper() - deg) { - // - // for the last span if the parameter is outside of - // the domain of the curve than use the last knot - // and normalize with the last span Still set the - // spanindexcache to flatknots->Upper() - deg so that - // the IsCacheValid will know for sure we are extending - // the Bspline - // - - spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ; - } - else { - spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ; - } - } - else { - parametercache = flatknots->Value(LocalIndex) ; - spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ; - } - - if (rational) { - BSplCLib::BuildCache(parametercache, - spanlenghtcache, - periodic, - deg, - (flatknots->Array1()), - poles->Array1(), - weights->Array1(), - cachepoles->ChangeArray1(), - cacheweights->ChangeArray1()) ; - } - else { - BSplCLib::BuildCache(parametercache, - spanlenghtcache, - periodic, - deg, - (flatknots->Array1()), - poles->Array1(), - *((TColStd_Array1OfReal*) NULL), - cachepoles->ChangeArray1(), - *((TColStd_Array1OfReal*) NULL)) ; - } - validcache = 1 ; -} - diff --git a/src/Geom/Geom_BSplineCurve_1.cxx b/src/Geom/Geom_BSplineCurve_1.cxx index ec08ce5a43..e36433e072 100644 --- a/src/Geom/Geom_BSplineCurve_1.cxx +++ b/src/Geom/Geom_BSplineCurve_1.cxx @@ -30,7 +30,6 @@ #include #include #include -#include #include #define POLES (poles->Array1()) @@ -181,33 +180,24 @@ Standard_Integer Geom_BSplineCurve::Degree () const void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if(!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD0(NewU, - deg, - parametercache, - spanlenghtcache, - cachepoles->Array1(), - cacheweights->Array1(), + BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), P); } - else + else { - BSplCLib::CacheD0(NewU, - deg, - parametercache, - spanlenghtcache, - cachepoles->Array1(), + BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES, *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), P); } } @@ -221,36 +211,25 @@ void Geom_BSplineCurve::D1 (const Standard_Real U, gp_Pnt& P, gp_Vec& V1) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if(!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD1(NewU, - deg, - parametercache, - spanlenghtcache, - cachepoles->Array1(), - cacheweights->Array1(), - P, - V1); + BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1); } - else + else { - BSplCLib::CacheD1(NewU, - deg, - parametercache, - spanlenghtcache, - cachepoles->Array1(), + BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES, *((TColStd_Array1OfReal*) NULL), - P, - V1); + knots->Array1(), mults->Array1(), + P, V1); } } @@ -264,37 +243,25 @@ void Geom_BSplineCurve::D2(const Standard_Real U, gp_Vec& V1, gp_Vec& V2) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if(!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD2(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P, - V1, - V2); + BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1, V2); } - else { - BSplCLib::CacheD2(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - *((TColStd_Array1OfReal*) NULL), - P, - V1, - V2); + else + { + BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P, V1, V2); } } @@ -309,41 +276,25 @@ void Geom_BSplineCurve::D3(const Standard_Real U, gp_Vec& V2, gp_Vec& V3) const { - - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if(!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD3(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P, - V1, - V2, - V3) ; + BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1, V2, V3); } - else + else { - BSplCLib::CacheD3(NewU, - deg, - parametercache, - spanlenghtcache, - cachepoles->Array1(), - *((TColStd_Array1OfReal*) NULL), - P, - V1, - V2, - V3) ; + BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P, V1, V2, V3); } } @@ -352,19 +303,19 @@ void Geom_BSplineCurve::D3(const Standard_Real U, //purpose : //======================================================================= -gp_Vec Geom_BSplineCurve::DN (const Standard_Real U, - const Standard_Integer N ) const +gp_Vec Geom_BSplineCurve::DN(const Standard_Real U, + const Standard_Integer N) const { gp_Vec V; if (rational) { BSplCLib::DN(U,N,0,deg,periodic,POLES, - weights->Array1(), - FKNOTS,FMULTS,V); + weights->Array1(), + FKNOTS,FMULTS,V); } else { BSplCLib::DN(U,N,0,deg,periodic,POLES, - *((TColStd_Array1OfReal*) NULL), - FKNOTS,FMULTS,V); + *((TColStd_Array1OfReal*) NULL), + FKNOTS,FMULTS,V); } return V; } @@ -437,6 +388,11 @@ void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const K = knots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineCurve::Knots() const +{ + return knots->Array1(); +} + //======================================================================= //function : KnotSequence //purpose : @@ -449,6 +405,11 @@ void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const K = flatknots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineCurve::KnotSequence() const +{ + return flatknots->Array1(); +} + //======================================================================= //function : LastUKnotIndex //purpose : @@ -668,6 +629,11 @@ void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const M = mults->Array1(); } +const TColStd_Array1OfInteger& Geom_BSplineCurve::Multiplicities() const +{ + return mults->Array1(); +} + //======================================================================= //function : NbKnots //purpose : @@ -708,6 +674,11 @@ void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const P = poles->Array1(); } +const TColgp_Array1OfPnt& Geom_BSplineCurve::Poles() const +{ + return poles->Array1(); +} + //======================================================================= //function : StartPoint //purpose : @@ -757,6 +728,13 @@ void Geom_BSplineCurve::Weights } } +const TColStd_Array1OfReal& Geom_BSplineCurve::Weights() const +{ + if (IsRational()) + return weights->Array1(); + return BSplCLib::NoWeights(); +} + //======================================================================= //function : IsRational //purpose : @@ -778,7 +756,6 @@ void Geom_BSplineCurve::Transform TColgp_Array1OfPnt & CPoles = poles->ChangeArray1(); for (Standard_Integer I = 1; I <= CPoles.Length(); I++) CPoles (I).Transform (T); - InvalidateCache() ; maxderivinvok = 0; } diff --git a/src/Geom/Geom_BSplineSurface.cdl b/src/Geom/Geom_BSplineSurface.cdl index d1ddf3e147..14f17e73bc 100644 --- a/src/Geom/Geom_BSplineSurface.cdl +++ b/src/Geom/Geom_BSplineSurface.cdl @@ -147,8 +147,7 @@ uses Array1OfInteger from TColStd, BSplKnotDistribution from GeomAbs, Curve from Geom, Geometry from Geom, - Shape from GeomAbs, - Mutex from Standard + Shape from GeomAbs raises ConstructionError from Standard, DimensionError from Standard, @@ -919,16 +918,6 @@ is -- |1.0, 2.0, 0.5| -- if Weights = |1.0, 2.0, 0.5| returns False -- |1.0, 2.0, 0.5| - - IsCacheValid(me; UParameter, VParameter : Real) returns Boolean ; - - ---Purpose : - -- Tells whether the Cache is valid for the - -- given parameter - -- Warnings : the parameter must be normalized within - -- the period if the curve is periodic. Otherwise - -- the answer will be false - -- Bounds (me; U1, U2, V1, V2 : out Real); ---Purpose : @@ -1017,6 +1006,11 @@ is ---Purpose : -- Raised if the length of P in the U and V direction -- is not equal to NbUpoles and NbVPoles. + Poles (me) + returns Array2OfPnt from TColgp + ---Purpose : Returns the poles of the B-spline surface. + ---C++ : return const & + is static; UDegree (me) returns Integer; @@ -1055,6 +1049,11 @@ is ---Purpose : -- Raised if the length of Ku is not equal to the number of knots -- in the U direction. + UKnots (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the knots in the U direction. + ---C++ : return const & + is static; UKnotSequence (me; Ku : out Array1OfReal from TColStd) @@ -1066,6 +1065,15 @@ is raises DimensionError; ---Purpose : -- Raised if the length of Ku is not equal to NbUPoles + UDegree + 1 + UKnotSequence (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the uknots sequence. + -- In this sequence the knots with a multiplicity greater than 1 + -- are repeated. + --- Example : + -- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4} + ---C++ : return const & + is static; UMultiplicity (me; UIndex : Integer) returns Integer @@ -1083,6 +1091,11 @@ is ---Purpose : -- Raised if the length of Mu is not equal to the number of -- knots in the U direction. + UMultiplicities (me) + returns Array1OfInteger from TColStd + ---Purpose : Returns the multiplicities of the knots in the U direction. + ---C++ : return const & + is static; VDegree (me) returns Integer; @@ -1120,6 +1133,11 @@ is ---Purpose : -- Raised if the length of Kv is not equal to the number of -- knots in the V direction. + VKnots (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the knots in the V direction. + ---C++ : return const & + is static; VKnotSequence (me; Kv : out Array1OfReal from TColStd) @@ -1131,6 +1149,15 @@ is raises DimensionError; ---Purpose : -- Raised if the length of Kv is not equal to NbVPoles + VDegree + 1 + VKnotSequence (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the vknots sequence. + -- In this sequence the knots with a multiplicity greater than 1 + -- are repeated. + --- Example : + -- Ku = {k1, k1, k1, k2, k3, k3, k4, k4, k4} + ---C++ : return const & + is static; VMultiplicity (me; VIndex : Integer) returns Integer @@ -1148,6 +1175,11 @@ is ---Purpose : -- Raised if the length of Mv is not equal to the number of -- knots in the V direction. + VMultiplicities (me) + returns Array1OfInteger from TColStd + ---Purpose : Returns the multiplicities of the knots in the V direction. + ---C++ : return const & + is static; Weight (me; UIndex, VIndex : Integer) returns Real @@ -1164,6 +1196,11 @@ is ---Purpose : -- Raised if the length of W in the U and V direction is -- not equal to NbUPoles and NbVPoles. + Weights (me) + returns Array2OfReal from TColStd + ---Purpose : Returns the weights of the B-spline surface. + ---C++ : return const & + is static; @@ -1389,16 +1426,6 @@ is is static private; - InvalidateCache(me : mutable) - ---Purpose : Invalidates the cache. This has to be private this has to be private - is static private; - - ValidateCache(me : mutable ; UParameter : Real; - VParameter : Real) - - is static private; - ---Purpose : updates the cache and validates it - fields @@ -1420,68 +1447,8 @@ fields vknots : HArray1OfReal from TColStd; umults : HArray1OfInteger from TColStd; vmults : HArray1OfInteger from TColStd; - -- Inplementation of the cache on surfaces - cachepoles : HArray2OfPnt from TColgp; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1]x[0 1]. The Taylor expension of lower degree - -- is stored as consecutive Pnt in the array that is - -- if udeg <= vdeg than the array stores the following - -- - -- (2,0) (3,0) - -- (1,0) f (u0,v0) f (u0,v0) - -- f (u0,v0) f (u0,v0) ------------- ----------- - -- 2 3! - -- - -- (2,1) (3,1) - -- (0,1) (1,1) f (u0,v0) f (u0,v0) - -- f (u0,v0) f (u0,v0) ------------- ----------- - -- 2 3! - -- - -- Otherwise it is stored in the following fashion - -- - -- - -- (0,2) (0,3) - -- (0,1) f (u0,v0) f (u0,v0) - -- f (u0,v0) f (u0,v0) ------------- ----------- - -- 2 3! - -- - -- (1,2) (1,3) - -- (1,0) (1,1) f (u0,v0) f (u0,v0) - -- f (u0,v0) f (u0,v0) ------------- ----------- - -- 2 3! - -- - -- The size of the array is (1,Max degree) (1, Min degree) - -- - cacheweights : HArray2OfReal from TColStd; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1]x[0 1]. The Taylor expension of lower degree - -- is stored as consecutive Real in the array as explained above - ucacheparameter : Real ; - vcacheparameter : Real ; - -- Parameters at which the Taylor expension is stored in - -- the cache - ucachespanlenght : Real ; - vcachespanlenght : Real ; - -- Since the Taylor expansion is normalized in the - -- cache to evaluate the cache one has to use - -- (UParameter - uparametercache) / ucachespanlenght - -- (VParameter - vparametercache) / vcachespanlenght - ucachespanindex : Integer ; - vcachespanindex : Integer ; - -- the span for which the cache is valid if - -- validcache is 1 - validcache : Integer ; - - -- usefull to evaluate the parametric resolutions - umaxderivinv : Real from Standard; - vmaxderivinv : Real from Standard; - maxderivinvok : Boolean from Standard; - - myMutex : Mutex from Standard; - -- protected bsplinesurface-cache - + umaxderivinv : Real from Standard; + vmaxderivinv : Real from Standard; + maxderivinvok : Boolean from Standard; + end; diff --git a/src/Geom/Geom_BSplineSurface.cxx b/src/Geom/Geom_BSplineSurface.cxx index a24a6be79f..857e9c702e 100644 --- a/src/Geom/Geom_BSplineSurface.cxx +++ b/src/Geom/Geom_BSplineSurface.cxx @@ -165,8 +165,6 @@ Geom_BSplineSurface::Geom_BSplineSurface maxderivinvok(0) { - Standard_Integer MinDegree, - MaxDegree ; // check @@ -196,19 +194,6 @@ Geom_BSplineSurface::Geom_BSplineSurface vmults = new TColStd_HArray1OfInteger (1,VMults.Length()); vmults->ChangeArray1() = VMults; - MinDegree = Min(udeg,vdeg) ; - MaxDegree = Max(udeg,vdeg) ; - cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1, - 1,MinDegree + 1) ; - - cacheweights.Nullify() ; - ucacheparameter = 0.0e0 ; - vcacheparameter = 0.0e0 ; - ucachespanlenght = 1.0e0 ; - vcachespanlenght = 1.0e0 ; - ucachespanindex = 0 ; - vcachespanindex = 0 ; - validcache = 0 ; UpdateUKnots(); UpdateVKnots(); @@ -238,8 +223,6 @@ Geom_BSplineSurface::Geom_BSplineSurface vdeg(VDegree), maxderivinvok(0) { - Standard_Integer MinDegree, - MaxDegree ; // check weights if (Weights.ColLength() != Poles.ColLength()) @@ -289,21 +272,6 @@ Geom_BSplineSurface::Geom_BSplineSurface vmults = new TColStd_HArray1OfInteger (1,VMults.Length()); vmults->ChangeArray1() = VMults; - MinDegree = Min(udeg,vdeg) ; - MaxDegree = Max(udeg,vdeg) ; - cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1, - 1,MinDegree + 1) ; - if (urational || vrational) { - cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1, - 1,MinDegree + 1); - } - ucacheparameter = 0.0e0 ; - vcacheparameter = 0.0e0 ; - ucachespanlenght = 1.0e0 ; - vcachespanlenght = 1.0e0 ; - ucachespanindex = 0 ; - vcachespanindex = 0 ; - validcache = 0 ; UpdateUKnots(); UpdateVKnots(); @@ -1258,8 +1226,6 @@ void Geom_BSplineSurface::UpdateUKnots() default : Usmooth = GeomAbs_C3; break; } } - - InvalidateCache() ; } //======================================================================= @@ -1298,18 +1264,8 @@ void Geom_BSplineSurface::UpdateVKnots() default : Vsmooth = GeomAbs_C3; break; } } - InvalidateCache() ; } -//======================================================================= -//function : InvalidateCache -//purpose : Invalidates the Cache of the surface -//======================================================================= - -void Geom_BSplineSurface::InvalidateCache() -{ - validcache = 0 ; -} //======================================================================= //function : Normalizes the parameters if the curve is periodic @@ -1362,177 +1318,6 @@ void Geom_BSplineSurface::PeriodicNormalization } } -//======================================================================= -//function : ValidateCache -//purpose : function that validates the cache of the surface -//======================================================================= - -void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter, - const Standard_Real Vparameter) -{ - Standard_Real NewParameter ; - Standard_Integer LocalIndex = 0 ; - Standard_Integer MinDegree, - MaxDegree ; - // - // check if the degree did not change - // - - MinDegree = Min(udeg,vdeg) ; - MaxDegree = Max(udeg,vdeg) ; - if (cachepoles->ColLength() < MaxDegree + 1 || - cachepoles->RowLength() < MinDegree + 1) { - cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1, - 1,MinDegree + 1); - } - // - // Verif + poussee pour les poids - // - if (urational || vrational) { - if (cacheweights.IsNull()) { - cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1, - 1,MinDegree + 1); - } - else { - if (cacheweights->ColLength() < MaxDegree + 1 || - cacheweights->RowLength() < MinDegree + 1) { - cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1, - 1,MinDegree + 1); - } - } - } - else if (!cacheweights.IsNull()) - cacheweights.Nullify(); - - BSplCLib::LocateParameter(udeg, - (ufknots->Array1()), - (BSplCLib::NoMults()), - Uparameter, - uperiodic, - LocalIndex, - NewParameter); - ucachespanindex = LocalIndex ; - if (Uparameter == ufknots->Value(LocalIndex + 1)) { - - LocalIndex += 1 ; - ucacheparameter = ufknots->Value(LocalIndex) ; - if (LocalIndex == ufknots->Upper() - udeg) { - // - // for the last span if the parameter is outside of - // the domain of the curve than use the last knot - // and normalize with the last span Still set the - // cachespanindex to flatknots->Upper() - deg so that - // the IsCacheValid will know for sure we are extending - // the Bspline - // - - ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ; - } - else { - ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ; - } - } - else { - ucacheparameter = ufknots->Value(LocalIndex) ; - ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ; - } - - LocalIndex = 0 ; - BSplCLib::LocateParameter(vdeg, - (vfknots->Array1()), - (BSplCLib::NoMults()), - Vparameter, - vperiodic, - LocalIndex, - NewParameter); - vcachespanindex = LocalIndex ; - if (Vparameter == vfknots->Value(LocalIndex + 1)) { - LocalIndex += 1 ; - vcacheparameter = vfknots->Value(LocalIndex) ; - if (LocalIndex == vfknots->Upper() - vdeg) { - // - // for the last span if the parameter is outside of - // the domain of the curve than use the last knot - // and normalize with the last span Still set the - // cachespanindex to flatknots->Upper() - deg so that - // the IsCacheValid will know for sure we are extending - // the Bspline - // - - vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ; - } - else { - vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ; - } - } - else { - vcacheparameter = vfknots->Value(LocalIndex) ; - vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ; - } - - Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, - uspanlenght_11 = ucachespanlenght/2, - vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, - vspanlenght_11 = vcachespanlenght/2 ; - if (urational || vrational) { - BSplSLib::BuildCache(uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - uperiodic, - vperiodic, - udeg, - vdeg, - ucachespanindex, - vcachespanindex, - (ufknots->Array1()), - (vfknots->Array1()), - poles->Array2(), - weights->Array2(), - cachepoles->ChangeArray2(), - cacheweights->ChangeArray2()) ; - } - else { - BSplSLib::BuildCache(uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - uperiodic, - vperiodic, - udeg, - vdeg, - ucachespanindex, - vcachespanindex, - (ufknots->Array1()), - (vfknots->Array1()), - poles->Array2(), - *((TColStd_Array2OfReal*) NULL), - cachepoles->ChangeArray2(), - *((TColStd_Array2OfReal*) NULL)) ; - } - validcache = 1 ; -} - -//======================================================================= -//function : IsCacheValid -//purpose : function that checks for the validity of the cache of the -// surface -//======================================================================= -Standard_Boolean Geom_BSplineSurface::IsCacheValid -(const Standard_Real U, - const Standard_Real V) const -{ - //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid() - Standard_Real aDeltaU = U - ucacheparameter; - Standard_Real aDeltaV = V - vcacheparameter; - - return ( validcache && - (aDeltaU >= 0.0e0) && - ((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) && - (aDeltaV >= 0.0e0) && - ((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) ); -} - //======================================================================= //function : SetWeight //purpose : @@ -1550,7 +1335,6 @@ void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex, } Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight; Rational(Weights, urational, vrational); - InvalidateCache(); } //======================================================================= @@ -1583,8 +1367,6 @@ void Geom_BSplineSurface::SetWeightCol } // Verifie si c'est rationnel Rational(Weights, urational, vrational); - - InvalidateCache(); } //======================================================================= @@ -1619,6 +1401,5 @@ void Geom_BSplineSurface::SetWeightRow } // Verifie si c'est rationnel Rational(Weights, urational, vrational); - InvalidateCache(); } diff --git a/src/Geom/Geom_BSplineSurface_1.cxx b/src/Geom/Geom_BSplineSurface_1.cxx index 20ea22e5b4..0a630956f4 100644 --- a/src/Geom/Geom_BSplineSurface_1.cxx +++ b/src/Geom/Geom_BSplineSurface_1.cxx @@ -109,48 +109,15 @@ Standard_Boolean Geom_BSplineSurface::IsCNv void Geom_BSplineSurface::D0(const Standard_Real U, const Standard_Real V, - gp_Pnt& P) const + gp_Pnt& P) const { - Standard_Real new_u(U), new_v(V); - PeriodicNormalization(new_u, new_v); + Standard_Real aNewU = U; + Standard_Real aNewV = V; + PeriodicNormalization(aNewU, aNewV); - Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; - Standard_Mutex::Sentry aSentry(MySurface->myMutex); - - if(!IsCacheValid(new_u, new_v)) - MySurface->ValidateCache(new_u, new_v); - - Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, - uspanlenght_11 = ucachespanlenght/2, - vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, - vspanlenght_11 = vcachespanlenght/2 ; - if (cacheweights.IsNull()) { - - BSplSLib::CacheD0(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - *((TColStd_Array2OfReal*) NULL), - P) ; - } - else { - BSplSLib::CacheD0(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - cacheweights->Array2(), - P) ; - } + BSplSLib::D0(aNewU,aNewV,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, + udeg,vdeg,urational,vrational,uperiodic,vperiodic, + P); } //======================================================================= @@ -160,56 +127,25 @@ void Geom_BSplineSurface::D0(const Standard_Real U, void Geom_BSplineSurface::D1(const Standard_Real U, const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V) const { - Standard_Real new_u(U), new_v(V); - PeriodicNormalization(new_u, new_v); + Standard_Real aNewU = U; + Standard_Real aNewV = V; + PeriodicNormalization(aNewU, aNewV); - Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; - Standard_Mutex::Sentry aSentry(MySurface->myMutex); + Standard_Integer uindex = 0, vindex = 0; - if(!IsCacheValid(new_u, new_v)) - MySurface->ValidateCache(new_u, new_v); + BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU); + uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic); - Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, - uspanlenght_11 = ucachespanlenght/2, - vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, - vspanlenght_11 = vcachespanlenght/2 ; + BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV); + vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); - if (cacheweights.IsNull()) { - - BSplSLib::CacheD1(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - *((TColStd_Array2OfReal*) NULL), - P, - D1U, - D1V) ; - } - else { - - BSplSLib::CacheD1(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - cacheweights->Array2(), - P, - D1U, - D1V) ; - } + BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, + udeg,vdeg,urational,vrational,uperiodic,vperiodic, + P, D1U, D1V); } //======================================================================= @@ -218,64 +154,30 @@ void Geom_BSplineSurface::D1(const Standard_Real U, //======================================================================= void Geom_BSplineSurface::D2 (const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV) const { - Standard_Real new_u(U), new_v(V); - PeriodicNormalization(new_u, new_v); + Standard_Real aNewU = U; + Standard_Real aNewV = V; + PeriodicNormalization(aNewU, aNewV); - Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; - Standard_Mutex::Sentry aSentry(MySurface->myMutex); + Standard_Integer uindex = 0, vindex = 0; - if(!IsCacheValid(new_u, new_v)) - MySurface->ValidateCache(new_u, new_v); + BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU); + uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic); - Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, - uspanlenght_11 = ucachespanlenght/2, - vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, - vspanlenght_11 = vcachespanlenght/2 ; - if (cacheweights.IsNull()) { - BSplSLib::CacheD2(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - *((TColStd_Array2OfReal*) NULL), - P, - D1U, - D1V, - D2U, - D2UV, - D2V); - } - else { - BSplSLib::CacheD2(new_u, - new_v, - udeg, - vdeg, - uparameter_11, - vparameter_11, - uspanlenght_11, - vspanlenght_11, - cachepoles->Array2(), - cacheweights->Array2(), - P, - D1U, - D1V, - D2U, - D2UV, - D2V); - } - } + BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV); + vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); + + BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, + udeg,vdeg,urational,vrational,uperiodic,vperiodic, + P, D1U, D1V, D2U, D2V, D2UV); +} //======================================================================= //function : D3 @@ -542,6 +444,11 @@ void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const P = poles->Array2(); } +const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const +{ + return poles->Array2(); +} + //======================================================================= //function : UIso //purpose : @@ -645,6 +552,11 @@ void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const Ku = uknots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const +{ + return uknots->Array1(); +} + //======================================================================= //function : VKnots //purpose : @@ -656,6 +568,11 @@ void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const Kv = vknots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const +{ + return vknots->Array1(); +} + //======================================================================= //function : UKnotSequence //purpose : @@ -667,6 +584,11 @@ void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const Ku = ufknots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const +{ + return ufknots->Array1(); +} + //======================================================================= //function : VKnotSequence //purpose : @@ -678,6 +600,11 @@ void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const Kv = vfknots->Array1(); } +const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const +{ + return vfknots->Array1(); +} + //======================================================================= //function : UMultiplicity //purpose : @@ -701,6 +628,11 @@ void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const Mu = umults->Array1(); } +const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const +{ + return umults->Array1(); +} + //======================================================================= //function : VIso //purpose : @@ -798,6 +730,11 @@ void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const Mv = vmults->Array1(); } +const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const +{ + return vmults->Array1(); +} + //======================================================================= //function : Weight //purpose : @@ -826,6 +763,13 @@ void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const W = weights->Array2(); } +const TColStd_Array2OfReal& Geom_BSplineSurface::Weights() const +{ + if (urational || vrational) + return weights->Array2(); + return BSplSLib::NoWeights(); +} + //======================================================================= //function : Transform //purpose : @@ -839,8 +783,6 @@ void Geom_BSplineSurface::Transform (const gp_Trsf& T) VPoles (i, j).Transform (T); } } - - InvalidateCache(); } //======================================================================= @@ -1555,8 +1497,6 @@ void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex, for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) { Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I); } - - InvalidateCache(); } //======================================================================= @@ -1593,8 +1533,6 @@ void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex, for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) { Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I); } - - InvalidateCache(); } //======================================================================= @@ -1620,7 +1558,6 @@ void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex, const gp_Pnt& P) { poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P); - InvalidateCache(); } //======================================================================= @@ -1676,7 +1613,6 @@ void Geom_BSplineSurface::MovePoint(const Standard_Real U, poles->ChangeArray2() = npoles; } maxderivinvok = 0; - InvalidateCache() ; } //======================================================================= diff --git a/src/Geom/Geom_OffsetCurve.cxx b/src/Geom/Geom_OffsetCurve.cxx index c273f9e7d7..a4a996c512 100644 --- a/src/Geom/Geom_OffsetCurve.cxx +++ b/src/Geom/Geom_OffsetCurve.cxx @@ -39,6 +39,7 @@ #include #include #include +#include typedef Geom_OffsetCurve OffsetCurve; typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve); @@ -62,6 +63,13 @@ static const Standard_Real MinStep = 1e-7; static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); +static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative +// Recalculate derivatives in the singular point +// Returns true if the direction of derivatives is changed +static Standard_Boolean AdjustDerivative( + const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1, + gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative); + //======================================================================= @@ -319,10 +327,8 @@ void Geom_OffsetCurve::D2 (const Standard_Real U, Pnt& P, Vec& V1, Vec& V2) cons //purpose : //======================================================================= -void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& P, Vec& theV1, Vec& V2, Vec& V3) -const { - - +void Geom_OffsetCurve::D3 (const Standard_Real theU, Pnt& theP, Vec& theV1, Vec& theV2, Vec& theV3) const +{ // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) @@ -336,137 +342,15 @@ const { // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir + // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir - const Standard_Real aTol = gp::Resolution(); - Standard_Boolean IsDirectionChange = Standard_False; - basisCurve->D3 (theU, P, theV1, V2, V3); - Vec V4 = basisCurve->DN (theU, 4); - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); + basisCurve->D3 (theU, theP, theV1, theV2, theV3); + Vec aV4 = basisCurve->DN (theU, 4); + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, aV4); - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = -basisCurve->DN (theU, anIndex + 1); - V3 = -basisCurve->DN (theU, anIndex + 2); - V4 = -basisCurve->DN (theU, anIndex + 3); - - IsDirectionChange = Standard_True; - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex + 1); - V3 = basisCurve->DN (theU, anIndex + 2); - V4 = basisCurve->DN (theU, anIndex + 3); - } - }//if(V1.Magnitude() <= aTol) - - - XYZ OffsetDir = direction.XYZ(); - XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir); - XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir); - XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir); - XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Standard_Real R6 = R3 * R3; - Standard_Real R7 = R5 * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir); - Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir); - if (R7 <= gp::Resolution()) { - if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); - // V3 = P"' (U) : - D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2)); - D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4)))); - D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - - 15.0*Dr*Dr*Dr/R6 - D3r)); - D3Ndir.Multiply (offsetValue/R); - - if(IsDirectionChange) - V3=-V3; - - V3.Add (Vec(D3Ndir)); - - // V2 = P" (U) : - Standard_Real R4 = R2 * R2; - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2)); - D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2))); - D2Ndir.Multiply (offsetValue / R); - V2.Add (Vec(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec(DNdir)); - } - else { - // V3 = P"' (U) : - D3Ndir.Divide (R); - D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3)); - D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5)))); - D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - - 15.0*Dr*Dr*Dr/R7 - D3r)); - D3Ndir.Multiply (offsetValue); - - if(IsDirectionChange) - V3=-V3; - - V3.Add (Vec(D3Ndir)); - - // V2 = P" (U) : - D2Ndir.Divide (R); - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3)); - D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3))); - D2Ndir.Multiply (offsetValue); - V2.Add (Vec(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - theV1.Add (Vec(DNdir)); - } - //P (U) : - D0(theU,P); + CSLib_Offset::D3(theP, theV1, theV2, theV3, aV4, direction, offsetValue, + IsDirectionChange, theP, theV1, theV2, theV3); } @@ -508,68 +392,13 @@ Vec Geom_OffsetCurve::DN (const Standard_Real U, const Standard_Integer N) const void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP, gp_Pnt& thePbasis, gp_Vec& theV1basis)const - { - const Standard_Real aTol = gp::Resolution(); +{ + basisCurve->D1(theU, thePbasis, theV1basis); + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1basis.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, theV1basis); - basisCurve->D1 (theU, thePbasis, theV1basis); - Standard_Real Ndu = theV1basis.Magnitude(); - - if(Ndu <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); - - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - gp_Vec V; - - do - { - V = basisCurve->DN(theU,++anIndex); - Ndu = V.Magnitude(); - } - while((Ndu <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - gp_Pnt P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - gp_Vec V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - theV1basis = -V; - else - theV1basis = V; - - Ndu = theV1basis.Magnitude(); - }//if(Ndu <= aTol) - - XYZ Ndir = (theV1basis.XYZ()).Crossed (direction.XYZ()); - Standard_Real R = Ndir.Modulus(); - if (R <= gp::Resolution()) - Geom_UndefinedValue::Raise("Exception: Undefined normal vector " - "because tangent vector has zero-magnitude!"); - - Ndir.Multiply (offsetValue/R); - Ndir.Add (thePbasis.XYZ()); - theP.SetXYZ(Ndir); + CSLib_Offset::D0(thePbasis, theV1basis, direction, offsetValue, IsDirectionChange, theP); } //======================================================================= @@ -578,96 +407,21 @@ void Geom_OffsetCurve::D0(const Standard_Real theU, gp_Pnt& theP, //======================================================================= void Geom_OffsetCurve::D1 ( const Standard_Real theU, - Pnt& P , Pnt& PBasis , - Vec& theV1, Vec& V1basis, Vec& V2basis) const { + Pnt& theP , Pnt& thePBasis , + Vec& theV1, Vec& theV1basis, Vec& theV2basis) const { // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R)) - const Standard_Real aTol = gp::Resolution(); + basisCurve->D2 (theU, thePBasis, theV1basis, theV2basis); - basisCurve->D2 (theU, PBasis, V1basis, V2basis); - theV1 = V1basis; - Vec V2 = V2basis; + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1basis.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1basis, theV2basis); - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); - - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = - basisCurve->DN (theU, anIndex+1); - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex+1); - } - - V2basis = V2; - V1basis = theV1; - }//if(theV1.Magnitude() <= aTol) - - XYZ OffsetDir = direction.XYZ(); - XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir); - XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - if (R3 <= gp::Resolution()) { - //We try another computation but the stability is not very good. - if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec(DNdir)); - } - else { - // Same computation as IICURV in EUCLID-IS because the stability is - // better - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue * Dr/R3)); - theV1.Add (Vec(DNdir)); - } - D0(theU,P); + CSLib_Offset::D1(thePBasis, theV1basis, theV2basis, direction, offsetValue, IsDirectionChange, theP, theV1); } @@ -676,11 +430,11 @@ void Geom_OffsetCurve::D1 ( const Standard_Real theU, //purpose : //======================================================================= -void Geom_OffsetCurve::D2 (const Standard_Real theU, - Pnt& P , Pnt& PBasis , - Vec& theV1 , Vec& V2 , - Vec& V1basis, Vec& V2basis, Vec& V3basis) const { - +void Geom_OffsetCurve::D2 (const Standard_Real theU, + Pnt& theP, Pnt& thePBasis, + Vec& theV1, Vec& theV2, + Vec& theV1basis, Vec& theV2basis, Vec& theV3basis) const +{ // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction) @@ -689,129 +443,15 @@ void Geom_OffsetCurve::D2 (const Standard_Real theU, // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) + // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2))) - const Standard_Real aTol = gp::Resolution(); - Standard_Boolean IsDirectionChange = Standard_False; - basisCurve->D3 (theU, PBasis, V1basis, V2basis, V3basis); + basisCurve->D3 (theU, thePBasis, theV1basis, theV2basis, theV3basis); - theV1 = V1basis; - V2 = V2basis; - Vec V3 = V3basis; - - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); + if(theV1basis.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1basis, theV2basis, theV3basis); - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = -basisCurve->DN (theU, anIndex+1); - V3 = -basisCurve->DN (theU, anIndex + 2); - - IsDirectionChange = Standard_True; - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex+1); - V3 = basisCurve->DN (theU, anIndex + 2); - } - - V2basis = V2; - V1basis = theV1; - }//if(V1.Magnitude() <= aTol) - - XYZ OffsetDir = direction.XYZ(); - XYZ Ndir = (theV1.XYZ()).Crossed (OffsetDir); - XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir); - XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir); - - if (R5 <= gp::Resolution()) { - //We try another computation but the stability is not very good - //dixit ISG. - if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise(); - // V2 = P" (U) : - Standard_Real R4 = R2 * R2; - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2)); - D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2))); - D2Ndir.Multiply (offsetValue / R); - - if(IsDirectionChange) - V2=-V2; - - V2.Add (Vec(D2Ndir)); - - // V1 = P' (U) : - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec(DNdir)); - } - else { - // Same computation as IICURV in EUCLID-IS because the stability is - // better. - // V2 = P" (U) : - D2Ndir.Multiply (offsetValue/R); - D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3)); - D2Ndir.Add (Ndir.Multiplied ( - offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3)) - ) - ); - - if(IsDirectionChange) - V2=-V2; - - V2.Add (Vec(D2Ndir)); - - // V1 = P' (U) : - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - theV1.Add (Vec(DNdir)); - } - //P (U) : - D0(theU,P); + CSLib_Offset::D2(thePBasis, theV1basis, theV2basis, theV3basis, direction, offsetValue, + IsDirectionChange, theP, theV1, theV2); } @@ -929,3 +569,57 @@ GeomAbs_Shape Geom_OffsetCurve::GetBasisCurveContinuity() const { return myBasisCurveContinuity; } + + +// ============= Auxiliary functions =================== +Standard_Boolean AdjustDerivative(const Handle(Geom_Curve)& theCurve, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec& theD1, gp_Vec& theD2, + gp_Vec& theD3, gp_Vec& theD4) +{ + static const Standard_Real aTol = gp::Resolution(); + + Standard_Boolean IsDirectionChange = Standard_False; + const Standard_Real anUinfium = theCurve->FirstParameter(); + const Standard_Real anUsupremum = theCurve->LastParameter(); + + const Standard_Real DivisionFactor = 1.e-3; + Standard_Real du; + if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) + du = 0.0; + else + du = anUsupremum - anUinfium; + + const Standard_Real aDelta = Max(du * DivisionFactor, MinStep); + + //Derivative is approximated by Taylor-series + Standard_Integer anIndex = 1; //Derivative order + gp_Vec V; + + do + { + V = theCurve->DN(theU, ++anIndex); + } + while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder); + + Standard_Real u; + + if(theU-anUinfium < aDelta) + u = theU+aDelta; + else + u = theU-aDelta; + + gp_Pnt P1, P2; + theCurve->D0(Min(theU, u), P1); + theCurve->D0(Max(theU, u), P2); + + gp_Vec V1(P1, P2); + IsDirectionChange = V.Dot(V1) < 0.0; + Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0; + + theD1 = V * aSign; + gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4}; + for (Standard_Integer i = 1; i < theMaxDerivative; i++) + *(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign; + + return IsDirectionChange; +} diff --git a/src/Geom/Geom_SurfaceOfRevolution.cxx b/src/Geom/Geom_SurfaceOfRevolution.cxx index 2f28155511..b2fc9ba9c1 100644 --- a/src/Geom/Geom_SurfaceOfRevolution.cxx +++ b/src/Geom/Geom_SurfaceOfRevolution.cxx @@ -397,6 +397,10 @@ void Geom_SurfaceOfRevolution::D1 XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q') XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir @@ -463,6 +467,10 @@ void Geom_SurfaceOfRevolution::D2 XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q') XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir @@ -558,6 +566,10 @@ void Geom_SurfaceOfRevolution::D3 XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q') XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''') @@ -763,6 +775,11 @@ void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U, XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); + XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q') XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir @@ -818,6 +835,11 @@ void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U, XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); + XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q') XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir @@ -896,6 +918,11 @@ void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U, XYZ Vdir = direction.XYZ(); //Vdir Q.Subtract(C); //CQ XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ + // If the point is placed on the axis of revolution then derivatives on U are undefined. + // Manually set them to zero. + if (VcrossCQ.SquareModulus() < Precision::SquareConfusion()) + VcrossCQ.SetCoord(0.0, 0.0, 0.0); + XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q') XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q") XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''') diff --git a/src/Geom2d/Geom2d_BSplineCurve.cdl b/src/Geom2d/Geom2d_BSplineCurve.cdl index 0196187a54..319ee5ba4e 100644 --- a/src/Geom2d/Geom2d_BSplineCurve.cdl +++ b/src/Geom2d/Geom2d_BSplineCurve.cdl @@ -124,8 +124,7 @@ uses Array1OfInteger from TColStd, Vec2d from gp, BSplKnotDistribution from GeomAbs, Geometry from Geom2d, - Shape from GeomAbs, - Mutex from Standard + Shape from GeomAbs raises ConstructionError from Standard, DimensionError from Standard, @@ -642,17 +641,6 @@ is -- Returns True if the weights are not identical. -- The tolerance criterion is Epsilon of the class Real. - IsCacheValid(me; Parameter : Real) returns Boolean - - ---Purpose : - -- Tells whether the Cache is valid for the - -- given parameter - -- Warnings : the parameter must be normalized within - -- the period if the curve is periodic. Otherwise - -- the answer will be false - -- - is static private; - Continuity (me) returns Shape from GeomAbs; --- Purpose : -- Returns the global continuity of the curve : @@ -843,6 +831,11 @@ is raises DimensionError; --- Purpose : -- Raised if the length of K is not equal to the number of knots. + Knots (me) + returns Array1OfReal from TColStd + ---Purpose : returns the knot values of the B-spline curve; + ---C++ : return const & + is static; KnotSequence (me; K : out Array1OfReal from TColStd) @@ -854,6 +847,15 @@ is raises DimensionError; --- Purpose : -- Raised if the length of K is not equal to NbPoles + Degree + 1 + KnotSequence (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the knots sequence. + -- In this sequence the knots with a multiplicity greater than 1 + -- are repeated. + -- Example : + -- K = {k1, k1, k1, k2, k3, k3, k4, k4, k4} + ---C++ : return const & + is static; @@ -919,6 +921,11 @@ is raises DimensionError; --- Purpose : -- Raised if the length of M is not equal to NbKnots. + Multiplicities (me) + returns Array1OfInteger from TColStd + ---Purpose : returns the multiplicity of the knots of the curve. + ---C++ : return const & + is static; NbKnots (me) returns Integer; @@ -942,6 +949,11 @@ is raises DimensionError; --- Purpose : -- Raised if the length of P is not equal to the number of poles. + Poles (me) + returns Array1OfPnt2d from TColgp + ---Purpose : Returns the poles of the B-spline curve; + ---C++ : return const & + is static; StartPoint (me) returns Pnt2d; @@ -963,6 +975,11 @@ is raises DimensionError; --- Purpose : -- Raised if the length of W is not equal to NbPoles. + Weights (me) + returns Array1OfReal from TColStd + ---Purpose : Returns the weights of the B-spline curve; + ---C++ : return const & + is static; @@ -996,17 +1013,8 @@ is UpdateKnots(me : mutable) ---Purpose: Recompute the flatknots, the knotsdistribution, the continuity. is static private; - - InvalidateCache(me : mutable) - ---Purpose : Invalidates the cache. This has to be private this has to be private - is static private; - ValidateCache(me : mutable ; Parameter : Real) - - is static private; - ---Purpose : updates the cache and validates it - fields rational : Boolean; @@ -1019,35 +1027,7 @@ fields flatknots : HArray1OfReal from TColStd; knots : HArray1OfReal from TColStd; mults : HArray1OfInteger from TColStd; - cachepoles : HArray1OfPnt2d from TColgp; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1] see below - cacheweights : HArray1OfReal from TColStd; - -- Taylor expansion of the poles function, in homogeneous - -- form if the curve is rational. The taylor expansion - -- is normalized so that the span corresponds to - -- [0 1] see below - validcache : Integer; - -- = 1 the cache is valid - -- = 0 the cache is invalid - parametercache : Real; - -- Parameter at which the Taylor expension is stored in - -- the cache - spanlenghtcache : Real; - -- Since the Taylor expansion is normalized in the - -- cache to evaluate the cache one has to use - -- (Parameter - refcache) * normcache - spanindexcache : Integer; - -- the span for which the cache is valid if - -- validcache is 1 - - -- usefull to evaluate the parametric resolution maxderivinv : Real from Standard; maxderivinvok : Boolean from Standard; - myMutex : Mutex from Standard; - -- protected bspline-cache - end; diff --git a/src/Geom2d/Geom2d_BSplineCurve.cxx b/src/Geom2d/Geom2d_BSplineCurve.cxx index a9594edf0c..fa3ace8729 100644 --- a/src/Geom2d/Geom2d_BSplineCurve.cxx +++ b/src/Geom2d/Geom2d_BSplineCurve.cxx @@ -123,12 +123,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve { // check - CheckCurveData (Poles, - Knots, - Mults, - Degree, - Periodic); - + CheckCurveData(Poles, + Knots, + Mults, + Degree, + Periodic); // copy arrays @@ -142,10 +141,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve mults->ChangeArray1() = Mults; UpdateKnots(); - cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1); - parametercache = 0.0e0 ; - spanlenghtcache = 0.0e0 ; - spanindexcache = 0 ; } //======================================================================= @@ -169,11 +164,11 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve // check - CheckCurveData (Poles, - Knots, - Mults, - Degree, - Periodic); + CheckCurveData(Poles, + Knots, + Mults, + Degree, + Periodic); if (Weights.Length() != Poles.Length()) Standard_ConstructionError::Raise("Geom2d_BSplineCurve :Weights and Poles array size mismatch"); @@ -192,11 +187,9 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve poles = new TColgp_HArray1OfPnt2d(1,Poles.Length()); poles->ChangeArray1() = Poles; - cachepoles = new TColgp_HArray1OfPnt2d(1,Degree + 1); if (rational) { weights = new TColStd_HArray1OfReal(1,Weights.Length()); weights->ChangeArray1() = Weights; - cacheweights = new TColStd_HArray1OfReal(1,Degree + 1); } knots = new TColStd_HArray1OfReal(1,Knots.Length()); @@ -206,10 +199,6 @@ Geom2d_BSplineCurve::Geom2d_BSplineCurve mults->ChangeArray1() = Mults; UpdateKnots(); - - parametercache = 0.0e0 ; - spanlenghtcache = 0.0e0 ; - spanindexcache = 0 ; } //======================================================================= @@ -1090,7 +1079,6 @@ void Geom2d_BSplineCurve::SetPole if (Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("BSpline curve : SetPole : index and #pole mismatch"); poles->SetValue (Index, P); maxderivinvok = 0; - InvalidateCache(); } //======================================================================= @@ -1140,7 +1128,6 @@ void Geom2d_BSplineCurve::SetWeight } maxderivinvok = 0; - InvalidateCache() ; } //======================================================================= @@ -1149,11 +1136,11 @@ void Geom2d_BSplineCurve::SetWeight //======================================================================= void Geom2d_BSplineCurve::MovePoint(const Standard_Real U, - const gp_Pnt2d& P, - const Standard_Integer Index1, - const Standard_Integer Index2, - Standard_Integer& FirstModifiedPole, - Standard_Integer& LastmodifiedPole) + const gp_Pnt2d& P, + const Standard_Integer Index1, + const Standard_Integer Index2, + Standard_Integer& FirstModifiedPole, + Standard_Integer& LastmodifiedPole) { if (Index1 < 1 || Index1 > poles->Length() || Index2 < 1 || Index2 > poles->Length() || Index1 > Index2) { @@ -1164,12 +1151,11 @@ void Geom2d_BSplineCurve::MovePoint(const Standard_Real U, D0(U, P0); gp_Vec2d Displ(P0, P); BSplCLib::MovePoint(U, Displ, Index1, Index2, deg, rational, poles->Array1(), - weights->Array1(), flatknots->Array1(), - FirstModifiedPole, LastmodifiedPole, npoles); + weights->Array1(), flatknots->Array1(), + FirstModifiedPole, LastmodifiedPole, npoles); if (FirstModifiedPole) { poles->ChangeArray1() = npoles; maxderivinvok = 0; - InvalidateCache() ; } } @@ -1222,7 +1208,6 @@ MovePointAndTangent(const Standard_Real U, if (!ErrorStatus) { poles->ChangeArray1() = new_poles; maxderivinvok = 0; - InvalidateCache() ; } } @@ -1266,33 +1251,6 @@ void Geom2d_BSplineCurve::UpdateKnots() default : smooth = GeomAbs_C3; break; } } - InvalidateCache() ; -} - -//======================================================================= -//function : Invalidate the Cache -//purpose : as the name says -//======================================================================= - -void Geom2d_BSplineCurve::InvalidateCache() -{ - validcache = 0 ; -} - -//======================================================================= -//function : check if the Cache is valid -//purpose : as the name says -//======================================================================= - -Standard_Boolean Geom2d_BSplineCurve::IsCacheValid -(const Standard_Real U) const -{ - //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid() - Standard_Real aDelta = U - parametercache; - - return ( validcache && - (aDelta >= 0.0e0) && - ((aDelta < spanlenghtcache) || (spanindexcache == flatknots->Upper() - deg)) ); } //======================================================================= @@ -1315,83 +1273,3 @@ void Geom2d_BSplineCurve::PeriodicNormalization(Standard_Real& Parameter) const } } -//======================================================================= -//function : Validate the Cache -//purpose : that is compute the cache so that it is valid -//======================================================================= - -void Geom2d_BSplineCurve::ValidateCache(const Standard_Real Parameter) -{ - Standard_Real NewParameter ; - Standard_Integer LocalIndex = 0 ; - // - // check if the degree did not change - // - if (cachepoles->Upper() < deg + 1) - cachepoles = new TColgp_HArray1OfPnt2d(1,deg + 1); - if (rational) - { - if (cacheweights.IsNull() || cacheweights->Upper() < deg + 1) - cacheweights = new TColStd_HArray1OfReal(1,deg + 1); - } - else if (!cacheweights.IsNull()) - cacheweights.Nullify(); - - BSplCLib::LocateParameter(deg, - (flatknots->Array1()), - (BSplCLib::NoMults()), - Parameter, - periodic, - LocalIndex, - NewParameter); - spanindexcache = LocalIndex ; - if (Parameter == flatknots->Value(LocalIndex + 1)) { - - LocalIndex += 1 ; - parametercache = flatknots->Value(LocalIndex) ; - if (LocalIndex == flatknots->Upper() - deg) { - // - // for the last span if the parameter is outside of - // the domain of the curve than use the last knot - // and normalize with the last span Still set the - // spanindexcache to flatknots->Upper() - deg so that - // the IsCacheValid will know for sure we are extending - // the Bspline - // - - spanlenghtcache = flatknots->Value(LocalIndex - 1) - parametercache ; - } - else { - spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ; - } - } - else { - parametercache = flatknots->Value(LocalIndex) ; - spanlenghtcache = flatknots->Value(LocalIndex + 1) - parametercache ; - } - - if (rational) { - BSplCLib::BuildCache(parametercache, - spanlenghtcache, - periodic, - deg, - (flatknots->Array1()), - poles->Array1(), - weights->Array1(), - cachepoles->ChangeArray1(), - cacheweights->ChangeArray1()) ; - } - else { - BSplCLib::BuildCache(parametercache, - spanlenghtcache, - periodic, - deg, - (flatknots->Array1()), - poles->Array1(), - *((TColStd_Array1OfReal*) NULL), - cachepoles->ChangeArray1(), - *((TColStd_Array1OfReal*) NULL)) ; - } - validcache = 1 ; -} - diff --git a/src/Geom2d/Geom2d_BSplineCurve_1.cxx b/src/Geom2d/Geom2d_BSplineCurve_1.cxx index b80b4151e2..0a5d6aad4d 100644 --- a/src/Geom2d/Geom2d_BSplineCurve_1.cxx +++ b/src/Geom2d/Geom2d_BSplineCurve_1.cxx @@ -30,7 +30,7 @@ #include #include #include -#include +#include #define POLES (poles->Array1()) #define KNOTS (knots->Array1()) @@ -183,36 +183,28 @@ Standard_Integer Geom2d_BSplineCurve::Degree () const //purpose : //======================================================================= -void Geom2d_BSplineCurve::D0 ( const Standard_Real U, - gp_Pnt2d& P) const +void Geom2d_BSplineCurve::D0(const Standard_Real U, + gp_Pnt2d& P) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if (!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD0(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P) ; + BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P); } - else { - BSplCLib::CacheD0(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - BSplCLib::NoWeights(), - P) ; + else + { + BSplCLib::D0(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P); } } @@ -222,39 +214,29 @@ void Geom2d_BSplineCurve::D0 ( const Standard_Real U, //purpose : //======================================================================= -void Geom2d_BSplineCurve::D1 (const Standard_Real U, - gp_Pnt2d& P, - gp_Vec2d& V1) const +void Geom2d_BSplineCurve::D1(const Standard_Real U, + gp_Pnt2d& P, + gp_Vec2d& V1) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if (!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD1(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P, - V1) ; + BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1); } - else { - BSplCLib::CacheD1(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - BSplCLib::NoWeights(), - P, - V1) ; + else + { + BSplCLib::D1(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P, V1); } } @@ -263,42 +245,30 @@ void Geom2d_BSplineCurve::D1 (const Standard_Real U, //purpose : //======================================================================= -void Geom2d_BSplineCurve::D2 (const Standard_Real U , - gp_Pnt2d& P , - gp_Vec2d& V1, - gp_Vec2d& V2 ) const +void Geom2d_BSplineCurve::D2(const Standard_Real U, + gp_Pnt2d& P, + gp_Vec2d& V1, + gp_Vec2d& V2) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if (!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD2(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P, - V1, - V2) ; + BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1, V2); } - else { - BSplCLib::CacheD2(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - BSplCLib::NoWeights(), - P, - V1, - V2) ; + else + { + BSplCLib::D2(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P, V1, V2); } } @@ -307,45 +277,31 @@ void Geom2d_BSplineCurve::D2 (const Standard_Real U , //purpose : //======================================================================= -void Geom2d_BSplineCurve::D3 (const Standard_Real U , - gp_Pnt2d& P , - gp_Vec2d& V1, - gp_Vec2d& V2, - gp_Vec2d& V3 ) const +void Geom2d_BSplineCurve::D3(const Standard_Real U, + gp_Pnt2d& P, + gp_Vec2d& V1, + gp_Vec2d& V2, + gp_Vec2d& V3) const { - Standard_Real NewU(U); - PeriodicNormalization(NewU); - - Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; - Standard_Mutex::Sentry aSentry(MyCurve->myMutex); - - if (!IsCacheValid(NewU)) - MyCurve->ValidateCache(NewU); - - if(rational) + Standard_Integer aSpanIndex = 0; + Standard_Real aNewU(U); + PeriodicNormalization(aNewU); + BSplCLib::LocateParameter(deg, knots->Array1(), mults->Array1(), U, periodic, aSpanIndex, aNewU); + if (aNewU < knots->Value(aSpanIndex)) + aSpanIndex--; + if (rational) { - BSplCLib::CacheD3(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - cacheweights->Array1(), - P, - V1, - V2, - V3) ; + BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES, + weights->Array1(), + knots->Array1(), mults->Array1(), + P, V1, V2, V3); } - else { - BSplCLib::CacheD3(NewU, - deg, - parametercache, - spanlenghtcache, - (cachepoles->Array1()), - BSplCLib::NoWeights(), - P, - V1, - V2, - V3) ; + else + { + BSplCLib::D3(aNewU,aSpanIndex,deg,periodic,POLES, + *((TColStd_Array1OfReal*) NULL), + knots->Array1(), mults->Array1(), + P, V1, V2, V3); } } @@ -354,20 +310,20 @@ void Geom2d_BSplineCurve::D3 (const Standard_Real U , //purpose : //======================================================================= -gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U, - const Standard_Integer N ) const +gp_Vec2d Geom2d_BSplineCurve::DN(const Standard_Real U, + const Standard_Integer N) const { gp_Vec2d V; if ( rational ) { BSplCLib::DN(U,N,0,deg,periodic,POLES, - weights->Array1(), - FKNOTS,FMULTS,V); + weights->Array1(), + FKNOTS,FMULTS,V); } - else { + else { BSplCLib::DN(U,N,0,deg,periodic,POLES, - *((TColStd_Array1OfReal*) NULL), - FKNOTS,FMULTS,V); + *((TColStd_Array1OfReal*) NULL), + FKNOTS,FMULTS,V); } return V; } @@ -440,6 +396,11 @@ void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const K = knots->Array1(); } +const TColStd_Array1OfReal& Geom2d_BSplineCurve::Knots() const +{ + return knots->Array1(); +} + //======================================================================= //function : KnotSequence //purpose : @@ -452,6 +413,11 @@ void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const K = flatknots->Array1(); } +const TColStd_Array1OfReal& Geom2d_BSplineCurve::KnotSequence() const +{ + return flatknots->Array1(); +} + //======================================================================= //function : LastUKnotIndex //purpose : @@ -676,6 +642,11 @@ void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const M = mults->Array1(); } +const TColStd_Array1OfInteger& Geom2d_BSplineCurve::Multiplicities() const +{ + return mults->Array1(); +} + //======================================================================= //function : NbKnots //purpose : @@ -716,6 +687,11 @@ void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const P = poles->Array1(); } +const TColgp_Array1OfPnt2d& Geom2d_BSplineCurve::Poles() const +{ + return poles->Array1(); +} + //======================================================================= //function : StartPoint //purpose : @@ -764,6 +740,13 @@ void Geom2d_BSplineCurve::Weights } } +const TColStd_Array1OfReal& Geom2d_BSplineCurve::Weights() const +{ + if (IsRational()) + return weights->Array1(); + return BSplCLib::NoWeights(); +} + //======================================================================= //function : IsRational //purpose : @@ -786,7 +769,6 @@ void Geom2d_BSplineCurve::Transform for (Standard_Integer I = 1; I <= CPoles.Length(); I++) CPoles (I).Transform (T); - InvalidateCache(); // maxderivinvok = 0; } diff --git a/src/Geom2d/Geom2d_OffsetCurve.cxx b/src/Geom2d/Geom2d_OffsetCurve.cxx index 07126a7475..79d86bad0e 100644 --- a/src/Geom2d/Geom2d_OffsetCurve.cxx +++ b/src/Geom2d/Geom2d_OffsetCurve.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,14 @@ static const int maxDerivOrder = 3; static const Standard_Real MinStep = 1e-7; static const Standard_Real MyAngularToleranceForG1 = Precision::Angular(); +static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative + +// Recalculate derivatives in the singular point +// Returns true if the direction of derivatives is changed +static Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative, + gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative); + //======================================================================= //function : Copy //purpose : @@ -211,163 +220,38 @@ GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const //purpose : //======================================================================= -void Geom2d_OffsetCurve::D0 (const Standard_Real theU, - Pnt2d& theP ) const +void Geom2d_OffsetCurve::D0 (const Standard_Real theU, + Pnt2d& theP) const { - const Standard_Real aTol = gp::Resolution(); - Vec2d vD1; - basisCurve->D1 (theU, theP, vD1); - Standard_Real Ndu = vD1.Magnitude(); - if(Ndu <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); + Standard_Boolean IsDirectionChange = Standard_False; + if(vD1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 1, theU, vD1); - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec2d V; - - do - { - V = basisCurve->DN(theU,++anIndex); - Ndu = V.Magnitude(); - } - while((Ndu <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt2d P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec2d V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - vD1 = -V; - else - vD1 = V; - - Ndu = vD1.Magnitude(); - }//if(Ndu <= aTol) - - if (Ndu <= aTol) - Geom2d_UndefinedValue::Raise("Exception: Undefined normal vector " - "because tangent vector has zero-magnitude!"); - - Standard_Real A = vD1.Y(); - Standard_Real B = - vD1.X(); - A = A * offsetValue/Ndu; - B = B * offsetValue/Ndu; - theP.SetCoord(theP.X() + A, theP.Y() + B); - } + CSLib_Offset::D0(theP, vD1, offsetValue, IsDirectionChange, theP); +} //======================================================================= //function : D1 //purpose : //======================================================================= -void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) const - { +void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& theP, Vec2d& theV1) const +{ // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ Z|| and Ndir = P' ^ Z // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R)) - const Standard_Real aTol = gp::Resolution(); - Vec2d V2; - basisCurve->D2 (theU, P, theV1, V2); - - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); + basisCurve->D2 (theU, theP, theV1, V2); - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec2d V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt2d P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec2d V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = - basisCurve->DN (theU, anIndex+1); - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex+1); - } - }//if(theV1.Magnitude() <= aTol) + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 2, theU, theV1, V2); - XY Ndir (theV1.Y(), -theV1.X()); - XY DNdir (V2.Y(), -V2.X()); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - if (R3 <= gp::Resolution()) { - //We try another computation but the stability is not very good. - if (R2 <= gp::Resolution()) Geom2d_UndefinedDerivative::Raise(); - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec2d(DNdir)); - } - else { - // Same computation as IICURV in EUCLID-IS because the stability is - // better - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - theV1.Add (Vec2d(DNdir)); - } - - D0(theU, P); + CSLib_Offset::D1(theP, theV1, V2, offsetValue, IsDirectionChange, theP, theV1); } //======================================================================= @@ -376,8 +260,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real theU, Pnt2d& P, Vec2d& theV1) c //======================================================================= void Geom2d_OffsetCurve::D2 (const Standard_Real theU, - Pnt2d& P, - Vec2d& theV1, Vec2d& V2) const + Pnt2d& theP, + Vec2d& theV1, Vec2d& theV2) const { // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ Z|| and Ndir = P' ^ Z @@ -388,124 +272,13 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU, // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2))) Vec2d V3; - basisCurve->D3 (theU, P, theV1, V2, V3); - - const Standard_Real aTol = gp::Resolution(); + basisCurve->D3 (theU, theP, theV1, theV2, V3); Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 3, theU, theV1, theV2, V3); - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); - - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec2d V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt2d P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec2d V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = -basisCurve->DN (theU, anIndex+1); - V3 = -basisCurve->DN (theU, anIndex + 2); - - IsDirectionChange = Standard_True; - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex+1); - V3 = basisCurve->DN (theU, anIndex + 2); - } - }//if(V1.Magnitude() <= aTol) - - XY Ndir (theV1.Y(), -theV1.X()); - XY DNdir (V2.Y(), -V2.X()); - XY D2Ndir (V3.Y(), -V3.X()); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir); - if (R5 <= gp::Resolution()) - { - //We try another computation but the stability is not very good - //dixit ISG. - if (R4 <= gp::Resolution()) - { - Geom2d_UndefinedDerivative::Raise(); - } - // V2 = P" (U) : - Standard_Real R4 = R2 * R2; - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2)); - D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2))); - D2Ndir.Multiply (offsetValue / R); - - if(IsDirectionChange) - V2=-V2; - - V2.Add (Vec2d(D2Ndir)); - - // V1 = P' (U) : - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec2d(DNdir)); - } - else - { - // Same computation as IICURV in EUCLID-IS because the stability is - // better. - // V2 = P" (U) : - D2Ndir.Multiply (offsetValue/R); - D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3)); - D2Ndir.Add (Ndir.Multiplied - (offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3)))); - - if(IsDirectionChange) - V2=-V2; - - V2.Add (Vec2d(D2Ndir)); - - // V1 = P' (U) - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - theV1.Add (Vec2d(DNdir)); - } - - //P (U) : - D0(theU, P); + CSLib_Offset::D2(theP, theV1, theV2, V3, offsetValue, IsDirectionChange, theP, theV1, theV2); } @@ -515,9 +288,9 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real theU, //======================================================================= void Geom2d_OffsetCurve::D3 (const Standard_Real theU, - Pnt2d& P, - Vec2d& theV1, Vec2d& V2, Vec2d& V3) const { - + Pnt2d& theP, + Vec2d& theV1, Vec2d& theV2, Vec2d& theV3) const +{ // P(u) = p(u) + Offset * Ndir / R // with R = || p' ^ Z|| and Ndir = P' ^ Z @@ -532,149 +305,16 @@ void Geom2d_OffsetCurve::D3 (const Standard_Real theU, // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir + // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir - const Standard_Real aTol = gp::Resolution(); - - Standard_Boolean IsDirectionChange = Standard_False; - - basisCurve->D3 (theU, P, theV1, V2, V3); + basisCurve->D3 (theU, theP, theV1, theV2, theV3); Vec2d V4 = basisCurve->DN (theU, 4); - if(theV1.Magnitude() <= aTol) - { - const Standard_Real anUinfium = basisCurve->FirstParameter(); - const Standard_Real anUsupremum = basisCurve->LastParameter(); + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(basisCurve, 4, theU, theV1, theV2, theV3, V4); - const Standard_Real DivisionFactor = 1.e-3; - Standard_Real du; - if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) - du = 0.0; - else - du = anUsupremum-anUinfium; - - const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - - Standard_Integer anIndex = 1; //Derivative order - Vec2d V; - - do - { - V = basisCurve->DN(theU,++anIndex); - } - while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); - - Standard_Real u; - - if(theU-anUinfium < aDelta) - u = theU+aDelta; - else - u = theU-aDelta; - - Pnt2d P1, P2; - basisCurve->D0(Min(theU, u),P1); - basisCurve->D0(Max(theU, u),P2); - - Vec2d V1(P1,P2); - Standard_Real aDirFactor = V.Dot(V1); - - if(aDirFactor < 0.0) - { - theV1 = -V; - V2 = -basisCurve->DN (theU, anIndex + 1); - V3 = -basisCurve->DN (theU, anIndex + 2); - V4 = -basisCurve->DN (theU, anIndex + 3); - - IsDirectionChange = Standard_True; - } - else - { - theV1 = V; - V2 = basisCurve->DN (theU, anIndex + 1); - V3 = basisCurve->DN (theU, anIndex + 2); - V4 = basisCurve->DN (theU, anIndex + 3); - } - }//if(V1.Magnitude() <= aTol) - - XY Ndir (theV1.Y(), -theV1.X()); - XY DNdir (V2.Y(), -V2.X()); - XY D2Ndir (V3.Y(), -V3.X()); - XY D3Ndir (V4.Y(), -V4.X()); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Standard_Real R6 = R3 * R3; - Standard_Real R7 = R5 * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir); - Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir); - - if (R7 <= gp::Resolution()) - { - //We try another computation but the stability is not very good - //dixit ISG. - - if (R6 <= gp::Resolution()) - Geom2d_UndefinedDerivative::Raise(); - - // V3 = P"' (U) : - D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R2)); - D3Ndir.Subtract ( - (DNdir.Multiplied ((3.0 * offsetValue) * ((D2r/R2) + (Dr*Dr)/R4)))); - D3Ndir.Add (Ndir.Multiplied ( - (offsetValue * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r)))); - D3Ndir.Multiply (offsetValue/R); - - if(IsDirectionChange) - V3=-V3; - - V3.Add (Vec2d(D3Ndir)); - - - // V2 = P" (U) : - Standard_Real R4 = R2 * R2; - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2)); - D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2))); - D2Ndir.Multiply (offsetValue / R); - V2.Add (Vec2d(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - theV1.Add (Vec2d(DNdir)); - } - else - { - // Same computation as IICURV in EUCLID-IS because the stability is - // better. - // V3 = P"' (U) : - D3Ndir.Multiply (offsetValue/R); - D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R3)); - D3Ndir.Subtract (DNdir.Multiplied ( - ((3.0 * offsetValue) * ((D2r/R3) + (Dr*Dr)/R5))) ); - D3Ndir.Add (Ndir.Multiplied ( - (offsetValue * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r)))); - - if(IsDirectionChange) - V3=-V3; - - V3.Add (Vec2d(D3Ndir)); - - // V2 = P" (U) : - D2Ndir.Multiply (offsetValue/R); - D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3)); - D2Ndir.Subtract (Ndir.Multiplied ( - offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3)))); - V2.Add (Vec2d(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - theV1.Add (Vec2d(DNdir)); - } - //P (U) : - D0(theU, P); - } + CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, offsetValue, IsDirectionChange, + theP, theV1, theV2, theV3); +} //======================================================================= //function : DN @@ -709,10 +349,10 @@ Standard_RangeError_Raise_if (N < 1, "Exception: Geom2d_OffsetCurve::DN(). N<1." void Geom2d_OffsetCurve::Value (const Standard_Real theU, Pnt2d& theP, Pnt2d& thePbasis, Vec2d& theV1basis ) const - { +{ basisCurve->D1(theU, thePbasis, theV1basis); D0(theU,theP); - } +} //======================================================================= @@ -741,30 +381,8 @@ void Geom2d_OffsetCurve::D1 (const Standard_Real U, if (Index != 2) { V2 = basisCurve->DN (U, Index); } - XY Ndir (V1.Y(), -V1.X()); - XY DNdir (V2.Y(), -V2.X()); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - if (R3 <= gp::Resolution()) { - //We try another computation but the stability is not very good. - if (R2 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); } - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue / R2); - V1.Add (Vec2d(DNdir)); - } - else { - // Same computation as IICURV in EUCLID-IS because the stability is - // better - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - V1.Add (Vec2d(DNdir)); - } - Ndir.Multiply (offsetValue/R); - Ndir.Add (Pbasis.XY()); - P.SetXY (Ndir); + + CSLib_Offset::D1(P, V1, V2, offsetValue, Standard_False, P, V1); } @@ -800,52 +418,8 @@ void Geom2d_OffsetCurve::D2 (const Standard_Real U, V2 = basisCurve->DN (U, Index); V3 = basisCurve->DN (U, Index + 1); } - XY Ndir (V1.Y(), -V1.X()); - XY DNdir (V2.Y(), -V2.X()); - XY D2Ndir (V3.Y(), -V3.X()); - Standard_Real R2 = Ndir.SquareModulus(); - Standard_Real R = Sqrt (R2); - Standard_Real R3 = R2 * R; - Standard_Real R4 = R2 * R2; - Standard_Real R5 = R3 * R2; - Standard_Real Dr = Ndir.Dot (DNdir); - Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir); - if (R5 <= gp::Resolution()) { - //We try another computation but the stability is not very good - //dixit ISG. - if (R4 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); } - // V2 = P" (U) : - Standard_Real R4 = R2 * R2; - D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2)); - D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2))); - D2Ndir.Multiply (offsetValue / R); - V2.Add (Vec2d(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply(R); - DNdir.Subtract (Ndir.Multiplied (Dr/R)); - DNdir.Multiply (offsetValue/R2); - V1.Add (Vec2d(DNdir)); - } - else { - // Same computation as IICURV in EUCLID-IS because the stability is - // better. - // V2 = P" (U) : - D2Ndir.Multiply (offsetValue/R); - D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3)); - D2Ndir.Subtract (Ndir.Multiplied ( - offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3)) - ) - ); - V2.Add (Vec2d(D2Ndir)); - // V1 = P' (U) : - DNdir.Multiply (offsetValue/R); - DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3)); - V1.Add (Vec2d(DNdir)); - } - //P (U) : - Ndir.Multiply (offsetValue/R); - Ndir.Add (Pbasis.XY()); - P.SetXY (Ndir); + + CSLib_Offset::D2(P, V1, V2, V3, offsetValue, Standard_False, P, V1, V2); } //======================================================================= @@ -961,3 +535,57 @@ GeomAbs_Shape Geom2d_OffsetCurve::GetBasisCurveContinuity() const { return myBasisCurveContinuity; } + + +// ============= Auxiliary functions =================== +Standard_Boolean AdjustDerivative(const Handle(Geom2d_Curve)& theCurve, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2, + gp_Vec2d& theD3, gp_Vec2d& theD4) +{ + static const Standard_Real aTol = gp::Resolution(); + + Standard_Boolean IsDirectionChange = Standard_False; + const Standard_Real anUinfium = theCurve->FirstParameter(); + const Standard_Real anUsupremum = theCurve->LastParameter(); + + const Standard_Real DivisionFactor = 1.e-3; + Standard_Real du; + if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) + du = 0.0; + else + du = anUsupremum - anUinfium; + + const Standard_Real aDelta = Max(du * DivisionFactor, MinStep); + + //Derivative is approximated by Taylor-series + Standard_Integer anIndex = 1; //Derivative order + Vec2d V; + + do + { + V = theCurve->DN(theU, ++anIndex); + } + while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder); + + Standard_Real u; + + if(theU-anUinfium < aDelta) + u = theU+aDelta; + else + u = theU-aDelta; + + Pnt2d P1, P2; + theCurve->D0(Min(theU, u),P1); + theCurve->D0(Max(theU, u),P2); + + Vec2d V1(P1,P2); + IsDirectionChange = V.Dot(V1) < 0.0; + Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0; + + theD1 = V * aSign; + gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4}; + for (Standard_Integer i = 1; i < theMaxDerivative; i++) + *(aDeriv[i-1]) = theCurve->DN(theU, anIndex + i) * aSign; + + return IsDirectionChange; +} diff --git a/src/Geom2dAdaptor/Geom2dAdaptor.cdl b/src/Geom2dAdaptor/Geom2dAdaptor.cdl index d4f7ff559d..f01e1c9118 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor.cdl +++ b/src/Geom2dAdaptor/Geom2dAdaptor.cdl @@ -27,7 +27,8 @@ uses gp, Standard, TColStd, - TColgp + TColgp, + BSplCLib is diff --git a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cdl b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cdl index b53c131f67..7609c0408c 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cdl +++ b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cdl @@ -33,7 +33,8 @@ uses Vec2d from gp, BSplineCurve from Geom2d, CurveType from GeomAbs, Shape from GeomAbs, - HCurve2d from Adaptor2d + HCurve2d from Adaptor2d, + Cache from BSplCLib raises NoSuchObject from Standard, @@ -123,19 +124,44 @@ is --- Purpose : Computes the point of parameter U on the curve is redefined static; + ValueBSpline(me; U: Real) returns Pnt2d from gp + --- Purpose : Computes the point of parameter U on the B-spline curve + is private; + + ValueOffset(me; U: Real) returns Pnt2d from gp + --- Purpose : Computes the point of parameter U on the offset curve + is private; + D0 (me; U : Real; P : out Pnt2d from gp) --- Purpose : Computes the point of parameter U. is redefined static; + D0BSpline(me; theU : Real; theP : out Pnt2d from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + is private; + + D0Offset(me; theU : Real; theP : out Pnt2d from gp) + --- Purpose : Computes the point of parameter U on the offset curve + is private; + D1 (me; U : Real; P : out Pnt2d from gp ; V : out Vec2d from gp) --- Purpose : Computes the point of parameter U on the curve with its -- first derivative. - raises DomainError from Standard --- Purpose : Raised if the continuity of the current interval -- is not C1. is redefined static; + + D1BSpline(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its derivative + is private; + + D1Offset(me; theU : Real; theP : out Pnt2d from gp ; theV : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its derivative + is private; D2 (me; U : Real; P : out Pnt2d from gp; V1, V2 : out Vec2d from gp) --- Purpose : @@ -147,6 +173,16 @@ is -- is not C2. is redefined static; + D2BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its first and second derivatives + is private; + + D2Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2 : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its first and second derivatives + is private; + D3 (me; U : Real; P : out Pnt2d from gp; V1, V2, V3 : out Vec2d from gp) --- Purpose : -- Returns the point P of parameter U, the first, the second @@ -156,6 +192,16 @@ is --- Purpose : Raised if the continuity of the current interval -- is not C3. is redefined static; + + D3BSpline(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its first, second and third derivatives + is private; + + D3Offset(me; theU : Real; theP : out Pnt2d from gp; theV1, theV2, theV3 : out Vec2d from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its first, second and third derivatives + is private; DN (me; U : Real; N : Integer) returns Vec2d from gp --- Purpose : @@ -169,6 +215,18 @@ is --- Purpose : Raised if N < 1. is redefined static; + DNBSpline(me; theU : Real; N : Integer) returns Vec2d from gp + --- Purpose : + -- The returned vector gives the value of the derivative for the + -- order of derivation N. + is private; + + DNOffset(me; theU : Real; N : Integer) returns Vec2d from gp + --- Purpose : + -- The returned vector gives the value of the derivative for the + -- order of derivation N. + is private; + Resolution(me; Ruv :Real) returns Real ---Purpose : returns the parametric resolution @@ -243,6 +301,11 @@ is load(me : in out; C : Curve from Geom2d; UFirst,ULast : Real) is private; + + RebuildCache(me; theParameter : Real) + ---Purpose: Rebuilds B-spline cache + -- \param theParameter the value on the knot axis which identifies the caching span + is static private; fields @@ -250,6 +313,8 @@ fields myTypeCurve : CurveType from GeomAbs ; myFirst : Real from Standard ; myLast : Real from Standard; + myCurveCache : Cache from BSplCLib; + myOffsetBaseCurveAdaptor : HCurve2d from Adaptor2d; end Curve; diff --git a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx index 4241b19abb..e1869eb2e5 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx +++ b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,9 @@ #include #include #include +#include +#include +#include //#include #include @@ -52,6 +56,17 @@ #define myBspl (*((Handle(Geom2d_BSplineCurve)*)&myCurve)) #define PosTol Precision::PConfusion()/2 +static const int maxDerivOrder = 3; +static const Standard_Real MinStep = 1e-7; + +static gp_Vec2d dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative + +// Recalculate derivatives in the singular point +// Returns true is the direction of derivatives is changed +static Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2 = dummyDerivative, + gp_Vec2d& theD3 = dummyDerivative, gp_Vec2d& theD4 = dummyDerivative); + //======================================================================= //function : LocalContinuity //purpose : Computes the Continuity of a BSplineCurve @@ -197,6 +212,16 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, } else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) { myTypeCurve = GeomAbs_BSplineCurve; + // Create cache for B-spline + myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(), + myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights()); + } + else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) + { + myTypeCurve = GeomAbs_OtherCurve; + // Create nested adaptor for base curve + Handle(Geom2d_Curve) aBase = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->BasisCurve(); + myOffsetBaseCurveAdaptor = new Geom2dAdaptor_HCurve(aBase); } else { myTypeCurve = GeomAbs_OtherCurve; @@ -218,7 +243,7 @@ GeomAbs_Shape Geom2dAdaptor_Curve::Continuity() const if (myTypeCurve == GeomAbs_BSplineCurve) { return LocalContinuity(myFirst, myLast); } - else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){ GeomAbs_Shape S = (*((Handle(Geom2d_OffsetCurve)*)&myCurve))->GetBasisCurveContinuity(); switch(S){ @@ -330,7 +355,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const } } } - else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){ GeomAbs_Shape BaseS=GeomAbs_C0; switch(S){ case GeomAbs_G1: @@ -342,9 +367,7 @@ Standard_Integer Geom2dAdaptor_Curve::NbIntervals(const GeomAbs_Shape S) const case GeomAbs_C2: BaseS = GeomAbs_C3; break; default: BaseS = GeomAbs_CN; } - Geom2dAdaptor_Curve C - ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()); - myNbIntervals = C.NbIntervals(BaseS); + myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS); } return myNbIntervals; @@ -447,7 +470,7 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T, } } } - else if (myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))){ + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)){ GeomAbs_Shape BaseS=GeomAbs_C0; switch(S){ case GeomAbs_G1: @@ -459,10 +482,8 @@ void Geom2dAdaptor_Curve::Intervals(TColStd_Array1OfReal& T, case GeomAbs_C2: BaseS = GeomAbs_C3; break; default: BaseS = GeomAbs_CN; } - Geom2dAdaptor_Curve C - ((*((Handle(Geom2d_OffsetCurve)*)&myCurve))->BasisCurve()); - myNbIntervals = C.NbIntervals(BaseS); - C.Intervals(T, BaseS); + myNbIntervals = myOffsetBaseCurveAdaptor->NbIntervals(BaseS); + myOffsetBaseCurveAdaptor->Intervals(T, BaseS); } T( T.Lower() ) = myFirst; @@ -525,6 +546,17 @@ Standard_Real Geom2dAdaptor_Curve::Period() const return myCurve->LastParameter() - myCurve->FirstParameter(); } +//======================================================================= +//function : RebuildCache +//purpose : +//======================================================================= +void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const +{ + myCurveCache->BuildCache(theParameter, myBspl->Degree(), + myBspl->IsPeriodic(), myBspl->KnotSequence(), + myBspl->Poles(), myBspl->Weights()); +} + //======================================================================= //function : Value //purpose : @@ -532,24 +564,65 @@ Standard_Real Geom2dAdaptor_Curve::Period() const gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + return ValueBSpline(U); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + return ValueOffset(U); + + return myCurve->Value(U); +} + +//======================================================================= +//function : ValueBSpline +//purpose : Computes the point of parameter U on the B-spline curve +//======================================================================= +gp_Pnt2d Geom2dAdaptor_Curve::ValueBSpline(const Standard_Real theU) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) + { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) + { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - return myBspl->LocalValue(U, Ideb, Ifin); + return myBspl->LocalValue(theU, Ideb, Ifin); } - else { - return myCurve->Value( U); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + gp_Pnt2d aRes; + myCurveCache->D0(theU, aRes); + return aRes; } + return myCurve->Value(theU); +} + +//======================================================================= +//function : ValueOffset +//purpose : Computes the point of parameter U on the offset curve +//======================================================================= +gp_Pnt2d Geom2dAdaptor_Curve::ValueOffset(const Standard_Real theU) const +{ + gp_Pnt2d aP; + gp_Vec2d aD1; + myOffsetBaseCurveAdaptor->D1(theU, aP, aD1); + Standard_Boolean isDirectionChange = Standard_False; + const Standard_Real aTol = gp::Resolution(); + if(aD1.SquareMagnitude() <= aTol) + isDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aD1); + + Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset(); + CSLib_Offset::D0(aP, aD1, anOffset, isDirectionChange, aP); + return aP; } //======================================================================= @@ -559,24 +632,59 @@ gp_Pnt2d Geom2dAdaptor_Curve::Value(const Standard_Real U) const void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + { + D0BSpline(U, P); + return; + } + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + { + D0Offset(U, P); + return; + } + + myCurve->D0(U, P); +} + +//======================================================================= +//function : D0BSpline +//purpose : Computes the point of parameter theU on the B-spline curve +//======================================================================= +void Geom2dAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt2d& theP) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD0( U, Ideb, Ifin, P); + myBspl->LocalD0(theU, Ideb, Ifin, theP); + return; } - else { - myCurve->D0(U, P); - } + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D0(theU, theP); + return; + } + myCurve->D0(theU, theP); +} + +//======================================================================= +//function : D0Offset +//purpose : Computes the point of parameter theU on the offset curve +//======================================================================= +void Geom2dAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt2d& theP) const +{ + theP = ValueOffset(theU); } //======================================================================= @@ -584,27 +692,75 @@ void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const //purpose : //======================================================================= -void Geom2dAdaptor_Curve::D1(const Standard_Real U, - gp_Pnt2d& P, gp_Vec2d& V) const +void Geom2dAdaptor_Curve::D1(const Standard_Real U, + gp_Pnt2d& P, gp_Vec2d& V) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + { + D1BSpline(U, P, V); + return; + } + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + { + D1Offset(U, P, V); + return; + } + + myCurve->D1(U, P, V); +} + +//======================================================================= +//function : D1BSpline +//purpose : Computes the point of parameter theU on the B-spline curve and its derivative +//======================================================================= +void Geom2dAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD1( U, Ideb, Ifin, P, V); - } - else { - myCurve->D1( U, P, V); + myBspl->LocalD1(theU, Ideb, Ifin, theP, theV); + return; } + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D1(theU, theP, theV); + return; + } + myCurve->D1(theU, theP, theV); +} + +//======================================================================= +//function : D1Offset +//purpose : Computes the point of parameter theU on the offset curve and its derivative +//======================================================================= +void Geom2dAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt2d& theP, gp_Vec2d& theV) const +{ + // P(u) = p(u) + Offset * Ndir / R + // with R = || p' ^ Z|| and Ndir = P' ^ Z + + // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R)) + + gp_Vec2d V2; + myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, V2); + + Standard_Boolean IsDirectionChange = Standard_False; + if(theV.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, V2); + + Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset(); + CSLib_Offset::D1(theP, theV, V2, anOffset, IsDirectionChange, theP, theV); } //======================================================================= @@ -613,26 +769,78 @@ void Geom2dAdaptor_Curve::D1(const Standard_Real U, //======================================================================= void Geom2dAdaptor_Curve::D2(const Standard_Real U, - gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const + gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + { + D2BSpline(U, P, V1, V2); + return; + } + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + { + D2Offset(U, P, V1, V2); + return; + } + + myCurve->D2(U, P, V1, V2); +} + +//======================================================================= +//function : D2BSpline +//purpose : Computes the point of parameter theU on the B-spline curve and its first and second derivatives +//======================================================================= +void Geom2dAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt2d& theP, + gp_Vec2d& theV1, gp_Vec2d& theV2) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2); + myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2); + return; } - else { - myCurve->D2( U, P, V1, V2); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D2(theU, theP, theV1, theV2); + return; } + myCurve->D2(theU, theP, theV1, theV2); +} +//======================================================================= +//function : D2Offset +//purpose : Computes the point of parameter theU on the offset curve and its first and second derivatives +//======================================================================= +void Geom2dAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt2d& theP, + gp_Vec2d& theV1, gp_Vec2d& theV2) const +{ + // P(u) = p(u) + Offset * Ndir / R + // with R = || p' ^ Z|| and Ndir = P' ^ Z + + // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R)) + + // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) + + // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2))) + + gp_Vec2d V3; + myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3); + + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3); + + Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset(); + CSLib_Offset::D2(theP, theV1, theV2, V3, anOffset, IsDirectionChange, theP, theV1, theV2); } //======================================================================= @@ -641,27 +849,86 @@ void Geom2dAdaptor_Curve::D2(const Standard_Real U, //======================================================================= void Geom2dAdaptor_Curve::D3(const Standard_Real U, - gp_Pnt2d& P, gp_Vec2d& V1, - gp_Vec2d& V2, gp_Vec2d& V3) const + gp_Pnt2d& P, gp_Vec2d& V1, + gp_Vec2d& V2, gp_Vec2d& V3) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve) && - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + { + D3BSpline(U, P, V1, V2, V3); + return; + } + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + { + D3Offset(U, P, V1, V2, V3); + return; + } + + myCurve->D3(U, P, V1, V2, V3); +} + +//======================================================================= +//function : D3BSpline +//purpose : Computes the point of parameter theU on the B-spline curve and its 1st - 3rd derivatives +//======================================================================= +void Geom2dAdaptor_Curve::D3BSpline(const Standard_Real theU, gp_Pnt2d& theP, + gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3); + myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3); + return; } - else { - myCurve->D3( U, P, V1, V2, V3); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D3(theU, theP, theV1, theV2, theV3); + return; } + myCurve->D3(theU, theP, theV1, theV2, theV3); +} +//======================================================================= +//function : D3Offset +//purpose : Computes the point of parameter theU on the offset curve and its 1st - 3rd derivatives +//======================================================================= +void Geom2dAdaptor_Curve::D3Offset(const Standard_Real theU, gp_Pnt2d& theP, + gp_Vec2d& theV1, gp_Vec2d& theV2, gp_Vec2d& theV3) const +{ + // P(u) = p(u) + Offset * Ndir / R + // with R = || p' ^ Z|| and Ndir = P' ^ Z + + // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R)) + + // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) + + // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2))) + + //P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir - + // (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir - + // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir + + // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir + + Standard_Boolean IsDirectionChange = Standard_False; + + myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3); + gp_Vec2d V4 = myOffsetBaseCurveAdaptor->DN (theU, 4); + + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4); + + Standard_Real anOffset = Handle(Geom2d_OffsetCurve)::DownCast(myCurve)->Offset(); + CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffset, IsDirectionChange, + theP, theV1, theV2, theV3); } //======================================================================= @@ -670,10 +937,21 @@ void Geom2dAdaptor_Curve::D3(const Standard_Real U, //======================================================================= gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, - const Standard_Integer N) const + const Standard_Integer N) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve) && - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + return DNBSpline(U, N); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) + return DNOffset(U, N); + + return myCurve->DN(U, N); +} + +gp_Vec2d Geom2dAdaptor_Curve::DNBSpline(const Standard_Real U, + const Standard_Integer N) const +{ + if (U==myFirst || U==myLast) + { Standard_Integer Ideb = 0, Ifin = 0; if (U==myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); @@ -686,10 +964,32 @@ gp_Vec2d Geom2dAdaptor_Curve::DN(const Standard_Real U, if (Ideb>=Ifin) Ideb = Ifin-1; } return myBspl->LocalDN( U, Ideb, Ifin, N); - } - else { - return myCurve->DN( U, N); } + + return myCurve->DN( U, N); +} + +gp_Vec2d Geom2dAdaptor_Curve::DNOffset(const Standard_Real U, + const Standard_Integer N) const +{ + gp_Pnt2d aPnt; + gp_Vec2d aVec, aVN; + + switch (N) + { + case 1: + D1Offset(U, aPnt, aVN); + break; + case 2: + D2Offset(U, aPnt, aVec, aVN); + break; + case 3: + D3Offset(U, aPnt, aVec, aVec, aVN); + break; + default: + aVN = myCurve->DN(U, N); + } + return aVN; } //======================================================================= @@ -906,3 +1206,57 @@ Standard_Integer Geom2dAdaptor_Curve::NbSamples() const { return nbPoints(myCurve); } + + +// ============= Auxiliary functions =================== +Standard_Boolean AdjustDerivative(const Handle(Adaptor2d_HCurve2d)& theAdaptor, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec2d& theD1, gp_Vec2d& theD2, + gp_Vec2d& theD3, gp_Vec2d& theD4) +{ + static const Standard_Real aTol = gp::Resolution(); + + Standard_Boolean IsDirectionChange = Standard_False; + const Standard_Real anUinfium = theAdaptor->FirstParameter(); + const Standard_Real anUsupremum = theAdaptor->LastParameter(); + + const Standard_Real DivisionFactor = 1.e-3; + Standard_Real du; + if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) + du = 0.0; + else + du = anUsupremum - anUinfium; + + const Standard_Real aDelta = Max(du * DivisionFactor, MinStep); + + //Derivative is approximated by Taylor-series + Standard_Integer anIndex = 1; //Derivative order + gp_Vec2d V; + + do + { + V = theAdaptor->DN(theU, ++anIndex); + } + while((V.Magnitude() <= aTol) && anIndex < maxDerivOrder); + + Standard_Real u; + + if(theU-anUinfium < aDelta) + u = theU+aDelta; + else + u = theU-aDelta; + + gp_Pnt2d P1, P2; + theAdaptor->D0(Min(theU, u),P1); + theAdaptor->D0(Max(theU, u),P2); + + gp_Vec2d V1(P1, P2); + IsDirectionChange = V.Dot(V1) < 0.0; + Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0; + + theD1 = V * aSign; + gp_Vec2d* aDeriv[3] = {&theD2, &theD3, &theD4}; + for (Standard_Integer i = 1; i < theMaxDerivative; i++) + *(aDeriv[i-1]) = theAdaptor->DN(theU, anIndex + i) * aSign; + + return IsDirectionChange; +} diff --git a/src/GeomAdaptor/GeomAdaptor.cdl b/src/GeomAdaptor/GeomAdaptor.cdl index 55008f583d..bda2d10161 100644 --- a/src/GeomAdaptor/GeomAdaptor.cdl +++ b/src/GeomAdaptor/GeomAdaptor.cdl @@ -28,7 +28,9 @@ uses TColStd, Geom2dAdaptor, TColgp, - Precision + Precision, + BSplCLib, + BSplSLib is class Curve; diff --git a/src/GeomAdaptor/GeomAdaptor_Curve.cdl b/src/GeomAdaptor/GeomAdaptor_Curve.cdl index c2863744ed..626669d0cd 100644 --- a/src/GeomAdaptor/GeomAdaptor_Curve.cdl +++ b/src/GeomAdaptor/GeomAdaptor_Curve.cdl @@ -33,7 +33,8 @@ uses Vec from gp, BSplineCurve from Geom, CurveType from GeomAbs, Shape from GeomAbs, - HCurve from Adaptor3d + HCurve from Adaptor3d, + Cache from BSplCLib raises NoSuchObject from Standard, ConstructionError from Standard, @@ -129,10 +130,26 @@ is --- Purpose : Computes the point of parameter U on the curve is redefined static; + ValueBSpline(me; U: Real) returns Pnt from gp + --- Purpose : Computes the point of parameter U on the B-spline curve + is private; + + ValueOffset(me; U: Real) returns Pnt from gp + --- Purpose : Computes the point of parameter U on the offset curve + is private; + D0 (me; U : Real; P : out Pnt from gp) --- Purpose : Computes the point of parameter U. is redefined static; + D0BSpline(me; theU : Real; theP : out Pnt from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + is private; + + D0Offset(me; theU : Real; theP : out Pnt from gp) + --- Purpose : Computes the point of parameter U on the offset curve + is private; + D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp) --- Purpose : Computes the point of parameter U on the curve -- with its first derivative. @@ -142,6 +159,16 @@ is -- derivatives are computed on the current interval. -- else the derivatives are computed on the basis curve. is redefined static; + + D1BSpline(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its derivative + is private; + + D1Offset(me; theU : Real; theP : out Pnt from gp ; theV : out Vec from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its derivative + is private; D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp) --- Purpose : @@ -154,6 +181,16 @@ is -- else the derivatives are computed on the basis curve. is redefined static; + D2BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its first and second derivatives + is private; + + D2Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2 : out Vec from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its first and second derivatives + is private; + D3 (me; U : Real; P : out Pnt from gp; V1, V2, V3 : out Vec from gp) --- Purpose : -- Returns the point P of parameter U, the first, the second @@ -164,6 +201,16 @@ is -- derivatives are computed on the current interval. -- else the derivatives are computed on the basis curve. is redefined static; + + D3BSpline(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp) + --- Purpose : Computes the point of parameter U on the B-spline curve + -- and its first, second and third derivatives + is private; + + D3Offset(me; theU : Real; theP : out Pnt from gp; theV1, theV2, theV3 : out Vec from gp) + --- Purpose : Computes the point of parameter U on the offset curve + -- and its first, second and third derivatives + is private; DN (me; U : Real; N : Integer) returns Vec from gp --- Purpose : @@ -179,6 +226,19 @@ is is redefined static; + DNBSpline(me; theU : Real; N : Integer) returns Vec from gp + --- Purpose : + -- The returned vector gives the value of the derivative for the + -- order of derivation N. + is private; + + DNOffset(me; theU : Real; N : Integer) returns Vec from gp + --- Purpose : + -- The returned vector gives the value of the derivative for the + -- order of derivation N. + is private; + + Resolution(me; R3d :Real) returns Real ---Purpose : returns the parametric resolution is redefined static; @@ -279,6 +339,11 @@ is load(me : in out; C : Curve from Geom; UFirst,ULast : Real) is private; + + RebuildCache(me; theParameter : Real) + ---Purpose: Rebuilds B-spline cache + -- \param theParameter the value on the knot axis which identifies the caching span + is static private; fields @@ -286,6 +351,8 @@ fields myTypeCurve : CurveType from GeomAbs ; myFirst : Real from Standard ; myLast : Real from Standard; + myCurveCache : Cache from BSplCLib; + myOffsetBaseCurveAdaptor : HCurve from Adaptor3d; friends class Surface from GeomAdaptor diff --git a/src/GeomAdaptor/GeomAdaptor_Curve.cxx b/src/GeomAdaptor/GeomAdaptor_Curve.cxx index 05c471f88d..5f9ea8d453 100644 --- a/src/GeomAdaptor/GeomAdaptor_Curve.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Curve.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -48,10 +49,22 @@ #include #include #include +#include #define myBspl (*((Handle(Geom_BSplineCurve)*)&myCurve)) #define PosTol Precision::PConfusion()/2 +static const int maxDerivOrder = 3; +static const Standard_Real MinStep = 1e-7; + +static gp_Vec dummyDerivative; // used as empty value for unused derivatives in AdjustDerivative +// Recalculate derivatives in the singular point +// Returns true if the direction of derivatives is changed +static Standard_Boolean AdjustDerivative( + const Handle(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative, Standard_Real theU, gp_Vec& theD1, + gp_Vec& theD2 = dummyDerivative, gp_Vec& theD3 = dummyDerivative, gp_Vec& theD4 = dummyDerivative); + + //======================================================================= //function : LocalContinuity //purpose : Computes the Continuity of a BSplineCurve @@ -155,6 +168,15 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C, } else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) { myTypeCurve = GeomAbs_BSplineCurve; + // Create cache for B-spline + myCurveCache = new BSplCLib_Cache(myBspl->Degree(), myBspl->IsPeriodic(), + myBspl->KnotSequence(), myBspl->Poles(), myBspl->Weights()); + } + else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) { + myTypeCurve = GeomAbs_OtherCurve; + // Create nested adaptor for base curve + Handle(Geom_Curve) aBase = Handle(Geom_OffsetCurve)::DownCast(myCurve)->BasisCurve(); + myOffsetBaseCurveAdaptor = new GeomAdaptor_HCurve(aBase); } else { myTypeCurve = GeomAbs_OtherCurve; @@ -510,6 +532,17 @@ Standard_Real GeomAdaptor_Curve::Period() const return myCurve->LastParameter() - myCurve->FirstParameter(); } +//======================================================================= +//function : RebuildCache +//purpose : +//======================================================================= +void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const +{ + myCurveCache->BuildCache(theParameter, myBspl->Degree(), + myBspl->IsPeriodic(), myBspl->KnotSequence(), + myBspl->Poles(), myBspl->Weights()); +} + //======================================================================= //function : Value //purpose : @@ -517,22 +550,64 @@ Standard_Real GeomAdaptor_Curve::Period() const gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + return ValueBSpline(U); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + return ValueOffset(U); + return myCurve->Value(U); +} + +//======================================================================= +//function : ValueBSpline +//purpose : +//======================================================================= +gp_Pnt GeomAdaptor_Curve::ValueBSpline(const Standard_Real theU) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - return myBspl->LocalValue(U, Ideb, Ifin); + return myBspl->LocalValue(theU, Ideb, Ifin); } - return myCurve->Value(U); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + gp_Pnt aRes; + myCurveCache->D0(theU, aRes); + return aRes; + } + return myCurve->Value(theU); +} + +//======================================================================= +//function : ValueOffset +//purpose : +//======================================================================= +gp_Pnt GeomAdaptor_Curve::ValueOffset(const Standard_Real theU) const +{ + gp_Pnt aP; + gp_Vec aV; + myOffsetBaseCurveAdaptor->D1(theU, aP, aV); + Standard_Boolean IsDirectionChange = Standard_False; + if(aV.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 1, theU, aV); + + Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve); + Standard_Real anOffsetVal = anOffC->Offset(); + const gp_Dir& anOffsetDir = anOffC->Direction(); + + CSLib_Offset::D0(aP, aV, anOffsetDir, anOffsetVal, IsDirectionChange, aP); + return aP; } //======================================================================= @@ -542,24 +617,53 @@ gp_Pnt GeomAdaptor_Curve::Value(const Standard_Real U) const void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + D0BSpline(U, P); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + D0Offset(U, P); + else + myCurve->D0(U, P); +} + +//======================================================================= +//function : D0BSpline +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D0BSpline(const Standard_Real theU, gp_Pnt& theP) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD0( U, Ideb, Ifin, P); + myBspl->LocalD0(theU, Ideb, Ifin, theP); + return; } - else { - myCurve->D0(U, P); - } + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D0(theU, theP); + return; + } + myCurve->D0(theU, theP); +} + +//======================================================================= +//function : D0Offset +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D0Offset(const Standard_Real theU, gp_Pnt& theP) const +{ + theP = ValueOffset(theU); } //======================================================================= @@ -569,52 +673,133 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + D1BSpline(U, P, V); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + D1Offset(U, P, V); + else + myCurve->D1(U, P, V); +} + +//======================================================================= +//function : D1BSpline +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D1BSpline(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD1( U, Ideb, Ifin, P, V); - } - else { - myCurve->D1( U, P, V); + myBspl->LocalD1(theU, Ideb, Ifin, theP, theV); + return; } + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D1(theU, theP, theV); + return; + } + myCurve->D1(theU, theP, theV); } +//======================================================================= +//function : D1Offset +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D1Offset(const Standard_Real theU, gp_Pnt& theP, gp_Vec& theV) const +{ + gp_Vec aV2; + myOffsetBaseCurveAdaptor->D2 (theU, theP, theV, aV2); + + Standard_Boolean IsDirectionChange = Standard_False; + if(theV.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 2, theU, theV, aV2); + + Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve); + Standard_Real anOffsetVal = anOffC->Offset(); + const gp_Dir& anOffsetDir = anOffC->Direction(); + CSLib_Offset::D1(theP, theV, aV2, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV); +} + + //======================================================================= //function : D2 //purpose : //======================================================================= void GeomAdaptor_Curve::D2(const Standard_Real U, - gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const + gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve)&& - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + D2BSpline(U, P, V1, V2); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + D2Offset(U, P, V1, V2); + else + myCurve->D2(U, P, V1, V2); +} + +//======================================================================= +//function : D2BSpline +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D2BSpline(const Standard_Real theU, gp_Pnt& theP, + gp_Vec& theV1, gp_Vec& theV2) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD2( U, Ideb, Ifin, P, V1, V2); + myBspl->LocalD2(theU, Ideb, Ifin, theP, theV1, theV2); + return; } - else { - myCurve->D2( U, P, V1, V2); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D2(theU, theP, theV1, theV2); + return; } + myCurve->D2(theU, theP, theV1, theV2); +} + +//======================================================================= +//function : D2Offset +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D2Offset(const Standard_Real theU, gp_Pnt& theP, + gp_Vec& theV1, gp_Vec& theV2) const +{ + gp_Vec V3; + myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, V3); + + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 3, theU, theV1, theV2, V3); + + Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve); + Standard_Real anOffsetVal = anOffC->Offset(); + const gp_Dir& anOffsetDir = anOffC->Direction(); + CSLib_Offset::D2(theP, theV1, theV2, V3, anOffsetDir, anOffsetVal, IsDirectionChange, theP, theV1, theV2); } //======================================================================= @@ -623,27 +808,71 @@ void GeomAdaptor_Curve::D2(const Standard_Real U, //======================================================================= void GeomAdaptor_Curve::D3(const Standard_Real U, - gp_Pnt& P, gp_Vec& V1, - gp_Vec& V2, gp_Vec& V3) const + gp_Pnt& P, gp_Vec& V1, + gp_Vec& V2, gp_Vec& V3) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve) && - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + D3BSpline(U, P, V1, V2, V3); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + D3Offset(U, P, V1, V2, V3); + else + myCurve->D3(U, P, V1, V2, V3); +} + +//======================================================================= +//function : D3BSpline +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D3BSpline(const Standard_Real theU, + gp_Pnt& theP, gp_Vec& theV1, + gp_Vec& theV2, gp_Vec& theV3) const +{ + if (theU == myFirst || theU == myLast) + { Standard_Integer Ideb = 0, Ifin = 0; - if (U==myFirst) { + if (theU == myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); if (Ideb<1) Ideb=1; if (Ideb>=Ifin) Ifin = Ideb+1; } - if (U==myLast) { + if (theU == myLast) { myBspl->LocateU(myLast, PosTol, Ideb, Ifin); if (Ifin>myBspl->NbKnots()) Ifin = myBspl->NbKnots(); if (Ideb>=Ifin) Ideb = Ifin-1; } - myBspl->LocalD3( U, Ideb, Ifin, P, V1, V2, V3); + myBspl->LocalD3(theU, Ideb, Ifin, theP, theV1, theV2, theV3); + return; } - else { - myCurve->D3( U, P, V1, V2, V3); + else if (!myCurveCache.IsNull()) // use cached B-spline data + { + if (!myCurveCache->IsCacheValid(theU)) + RebuildCache(theU); + myCurveCache->D3(theU, theP, theV1, theV2, theV3); + return; } + myCurve->D3(theU, theP, theV1, theV2, theV3); +} + +//======================================================================= +//function : D3Offset +//purpose : +//======================================================================= +void GeomAdaptor_Curve::D3Offset(const Standard_Real theU, + gp_Pnt& theP, gp_Vec& theV1, + gp_Vec& theV2, gp_Vec& theV3) const +{ + myOffsetBaseCurveAdaptor->D3 (theU, theP, theV1, theV2, theV3); + gp_Vec V4 = myOffsetBaseCurveAdaptor->DN(theU, 4); + + Standard_Boolean IsDirectionChange = Standard_False; + if(theV1.SquareMagnitude() <= gp::Resolution()) + IsDirectionChange = AdjustDerivative(myOffsetBaseCurveAdaptor, 4, theU, theV1, theV2, theV3, V4); + + Handle(Geom_OffsetCurve) anOffC = Handle(Geom_OffsetCurve)::DownCast(myCurve); + Standard_Real anOffsetVal = anOffC->Offset(); + const gp_Dir& anOffsetDir = anOffC->Direction(); + CSLib_Offset::D3(theP, theV1, theV2, theV3, V4, anOffsetDir, anOffsetVal, IsDirectionChange, + theP, theV1, theV2, theV3); } //======================================================================= @@ -652,10 +881,21 @@ void GeomAdaptor_Curve::D3(const Standard_Real U, //======================================================================= gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U, - const Standard_Integer N) const + const Standard_Integer N) const { - if ( (myTypeCurve == GeomAbs_BSplineCurve) && - (U==myFirst || U==myLast) ) { + if (myTypeCurve == GeomAbs_BSplineCurve) + return DNBSpline(U, N); + else if (myCurve->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) + return DNOffset(U, N); + + return myCurve->DN(U, N); +} + +gp_Vec GeomAdaptor_Curve::DNBSpline(const Standard_Real U, + const Standard_Integer N) const +{ + if ((U==myFirst || U==myLast)) + { Standard_Integer Ideb = 0, Ifin = 0; if (U==myFirst) { myBspl->LocateU(myFirst, PosTol, Ideb, Ifin); @@ -668,10 +908,31 @@ gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U, if (Ideb>=Ifin) Ideb = Ifin-1; } return myBspl->LocalDN( U, Ideb, Ifin, N); - } - else { - return myCurve->DN( U, N); } + return myCurve->DN( U, N); +} + +gp_Vec GeomAdaptor_Curve::DNOffset(const Standard_Real U, + const Standard_Integer N) const +{ + gp_Pnt aPnt; + gp_Vec aVec, aVN; + + switch (N) + { + case 1: + D1Offset(U, aPnt, aVN); + break; + case 2: + D2Offset(U, aPnt, aVec, aVN); + break; + case 3: + D3Offset(U, aPnt, aVec, aVec, aVN); + break; + default: + aVN = myCurve->DN(U, N); + } + return aVN; } //======================================================================= @@ -857,3 +1118,56 @@ Handle(Geom_BSplineCurve) GeomAdaptor_Curve::BSpline() const return *((Handle(Geom_BSplineCurve)*)&myCurve); } + +// ============= Auxiliary functions =================== +Standard_Boolean AdjustDerivative(const Handle(Adaptor3d_HCurve)& theAdaptor, Standard_Integer theMaxDerivative, + Standard_Real theU, gp_Vec& theD1, gp_Vec& theD2, + gp_Vec& theD3, gp_Vec& theD4) +{ + static const Standard_Real aTol = gp::Resolution(); + + Standard_Boolean IsDirectionChange = Standard_False; + const Standard_Real anUinfium = theAdaptor->FirstParameter(); + const Standard_Real anUsupremum = theAdaptor->LastParameter(); + + const Standard_Real DivisionFactor = 1.e-3; + Standard_Real du; + if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst())) + du = 0.0; + else + du = anUsupremum - anUinfium; + + const Standard_Real aDelta = Max(du * DivisionFactor, MinStep); + + //Derivative is approximated by Taylor-series + Standard_Integer anIndex = 1; //Derivative order + gp_Vec V; + + do + { + V = theAdaptor->DN(theU, ++anIndex); + } + while((V.SquareMagnitude() <= aTol) && anIndex < maxDerivOrder); + + Standard_Real u; + + if(theU-anUinfium < aDelta) + u = theU+aDelta; + else + u = theU-aDelta; + + gp_Pnt P1, P2; + theAdaptor->D0(Min(theU, u), P1); + theAdaptor->D0(Max(theU, u), P2); + + gp_Vec V1(P1, P2); + IsDirectionChange = V.Dot(V1) < 0.0; + Standard_Real aSign = IsDirectionChange ? -1.0 : 1.0; + + theD1 = V * aSign; + gp_Vec* aDeriv[3] = {&theD2, &theD3, &theD4}; + for (Standard_Integer i = 1; i < theMaxDerivative; i++) + *(aDeriv[i-1]) = theAdaptor->DN(theU, anIndex + i) * aSign; + + return IsDirectionChange; +} diff --git a/src/GeomAdaptor/GeomAdaptor_Surface.cdl b/src/GeomAdaptor/GeomAdaptor_Surface.cdl index 8742473a41..8c02eec856 100644 --- a/src/GeomAdaptor/GeomAdaptor_Surface.cdl +++ b/src/GeomAdaptor/GeomAdaptor_Surface.cdl @@ -38,7 +38,8 @@ uses Shape from GeomAbs, Curve from GeomAdaptor, HCurve from Adaptor3d, - HSurface from Adaptor3d + HSurface from Adaptor3d, + Cache from BSplSLib raises NoSuchObject from Standard, @@ -386,6 +387,12 @@ is TolV : Real = 0.0) is private; + RebuildCache(me; theU, theV : Real) + ---Purpose: Rebuilds B-spline cache + -- \param theU first parameter to identify the span for caching + -- \param theV second parameter to identify the span for caching + is static private; + fields mySurface : Surface from Geom; @@ -395,5 +402,6 @@ fields myVFirst : Real from Standard; myVLast : Real from Standard; myTolU, myTolV : Real from Standard; + mySurfaceCache : Cache from BSplSLib; end Surface; diff --git a/src/GeomAdaptor/GeomAdaptor_Surface.cxx b/src/GeomAdaptor/GeomAdaptor_Surface.cxx index 8e251fc07d..ee4e2d6cd7 100644 --- a/src/GeomAdaptor/GeomAdaptor_Surface.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Surface.cxx @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -131,7 +132,7 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, mySurfaceType = GeomAbs_BezierSurface; else if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { Load((*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface(), - UFirst,ULast,VFirst,VLast); + UFirst,ULast,VFirst,VLast); } else if ( TheType == STANDARD_TYPE(Geom_Plane)) mySurfaceType = GeomAbs_Plane; @@ -149,7 +150,12 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, mySurfaceType = GeomAbs_SurfaceOfExtrusion; else if ( TheType == STANDARD_TYPE(Geom_BSplineSurface)) { mySurfaceType = GeomAbs_BSplineSurface; - myBspl = *((Handle(Geom_BSplineSurface)*)&S); + myBspl = *((Handle(Geom_BSplineSurface)*)&mySurface); + // Create cache for B-spline + mySurfaceCache = new BSplSLib_Cache( + myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), + myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), + myBspl->Poles(), myBspl->Weights()); } else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface)) mySurfaceType = GeomAbs_OffsetSurface; @@ -599,6 +605,19 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const return mySurface->VPeriod(); } +//======================================================================= +//function : RebuildCache +//purpose : +//======================================================================= +void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU, + const Standard_Real theV) const +{ + mySurfaceCache->BuildCache(theU, theV, + myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), + myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), + myBspl->Poles(), myBspl->Weights()); +} + //======================================================================= //function : Value //purpose : @@ -607,6 +626,15 @@ Standard_Real GeomAdaptor_Surface::VPeriod() const gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U, const Standard_Real V) const { + if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull()) + { + if (!mySurfaceCache->IsCacheValid(U, V)) + RebuildCache(U, V); + gp_Pnt P; + mySurfaceCache->D0(U, V, P); + return P; + } + return mySurface->Value(U,V); } @@ -618,6 +646,14 @@ gp_Pnt GeomAdaptor_Surface::Value(const Standard_Real U, void GeomAdaptor_Surface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const { + if (mySurfaceType == GeomAbs_BSplineSurface && !mySurfaceCache.IsNull()) + { + if (!mySurfaceCache->IsCacheValid(U, V)) + RebuildCache(U, V); + mySurfaceCache->D0(U, V, P); + return; + } + mySurface->D0(U,V,P); } @@ -629,11 +665,11 @@ void GeomAdaptor_Surface::D0(const Standard_Real U, void GeomAdaptor_Surface::D1(const Standard_Real U, const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V ) const + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V ) const { - Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0; + Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} @@ -641,39 +677,42 @@ void GeomAdaptor_Surface::D1(const Standard_Real U, else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} switch(mySurfaceType) { - case GeomAbs_BSplineSurface: - { - if((USide==0)&&(VSide==0)){ - myBspl->D1(u,v,P,D1U,D1V); - } - else { - if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide)) - myBspl->LocalD1 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V); - else myBspl->D1(u,v,P,D1U,D1V); - } - break; + case GeomAbs_BSplineSurface: + if ((USide != 0 || VSide != 0) && + IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) + myBspl->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V); + else if (!mySurfaceCache.IsNull()) + { + if (!mySurfaceCache->IsCacheValid(U, V)) + RebuildCache(U, V); + mySurfaceCache->D1(U, V, P, D1U, D1V); } - - case GeomAbs_SurfaceOfExtrusion : - - if(USide==0) myExtSurf->D1(u,v,P,D1U,D1V); - else myExtSurf->LocalD1(u,v,USide,P,D1U,D1V); - break; - - case GeomAbs_SurfaceOfRevolution : - - if(VSide==0) myRevSurf->D1 (u, v, P,D1U,D1V ); - else myRevSurf->LocalD1 (u, v, VSide, P,D1U,D1V ); - break; - - case GeomAbs_OffsetSurface : - { - if((USide==0)&&(VSide==0)) myOffSurf->D1 (u, v,P,D1U,D1V ); - else myOffSurf->LocalD1 (u, v, USide, VSide ,P,D1U,D1V ); - break; - } - default : - mySurface->D1(u,v,P,D1U,D1V); + else + myBspl->D1(u, v, P, D1U, D1V); + break; + + case GeomAbs_SurfaceOfExtrusion: + if (USide==0) + myExtSurf->D1(u, v, P, D1U, D1V); + else + myExtSurf->LocalD1(u, v, USide, P, D1U, D1V); + break; + + case GeomAbs_SurfaceOfRevolution: + if (VSide==0) + myRevSurf->D1(u, v, P, D1U, D1V); + else + myRevSurf->LocalD1(u, v, VSide, P, D1U, D1V); + break; + + case GeomAbs_OffsetSurface: + if (USide==0 && VSide==0) + myOffSurf->D1(u, v, P, D1U, D1V); + else + myOffSurf->LocalD1(u, v, USide, VSide, P, D1U, D1V); + break; + default: + mySurface->D1(u, v, P, D1U, D1V); } } @@ -683,50 +722,56 @@ void GeomAdaptor_Surface::D1(const Standard_Real U, //======================================================================= void GeomAdaptor_Surface::D2(const Standard_Real U, - const Standard_Real V, gp_Pnt& P, - gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, - gp_Vec& D2V, gp_Vec& D2UV) const + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV) const { - Standard_Integer Ideb,Ifin,IVdeb,IVfin,USide=0,VSide=0; + Standard_Integer Ideb, Ifin, IVdeb, IVfin, USide=0, VSide=0; Standard_Real u = U, v = V; if (Abs(U-myUFirst) <= myTolU) {USide= 1; u = myUFirst;} else if (Abs(U-myULast) <= myTolU) {USide= -1; u = myULast;} if (Abs(V-myVFirst) <= myTolV) {VSide= 1; v = myVFirst;} else if (Abs(V-myVLast) <= myTolV) {VSide= -1; v = myVLast;} - switch(mySurfaceType) + switch(mySurfaceType) { + case GeomAbs_BSplineSurface: + if((USide != 0 || VSide != 0) && + IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) + myBspl->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV); + else if (!mySurfaceCache.IsNull()) { - case GeomAbs_BSplineSurface: - - if((USide==0)&&(VSide==0)) myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); - else{ - if(IfUVBound(u,v,Ideb,Ifin,IVdeb,IVfin,USide,VSide)) - myBspl->LocalD2 (u, v, Ideb, Ifin,IVdeb ,IVfin ,P ,D1U,D1V,D2U,D2V,D2UV); - else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); - } - break; - - case GeomAbs_SurfaceOfExtrusion : - - if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); - else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV); - break; - - case GeomAbs_SurfaceOfRevolution : - - if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV ); - else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV ); - break; - - case GeomAbs_OffsetSurface : - { - if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV ); - else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV ); - break; - } - default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); - break;} + if (!mySurfaceCache->IsCacheValid(U, V)) + RebuildCache(U, V); + mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); } + else myBspl->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); + break; + + case GeomAbs_SurfaceOfExtrusion : + + if(USide==0) myExtSurf->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); + else myExtSurf->LocalD2(u,v,USide,P,D1U,D1V,D2U,D2V,D2UV); + break; + + case GeomAbs_SurfaceOfRevolution : + + if(VSide==0) myRevSurf->D2 (u, v, P,D1U,D1V,D2U,D2V,D2UV ); + else myRevSurf->LocalD2 (u, v, VSide, P,D1U,D1V,D2U,D2V,D2UV ); + break; + + case GeomAbs_OffsetSurface : + { + if((USide==0)&&(VSide==0)) myOffSurf->D2 (u, v,P,D1U,D1V,D2U,D2V,D2UV ); + else myOffSurf->LocalD2 (u, v, USide, VSide ,P,D1U,D1V,D2U,D2V,D2UV ); + break; + } + default : { mySurface->D2(u,v,P,D1U,D1V,D2U,D2V,D2UV); + break;} + } } diff --git a/src/GeomInt/GeomInt_IntSS_1.cxx b/src/GeomInt/GeomInt_IntSS_1.cxx index c6a164b9f9..90b8db746e 100644 --- a/src/GeomInt/GeomInt_IntSS_1.cxx +++ b/src/GeomInt/GeomInt_IntSS_1.cxx @@ -958,13 +958,19 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index, Standard_Real aDist = Max(BS->StartPoint().XYZ().SquareModulus(), BS->EndPoint().XYZ().SquareModulus()); Standard_Real eps = Epsilon(aDist); - if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps && - !BS->IsClosed() && !BS->IsPeriodic()) + if(BS->StartPoint().SquareDistance(BS->EndPoint()) < 2.*eps) { - //force Closed() - gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.); - BS->SetPole(1, aPm); - BS->SetPole(BS->NbPoles(), aPm); + // Avoid creating B-splines containing two coincident poles only + if (mbspc.Degree() == 1 && nbpoles == 2) + continue; + + if (!BS->IsClosed() && !BS->IsPeriodic()) + { + //force Closed() + gp_Pnt aPm((BS->Pole(1).XYZ() + BS->Pole(BS->NbPoles()).XYZ()) / 2.); + BS->SetPole(1, aPm); + BS->SetPole(BS->NbPoles(), aPm); + } } sline.Append(BS); diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx index c504dbc0ed..41d00b2327 100644 --- a/src/GeomLib/GeomLib.cxx +++ b/src/GeomLib/GeomLib.cxx @@ -1705,6 +1705,8 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface, NewP(ii,jj).SetCoord(3,PRes(indice+2)); if (rational) { ww = PRes(indice+3); + if (Abs(ww - 1.0) < EpsW) + ww = 1.0; if (ww < EpsW) { NullWeight = Standard_True; } @@ -1725,6 +1727,8 @@ void GeomLib::ExtendSurfByLength(Handle(Geom_BoundedSurface)& Surface, NewP(ii,jj).SetCoord(3,PRes(indice+2)); if (rational) { ww = PRes(indice+3); + if (Abs(ww - 1.0) < EpsW) + ww = 1.0; if (ww < EpsW) { NullWeight = Standard_True; } diff --git a/src/IntCurve/IntCurve_IntPolyPolyGen.gxx b/src/IntCurve/IntCurve_IntPolyPolyGen.gxx index e63dc3212d..31308b2463 100644 --- a/src/IntCurve/IntCurve_IntPolyPolyGen.gxx +++ b/src/IntCurve/IntCurve_IntPolyPolyGen.gxx @@ -679,20 +679,25 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1 aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol), aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol); - if( (aPoly1->DeflectionOverEstimation() > TolConf) || + if( (aPoly1->DeflectionOverEstimation() > TolConf) && (aPoly2->DeflectionOverEstimation() > TolConf)) { const Standard_Real aDeflectionSum = Max(aPoly1->DeflectionOverEstimation(), TolConf) + Max(aPoly2->DeflectionOverEstimation(), TolConf); - aPoly2->SetDeflectionOverEstimation(aDeflectionSum); - aPoly1->SetDeflectionOverEstimation(aDeflectionSum); - - const Bnd_Box2d aB1 = aPoly1->Bounding(), aB2 = aPoly2->Bounding(); - - aPoly1->ComputeWithBox(C1, aB2); - aPoly2->ComputeWithBox(C2, aB1); + if (nbsamplesOnC2 > nbsamplesOnC1) + { + aPoly2->ComputeWithBox(C2, aPoly1->Bounding()); + aPoly1->SetDeflectionOverEstimation(aDeflectionSum); + aPoly1->ComputeWithBox(C1, aPoly2->Bounding()); + } + else + { + aPoly1->ComputeWithBox(C1, aPoly2->Bounding()); + aPoly2->SetDeflectionOverEstimation(aDeflectionSum); + aPoly2->ComputeWithBox(C2, aPoly1->Bounding()); + } } //---------------------------------------------------------------------- diff --git a/src/IntPatch/IntPatch_ImpPrmIntersection.cxx b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx index 032031fbea..ddf71a7bc8 100644 --- a/src/IntPatch/IntPatch_ImpPrmIntersection.cxx +++ b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx @@ -569,7 +569,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur Standard_Real rvalf = Sign(1.,Valf(1)); for(Standard_Integer i = 2; i <= aNbSamples; ++i) { - D1->SamplePoint(i,s2d, s3d); + T->SamplePoint(i,s2d, s3d); UVap(1)=s2d.X(); UVap(2)=s2d.Y(); Func.Value(UVap,Valf); diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index af1f28bfdc..218a2d1453 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -1986,37 +1986,20 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1, const Standard_Real aTol = 1.0e-14; Handle(Geom_Surface) aS1, aS2; - switch(theASurf1->GetType()) - { - case GeomAbs_BezierSurface: - aS1 = theASurf1->Surface().Bezier(); - break; - case GeomAbs_BSplineSurface: - aS1 = theASurf1->Surface().BSpline(); - break; - default: - return Standard_True; - } - - switch(theASurf2->GetType()) - { - case GeomAbs_BezierSurface: - aS2 = theASurf2->Surface().Bezier(); - break; - case GeomAbs_BSplineSurface: - aS2 = theASurf2->Surface().BSpline(); - break; - default: - return Standard_True; - } + if (theASurf1->GetType() != GeomAbs_BezierSurface && + theASurf1->GetType() != GeomAbs_BSplineSurface) + return Standard_True; + if (theASurf2->GetType() != GeomAbs_BezierSurface && + theASurf2->GetType() != GeomAbs_BSplineSurface) + return Standard_True; Standard_Boolean aStatus = Standard_False; gp_Pnt aP1, aP2; gp_Vec aD1u, aD1v, aD2U, aD2V; - aS1->D1(theU1, theV1, aP1, aD1u, aD1v); - aS2->D1(theU2, theV2, aP2, aD2U, aD2V); + theASurf1->D1(theU1, theV1, aP1, aD1u, aD1v); + theASurf2->D1(theU2, theV2, aP2, aD2U, aD2V); Standard_Real aSQDistPrev = aP1.SquareDistance(aP2); @@ -2053,8 +2036,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1, gp_Pnt aPt1, aPt2; - aS1->D1(aPARu, aPARv, aPt1, aD1u, aD1v); - aS2->D1(aParU, aParV, aPt2, aD2U, aD2V); + theASurf1->D1(aPARu, aPARv, aPt1, aD1u, aD1v); + theASurf2->D1(aParU, aParV, aPt2, aD2U, aD2V); Standard_Real aSQDist = aPt1.SquareDistance(aPt2); @@ -2078,8 +2061,8 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1, } else { - aS1->D1(theU1, theV1, aPt1, aD1u, aD1v); - aS2->D1(theU2, theV2, aPt2, aD2U, aD2V); + theASurf1->D1(theU1, theV1, aPt1, aD1u, aD1v); + theASurf2->D1(theU2, theV2, aPt2, aD2U, aD2V); gp_Vec aP12(aPt1, aPt2); aGradFu = -aP12.Dot(aD1u); diff --git a/src/ShapeAnalysis/ShapeAnalysis_Curve.cxx b/src/ShapeAnalysis/ShapeAnalysis_Curve.cxx index 0d8b306e3d..72de391188 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Curve.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Curve.cxx @@ -122,10 +122,11 @@ Standard_Real ShapeAnalysis_Curve::Project(const Handle(Geom_Curve)& C3D, Standard_Real uMin = (cf < cl ? cf : cl); Standard_Real uMax = (cf < cl ? cl : cf); + GeomAdaptor_Curve GAC(C3D, uMin, uMax); if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end - gp_Pnt LowBound = C3D->Value(uMin); - gp_Pnt HigBound = C3D->Value(uMax); + gp_Pnt LowBound = GAC.Value(uMin); + gp_Pnt HigBound = GAC.Value(uMax); distmin = LowBound.Distance(P3D); if (distmin <= prec) { param = uMin; @@ -140,7 +141,6 @@ Standard_Real ShapeAnalysis_Curve::Project(const Handle(Geom_Curve)& C3D, } } - GeomAdaptor_Curve GAC(C3D, uMin, uMax); if (!C3D->IsClosed()) { //modified by rln on 16/12/97 after CSR# PRO11641 entity 20767 //the VIso was not closed (according to C3D->IsClosed()) while it "almost" @@ -403,10 +403,11 @@ Standard_Real ShapeAnalysis_Curve::NextProject(const Standard_Real paramPrev, Standard_Real uMin = (cf < cl ? cf : cl); Standard_Real uMax = (cf < cl ? cl : cf); Standard_Real distmin = Precision::Infinite(); + GeomAdaptor_Curve GAC(C3D, uMin, uMax); if (C3D->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) { Standard_Real prec = ( AdjustToEnds ? preci : Precision::Confusion() ); //:j8 abv 10 Dec 98: tr10_r0501_db.stp #9423: protection against densing of points near one end - gp_Pnt LowBound = C3D->Value(uMin); - gp_Pnt HigBound = C3D->Value(uMax); + gp_Pnt LowBound = GAC.Value(uMin); + gp_Pnt HigBound = GAC.Value(uMax); distmin = LowBound.Distance(P3D); if (distmin <= prec) { param = uMin; @@ -421,7 +422,6 @@ Standard_Real ShapeAnalysis_Curve::NextProject(const Standard_Real paramPrev, } } - GeomAdaptor_Curve GAC(C3D, uMin, uMax); if (!C3D->IsClosed()) { //modified by rln on 16/12/97 after CSR# PRO11641 entity 20767 //the VIso was not closed (according to C3D->IsClosed()) while it "almost" @@ -1017,11 +1017,13 @@ Standard_Boolean ShapeAnalysis_Curve::GetSamplePoints (const Handle(Geom_Curve)& Handle(Geom_TrimmedCurve) aC = Handle(Geom_TrimmedCurve)::DownCast(curve); return GetSamplePoints(aC->BasisCurve(),first,last,seq); } + + GeomAdaptor_Curve GAC(curve); Standard_Real step = ( last - first ) / (Standard_Real)( nbp - 1 ); Standard_Real par = first, stop = last - 0.5 * step; for ( ; par < stop; par += step ) - seq.Append(curve->Value(par)); - seq.Append(curve->Value(last)); + seq.Append(GAC.Value(par)); + seq.Append(GAC.Value(last)); return Standard_True; } //======================================================================= @@ -1043,8 +1045,8 @@ Standard_Boolean ShapeAnalysis_Curve::GetSamplePoints (const Handle(Geom2d_Curve Standard_Real step = ( last - first ) / (Standard_Real)( nbs - 1 ); Standard_Real par = first, stop = last - 0.5 * step; for ( ; par < stop; par += step ) - seq.Append(curve->Value(par)); - seq.Append(curve->Value(last)); + seq.Append(C.Value(par)); + seq.Append(C.Value(last)); return Standard_True; /* Standard_Integer i; diff --git a/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx b/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx index c342550067..264639cba6 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx @@ -1068,7 +1068,7 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated (const Standard_Integer nu // from 3d curve (but only if edge is SameParameter) static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge, const Handle(ShapeAnalysis_Surface) &surf, - const Handle(Geom2d_Curve) &Crv2d, + const Geom2dAdaptor_Curve &Crv2d, const Standard_Real param ) { if ( BRep_Tool::SameParameter ( edge ) ) { @@ -1078,7 +1078,8 @@ static gp_Pnt GetPointOnEdge ( const TopoDS_Edge &edge, if ( ! ConS.IsNull() ) return ConS->Value ( param ).Transformed ( L.Transformation() ); } - return surf->Value ( Crv2d->Value ( param ) ); + gp_Pnt2d aP2d = Crv2d.Value(param); + return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y()); } //======================================================================= @@ -1132,7 +1133,7 @@ Standard_Boolean ShapeAnalysis_Wire::CheckSelfIntersectingEdge (const Standard_I const IntRes2d_Transition &Tr2 = IP.TransitionOfSecond(); if ( Tr1.PositionOnCurve() != IntRes2d_Middle && Tr2.PositionOnCurve() != IntRes2d_Middle ) continue; - gp_Pnt pint = GetPointOnEdge ( edge, mySurf, Crv, IP.ParamOnFirst() ); + gp_Pnt pint = GetPointOnEdge ( edge, mySurf, AC, IP.ParamOnFirst() ); Standard_Real dist21 = pnt1.SquareDistance ( pint ); Standard_Real dist22 = pnt2.SquareDistance ( pint ); if ( dist21 > tol1 * tol1 && dist22 > tol2 * tol2 ) { @@ -1222,11 +1223,11 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges (const Standard_Inte Standard_Real tolint = 1.0e-10; //szv#4:S4163:12Mar99 warning - IntRes2d_Domain d1 ( Crv1->Value ( a1 ), a1, tolint, - Crv1->Value ( b1 ), b1, tolint ); - IntRes2d_Domain d2 ( Crv2->Value ( a2 ), a2, tolint, - Crv2->Value ( b2 ), b2, tolint ); Geom2dAdaptor_Curve C1 ( Crv1 ), C2 ( Crv2 ); + IntRes2d_Domain d1 ( C1.Value ( a1 ), a1, tolint, + C1.Value ( b1 ), b1, tolint ); + IntRes2d_Domain d2 ( C2.Value ( a2 ), a2, tolint, + C2.Value ( b2 ), b2, tolint ); //:64 abv 25 Dec 97: Attention! // Since Intersection algorithm is not symmetrical, for consistency with BRepCheck @@ -1282,8 +1283,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges (const Standard_Inte param2-b2 > ::Precision::PConfusion() ) continue; //:82 abv 21 Jan 98: point of intersection on Crv1 and Crv2 is different - gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) ); - gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) ); + gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) ); + gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 ); //:h0: thesurf.Value ( Crv2->Value ( param2 ) ); gp_Pnt pint = 0.5 * ( pi1.XYZ() + pi2.XYZ() ); Standard_Real di1 = pi1.SquareDistance ( pnt ); Standard_Real di2 = pi2.SquareDistance ( pnt ); @@ -1413,8 +1414,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges(const Standard_Integ Tr2.PositionOnCurve() != IntRes2d_Middle ) continue; Standard_Real param1 = IP.ParamOnFirst(); Standard_Real param2 = IP.ParamOnSecond(); - gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, Crv1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) ); - gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, Crv2, param2 ); + gp_Pnt pi1 = GetPointOnEdge ( edge1, mySurf, C1, param1 ); //:h0: thesurf.Value ( Crv1->Value ( param1 ) ); + gp_Pnt pi2 = GetPointOnEdge ( edge2, mySurf, C2, param2 ); Standard_Boolean OK1 = Standard_False; Standard_Boolean OK2 = Standard_False; @@ -1494,13 +1495,15 @@ Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num, myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); return Standard_False; } - c2d->D1 ( b, p2d1, v1 ); + Geom2dAdaptor_Curve anAdapt(c2d); + anAdapt.D1(b, p2d1, v1); if ( E1.Orientation() == TopAbs_REVERSED ) v1.Reverse(); if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) { myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); return Standard_False; } - c2d->D1 ( a, p2d2, v2 ); + anAdapt.Load(c2d); + anAdapt.D1(a, p2d2, v2); if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse(); v12 = p2d2.XY() - p2d1.XY(); myMax2d = v12.SquareMagnitude(); diff --git a/src/ShapeFix/ShapeFix_EdgeProjAux.cxx b/src/ShapeFix/ShapeFix_EdgeProjAux.cxx index b13e073832..644118bcba 100644 --- a/src/ShapeFix/ShapeFix_EdgeProjAux.cxx +++ b/src/ShapeFix/ShapeFix_EdgeProjAux.cxx @@ -426,7 +426,7 @@ void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci) Standard_Real wmid; sac.Project(COnS,mid,preci,pnt,wmid,Standard_False); wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period); - if(w1>w2) { + if(w1>=w2) { if(w2 > wmid) myFirstParam -= period; else if (w1 > wmid) UpdateParam2d(theCurve2d); diff --git a/src/ShapeFix/ShapeFix_Face.cxx b/src/ShapeFix/ShapeFix_Face.cxx index fa94e53884..acce19f1fd 100644 --- a/src/ShapeFix/ShapeFix_Face.cxx +++ b/src/ShapeFix/ShapeFix_Face.cxx @@ -1281,6 +1281,16 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap found = (staout != clas.Perform (unp1,Standard_False)); } } + // Additional check of diagonal steps for toroidal surfaces + if (!found && uclosed && vclosed) + { + for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0) + for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0) + { + unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY); + found = (staout != clas.Perform(unp1, Standard_False)); + } + } } if(found) { if(stb==TopAbs_IN) stb = TopAbs_OUT; diff --git a/src/ShapeFix/ShapeFix_IntersectionTool.cxx b/src/ShapeFix/ShapeFix_IntersectionTool.cxx index 7f366fd5ea..0145ef8f4b 100644 --- a/src/ShapeFix/ShapeFix_IntersectionTool.cxx +++ b/src/ShapeFix/ShapeFix_IntersectionTool.cxx @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -68,7 +70,7 @@ ShapeFix_IntersectionTool::ShapeFix_IntersectionTool(const Handle(ShapeBuild_ReS //======================================================================= static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge, const Handle(ShapeAnalysis_Surface) &surf, - const Handle(Geom2d_Curve) &Crv2d, + const Geom2dAdaptor_Curve &Crv2d, const Standard_Real param ) { if( BRep_Tool::SameParameter(edge) ) { @@ -78,7 +80,8 @@ static gp_Pnt GetPointOnEdge(const TopoDS_Edge &edge, if( !ConS.IsNull() ) return ConS->Value(param).Transformed(L.Transformation()); } - return surf->Value(Crv2d->Value(param)); + gp_Pnt2d aP2d = Crv2d.Value(param); + return surf->Adaptor3d()->Value(aP2d.X(), aP2d.Y()); } @@ -868,9 +871,9 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire if( !sae.PCurve(edge1, face, Crv1, a1, b1, Standard_False) ) return Standard_False; if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) return Standard_False; Standard_Real tolint = 1.0e-10; - IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint); - IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint); Geom2dAdaptor_Curve C1(Crv1), C2(Crv2); + IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint); + IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint); Geom2dInt_GInter Inter; Inter.Perform( C1, d1, C2, d2, tolint, tolint ); if(!Inter.IsDone()) continue; @@ -883,8 +886,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire Tr2.PositionOnCurve() == IntRes2d_Middle ) { Standard_Real param1 = IP.ParamOnFirst(); Standard_Real param2 = IP.ParamOnSecond(); - gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1); - gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2); + gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1); + gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2); BRep_Builder B; TopoDS_Vertex V; Standard_Real tolV=0; @@ -1023,10 +1026,10 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire IntRes2d_IntersectionPoint IPL = IS.LastPoint(); Standard_Real p12 = IPL.ParamOnFirst(); Standard_Real p22 = IPL.ParamOnSecond(); - gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11); - gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12); - gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21); - gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22); + gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11); + gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12); + gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21); + gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22); // next string commented by skl 29.12.2004 for OCC7624 //if( Pnt11.Distance(Pnt21)>myPreci || Pnt12.Distance(Pnt22)>myPreci ) continue; if( Pnt11.Distance(Pnt21)>MaxTolVert || Pnt12.Distance(Pnt22)>MaxTolVert ) continue; @@ -1155,8 +1158,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire if( !IsModified1 && !IsModified2 ) { Standard_Real param1 = (p11+p12)/2; Standard_Real param2 = (p21+p22)/2; - gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1); - gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2); + gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1); + gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2); gp_Pnt P0( (Pnt10.X()+Pnt20.X())/2, (Pnt10.Y()+Pnt20.Y())/2, (Pnt10.Z()+Pnt20.Z())/2 ); dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(P0)); @@ -1516,9 +1519,9 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires if( !sae.PCurve(edge2, face, Crv2, a2, b2, Standard_False) ) continue; //return Standard_False;gka 06.09.04 Standard_Real tolint = 1.0e-10; - IntRes2d_Domain d1(Crv1->Value(a1),a1,tolint,Crv1->Value(b1),b1,tolint); - IntRes2d_Domain d2(Crv2->Value(a2),a2,tolint,Crv2->Value(b2),b2,tolint); Geom2dAdaptor_Curve C1(Crv1), C2(Crv2); + IntRes2d_Domain d1(C1.Value(a1),a1,tolint,C1.Value(b1),b1,tolint); + IntRes2d_Domain d2(C2.Value(a2),a2,tolint,C2.Value(b2),b2,tolint); Geom2dInt_GInter Inter; Inter.Perform( C1, d1, C2, d2, tolint, tolint ); if(!Inter.IsDone()) continue; @@ -1532,8 +1535,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires // create new vertex and split both edges Standard_Real param1 = IP.ParamOnFirst(); Standard_Real param2 = IP.ParamOnSecond(); - gp_Pnt pi1 = GetPointOnEdge(edge1,sas,Crv1,param1); - gp_Pnt pi2 = GetPointOnEdge(edge2,sas,Crv2,param2); + gp_Pnt pi1 = GetPointOnEdge(edge1,sas,C1,param1); + gp_Pnt pi2 = GetPointOnEdge(edge2,sas,C2,param2); gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 ); BRep_Builder B; TopoDS_Vertex V; @@ -1597,10 +1600,10 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires IntRes2d_IntersectionPoint IPL = IS.LastPoint(); Standard_Real p12 = IPL.ParamOnFirst(); Standard_Real p22 = IPL.ParamOnSecond(); - gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,Crv1,p11); - gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,Crv1,p12); - gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,Crv2,p21); - gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,Crv2,p22); + gp_Pnt Pnt11 = GetPointOnEdge(edge1,sas,C1,p11); + gp_Pnt Pnt12 = GetPointOnEdge(edge1,sas,C1,p12); + gp_Pnt Pnt21 = GetPointOnEdge(edge2,sas,C2,p21); + gp_Pnt Pnt22 = GetPointOnEdge(edge2,sas,C2,p22); // analysis for edge1 TopoDS_Vertex V1 = sae.FirstVertex(edge1); @@ -1888,8 +1891,8 @@ Standard_Boolean ShapeFix_IntersectionTool::FixIntersectingWires (Pnt11.Z()+Pnt12.Z())/2 ); Standard_Real param1 = (p11+p12)/2; Standard_Real param2 = (p21+p22)/2; - gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,Crv1,param1); - gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,Crv2,param2); + gp_Pnt Pnt10 = GetPointOnEdge(edge1,sas,C1,param1); + gp_Pnt Pnt20 = GetPointOnEdge(edge2,sas,C2,param2); dist1 = Max(Pnt11.Distance(P0),Pnt12.Distance(Pnt10)); dist2 = Max(Pnt21.Distance(P0),Pnt22.Distance(Pnt10)); Standard_Real tolV = Max(dist1,dist2); diff --git a/src/ShapeFix/ShapeFix_Wire.cxx b/src/ShapeFix/ShapeFix_Wire.cxx index 19fc9ab7ad..f3f05d68f2 100644 --- a/src/ShapeFix/ShapeFix_Wire.cxx +++ b/src/ShapeFix/ShapeFix_Wire.cxx @@ -3132,7 +3132,11 @@ Standard_Boolean ShapeFix_Wire::FixNotchedEdges() myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); } else - FixDummySeam(n1); + { + FixDummySeam(n1); + // The seam edge is removed from the list. So, need to step back to avoid missing of edge processing + i--; + } i--; if(!Context().IsNull()) //skl 07.03.2002 for OCC180 diff --git a/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx b/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx index 2078652d20..464622d3ec 100644 --- a/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx +++ b/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx @@ -421,7 +421,8 @@ void StepToTopoDS_TranslateEdge::MakeFromCurve3D TP->AddWarning(C3D,"Update of 3D-Parameters has failed"); //:d5: instead of AdjustCurve above which is incorrect if U1 and U2 are not ends - gp_Pnt pU1 = C1->Value ( U1 ), pU2 = C1->Value ( U2 ); + GeomAdaptor_Curve aCA(C1); + gp_Pnt pU1 = aCA.Value ( U1 ), pU2 = aCA.Value ( U2 ); temp1 = pU1.Distance ( pv1 ); temp2 = pU2.Distance ( pv2 ); if ( temp1 > preci || temp2 > preci ) { diff --git a/src/math/math_FunctionRoots.cxx b/src/math/math_FunctionRoots.cxx index 3d743d37db..d084ac8a84 100644 --- a/src/math/math_FunctionRoots.cxx +++ b/src/math/math_FunctionRoots.cxx @@ -440,7 +440,8 @@ math_FunctionRoots::math_FunctionRoots(math_FunctionWithDerivative& F, F.Value(x1,f1); f1-=K; F.Value(x2,f2); f2-=K; //-- printf("\n *************** RECHERCHE MINIMUM **********\n"); - while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > 0)) { + Standard_Real tolX = 0.001 * NEpsX; + while(Abs(x3-x0) > tolCR*(Abs(x1)+Abs(x2)) && (Abs(x1 -x2) > tolX)) { //-- printf("\n (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) (%10.5g,%10.5g) ", //-- x0,f0,x1,f1,x2,f2,x3,f3); if(recherche_minimum) { diff --git a/src/math/math_TrigonometricFunctionRoots.cxx b/src/math/math_TrigonometricFunctionRoots.cxx index 4d5f4f99a4..3d5b9919c3 100644 --- a/src/math/math_TrigonometricFunctionRoots.cxx +++ b/src/math/math_TrigonometricFunctionRoots.cxx @@ -151,7 +151,7 @@ void math_TrigonometricFunctionRoots::Perform(const Standard_Real A, InfiniteStatus = Standard_False; Done = Standard_True; - Eps = 1.e-12; + Eps = 1.5e-12; Depi = M_PI+M_PI; if (InfBound <= RealFirst() && SupBound >= RealLast()) { diff --git a/tests/boolean/bfuse_complex/F5 b/tests/boolean/bfuse_complex/F5 index ab90b6fb15..c075d2b074 100644 --- a/tests/boolean/bfuse_complex/F5 +++ b/tests/boolean/bfuse_complex/F5 @@ -1,6 +1,5 @@ # Original bug : pro10658 # Date : 24mar98 -puts "TODO #26080 ALL: Faulty shapes in variables faulty_1" puts "TODO ALL Error : The area of the resulting shape is" restore [locate_data_file CTO900_pro10658a.rle] a restore [locate_data_file pro10658b.rle] b diff --git a/tests/boolean/bfuse_complex/Q2 b/tests/boolean/bfuse_complex/Q2 index 1343c8a154..45a88e0f0d 100644 --- a/tests/boolean/bfuse_complex/Q2 +++ b/tests/boolean/bfuse_complex/Q2 @@ -1,5 +1,4 @@ # pro10658 -puts "TODO #26080 ALL: Faulty shapes in variables faulty_1" puts "TODO ALL Error : The area of the resulting shape is" restore [locate_data_file CTO900_pro10658a.rle] a restore [locate_data_file pro10658b.rle] b diff --git a/tests/boolean/bsection/M9 b/tests/boolean/bsection/M9 index b3608d72c7..dd1501d700 100644 --- a/tests/boolean/bsection/M9 +++ b/tests/boolean/bsection/M9 @@ -18,7 +18,10 @@ compound result repeat 21 { plane p_$i 0 $i*100 0 0 1 0 mkface f_$i p_$i - bsection s_$i b f_$i + set bsres [bsection s_$i b f_$i] + if { [regexp {Error} $bsres] } { + puts "Error: bsection not done" + } compound result s_$i result set dist [expr $i * 100] puts "OK Section:$dist" diff --git a/tests/boolean/bsection/N4 b/tests/boolean/bsection/N4 index 529abd5f0c..334408334c 100644 --- a/tests/boolean/bsection/N4 +++ b/tests/boolean/bsection/N4 @@ -8,7 +8,10 @@ set i 1 repeat 199 { plane p_$i 0 $i*100 0 0 1 0 mkface f_$i p_$i - bsection s_$i a f_$i + set bsres [bsection s_$i a f_$i] + if { [regexp {Error} $bsres] } { + puts "Error: bsection not done" + } compound result s_$i result set dist [expr $i * 100] puts "OK Section:$dist" diff --git a/tests/boolean/volumemaker/F8 b/tests/boolean/volumemaker/F8 index a2840c15ca..578fc829ac 100644 --- a/tests/boolean/volumemaker/F8 +++ b/tests/boolean/volumemaker/F8 @@ -1,7 +1,7 @@ # test script on make volume operation # cone cylinder plane -puts "TODO OCC26020 ALL: Error: bopcheck failed" +puts "TODO OCC26020 Windows: Error: bopcheck failed" # planar face plane pln_f1 27.577164466275352 -1038.2137499999999 27.577164466275359 0.70710678118654746 4.4408920985006262e-016 0.70710678118654768 diff --git a/tests/bugs/modalg_2/bug5805_21 b/tests/bugs/modalg_2/bug5805_21 index 01e486c994..24a683fec1 100755 --- a/tests/bugs/modalg_2/bug5805_21 +++ b/tests/bugs/modalg_2/bug5805_21 @@ -30,7 +30,7 @@ set distance -0.1 catch { OFFSETSHAPE $distance {} $calcul $type } -set square 253.552 +set square 253.902 set nb_v_good 2 set nb_e_good 3 diff --git a/tests/bugs/modalg_2/bug5805_22 b/tests/bugs/modalg_2/bug5805_22 index 9ea1cba1e8..bc6ae303a0 100755 --- a/tests/bugs/modalg_2/bug5805_22 +++ b/tests/bugs/modalg_2/bug5805_22 @@ -30,7 +30,7 @@ set distance -0.1 catch { OFFSETSHAPE $distance {s_3} $calcul $type } -set square 502.411 +set square 502.366 set nb_v_good 3 set nb_e_good 5 diff --git a/tests/bugs/modalg_2/bug5805_23 b/tests/bugs/modalg_2/bug5805_23 index 87ca0f367d..e670f809f2 100755 --- a/tests/bugs/modalg_2/bug5805_23 +++ b/tests/bugs/modalg_2/bug5805_23 @@ -30,7 +30,7 @@ set distance -0.1 catch { OFFSETSHAPE $distance {s_2} $calcul $type } -set square 502.411 +set square 502.366 set nb_v_good 3 set nb_e_good 5 diff --git a/tests/bugs/modalg_2/bug5805_24 b/tests/bugs/modalg_2/bug5805_24 index 11542cb0e1..4ad85530c8 100755 --- a/tests/bugs/modalg_2/bug5805_24 +++ b/tests/bugs/modalg_2/bug5805_24 @@ -30,7 +30,7 @@ set distance -0.1 catch { OFFSETSHAPE $distance {s_3 s_2} $calcul $type } -set square 489.812 +set square 489.372 set nb_v_good 3 set nb_e_good 5 diff --git a/tests/bugs/modalg_2/bug5805_41 b/tests/bugs/modalg_2/bug5805_41 index 6f1dbf1644..3f40a62840 100755 --- a/tests/bugs/modalg_2/bug5805_41 +++ b/tests/bugs/modalg_2/bug5805_41 @@ -1,6 +1,6 @@ -puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape" -puts "TODO OCC25925 ALL: result is not a topological shape" -puts "TODO OCC25925 ALL: TEST INCOMPLETE" +puts "TODO OCC24862 ALL: Error : Result shape is WRONG" +puts "TODO OCC24862 ALL: Error : The square of result shape is" +puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_" puts "============" puts "OCC5805" diff --git a/tests/bugs/modalg_2/bug5805_43 b/tests/bugs/modalg_2/bug5805_43 index 8f84630a3e..bcb3735f7a 100755 --- a/tests/bugs/modalg_2/bug5805_43 +++ b/tests/bugs/modalg_2/bug5805_43 @@ -1,7 +1,6 @@ -puts "TODO OCC25925 ALL: Tcl Exception: result is not a topological shape!!!" -puts "TODO OCC25925 ALL: ERROR. offsetperform operation not done" -puts "TODO OCC25925 ALL: Faulty OCC5805 : result is not Closed shape" -puts "TODO OCC25925 ALL: TEST INCOMPLETE" +puts "TODO OCC24862 ALL: Error : Result shape is WRONG" +puts "TODO OCC24862 ALL: Error : The square of result shape is" +puts "TODO OCC24682 ALL: Faulty shapes in variables faulty_1 to faulty_" puts "============" puts "OCC5805" diff --git a/tests/bugs/modalg_4/bug714 b/tests/bugs/modalg_4/bug714 index 5c34c5cff7..0100b40a24 100755 --- a/tests/bugs/modalg_4/bug714 +++ b/tests/bugs/modalg_4/bug714 @@ -7,8 +7,6 @@ puts "" ## After command sew in DRAW on attached shape free wires are disappeared. #################################################### -puts "TODO OCC25593 ALL: Faulty shapes in variables faulty_1 to faulty_4" - restore [locate_data_file OCC714.brep] a checkshape a diff --git a/tests/bugs/modalg_5/bug24200 b/tests/bugs/modalg_5/bug24200 index e1e64efb90..5468cb52b1 100644 --- a/tests/bugs/modalg_5/bug24200 +++ b/tests/bugs/modalg_5/bug24200 @@ -21,7 +21,7 @@ vertex v2 x y z distmini d v1 v2 regexp {([-0-9.+eE]+)} [dump d_val] full dist -set checkdist 2.54211497292521e-013 +set checkdist 1.13686837721616e-013 if { [expr 1.*abs($checkdist - $dist)/$checkdist] > 0.1 } { puts "Error : Distance is wrong" diff --git a/tests/bugs/modalg_5/bug24303 b/tests/bugs/modalg_5/bug24303 index ec3aeb7b90..7a8d18d6de 100755 --- a/tests/bugs/modalg_5/bug24303 +++ b/tests/bugs/modalg_5/bug24303 @@ -10,12 +10,12 @@ pload QAcommands set status 0 -set info1 [OCC24303 4] +set info1 [OCC24303 5] regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance -if { [info exists Sol4] } { - set info2 [dump Sol4] +if { [info exists Sol5] } { + set info2 [dump Sol5] regexp {Center +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full CenterX CenterY regexp {XAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full XAxisX XAxisY regexp {YAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full YAxisX YAxisY diff --git a/tests/bugs/modalg_5/bug25175 b/tests/bugs/modalg_5/bug25175 index ce77c625fb..aeb426189d 100644 --- a/tests/bugs/modalg_5/bug25175 +++ b/tests/bugs/modalg_5/bug25175 @@ -14,7 +14,7 @@ sewing result 0.1 a checkmaxtol result 0.0076621571738049385 checknbshapes result -shell 1 -checkfreebounds result 2 +checkfreebounds result 0 set 2dviewer 1 diff --git a/tests/bugs/modalg_6/bug25908 b/tests/bugs/modalg_6/bug25908 index e3e368c896..7af868079b 100755 --- a/tests/bugs/modalg_6/bug25908 +++ b/tests/bugs/modalg_6/bug25908 @@ -20,15 +20,15 @@ compound vl v1l vnl vol vil result set nbshapes_expected " Number of shapes in shape - VERTEX : 169 - EDGE : 85 + VERTEX : 165 + EDGE : 83 WIRE : 0 FACE : 0 SHELL : 0 SOLID : 0 COMPSOLID : 0 COMPOUND : 1 - SHAPE : 255 + SHAPE : 249 " checknbshapes result -ref ${nbshapes_expected} -t -m "HLRToShape" diff --git a/tests/bugs/moddata_1/bug16119 b/tests/bugs/moddata_1/bug16119 index 43330f18ec..9a403ad7fe 100755 --- a/tests/bugs/moddata_1/bug16119 +++ b/tests/bugs/moddata_1/bug16119 @@ -39,9 +39,9 @@ set deltaY [dval dvy1-dvy2] set deltaZ [dval dvz1-dvz2] set percent_max 0.1 -set good_deltaX 4.4408920985006262e-015 -set good_deltaY -4.6629367034256575e-015 -set good_deltaZ -2.6645352591003757e-015 +set good_deltaX -3.5527136788005009e-015 +set good_deltaY -3.5527136788005009e-015 +set good_deltaZ 8.8817841970012523e-016 set deltaX_percent [GetPercent ${deltaX} ${good_deltaX}] puts "deltaX_percent = ${deltaX_percent}" diff --git a/tests/bugs/moddata_1/bug22759 b/tests/bugs/moddata_1/bug22759 index 82c4d6cb58..34ec762706 100755 --- a/tests/bugs/moddata_1/bug22759 +++ b/tests/bugs/moddata_1/bug22759 @@ -28,14 +28,14 @@ regexp {deflection +([-0-9.+eE]+)} $tri_info full defl set env(os_type) $tcl_platform(platform) if { [string compare $env(os_type) "windows"] != 0 } { puts "OS = Linux" - set good_tri 520414 - set good_nod 263938 - set good_defl 0.0026800432954056617 + set good_tri 615414 + set good_nod 311438 + set good_defl 0.0032657364637550075 } else { puts "OS = Windows NT" - set good_tri 520414 - set good_nod 263938 - set good_defl 0.0026800432954056617 + set good_tri 615414 + set good_nod 311438 + set good_defl 0.0032657364637550075 } proc GetPercent {Value GoodValue} { diff --git a/tests/bugs/moddata_2/bug36 b/tests/bugs/moddata_2/bug36 index e51abe82ee..49101e096b 100755 --- a/tests/bugs/moddata_2/bug36 +++ b/tests/bugs/moddata_2/bug36 @@ -26,7 +26,7 @@ if [catch { igesbrep $filepath a * } res] { checkmaxtol result 2.5472812372261969e-005 checknbshapes result -shell 13 - checkfreebounds result 1249 + checkfreebounds result 1247 } set 2dviewer 0 diff --git a/tests/bugs/moddata_2/bug498 b/tests/bugs/moddata_2/bug498 index b1be064b6e..59685b82c2 100755 --- a/tests/bugs/moddata_2/bug498 +++ b/tests/bugs/moddata_2/bug498 @@ -1,5 +1,3 @@ -puts "TODO OCC12345 ALL: Faulty OCC498: Wrong 3d point from offset surface by parameters" - puts "=========" puts " OCC498 " puts "=========" diff --git a/tests/bugs/moddata_3/bug25207 b/tests/bugs/moddata_3/bug25207 index 850b3cc48b..da212401bf 100755 --- a/tests/bugs/moddata_3/bug25207 +++ b/tests/bugs/moddata_3/bug25207 @@ -25,16 +25,16 @@ set tol_abs 1.0e-05 set tol_rel 0.01 set expected_dmax 0.0013771610718045313 -set expected_ufmax 0.890625 +set expected_ufmax 0.953125 checkreal "dmax" ${dmax} ${expected_dmax} ${tol_abs} ${tol_rel} checkreal "ufmax" ${ufmax} ${expected_ufmax} ${tol_abs} ${tol_rel} -set expected_ulmax 0.90625 +set expected_ulmax 0.96875 if { ${ulmax} != ${expected_ulmax} } { puts "Error : bad value of ulmax=${ulmax}" } -set expected_i 69 +set expected_i 73 if { ${i} != ${expected_i} } { puts "Error : bad value of i=${i}" } diff --git a/tests/de/iges_1/F9 b/tests/de/iges_1/F9 index ccf2fc95c2..b524f8243f 100644 --- a/tests/de/iges_1/F9 +++ b/tests/de/iges_1/F9 @@ -1,6 +1,4 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: TPSTAT : Faulty" - set filename UKI60095.igs diff --git a/tests/de/iges_1/J2 b/tests/de/iges_1/J2 index 1341137454..c62d702fef 100644 --- a/tests/de/iges_1/J2 +++ b/tests/de/iges_1/J2 @@ -11,7 +11,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) Summary = 18221 ( 18221 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 900 ( 900 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 8213 ( 8213 ) TOLERANCE : MaxTol = 0.004034169186 ( 0.004034577888 ) AvgTol = 7.709492698e-006 ( 1.210857047e-005 ) -LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 929 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1829 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1829 ) LayerLabels = 900 ( 1829 ) +LABELS : N0Labels = 900 ( 900 ) N1Labels = 0 ( 930 ) N2Labels = 0 ( 0 ) TotalLabels = 900 ( 1830 ) NameLabels = 900 ( 900 ) ColorLabels = 900 ( 1830 ) LayerLabels = 900 ( 1830 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 1 ( 1 ) COLORS : Colors = YELLOW ( YELLOW ) diff --git a/tests/de/iges_1/J3 b/tests/de/iges_1/J3 index a92868756a..1fecba166b 100644 --- a/tests/de/iges_1/J3 +++ b/tests/de/iges_1/J3 @@ -8,10 +8,10 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 1091 ) Summary = 42 ( 1091 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22098 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10005 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) Summary = 22098 ( 22096 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1038 ( 1038 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 10005 ( 10004 ) TOLERANCE : MaxTol = 0.5433123154 ( 0.5433122968 ) AvgTol = 0.002230678782 ( 0.002235663837 ) -LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1450 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2488 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2488 ) LayerLabels = 1038 ( 2488 ) +LABELS : N0Labels = 1038 ( 1038 ) N1Labels = 0 ( 1449 ) N2Labels = 0 ( 0 ) TotalLabels = 1038 ( 2487 ) NameLabels = 1038 ( 1038 ) ColorLabels = 1038 ( 2487 ) LayerLabels = 1038 ( 2487 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 2 ( 2 ) COLORS : Colors = GREEN RED ( GREEN RED ) diff --git a/tests/de/iges_1/J9 b/tests/de/iges_1/J9 index 8d4b65b6e7..ce3d7bb641 100644 --- a/tests/de/iges_1/J9 +++ b/tests/de/iges_1/J9 @@ -7,9 +7,9 @@ set filename CTS21655.igs set ref_data { DATA : Faulties = 0 ( 12 ) Warnings = 0 ( 1 ) Summary = 0 ( 13 ) TPSTAT : Faulties = 0 ( 28 ) Warnings = 116 ( 7 ) Summary = 116 ( 35 ) -CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 1 ) Solids = 0 ( 1 ) -NBSHAPES : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) Summary = 15092 ( 7703 ) -STATSHAPE : Solid = 0 ( 19 ) Shell = 0 ( 19 ) Face = 1191 ( 1191 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6291 ( 3138 ) +CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 1 ) Solids = 0 ( 1 ) +NBSHAPES : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) Summary = 15073 ( 7693 ) +STATSHAPE : Solid = 0 ( 18 ) Shell = 0 ( 18 ) Face = 1190 ( 1190 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 6283 ( 3134 ) TOLERANCE : MaxTol = 0.2496383637 ( 0.2496258832 ) AvgTol = 0.00219239232 ( 0.004111699336 ) LABELS : N0Labels = 27 ( 27 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 27 ( 27 ) NameLabels = 27 ( 27 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) diff --git a/tests/de/iges_1/K3 b/tests/de/iges_1/K3 index 160addc5a0..632d6a715b 100644 --- a/tests/de/iges_1/K3 +++ b/tests/de/iges_1/K3 @@ -1,18 +1,18 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR25923 ALL: NBSHAPES : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" - +puts "TODO CR23096 ALL: NBSHAPES : Faulty" +puts "TODO CR23096 ALL: Error : 2 differences with reference data found" set filename FRA62468-1.igs set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) -TPSTAT : Faulties = 0 ( 0 ) Warnings = 427 ( 5255 ) Summary = 427 ( 5255 ) +TPSTAT : Faulties = 0 ( 0 ) Warnings = 299 ( 5226 ) Summary = 299 ( 5226 ) CHECKSHAPE : Wires = 12 ( 20 ) Faces = 16 ( 18 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68354 ( 68418 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29043 ( 29075 ) -TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01115315301 ( 0.0111584608 ) -LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4437 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9895 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9829 ) LayerLabels = 5391 ( 9829 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) Summary = 68422 ( 68420 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 5163 ( 5163 ) FreeWire = 10 ( 10 ) FreeEdge = 283 ( 283 ) SharedEdge = 29075 ( 29079 ) +TOLERANCE : MaxTol = 0.9874083984 ( 0.9875071265 ) AvgTol = 0.01114309412 ( 0.01115568387 ) +LABELS : N0Labels = 5392 ( 5458 ) N1Labels = 18 ( 4427 ) N2Labels = 0 ( 0 ) TotalLabels = 5410 ( 9885 ) NameLabels = 5392 ( 5458 ) ColorLabels = 5391 ( 9819 ) LayerLabels = 5391 ( 9819 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 4 ( 4 ) COLORS : Colors = BLACK BLUE1 CYAN1 GREEN ( BLACK BLUE1 CYAN1 GREEN ) diff --git a/tests/de/iges_1/L8 b/tests/de/iges_1/L8 index 6bf191067a..11622673aa 100755 --- a/tests/de/iges_1/L8 +++ b/tests/de/iges_1/L8 @@ -1,19 +1,19 @@ # !!!! This file is generated automatically, do not edit manually! See end script +puts "TODO CR23096 ALL: TPSTAT : Faulty" +puts "TODO CR23096 ALL: NBSHAPES : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" -puts "TODO CR23096 ALL: TOLERANCE : Faulty" - set LinuxDiff 3 set filename PRO14319.igs set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) -TPSTAT : Faulties = 0 ( 0 ) Warnings = 2 ( 64 ) Summary = 2 ( 64 ) -CHECKSHAPE : Wires = 1 ( 7 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7360 ( 7320 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3632 ( 3603 ) -TOLERANCE : MaxTol = 0.3749733839 ( 0.3140268243 ) AvgTol = 0.002809949164 ( 0.0005120147149 ) -LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 788 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 849 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 849 ) LayerLabels = 0 ( 0 ) +TPSTAT : Faulties = 1 ( 0 ) Warnings = 3 ( 64 ) Summary = 4 ( 64 ) +CHECKSHAPE : Wires = 3 ( 5 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) Summary = 7731 ( 7831 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 61 ( 61 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3842 ( 3895 ) +TOLERANCE : MaxTol = 0.3140268251 ( 0.3140268243 ) AvgTol = 0.0009762560334 ( 0.000488212708 ) +LABELS : N0Labels = 61 ( 61 ) N1Labels = 0 ( 1080 ) N2Labels = 0 ( 0 ) TotalLabels = 61 ( 1141 ) NameLabels = 61 ( 61 ) ColorLabels = 61 ( 1141 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 3 ( 3 ) COLORS : Colors = CYAN1 GREEN WHITE ( CYAN1 GREEN WHITE ) diff --git a/tests/de/iges_1/M7 b/tests/de/iges_1/M7 index 89e885e4b0..8f92b92618 100644 --- a/tests/de/iges_1/M7 +++ b/tests/de/iges_1/M7 @@ -1,7 +1,6 @@ # !!!! This file is generated automatically, do not edit manually! See end script puts "TODO CR23096 ALL: LABELS : Faulty" - set filename 12ls328.igs set ref_data { diff --git a/tests/de/iges_1/O3 b/tests/de/iges_1/O3 index 867eba7169..ab78fbba35 100644 --- a/tests/de/iges_1/O3 +++ b/tests/de/iges_1/O3 @@ -1,5 +1,4 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: TOLERANCE : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" set LinuxDiff 1 diff --git a/tests/de/iges_1/O4 b/tests/de/iges_1/O4 index 758f385587..326d42c37a 100644 --- a/tests/de/iges_1/O4 +++ b/tests/de/iges_1/O4 @@ -10,7 +10,7 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 1 ) Summary = 0 ( 1 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 444 ( 1005 ) Summary = 444 ( 1005 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50232 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) Summary = 50219 ( 50230 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 300 ( 300 ) FreeWire = 119 ( 139 ) FreeEdge = 4488 ( 4487 ) SharedEdge = 24679 ( 24678 ) TOLERANCE : MaxTol = 1e-05 ( 0.06099237775 ) AvgTol = 3.184880431e-07 ( 1.621424764e-05 ) LABELS : N0Labels = 432 ( 432 ) N1Labels = 12 ( 845 ) N2Labels = 0 ( 0 ) TotalLabels = 444 ( 1277 ) NameLabels = 432 ( 687 ) ColorLabels = 320 ( 1277 ) LayerLabels = 320 ( 1277 ) diff --git a/tests/de/iges_1/P5 b/tests/de/iges_1/P5 index cdeab27728..54df8aa0a5 100755 --- a/tests/de/iges_1/P5 +++ b/tests/de/iges_1/P5 @@ -1,17 +1,18 @@ # !!!! This file is generated automatically, do not edit manually! See end script puts "TODO CR23096 ALL: LABELS : Faulty" +puts "TODO CR23096 ALL: Error : 3 differences with reference data found" set LinuxDiff 2 set filename brazo1.igs set ref_data { DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 ) -TPSTAT : Faulties = 0 ( 0 ) Warnings = 148 ( 478 ) Summary = 148 ( 478 ) +TPSTAT : Faulties = 0 ( 0 ) Warnings = 139 ( 454 ) Summary = 139 ( 454 ) CHECKSHAPE : Wires = 6 ( 8 ) Faces = 6 ( 8 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4666 ( 4542 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2144 ( 2074 ) -TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01125801875 ( 0.01225981249 ) -LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 242 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 465 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 465 ) LayerLabels = 223 ( 465 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) Summary = 4710 ( 4574 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 223 ( 223 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 2166 ( 2092 ) +TOLERANCE : MaxTol = 0.991254355 ( 0.991254355 ) AvgTol = 0.01133191355 ( 0.01225911215 ) +LABELS : N0Labels = 223 ( 223 ) N1Labels = 0 ( 256 ) N2Labels = 0 ( 0 ) TotalLabels = 223 ( 479 ) NameLabels = 223 ( 388 ) ColorLabels = 223 ( 479 ) LayerLabels = 223 ( 479 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 3 ( 3 ) COLORS : Colors = BLUE1 MAGENTA1 YELLOW ( BLUE1 MAGENTA1 YELLOW ) diff --git a/tests/de/iges_1/P7 b/tests/de/iges_1/P7 index 14d700fef8..b735728934 100644 --- a/tests/de/iges_1/P7 +++ b/tests/de/iges_1/P7 @@ -12,7 +12,7 @@ CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) So NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) Summary = 12751 ( 12759 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 770 ( 770 ) FreeWire = 36 ( 36 ) FreeEdge = 232 ( 232 ) SharedEdge = 5541 ( 5545 ) TOLERANCE : MaxTol = 0.9845041621 ( 0.9845038147 ) AvgTol = 0.00992720939 ( 0.009919874447 ) -LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1770 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2650 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2650 ) LayerLabels = 844 ( 2650 ) +LABELS : N0Labels = 880 ( 880 ) N1Labels = 0 ( 1784 ) N2Labels = 0 ( 0 ) TotalLabels = 880 ( 2664 ) NameLabels = 880 ( 1500 ) ColorLabels = 844 ( 2664 ) LayerLabels = 844 ( 2664 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 1 ( 1 ) COLORS : Colors = BLACK ( BLACK ) diff --git a/tests/de/iges_1/P9 b/tests/de/iges_1/P9 index 8883a5c894..90c9522db5 100644 --- a/tests/de/iges_1/P9 +++ b/tests/de/iges_1/P9 @@ -7,10 +7,10 @@ set filename ims003.igs set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 38 ( 183 ) Summary = 38 ( 183 ) -CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) +CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) Summary = 2511 ( 2510 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 114 ( 114 ) FreeWire = 23 ( 23 ) FreeEdge = 331 ( 331 ) SharedEdge = 983 ( 983 ) -TOLERANCE : MaxTol = 0.1829958579 ( 0.1829958769 ) AvgTol = 0.003259834421 ( 0.003329232309 ) +TOLERANCE : MaxTol = 0.1830141575 ( 0.1830141765 ) AvgTol = 0.003295423033 ( 0.003364815075 ) LABELS : N0Labels = 412 ( 412 ) N1Labels = 2 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 414 ( 412 ) NameLabels = 412 ( 412 ) ColorLabels = 389 ( 410 ) LayerLabels = 389 ( 410 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 5 ( 5 ) diff --git a/tests/de/iges_1/R8 b/tests/de/iges_1/R8 index f7303c0561..a5e3c29795 100755 --- a/tests/de/iges_1/R8 +++ b/tests/de/iges_1/R8 @@ -1,18 +1,19 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR25923 ALL: STATSHAPE : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" +puts "TODO CR23096 ALL: STATSHAPE : Faulty" +puts "TODO CR23096 ALL: Error : 3 differences with reference data found" set LinuxDiff 5 set filename BUC60743.igs set ref_data { DATA : Faulties = 0 ( 2 ) Warnings = 0 ( 0 ) Summary = 0 ( 2 ) -TPSTAT : Faulties = 3 ( 59 ) Warnings = 2205 ( 4736 ) Summary = 2208 ( 4795 ) -CHECKSHAPE : Wires = 7 ( 16 ) Faces = 6 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 2837 ) Summary = 45907 ( 39191 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3350 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19595 ( 16764 ) -TOLERANCE : MaxTol = 3.742696236 ( 5.769095076 ) AvgTol = 0.01636161939 ( 0.01749445935 ) -LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6319 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6330 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6319 ) LayerLabels = 2411 ( 5257 ) +TPSTAT : Faulties = 3 ( 59 ) Warnings = 2203 ( 4655 ) Summary = 2206 ( 4714 ) +CHECKSHAPE : Wires = 7 ( 17 ) Faces = 7 ( 12 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 2837 ) Summary = 45927 ( 39202 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 3349 ( 3349 ) FreeWire = 6 ( 6 ) FreeEdge = 67 ( 67 ) SharedEdge = 19607 ( 16774 ) +TOLERANCE : MaxTol = 4.854604894 ( 5.769095076 ) AvgTol = 0.01628658326 ( 0.01747356296 ) +LABELS : N0Labels = 11 ( 11 ) N1Labels = 2891 ( 6327 ) N2Labels = 0 ( 0 ) TotalLabels = 2902 ( 6338 ) NameLabels = 2900 ( 5879 ) ColorLabels = 2891 ( 6327 ) LayerLabels = 2411 ( 5258 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 4 ( 4 ) COLORS : Colors = BLACK BLUE1 RED YELLOW ( BLACK BLUE1 RED YELLOW ) diff --git a/tests/de/iges_2/A9 b/tests/de/iges_2/A9 index 59abafc95f..dfb3c16e64 100755 --- a/tests/de/iges_2/A9 +++ b/tests/de/iges_2/A9 @@ -10,10 +10,10 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 56 ( 12 ) Summary = 56 ( 12 ) CHECKSHAPE : Wires = 2 ( 1 ) Faces = 2 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25969 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10687 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 1106 ) Summary = 59777 ( 25971 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 2342 ( 2342 ) FreeWire = 2328 ( 2328 ) FreeEdge = 14016 ( 14016 ) SharedEdge = 24558 ( 10688 ) TOLERANCE : MaxTol = 0.9711309062 ( 0.9711309063 ) AvgTol = 0.01916076754 ( 0.01948753951 ) -LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3205 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3455 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3449 ) LayerLabels = 0 ( 0 ) +LABELS : N0Labels = 250 ( 250 ) N1Labels = 2268 ( 3204 ) N2Labels = 0 ( 0 ) TotalLabels = 2518 ( 3454 ) NameLabels = 2518 ( 3453 ) ColorLabels = 2512 ( 3448 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 4 ( 4 ) COLORS : Colors = CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ( CYAN1 LIGHTPINK PALEGOLDENROD ROSYBROWN ) diff --git a/tests/de/iges_2/B6 b/tests/de/iges_2/B6 index c41f7cde97..f4cd421a8c 100755 --- a/tests/de/iges_2/B6 +++ b/tests/de/iges_2/B6 @@ -5,8 +5,8 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 88 ( 191 ) Summary = 88 ( 191 ) CHECKSHAPE : Wires = 2 ( 2 ) Faces = 2 ( 2 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7836 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3350 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) Summary = 7842 ( 7833 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 569 ( 569 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 3353 ( 3348 ) TOLERANCE : MaxTol = 0.7161069967 ( 0.7585238415 ) AvgTol = 0.006717667602 ( 0.006937200018 ) LABELS : N0Labels = 568 ( 568 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 570 ( 570 ) NameLabels = 568 ( 568 ) ColorLabels = 569 ( 569 ) LayerLabels = 569 ( 569 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) diff --git a/tests/de/iges_2/B8 b/tests/de/iges_2/B8 index 6942fba71a..305198703d 100644 --- a/tests/de/iges_2/B8 +++ b/tests/de/iges_2/B8 @@ -1,19 +1,20 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: LABELS : Faulty" -puts "TODO CR25923 ALL: NBSHAPES : Faulty" -#puts "TODO CR23096 ALL: Error : 1 differences with reference data found :" +puts "TODO CR23096 ALL: CHECKSHAPE : Faulty" +puts "TODO CR23096 ALL: LABELS : Faulty" +puts "TODO CR23096 ALL: NBSHAPES : Faulty" +puts "TODO CR23096 ALL: Error : 2 differences with reference data found" set LinuxDiff 1 set filename FRA62468-2.igs set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) -TPSTAT : Faulties = 0 ( 0 ) Warnings = 349 ( 5016 ) Summary = 349 ( 5016 ) -CHECKSHAPE : Wires = 12 ( 19 ) Faces = 12 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63090 ( 63144 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26766 ( 26793 ) -TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01154225009 ( 0.01155173987 ) -LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3844 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 9009 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8933 ) LayerLabels = 5086 ( 8933 ) +TPSTAT : Faulties = 0 ( 0 ) Warnings = 253 ( 4993 ) Summary = 253 ( 4993 ) +CHECKSHAPE : Wires = 8 ( 11 ) Faces = 8 ( 7 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) Summary = 63158 ( 63146 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 4729 ( 4729 ) FreeWire = 18 ( 18 ) FreeEdge = 452 ( 452 ) SharedEdge = 26798 ( 26797 ) +TOLERANCE : MaxTol = 0.9804479161 ( 0.9805459497 ) AvgTol = 0.01153089031 ( 0.01154870945 ) +LABELS : N0Labels = 5089 ( 5165 ) N1Labels = 26 ( 3834 ) N2Labels = 0 ( 0 ) TotalLabels = 5115 ( 8999 ) NameLabels = 5089 ( 5165 ) ColorLabels = 5086 ( 8923 ) LayerLabels = 5086 ( 8923 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 3 ( 3 ) COLORS : Colors = BLUE1 CYAN1 GREEN ( BLUE1 CYAN1 GREEN ) diff --git a/tests/de/iges_2/C2 b/tests/de/iges_2/C2 index edc0c660e2..c3cdd97e6b 100644 --- a/tests/de/iges_2/C2 +++ b/tests/de/iges_2/C2 @@ -3,7 +3,7 @@ puts "TODO CR23096 ALL: TPSTAT : Faulty" puts "TODO CR23096 ALL: NBSHAPES : Faulty" puts "TODO CR23096 ALL: TOLERANCE : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" - +puts "TODO CR23096 ALL: Error : 3 differences with reference data found" set filename PRO10626.igs @@ -11,8 +11,8 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 2 ( 0 ) Warnings = 85 ( 295 ) Summary = 87 ( 295 ) CHECKSHAPE : Wires = 8 ( 13 ) Faces = 8 ( 13 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5352 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2221 ( 2228 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) Summary = 5328 ( 5349 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 419 ( 419 ) FreeWire = 4 ( 4 ) FreeEdge = 42 ( 42 ) SharedEdge = 2220 ( 2226 ) TOLERANCE : MaxTol = 4.547932063 ( 4.543567878 ) AvgTol = 0.03466358537 ( 0.03659099671 ) LABELS : N0Labels = 457 ( 457 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 457 ) NameLabels = 457 ( 457 ) ColorLabels = 451 ( 455 ) LayerLabels = 453 ( 457 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) diff --git a/tests/de/iges_2/D8 b/tests/de/iges_2/D8 index e657bbcf81..3526483744 100644 --- a/tests/de/iges_2/D8 +++ b/tests/de/iges_2/D8 @@ -10,10 +10,10 @@ set ref_data { DATA : Faulties = 0 ( 1 ) Warnings = 0 ( 0 ) Summary = 0 ( 1 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 650 ( 1843 ) Summary = 650 ( 1843 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17129 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7869 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) Summary = 17131 ( 17126 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 692 ( 692 ) FreeWire = 5 ( 5 ) FreeEdge = 36 ( 36 ) SharedEdge = 7867 ( 7867 ) TOLERANCE : MaxTol = 1.089725986e-005 ( 1.089659651e-005 ) AvgTol = 1.975835144e-006 ( 9.652818162e-006 ) -LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1400 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2093 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2093 ) LayerLabels = 692 ( 2093 ) +LABELS : N0Labels = 693 ( 693 ) N1Labels = 10 ( 1399 ) N2Labels = 0 ( 0 ) TotalLabels = 703 ( 2092 ) NameLabels = 693 ( 1341 ) ColorLabels = 692 ( 2092 ) LayerLabels = 692 ( 2092 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 3 ( 4 ) COLORS : Colors = CYAN1 WHITE YELLOW ( CYAN1 GREEN3 WHITE YELLOW ) diff --git a/tests/de/iges_2/F1 b/tests/de/iges_2/F1 index 894310e62e..51367769ed 100755 --- a/tests/de/iges_2/F1 +++ b/tests/de/iges_2/F1 @@ -14,7 +14,7 @@ TPSTAT : Faulties = 44 ( 0 ) Warnings = 169 ( 1291 ) Summary = 213 ( CHECKSHAPE : Wires = 0 ( 0 ) Faces = 1 ( 1 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) Summary = 8171 ( 8283 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 270 ( 270 ) FreeWire = 108 ( 108 ) FreeEdge = 606 ( 606 ) SharedEdge = 3685 ( 3689 ) -TOLERANCE : MaxTol = 5.750743843e+14 ( 4.784430882e+15 ) AvgTol = 2.722724827e+11 ( 2.206755414e+12 ) +TOLERANCE : MaxTol = 2.113937626e+17 ( 2.113937968e+17 ) AvgTol = 9.737589861e+13 ( 9.762248147e+13 ) LABELS : N0Labels = 7 ( 7 ) N1Labels = 450 ( 2042 ) N2Labels = 0 ( 0 ) TotalLabels = 457 ( 2049 ) NameLabels = 457 ( 698 ) ColorLabels = 450 ( 2043 ) LayerLabels = 449 ( 2042 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 7 ( 7 ) diff --git a/tests/de/iges_2/H9 b/tests/de/iges_2/H9 index b11adb9575..8c0e68f860 100755 --- a/tests/de/iges_2/H9 +++ b/tests/de/iges_2/H9 @@ -1,5 +1,6 @@ # !!!! This file is generated automatically, do not edit manually! See end script puts "TODO CR23096 ALL: NBSHAPES : Faulty" +puts "TODO CR23096 ALL: TOLERANCE : Faulty" puts "TODO CR23096 ALL: LABELS : Faulty" puts "TODO CR23096 ALL: COLORS : Faulty" puts "TODO CR25013 ALL: Error : 3 differences with reference data found" @@ -12,10 +13,10 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 3 ) Warnings = 274 ( 4465 ) Summary = 274 ( 4468 ) CHECKSHAPE : Wires = 2 ( 2 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39230 ( 39268 ) -STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17933 ( 17940 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) Summary = 39231 ( 39275 ) +STATSHAPE : Solid = 0 ( 0 ) Shell = 0 ( 0 ) Face = 1628 ( 1628 ) FreeWire = 22 ( 26 ) FreeEdge = 135 ( 135 ) SharedEdge = 17934 ( 17947 ) TOLERANCE : MaxTol = 4.337400808e+088 ( 8.082392835e+086 ) AvgTol = 2.040579288e+085 ( 5.099401401e+083 ) -LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9638 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9644 ) NameLabels = 1649 ( 2890 ) ColorLabels = 1645 ( 9643 ) LayerLabels = 489 ( 3997 ) +LABELS : N0Labels = 6 ( 6 ) N1Labels = 1643 ( 9621 ) N2Labels = 0 ( 0 ) TotalLabels = 1649 ( 9627 ) NameLabels = 1649 ( 2891 ) ColorLabels = 1645 ( 9626 ) LayerLabels = 489 ( 3997 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) NCOLORS : NColors = 4 ( 5 ) COLORS : Colors = BLUE1 CYAN1 GOLD3 GREEN ( BLUE1 CYAN1 GOLD3 GREEN YELLOW ) diff --git a/tests/de/iges_3/A2 b/tests/de/iges_3/A2 index d5d9ba21c5..473028b1f8 100755 --- a/tests/de/iges_3/A2 +++ b/tests/de/iges_3/A2 @@ -13,11 +13,11 @@ set filename UKI60094.igs 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 ) diff --git a/tests/de/iges_3/A4 b/tests/de/iges_3/A4 index cb0b7c19e7..459721600c 100755 --- a/tests/de/iges_3/A4 +++ b/tests/de/iges_3/A4 @@ -5,7 +5,7 @@ puts "TODO CR23096 ALL: STATSHAPE : Faulty" 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 diff --git a/tests/de/iges_3/B2 b/tests/de/iges_3/B2 index 7ce4231e7c..af95584da6 100755 --- a/tests/de/iges_3/B2 +++ b/tests/de/iges_3/B2 @@ -7,12 +7,12 @@ set LinuxDiff 3 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 ) diff --git a/tests/de/step_1/A3 b/tests/de/step_1/A3 index 0241b6353f..c94a8788e0 100644 --- a/tests/de/step_1/A3 +++ b/tests/de/step_1/A3 @@ -8,7 +8,7 @@ set ref_data { 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 ) diff --git a/tests/de/step_1/D9 b/tests/de/step_1/D9 index 89d3e85dd5..26ab6a1659 100644 --- a/tests/de/step_1/D9 +++ b/tests/de/step_1/D9 @@ -8,7 +8,7 @@ set ref_data { 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 ) diff --git a/tests/de/step_1/G9 b/tests/de/step_1/G9 index f43c761e52..316f8192cf 100644 --- a/tests/de/step_1/G9 +++ b/tests/de/step_1/G9 @@ -10,7 +10,7 @@ set filename trj4_k1_geo-tu-214.stp 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 ) diff --git a/tests/de/step_1/J6 b/tests/de/step_1/J6 index 6c718bf420..ff12ff4bb4 100755 --- a/tests/de/step_1/J6 +++ b/tests/de/step_1/J6 @@ -10,8 +10,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_1/J8 b/tests/de/step_1/J8 index ef72437008..877e9e5b8e 100644 --- a/tests/de/step_1/J8 +++ b/tests/de/step_1/J8 @@ -8,9 +8,9 @@ set filename bm1_sy_lever.stp 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 ) diff --git a/tests/de/step_2/B5 b/tests/de/step_2/B5 index d1f7760936..df21698164 100644 --- a/tests/de/step_2/B5 +++ b/tests/de/step_2/B5 @@ -10,7 +10,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 16 ( 364 ) Summary = 16 ( 364 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 ) diff --git a/tests/de/step_2/B6 b/tests/de/step_2/B6 index 42549ed258..4750365e2c 100644 --- a/tests/de/step_2/B6 +++ b/tests/de/step_2/B6 @@ -1,8 +1,5 @@ # !!!! 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 diff --git a/tests/de/step_2/E7 b/tests/de/step_2/E7 index d05786ec36..4726f81efe 100644 --- a/tests/de/step_2/E7 +++ b/tests/de/step_2/E7 @@ -1,16 +1,16 @@ # !!!! 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 ) diff --git a/tests/de/step_2/F4 b/tests/de/step_2/F4 index ae982f4742..9e4305716d 100755 --- a/tests/de/step_2/F4 +++ b/tests/de/step_2/F4 @@ -14,7 +14,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 4 ( 1 ) Summary = 4 ( 1 ) 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 ) diff --git a/tests/de/step_2/M4 b/tests/de/step_2/M4 index 1b540526c0..a4b99a4e7e 100644 --- a/tests/de/step_2/M4 +++ b/tests/de/step_2/M4 @@ -7,7 +7,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 4 ( 8 ) Summary = 4 ( 8 ) 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 ) diff --git a/tests/de/step_2/N8 b/tests/de/step_2/N8 index bfc960e9b2..3b7c5bea43 100644 --- a/tests/de/step_2/N8 +++ b/tests/de/step_2/N8 @@ -1,5 +1,4 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: TPSTAT : Faulty" set filename id_exhaust-B.stp diff --git a/tests/de/step_2/R2 b/tests/de/step_2/R2 index dbf4b23312..cc18f1564c 100644 --- a/tests/de/step_2/R2 +++ b/tests/de/step_2/R2 @@ -7,8 +7,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_2/S1 b/tests/de/step_2/S1 index 6811c4ba78..29df69d871 100644 --- a/tests/de/step_2/S1 +++ b/tests/de/step_2/S1 @@ -10,7 +10,7 @@ set ref_data { 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 ) diff --git a/tests/de/step_2/T1 b/tests/de/step_2/T1 index 3b32cdc71c..7cab7c8f0e 100644 --- a/tests/de/step_2/T1 +++ b/tests/de/step_2/T1 @@ -7,8 +7,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_2/T9 b/tests/de/step_2/T9 index bb9b8e7e88..6b7029363b 100644 --- a/tests/de/step_2/T9 +++ b/tests/de/step_2/T9 @@ -7,9 +7,9 @@ set ref_data { 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 ) diff --git a/tests/de/step_2/U8 b/tests/de/step_2/U8 index 6be1678888..f437a8ef3c 100644 --- a/tests/de/step_2/U8 +++ b/tests/de/step_2/U8 @@ -5,8 +5,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_2/Y5 b/tests/de/step_2/Y5 index f6a0f893b0..a36b39e710 100644 --- a/tests/de/step_2/Y5 +++ b/tests/de/step_2/Y5 @@ -9,8 +9,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_3/A4 b/tests/de/step_3/A4 index f1ff540024..fbcb11a9a1 100644 --- a/tests/de/step_3/A4 +++ b/tests/de/step_3/A4 @@ -8,8 +8,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_3/A8 b/tests/de/step_3/A8 index 472110dadb..cb95fa9ece 100644 --- a/tests/de/step_3/A8 +++ b/tests/de/step_3/A8 @@ -8,7 +8,7 @@ set filename PRO10109.stp 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 ) diff --git a/tests/de/step_3/A9 b/tests/de/step_3/A9 index faa789f0a1..320b7cb839 100755 --- a/tests/de/step_3/A9 +++ b/tests/de/step_3/A9 @@ -1,5 +1,4 @@ # !!!! 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 diff --git a/tests/de/step_3/B9 b/tests/de/step_3/B9 index 4ea8125e64..b6c65f0547 100644 --- a/tests/de/step_3/B9 +++ b/tests/de/step_3/B9 @@ -9,8 +9,8 @@ set ref_data { 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 ) diff --git a/tests/de/step_3/C5 b/tests/de/step_3/C5 index 1819f4c38d..c990ac4c4e 100644 --- a/tests/de/step_3/C5 +++ b/tests/de/step_3/C5 @@ -1,4 +1,5 @@ # !!!! This file is generated automatically, do not edit manually! See end script +puts "TODO CR23096 ALL: CHECKSHAPE : Faulty" puts "TODO CR23096 ALL: STATSHAPE : Faulty" diff --git a/tests/de/step_3/D3 b/tests/de/step_3/D3 index 5a4d676a83..8d39937697 100644 --- a/tests/de/step_3/D3 +++ b/tests/de/step_3/D3 @@ -1,6 +1,4 @@ # !!!! 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} diff --git a/tests/de/step_3/D8 b/tests/de/step_3/D8 index c283bb7cb3..3480b140ce 100755 --- a/tests/de/step_3/D8 +++ b/tests/de/step_3/D8 @@ -1,7 +1,6 @@ # !!!! 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 diff --git a/tests/de/step_3/E6 b/tests/de/step_3/E6 index 6eb4756a9d..07a99fd1b1 100755 --- a/tests/de/step_3/E6 +++ b/tests/de/step_3/E6 @@ -2,18 +2,18 @@ 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 ) diff --git a/tests/de/step_5/A1 b/tests/de/step_5/A1 index 7e9bf33475..60e976b711 100755 --- a/tests/de/step_5/A1 +++ b/tests/de/step_5/A1 @@ -1,14 +1,15 @@ # !!!! 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 ) diff --git a/tests/de/step_5/A4 b/tests/de/step_5/A4 index 776d188162..10876f5ae7 100644 --- a/tests/de/step_5/A4 +++ b/tests/de/step_5/A4 @@ -7,8 +7,8 @@ set ref_data { 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 ) diff --git a/tests/heal/split_angle/F2 b/tests/heal/split_angle/F2 index 851c38719f..3a4b784619 100644 --- a/tests/heal/split_angle/F2 +++ b/tests/heal/split_angle/F2 @@ -1,3 +1 @@ -puts "TODO OCC25593 ALL: Faulty shapes in variables faulty_1 to faulty_4 " - restore [locate_data_file wrong_checkshape_2.brep] a diff --git a/tests/heal/split_closed_faces/G5 b/tests/heal/split_closed_faces/G5 index ae80cdd8c9..3a4b784619 100644 --- a/tests/heal/split_closed_faces/G5 +++ b/tests/heal/split_closed_faces/G5 @@ -1,2 +1 @@ -puts "TODO OCC24035 ALL: Faulty shapes in variables faulty_1 to faulty_" restore [locate_data_file wrong_checkshape_2.brep] a diff --git a/tests/offset/wire_closed_inside_0_005/D1 b/tests/offset/wire_closed_inside_0_005/D1 index 13358e67c6..91b3741ac4 100644 --- a/tests/offset/wire_closed_inside_0_005/D1 +++ b/tests/offset/wire_closed_inside_0_005/D1 @@ -1,6 +1,5 @@ -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 diff --git a/tests/offset/wire_closed_inside_0_075/E8 b/tests/offset/wire_closed_inside_0_075/E8 index 7a01678666..fc9a7cfe06 100644 --- a/tests/offset/wire_closed_inside_0_075/E8 +++ b/tests/offset/wire_closed_inside_0_075/E8 @@ -1,4 +1,5 @@ -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 diff --git a/tests/offset/wire_closed_outside_0_005/D1 b/tests/offset/wire_closed_outside_0_005/D1 index 1d8031ec5a..0f54d31ec6 100644 --- a/tests/offset/wire_closed_outside_0_005/D1 +++ b/tests/offset/wire_closed_outside_0_005/D1 @@ -1,15 +1,15 @@ -#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 diff --git a/tests/offset/wire_closed_outside_0_005/E8 b/tests/offset/wire_closed_outside_0_005/E8 index ad5bec64ad..46d1adf91f 100644 --- a/tests/offset/wire_closed_outside_0_005/E8 +++ b/tests/offset/wire_closed_outside_0_005/E8 @@ -3,7 +3,7 @@ puts "TODO OCC23748 ALL: Faulty shapes in variables faulty_1 to faulty_" 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 diff --git a/tests/offset/wire_closed_outside_0_075/E8 b/tests/offset/wire_closed_outside_0_075/E8 index 355982ce95..7a32074b3e 100644 --- a/tests/offset/wire_closed_outside_0_075/E8 +++ b/tests/offset/wire_closed_outside_0_075/E8 @@ -3,7 +3,7 @@ puts "TODO OCC24255 ALL: Faulty shapes in variables faulty_1 to faulty_" 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