mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +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:
@@ -108,10 +108,61 @@
|
||||
#include <Approx_CurvilinearParameter.hxx>
|
||||
#include <Approx_CurveOnSurface.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
|
||||
#include <AppCont_Function.hxx>
|
||||
#include <Adaptor3d_HCurve.hxx>
|
||||
#include <GeomAdaptor_HCurve.hxx>
|
||||
#include <Approx_FitAndDivide.hxx>
|
||||
#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
|
||||
|
||||
#ifdef _WIN32
|
||||
Standard_IMPORT Draw_Viewer dout;
|
||||
#endif
|
||||
|
||||
//Class is used in fitcurve
|
||||
class CurveEvaluator : public AppCont_Function
|
||||
|
||||
{
|
||||
|
||||
public:
|
||||
Handle(Adaptor3d_HCurve) myCurve;
|
||||
|
||||
CurveEvaluator(const Handle(Adaptor3d_HCurve)& C)
|
||||
: myCurve(C)
|
||||
{
|
||||
myNbPnt = 1;
|
||||
myNbPnt2d = 0;
|
||||
}
|
||||
|
||||
Standard_Real FirstParameter() const
|
||||
{
|
||||
return myCurve->FirstParameter();
|
||||
}
|
||||
|
||||
Standard_Real LastParameter() const
|
||||
{
|
||||
return myCurve->LastParameter();
|
||||
}
|
||||
|
||||
Standard_Boolean Value(const Standard_Real theT,
|
||||
NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
|
||||
NCollection_Array1<gp_Pnt>& thePnt) const
|
||||
{
|
||||
thePnt(1) = myCurve->Value(theT);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean D1(const Standard_Real theT,
|
||||
NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
|
||||
NCollection_Array1<gp_Vec>& theVec) const
|
||||
{
|
||||
gp_Pnt aDummyPnt;
|
||||
myCurve->D1(theT, aDummyPnt, theVec(1));
|
||||
return Standard_True;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : anacurve
|
||||
//purpose :
|
||||
@@ -1672,6 +1723,99 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : fitcurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Integer fitcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n<3) return 1;
|
||||
|
||||
Handle(Geom_Curve) GC;
|
||||
GC = DrawTrSurf::GetCurve(a[2]);
|
||||
if (GC.IsNull())
|
||||
return 1;
|
||||
|
||||
Standard_Integer Dmin = 3;
|
||||
Standard_Integer Dmax = 14;
|
||||
Standard_Real Tol3d = 1.e-5;
|
||||
Standard_Boolean inverse = Standard_True;
|
||||
|
||||
if (n > 3)
|
||||
{
|
||||
Tol3d = Atof(a[3]);
|
||||
}
|
||||
|
||||
if (n > 4)
|
||||
{
|
||||
Dmax = atoi(a[4]);
|
||||
}
|
||||
|
||||
if (n > 5)
|
||||
{
|
||||
Standard_Integer inv = atoi(a[5]);
|
||||
if (inv > 0)
|
||||
{
|
||||
inverse = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
inverse = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
Handle(GeomAdaptor_HCurve) aGAC = new GeomAdaptor_HCurve(GC);
|
||||
|
||||
CurveEvaluator aCE(aGAC);
|
||||
|
||||
Approx_FitAndDivide anAppro(Dmin, Dmax, Tol3d, 0., Standard_True);
|
||||
anAppro.SetInvOrder(inverse);
|
||||
anAppro.Perform(aCE);
|
||||
|
||||
if (!anAppro.IsAllApproximated())
|
||||
{
|
||||
di << "Approximation failed \n";
|
||||
return 1;
|
||||
}
|
||||
Standard_Integer i;
|
||||
Standard_Integer NbCurves = anAppro.NbMultiCurves();
|
||||
|
||||
Convert_CompBezierCurvesToBSplineCurve Conv;
|
||||
|
||||
Standard_Real tol3d, tol2d, tolreached = 0.;
|
||||
for (i = 1; i <= NbCurves; i++) {
|
||||
anAppro.Error(i, tol3d, tol2d);
|
||||
tolreached = Max(tolreached, tol3d);
|
||||
AppParCurves_MultiCurve MC = anAppro.Value(i);
|
||||
TColgp_Array1OfPnt Poles(1, MC.Degree() + 1);
|
||||
MC.Curve(1, Poles);
|
||||
Conv.AddCurve(Poles);
|
||||
}
|
||||
Conv.Perform();
|
||||
Standard_Integer NbPoles = Conv.NbPoles();
|
||||
Standard_Integer NbKnots = Conv.NbKnots();
|
||||
|
||||
TColgp_Array1OfPnt NewPoles(1, NbPoles);
|
||||
TColStd_Array1OfReal NewKnots(1, NbKnots);
|
||||
TColStd_Array1OfInteger NewMults(1, NbKnots);
|
||||
|
||||
Conv.KnotsAndMults(NewKnots, NewMults);
|
||||
Conv.Poles(NewPoles);
|
||||
|
||||
BSplCLib::Reparametrize(GC->FirstParameter(),
|
||||
GC->LastParameter(),
|
||||
NewKnots);
|
||||
Handle(Geom_BSplineCurve) TheCurve = new Geom_BSplineCurve(NewPoles, NewKnots, NewMults, Conv.Degree());
|
||||
|
||||
DrawTrSurf::Set(a[1], TheCurve);
|
||||
di << a[1] << ": tolreached = " << tolreached << "\n";
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : newbspline
|
||||
//purpose : reduce the multiplicity of the knots to their minimum
|
||||
@@ -2060,6 +2204,8 @@ void GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
|
||||
__FILE__,
|
||||
approxcurveonsurf,g);
|
||||
|
||||
theCommands.Add("fitcurve", "fitcurve result curve [tol [maxdeg [inverse]]]", __FILE__, fitcurve, g);
|
||||
|
||||
theCommands.Add("length", "length curve [Tol]",
|
||||
__FILE__,
|
||||
length, g);
|
||||
|
Reference in New Issue
Block a user