From f2ca59c2a9373e82f3f711bfcd781b9405c710e8 Mon Sep 17 00:00:00 2001 From: skv Date: Fri, 1 Nov 2013 08:35:47 +0000 Subject: [PATCH] 0022351: EDF 2750 GEOM: Fillet 1D does not work on a corner --- src/GEOMImpl/GEOMImpl_Fillet1d.cxx | 111 +++++++++++++++++++++++++++-- src/GEOMImpl/GEOMImpl_Fillet1d.hxx | 3 + 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.cxx b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx index 18b1b31c8..041090e77 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1d.cxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1d.cxx @@ -36,6 +36,7 @@ #include #include #include +#include /** * class GEOMImpl_Fillet1d @@ -248,8 +249,109 @@ Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius) } myRadius = theRadius; + + // Compute the intervals. + const Standard_Real aTol = Precision::Confusion(); + Geom2dAPI_InterCurveCurve anAPIInter(myCurve1, myCurve2, aTol); + const Geom2dInt_GInter &anInter = anAPIInter.Intersector(); + Standard_Integer aNb = anInter.NbPoints(); + Standard_Integer i; + TColStd_ListOfReal aParams; + TColStd_ListIteratorOfListOfReal anIter; + + // Treat intersection points. + for(i = 1; i <= aNb; i++) { + const IntRes2d_IntersectionPoint &aPoint = anInter.Point(i); + Standard_Real aParam = aPoint.ParamOnFirst(); + + // Adjust parameter on periodic curve. + if (myCurve1->IsPeriodic()) { + aParam = ElCLib::InPeriod + (aParam, myStart1, myStart1 + myCurve1->Period()); + } + + if (aParam > myStart1 + aTol && aParam < myEnd1 - aTol) { + // Add the point in the list in increasing order. + for(anIter.Initialize(aParams); anIter.More(); anIter.Next()) { + if (anIter.Value() > aParam) { + aParams.InsertBefore(aParam, anIter); + break; + } + } + + if (!anIter.More()) { + aParams.Append(aParam); + } + } + } + + // Treat intersection segments. + aNb = anInter.NbSegments(); + + for(i = 1; i <= aNb; i++) { + const IntRes2d_IntersectionSegment &aSegment = anInter.Segment(i); + + if (aSegment.HasFirstPoint() && aSegment.HasLastPoint()) { + Standard_Real aParam1 = aSegment.FirstPoint().ParamOnFirst(); + Standard_Real aParam2 = aSegment.LastPoint().ParamOnFirst(); + + // Adjust parameters on periodic curve. + if (myCurve1->IsPeriodic()) { + ElCLib::AdjustPeriodic(myStart1, myStart1 + myCurve1->Period(), + aTol, aParam1, aParam2); + } + + if (aParam1 > myStart1 + aTol && aParam1 < myEnd1 - aTol && + aParam2 > myStart1 + aTol && aParam2 < myEnd1 - aTol) { + // Add the point in the list in increasing order. + const Standard_Real aParam = 0.5*(aParam1 + aParam2); + + for(anIter.Initialize(aParams); anIter.More(); anIter.Next()) { + if (anIter.Value() > aParam) { + aParams.InsertBefore(aParam, anIter); + break; + } + } + + if (!anIter.More()) { + aParams.Append(aParam); + } + } + } + } + + // Add start and end parameters to the list. + aParams.Prepend(myStart1); + aParams.Append(myEnd1); + anIter.Initialize(aParams); + + // Perform each interval. + Standard_Real aStart = anIter.Value(); + + for (anIter.Next(); anIter.More(); anIter.Next()) { + const Standard_Real anEnd = anIter.Value(); + + // Perform the interval. + performInterval(aStart, anEnd, aNBSteps); + aStart = anEnd; + } + + if (myResultParams.Extent()) + return Standard_True; + + return Standard_False; +} + +//======================================================================= +//function : performInterval +//purpose : +//======================================================================= +void GEOMImpl_Fillet1d::performInterval(const Standard_Real theStart, + const Standard_Real theEnd, + const Standard_Integer theNBSteps) +{ Standard_Real aParam, aStep, aDStep; - aStep = (myEnd1 - myStart1) / aNBSteps; + aStep = (theEnd - theStart) / theNBSteps; aDStep = aStep/1000.; Standard_Integer aCycle; @@ -257,7 +359,7 @@ Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius) { GEOMImpl_Fillet1dPoint *aLeft = NULL, *aRight = NULL; - for(aParam = myStart1 + aStep; aParam < myEnd1 || fabs(myEnd1 - aParam) < Precision::Confusion(); aParam += aStep) + for(aParam = theStart + aStep; aParam < theEnd || fabs(theEnd - aParam) < Precision::Confusion(); aParam += aStep) { if (!aLeft) { @@ -278,11 +380,6 @@ Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius) } delete aLeft; } - - if (myResultParams.Extent()) - return Standard_True; - - return Standard_False; } //======================================================================= diff --git a/src/GEOMImpl/GEOMImpl_Fillet1d.hxx b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx index 86464d67a..9a6b9ad9c 100644 --- a/src/GEOMImpl/GEOMImpl_Fillet1d.hxx +++ b/src/GEOMImpl/GEOMImpl_Fillet1d.hxx @@ -57,6 +57,9 @@ public: private: //! private methods + void performInterval(const Standard_Real theStart, + const Standard_Real theEnd, + const Standard_Integer theNBSteps); void fillPoint(GEOMImpl_Fillet1dPoint*); void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean); void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*); -- 2.39.2