#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp.hxx>
+#include <NCollection_List.hxx>
+#include <math_PSO.hxx>
+#include <math_BrentMinimum.hxx>
#define Us3 0.3333333333333333333333333333
Standard_Real U1 = firstu;
Standard_Real LTol = Precision::Confusion (); //protection longueur nulle
- Standard_Real ATol = Precision::Angular (); //protection angle nul
+ Standard_Real ATol = 1.e-2 * angularDeflection;
+ if(ATol > 1.e-2)
+ ATol = 1.e-2;
+ else if(ATol < 1.e-7)
+ ATol = 1.e-7;
D0 (C, lastu, LastPoint);
TColStd_Array1OfReal Intervs(1, NbInterv+1);
C.Intervals(Intervs, GeomAbs_CN);
- if (NotDone) {
+ if (NotDone || Du > 5. * Dusave) {
//C'est soit une droite, soit une singularite :
V1 = (LastPoint.XYZ() - CurrentPoint.XYZ());
L1 = V1.Modulus ();
//Si c'est une droite on verifie en calculant minNbPoints :
Standard_Boolean IsLine = Standard_True;
Standard_Integer NbPoints = (minNbPnts > 3) ? minNbPnts : 3;
+ switch (C.GetType()) {
+ case GeomAbs_BSplineCurve:
+ {
+ Handle_TheBSplineCurve BS = C.BSpline() ;
+ NbPoints = Max(BS->Degree() + 1, NbPoints);
+ break;
+ }
+ case GeomAbs_BezierCurve:
+ {
+ Handle_TheBezierCurve BZ = C.Bezier();
+ NbPoints = Max(BZ->Degree() + 1, NbPoints);
+ break;
+ }
+ default:
+ ;}
////
Standard_Real param = 0.;
for (i = 1; i <= NbInterv && IsLine; ++i)
i++;
}
}
+ //Additional check for intervals
+ Standard_Real MinLen2 = myMinLen * myMinLen;
+ Standard_Integer MaxNbp = 10 * Nbp;
+ for(i = 1; i < Nbp; ++i)
+ {
+ U1 = parameters(i);
+ U2 = parameters(i + 1);
+ // Check maximal deflection on interval;
+ Standard_Real dmax = 0.;
+ Standard_Real umax = 0.;
+ Standard_Real amax = 0.;
+ EstimDefl(C, U1, U2, dmax, umax);
+ const gp_Pnt& P1 = points(i);
+ const gp_Pnt& P2 = points(i+1);
+ D0(C, umax, MiddlePoint);
+ amax = EstimAngl(P1, MiddlePoint, P2);
+ if(dmax > curvatureDeflection || amax > AngleMax)
+ {
+ if(umax - U1 > uTol && U2 - umax > uTol)
+ {
+ if (P1.SquareDistance(MiddlePoint) > MinLen2 && P2.SquareDistance(MiddlePoint) > MinLen2)
+ {
+ parameters.InsertAfter(i, umax);
+ points.InsertAfter(i, MiddlePoint);
+ ++Nbp;
+ --i; //To compensate ++i in loop header: i must point to first part of splitted interval
+ if(Nbp > MaxNbp)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ //
+}
+
+//=======================================================================
+//function : EstimDefl
+//purpose : Estimation of maximal deflection for interval [U1, U2]
+//
+//=======================================================================
+void GCPnts_TangentialDeflection::EstimDefl (const TheCurve& C,
+ const Standard_Real U1, const Standard_Real U2,
+ Standard_Real& MaxDefl, Standard_Real& UMax)
+{
+ Standard_Real Du = (lastu - firstu);
+ //
+ TheMaxCurvLinDist aFunc(C, U1, U2);
+ //
+ const Standard_Integer aNbIter = 100;
+ Standard_Real reltol = Max(1.e-3, 2.*uTol/((Abs(U1) + Abs(U2))));
+ //
+ math_BrentMinimum anOptLoc(reltol, aNbIter, uTol);
+ anOptLoc.Perform(aFunc, U1, (U1+U2)/2., U2);
+ if(anOptLoc.IsDone())
+ {
+ MaxDefl = Sqrt(-anOptLoc.Minimum());
+ UMax = anOptLoc.Location();
+ return;
+ }
+ //
+ math_Vector aLowBorder(1,1);
+ math_Vector aUppBorder(1,1);
+ math_Vector aSteps(1,1);
+ //
+ aSteps(1) = Max(0.1 * Du, 100. * uTol);
+ Standard_Integer aNbParticles = Max(8, RealToInt(32 * (U2 - U1) / Du));
+ //
+ aLowBorder(1) = U1;
+ aUppBorder(1) = U2;
+ //
+ //
+ Standard_Real aValue;
+ math_Vector aT(1,1);
+ TheMaxCurvLinDistMV aFuncMV(aFunc);
+
+ math_PSO aFinder(&aFuncMV, aLowBorder, aUppBorder, aSteps, aNbParticles);
+ aFinder.Perform(aSteps, aValue, aT);
+ //
+ anOptLoc.Perform(aFunc, Max(aT(1) - aSteps(1), U1) , aT(1), Min(aT(1) + aSteps(1),U2));
+ if(anOptLoc.IsDone())
+ {
+ MaxDefl = Sqrt(-anOptLoc.Minimum());
+ UMax = anOptLoc.Location();
+ return;
+ }
+ MaxDefl = Sqrt(-aValue);
+ UMax = aT(1);
+ //
}