From 9a6ea9c4793d0d97bf79e9b2fc5e908fc7799dc3 Mon Sep 17 00:00:00 2001 From: aml Date: Thu, 26 Feb 2015 13:29:35 +0300 Subject: [PATCH] 0017129: ShapeFix projector makes 2d curves with oscillations Usage of Projlib added in case of uneven points distribution. Test cases are updated to the new behavior. Test cases for issue CR17129 Correction of test case for issue CR17129 --- .../ShapeConstruct_ProjectCurveOnSurface.cxx | 156 +++++++++++++----- tests/bugs/heal/bug17129 | 18 ++ tests/de/step_2/O3 | 8 +- tests/de/step_3/F2 | 2 - tests/de/step_4/B3 | 1 + tests/de/step_4/D2 | 2 +- 6 files changed, 136 insertions(+), 51 deletions(-) create mode 100644 tests/bugs/heal/bug17129 diff --git a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx index e25429ba22..1c6cf283ea 100644 --- a/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx +++ b/src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx @@ -33,15 +33,22 @@ #include #include +#include + #include #include #include +#include #include #include #include #include #include +#include +#include +#include +#include #include #include #include @@ -191,7 +198,6 @@ static Standard_Integer NbSurfIntervals(const Handle(GeomAdaptor_HSurface)& GAS, //function : Perform //purpose : //======================================================================= - Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curve)& c3d, const Standard_Real First, const Standard_Real Last, @@ -208,7 +214,6 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); return Standard_False; } - // Projection Analytique Handle(Geom_Curve) crv3dtrim = c3d; if ( ! c3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) ) @@ -252,15 +257,77 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv // $$$$ end :92 (big BSplineCurve C0) // this number should be "parametric dependent" - TColgp_Array1OfPnt points(1, nbPini); + TColgp_Array1OfPnt points(1, nbPini); TColStd_Array1OfReal params(1, nbPini); - - Standard_Integer iPnt; + NCollection_Sequence aKnotCoeffs; gp_Pnt p3d; + Standard_Integer iPnt; + + // In case of bspline compute parametrization speed on each + // knot interval inside [aFirstParam, aLastParam]. + // If quotient = (MaxSpeed / MinSpeed) >= aMaxQuotientCoeff then + // use PerformByProjLib algorithm. + if(!bspl.IsNull()) + { + Standard_Integer aNbIntPnts = NCONTROL; + Standard_Real aFirstParam = First; // First parameter of current interval. + Standard_Real aLastParam = Last; // Last parameter of current interval. + + // First index computation. + Standard_Integer anIdx = 1; + for(; anIdx <= bspl->NbKnots() && aFirstParam < Last; anIdx++) + { + if(bspl->Knot(anIdx) > First) + { + break; + } + } + + for(; anIdx <= bspl->NbKnots() && aFirstParam < Last; anIdx++) + { + // Fill current knot interval. + aLastParam = Min(Last, bspl->Knot(anIdx)); + Standard_Real aStep = (aLastParam - aFirstParam) / (aNbIntPnts - 1); + Standard_Integer anIntIdx; + gp_Pnt p3d1, p3d2; + Standard_Real aLength3d = 0.0; + for(anIntIdx = 0; anIntIdx < aNbIntPnts - 1; anIntIdx++) + { + // Start filling from first point. + Standard_Real aParam1 = aFirstParam + aStep * anIntIdx; + Standard_Real aParam2 = aFirstParam + aStep * (anIntIdx + 1); + c3d->D0 (aParam1, p3d1); + c3d->D0 (aParam2, p3d2); + aLength3d += p3d2.Distance(p3d1); + } + aKnotCoeffs.Append(aLength3d / (aLastParam - aFirstParam)); + aFirstParam = aLastParam; + } + + Standard_Real anEvenlyCoeff = 0; + if (aKnotCoeffs.Size() > 0) + { + anEvenlyCoeff = *std::max_element(aKnotCoeffs.begin(), aKnotCoeffs.end()) / + *std::min_element(aKnotCoeffs.begin(), aKnotCoeffs.end()); + } + + const Standard_Real aMaxQuotientCoeff = 1500.0; + if (anEvenlyCoeff > aMaxQuotientCoeff) + { + PerformByProjLib(c3d, First, Last, c2d); + // PerformByProjLib fail detection: + if (!c2d.IsNull()) + { + return Status (ShapeExtend_DONE); + } + } + } + Standard_Real deltaT, t; deltaT = (Last - First) / (nbPini-1); nbrPnt = nbPini; - for (iPnt = 1; iPnt <= nbPini; iPnt ++) { + for (iPnt = 1; iPnt <= nbPini; iPnt ++) + { if (iPnt == 1) t = First; else if (iPnt == nbPini) t = Last; else t = First + (iPnt - 1) * deltaT; @@ -270,8 +337,7 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curv params(iPnt) = t; } -// CALCUL par approximation - + // CALCUL par approximation TColgp_Array1OfPnt2d pnt2d(1, nbrPnt); ApproxPCurve (nbrPnt,points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed if (!c2d.IsNull()) { @@ -320,9 +386,9 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(Handle(G const Standard_Real First, const Standard_Real Last, Handle(Geom2d_Curve)& c2d, - const GeomAbs_Shape continuity, - const Standard_Integer maxdeg, - const Standard_Integer nbinterval) + const GeomAbs_Shape /*continuity*/, + const Standard_Integer /*maxdeg */, + const Standard_Integer /*nbinterval */) { //Standard_Boolean OK = Standard_True; //szv#4:S4163:12Mar99 unused c2d.Nullify(); @@ -331,51 +397,53 @@ Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(Handle(G return Standard_False; } - try { + try + { OCC_CATCH_SIGNALS Handle(GeomAdaptor_HSurface) GAS = mySurf->Adaptor3d(); - Standard_Real URes = GAS->ChangeSurface().UResolution ( myPreci ); - Standard_Real VRes = GAS->ChangeSurface().VResolution ( myPreci ); Handle(GeomAdaptor_HCurve) GAC = new GeomAdaptor_HCurve (c3d,First,Last); - ProjLib_CompProjectedCurve Projector ( GAS, GAC, URes, VRes ); - - Standard_Real ubeg, ufin; - Standard_Integer nbSol = Projector.NbCurves(); - if (nbSol==1) { - Projector.Bounds(1, ubeg, ufin); - if((ubeg<=First)&&(ufin>=Last)) { - Standard_Integer nbintervals = ( nbinterval < 1 ? - NbSurfIntervals(GAS, GeomAbs_C3)+GAC->NbIntervals(GeomAbs_C3)+2: - nbinterval); - Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve(); - HProjector->Set(Projector); - Handle(Adaptor2d_HCurve2d) HPCur = HProjector; - Approx_CurveOnSurface appr(HPCur, GAS, First, Last, myPreci, - continuity, maxdeg, - nbintervals, - Standard_False, Standard_True); - if ( appr.IsDone() ) - c2d = appr.Curve2d(); - } -#ifdef OCCT_DEBUG - else - cout<<"Warning: ProjLib cutting pcurve "<< First << " -> " << ubeg <<" ; "<< Last << " -> " << ufin << endl; -#endif + ProjLib_ProjectedCurve Projector(GAS, GAC); + + switch (Projector.GetType()) + { + case GeomAbs_Line : + c2d = new Geom2d_Line(Projector.Line()); + break; + case GeomAbs_Circle : + c2d = new Geom2d_Circle(Projector.Circle()); + break; + case GeomAbs_Ellipse : + c2d = new Geom2d_Ellipse(Projector.Ellipse()); + break; + case GeomAbs_Parabola : + c2d = new Geom2d_Parabola(Projector.Parabola()); + break; + case GeomAbs_Hyperbola : + c2d = new Geom2d_Hyperbola(Projector.Hyperbola()); + break; + case GeomAbs_BSplineCurve : + c2d = Projector.BSpline(); + break; + case GeomAbs_BezierCurve : + case GeomAbs_OtherCurve : + // Not possible, handling added to avoid gcc warning. + break; } -#ifdef OCCT_DEBUG - else cout<<"Warning: ProjLib "<< nbSol << " curves in ProjLib"<Print(cout); cout << endl; diff --git a/tests/bugs/heal/bug17129 b/tests/bugs/heal/bug17129 new file mode 100644 index 0000000000..f76edc0cab --- /dev/null +++ b/tests/bugs/heal/bug17129 @@ -0,0 +1,18 @@ +puts "============" +puts "OCC17129" +puts "============" +puts "" +####################################################################### +# ShapeFix projector makes 2d curves with oscillations +####################################################################### + +restore [locate_data_file bug17129_ff_1285_proj.brep] a +fixshape r a + +pcurve r + +#v2d2 +view 1 -2D- 728 20 400 400 + +2dfit +set only_screen_axo 1 diff --git a/tests/de/step_2/O3 b/tests/de/step_2/O3 index 9e847f0f6c..09b3c529eb 100644 --- a/tests/de/step_2/O3 +++ b/tests/de/step_2/O3 @@ -1,5 +1,5 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: TPSTAT : Faulty" +puts "TODO CR23096 ALL: NBSHAPES : Faulty" set filename ie_soapbox-A.stp @@ -8,9 +8,9 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 28 ( 20 ) Summary = 28 ( 20 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 112 ( 112 ) Summary = 687 ( 687 ) -STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 112 ( 112 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 288 ( 288 ) -TOLERANCE : MaxTol = 0.009966026823 ( 0.009966026821 ) AvgTol = 0.001107205459 ( 0.001088049274 ) +NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 112 ( 112 ) Summary = 685 ( 687 ) +STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 112 ( 112 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 286 ( 288 ) +TOLERANCE : MaxTol = 0.5384357498 ( 0.5384357497 ) AvgTol = 0.009441130625 ( 0.009436309132 ) 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 ) NCOLORS : NColors = 0 ( 0 ) diff --git a/tests/de/step_3/F2 b/tests/de/step_3/F2 index 5b2158d3e0..5a1de261d9 100644 --- a/tests/de/step_3/F2 +++ b/tests/de/step_3/F2 @@ -1,6 +1,4 @@ # !!!! This file is generated automatically, do not edit manually! See end script -puts "TODO CR23096 ALL: CHECKSHAPE : Faulty" - set filename PRO10368.stp diff --git a/tests/de/step_4/B3 b/tests/de/step_4/B3 index 54264f50fc..6385a5e170 100644 --- a/tests/de/step_4/B3 +++ b/tests/de/step_4/B3 @@ -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: TPSTAT : Faulty" set LinuxDiff 1 set LinuxFaulties {TOLERANCE} diff --git a/tests/de/step_4/D2 b/tests/de/step_4/D2 index ebb1bf03b6..8ecde034ba 100644 --- a/tests/de/step_4/D2 +++ b/tests/de/step_4/D2 @@ -7,7 +7,7 @@ TPSTAT : Faulties = 0 ( 0 ) Warnings = 10 ( 14 ) Summary = 10 ( 14 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) NBSHAPES : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 108 ( 108 ) Summary = 673 ( 673 ) STATSHAPE : Solid = 2 ( 2 ) Shell = 2 ( 2 ) Face = 108 ( 108 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 282 ( 282 ) -TOLERANCE : MaxTol = 0.01749235594 ( 0.01749235594 ) AvgTol = 0.003723787424 ( 0.003735669579 ) +TOLERANCE : MaxTol = 0.5384357498 ( 0.5384357497 ) AvgTol = 0.01216240032 ( 0.0121742825 ) 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 ) NCOLORS : NColors = 0 ( 0 )