1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0030435: Improving performance of Approx_ComputeCLine

1. Approx_ComputeCLine.gxx, Approx_FitAndDivide.hxx, Approx_FitAndDivide2d.hxx, BRepFill_ComputeCLine.hxx
It is base modification, which allows improve performance of approximation with help of Approx_ComputeCLine. The main idea of improvement is using degree selection by inverse order - from maxdegree to mindegree. If tolerance for maxdegree is not reached, there is no sense to make approximation for current number of knots with lower degree, it is necessary to cut parametric interval.

2. ProjLib_ComputeApprox, ProjLib_ComputeApproxOnPolarSurface, ProjLib_ComputeApproxOnPolarSurface, ProjLib_ProjectOnPlane
It is additional modification of methods using Approx_ComputeCLine.
Mainly, modifications concern to more optimal choosing parameters for approximation algorithm.

3. BRepCheck_Face
Small improvement of method Intersect(...), which intersects two wires on face.

4. BRepTopAdaptor_FClass2d
Impovement of treatment infinitely narrow faces.

5. ChFi3d/ChFi3d_Builder_6.cxx
Small improvement, which forbids extension of singular boundary of surface.
It was TODO problem in tests/bugs/modalg_7/bug27711_3

6. IntTools_EdgeEdge.cxx
Improvement of performance for cases of searching common parts between line  and analytical curve

7. GeomliteTest_CurveCommands.cxx
Adding Draw command fitcurve. This command is analog of approxcurve, but uses Approx_FitAndDivide algorithm.
Mainly to have direct draw command for testing Approx_ComputeCLine.

8. Extrema_ExtElC.cxx

Treatment of case "infinite solutions" for extrema line-ellipse

9. Modification of some tests according to new behavior of algorithm.

10. tests/perf/moddata/bug30435
Test for new improved algorithm.

11. Implementation QAcommand OCC30435 in QABugs_20.cxx used in test bug30435
This commit is contained in:
ifv
2019-01-10 13:07:01 +03:00
parent 130bc3c097
commit ba7f665dce
21 changed files with 611 additions and 53 deletions

View File

@@ -25,6 +25,8 @@
#include <Approx_Status.hxx>
#include <Precision.hxx>
const static Standard_Integer MAXSEGM = 1000;
//=======================================================================
//function : Approx_ComputeCLine
//purpose : The MultiLine <Line> will be approximated until tolerances
@@ -50,7 +52,8 @@ const AppParCurves_Constraint LastC)
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
myMaxSegments = IntegerLast();
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
alldone = Standard_False;
Perform(Line);
}
@@ -77,7 +80,8 @@ const AppParCurves_Constraint LastC)
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
myMaxSegments = IntegerLast();
myMaxSegments = MAXSEGM;
myInvOrder = Standard_True;
}
//=======================================================================
@@ -244,33 +248,117 @@ Standard_Boolean Approx_ComputeCLine::Compute(const MultiLine& Line,
{
Standard_Integer deg, NbPoints = 24;
const Standard_Integer NbPointsMax = 24;
const Standard_Real aMinRatio = 0.05;
const Standard_Integer aMaxDeg = 8;
//
Standard_Integer deg, NbPoints;
Standard_Boolean mydone;
Standard_Real Fv;
for (deg = mydegremin; deg <= mydegremax; deg++) {
AppCont_LeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC, deg, NbPoints);
mydone = LSquare.IsDone();
if (mydone) {
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
AppParCurves_MultiCurve aPrevCurve;
Standard_Real aPrevTol3d = RealLast(), aPrevTol2d = RealLast();
Standard_Boolean aPrevIsOk = Standard_False;
Standard_Boolean anInvOrder = myInvOrder;
if (anInvOrder && mydegremax > aMaxDeg)
{
if ((Ulast - Ufirst) / (Line.LastParameter() - Line.FirstParameter()) < aMinRatio)
{
anInvOrder = Standard_False;
}
}
if (anInvOrder)
{
for (deg = mydegremax; deg >= mydegremin; deg--) {
NbPoints = Min(2 * deg + 1, NbPointsMax);
AppCont_LeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC, deg, NbPoints);
mydone = LSquare.IsDone();
if (mydone)
{
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d)
{
if (deg == mydegremin)
{
// Stockage de la multicurve approximee.
tolreached = Standard_True;
myMultiCurves.Append(LSquare.Value());
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(TheTol3d);
Tolers2d.Append(TheTol2d);
return Standard_True;
}
aPrevTol3d = TheTol3d;
aPrevTol2d = TheTol2d;
aPrevCurve = LSquare.Value();
aPrevIsOk = Standard_True;
continue;
}
else if (aPrevIsOk)
{
// Stockage de la multicurve approximee.
tolreached = Standard_True;
TheTol3d = aPrevTol3d;
TheTol2d = aPrevTol2d;
myMultiCurves.Append(aPrevCurve);
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(aPrevTol3d);
Tolers2d.Append(aPrevTol2d);
return Standard_True;
}
}
else if (aPrevIsOk)
{
// Stockage de la multicurve approximee.
tolreached = Standard_True;
myMultiCurves.Append(LSquare.Value());
TheTol3d = aPrevTol3d;
TheTol2d = aPrevTol2d;
myMultiCurves.Append(aPrevCurve);
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(TheTol3d);
Tolers2d.Append(TheTol2d);
Tolers3d.Append(aPrevTol3d);
Tolers2d.Append(aPrevTol2d);
return Standard_True;
}
if (!aPrevIsOk && deg == mydegremax)
{
TheMultiCurve = LSquare.Value();
currenttol3d = TheTol3d;
currenttol2d = TheTol2d;
aPrevTol3d = TheTol3d;
aPrevTol2d = TheTol2d;
aPrevCurve = TheMultiCurve;
break;
}
}
if (deg == mydegremax) {
TheMultiCurve = LSquare.Value();
currenttol3d = TheTol3d;
currenttol2d = TheTol2d;
}
else
{
for (deg = mydegremin; deg <= mydegremax; deg++) {
NbPoints = Min(2 * deg + 1, NbPointsMax);
AppCont_LeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC, deg, NbPoints);
mydone = LSquare.IsDone();
if (mydone) {
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
// Stockage de la multicurve approximee.
tolreached = Standard_True;
myMultiCurves.Append(LSquare.Value());
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(TheTol3d);
Tolers2d.Append(TheTol2d);
return Standard_True;
}
}
if (deg == mydegremax) {
TheMultiCurve = LSquare.Value();
currenttol3d = TheTol3d;
currenttol2d = TheTol2d;
}
}
}
return Standard_False;
}
@@ -335,6 +423,15 @@ void Approx_ComputeCLine::SetMaxSegments(const Standard_Integer theMaxSegments)
myMaxSegments = theMaxSegments;
}
//=======================================================================
//function : SetInvOrder
//purpose :
//=======================================================================
void Approx_ComputeCLine::SetInvOrder(const Standard_Boolean theInvOrder)
{
myInvOrder = theInvOrder;
}
//=======================================================================
//function : IsAllApproximated
//purpose : returns False if at a moment of the approximation,

View File

@@ -64,6 +64,12 @@ public:
//! Changes the max number of segments, which is allowed for cutting.
Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments);
//! Set inverse order of degree selection:
//! if theInvOrdr = true, current degree is chosen by inverse order -
//! from maxdegree to mindegree.
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -118,6 +124,7 @@ private:
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
};

View File

@@ -64,6 +64,12 @@ public:
//! Changes the max number of segments, which is allowed for cutting.
Standard_EXPORT void SetMaxSegments (const Standard_Integer theMaxSegments);
//! Set inverse order of degree selection:
//! if theInvOrdr = true, current degree is chosen by inverse order -
//! from maxdegree to mindegree.
//! By default inverse order is used.
Standard_EXPORT void SetInvOrder(const Standard_Boolean theInvOrder);
//! returns False if at a moment of the approximation,
//! the status NoApproximation has been sent by the user
//! when more points were needed.
@@ -118,7 +124,7 @@ private:
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMaxSegments;
Standard_Boolean myInvOrder;
};