From a7f7c11ec74ed7a6788988d699a899cc07488f5e Mon Sep 17 00:00:00 2001 From: nbv Date: Fri, 22 Sep 2017 11:24:35 +0300 Subject: [PATCH] 0029093: BOP PaveFiller hungs and constantly consumes memory Method IntWalk_PWalking::ExtendLineInCommonZone(...) because it seems to be created for single case and (therefore) is not universal. It is bad idea to try to go along iso-line in case of tangent. Now, there is more intellectual method IntWalk_PWalking::PutToBoundary(...) but its current representation allows extending WLine to the boundary only. I.e. if tangent zone is in middle place of the surface this method will have no effect. --- src/IntWalk/IntWalk_PWalking.cxx | 420 ------------------------------- src/IntWalk/IntWalk_PWalking.hxx | 3 - tests/perf/modalg/bug29093 | 47 ++++ 3 files changed, 47 insertions(+), 423 deletions(-) create mode 100644 tests/perf/modalg/bug29093 diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index eed1c6334a..b6675a6a75 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -1295,8 +1295,6 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, //==================================================== //== Param was not in the limits (was reframed) //==================================================== - Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent(); - IntImp_ConstIsoparametric SauvChoixIso = ChoixIso; ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); // @@ -1598,33 +1596,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, } } - // - Standard_Boolean wasExtended = Standard_False; - - if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) - { - if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) - { - wasExtended = Standard_True; - Arrive = Standard_False; - ChoixIso = SauvChoixIso; - } - } - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); - - if(Arrive && - myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() && - myIntersectionOn2S.IsTangent() && bPrevNotTangent && - !wasExtended) - { - if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) - { - wasExtended = Standard_True; - Arrive = Standard_False; - ChoixIso = SauvChoixIso; - } - } }//else !TestArret() $ }//$$ end successful framing on border (!myIntersectionOn2S.IsEmpty()) else @@ -1644,398 +1616,6 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, done = Standard_True; } -// =========================================================================================================== -// function: ExtendLineInCommonZone -// purpose: Extends already computed line inside tangent zone in the direction given by theChoixIso. -// Returns Standard_True if the line was extended through tangent zone and the last computed point -// is outside the tangent zone (but it is not put into the line). Otherwise returns Standard_False. -// =========================================================================================================== -Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsoparametric theChoixIso, - const Standard_Boolean theDirectionFlag) -{ - Standard_Boolean bOutOfTangentZone = Standard_False; - Standard_Boolean bStop = !myIntersectionOn2S.IsTangent(); - Standard_Integer dIncKey = 1; - TColStd_Array1OfReal Param(1,4); - IntWalk_StatusDeflection aStatus = IntWalk_OK; - Standard_Integer nbIterWithoutAppend = 0; - Standard_Integer nbEqualPoints = 0; - Standard_Integer parit = 0; - Standard_Integer uvit = 0; - IntSurf_SequenceOfPntOn2S aSeqOfNewPoint; - - while (!bStop) { - nbIterWithoutAppend++; - - if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) { -#ifdef OCCT_DEBUG - cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl; -#endif - bStop = Standard_True; - break; - } - Standard_Real f = 0.; - - switch (theChoixIso) - { - case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break; - case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break; - case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break; - case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break; - } - - if(f<0.1) f=0.1; - - previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4)); - - Standard_Real dP1 = sensCheminement * pasuv[0] * previousd1.X() /f; - Standard_Real dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f; - Standard_Real dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; - Standard_Real dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f; - - if(theChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < 1.e-7) dP1 *= (5. * (Standard_Real)dIncKey); - if(theChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < 1.e-7) dP2 *= (5. * (Standard_Real)dIncKey); - if(theChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < 1.e-7) dP3 *= (5. * (Standard_Real)dIncKey); - if(theChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < 1.e-7) dP4 *= (5. * (Standard_Real)dIncKey); - - Param(1) += dP1; - Param(2) += dP2; - Param(3) += dP3; - Param(4) += dP4; - Standard_Real SvParam[4]; - IntImp_ConstIsoparametric ChoixIso = theChoixIso; - - for(parit = 0; parit < 4; parit++) { - SvParam[parit] = Param(parit+1); - } - math_FunctionSetRoot Rsnld(myIntersectionOn2S.Function()); - ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld, theChoixIso); - - if (!myIntersectionOn2S.IsDone()) { - return bOutOfTangentZone; - } - else { - if (myIntersectionOn2S.IsEmpty()) { - return bOutOfTangentZone; - } - - aStatus = TestDeflection(ChoixIso); - - if(aStatus == IntWalk_OK) { - - for(uvit = 0; uvit < 4; uvit++) { - if(pasuv[uvit] < pasInit[uvit]) { - pasuv[uvit] = pasInit[uvit]; - } - } - } - - switch(aStatus) { - case IntWalk_ArretSurPointPrecedent: - { - bStop = Standard_True; - bOutOfTangentZone = !myIntersectionOn2S.IsTangent(); - break; - } - case IntWalk_PasTropGrand: - { - for(parit = 0; parit < 4; parit++) { - Param(parit+1) = SvParam[parit]; - } - Standard_Boolean bDecrease = Standard_False; - - for(uvit = 0; uvit < 4; uvit++) { - if(pasSav[uvit] < pasInit[uvit]) { - pasInit[uvit] -= (pasInit[uvit] - pasSav[uvit]) * 0.1; - bDecrease = Standard_True; - } - } - - if(bDecrease) nbIterWithoutAppend--; - break; - } - case IntWalk_PointConfondu: - { - for(uvit = 0; uvit < 4; uvit++) { - if(pasuv[uvit] < pasInit[uvit]) { - pasuv[uvit] += (pasInit[uvit] - pasuv[uvit]) * 0.1; - } - } - break; - } - case IntWalk_OK: - case IntWalk_ArretSurPoint: - { - // - bStop = TestArret(theDirectionFlag, Param, ChoixIso); - // - - // - if(!bStop) { - Standard_Real u11,v11,u12,v12; - myIntersectionOn2S.Point().Parameters(u11,v11,u12,v12); - Standard_Real u21,v21,u22,v22; - previousPoint.Parameters(u21,v21,u22,v22); - - if(((fabs(u11-u21) < ResoU1) && (fabs(v11-v21) < ResoV1)) || - ((fabs(u12-u22) < ResoU2) && (fabs(v12-v22) < ResoV2))) { - nbEqualPoints++; - } - else { - nbEqualPoints = 0; - } - } - // - - bStop = bStop || !myIntersectionOn2S.IsTangent(); - bOutOfTangentZone = !myIntersectionOn2S.IsTangent(); - - if(!bStop) { - Standard_Boolean pointisvalid = Standard_False; - Standard_Real u1,v1,u2,v2; - myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); - - if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && - v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && - v1 >= Vm1 && v2 >= Vm2) - pointisvalid = Standard_True; - - if(pointisvalid) { - previousPoint = myIntersectionOn2S.Point(); - previoustg = myIntersectionOn2S.IsTangent(); - - if(!previoustg) { - previousd = myIntersectionOn2S.Direction(); - previousd1 = myIntersectionOn2S.DirectionOnS1(); - previousd2 = myIntersectionOn2S.DirectionOnS2(); - } - Standard_Boolean bAddPoint = Standard_True; - - if(line->NbPoints() >= 1) { - gp_Pnt pf = line->Value(1).Value(); - gp_Pnt pl = previousPoint.Value(); - - if(pf.Distance(pl) < Precision::Confusion()) { - dIncKey++; - if(dIncKey == 5000) return bOutOfTangentZone; - else bAddPoint = Standard_False; - } - } - - if(bAddPoint) { - aSeqOfNewPoint.Append(previousPoint); - nbIterWithoutAppend = 0; - } - } - - if (line->NbPoints() == 2) { - for(uvit = 0; uvit < 4; uvit++) { - pasSav[uvit] = pasuv[uvit]; - } - } - - if ( !pointisvalid ) { - // decrease step if out of bounds - // otherwise the same calculations will be - // repeated several times - if ( ( u1 > UM1 ) || ( u1 < Um1 ) ) - pasuv[0] *= 0.5; - - if ( ( v1 > VM1 ) || ( v1 < Vm1 ) ) - pasuv[1] *= 0.5; - - if ( ( u2 > UM2 ) || ( u2 < Um2 ) ) - pasuv[2] *= 0.5; - - if ( ( v2 > VM2 ) || ( v2 < Vm2 ) ) - pasuv[3] *= 0.5; - } - } // end if(!bStop) - else { //if(bStop) - if(close && (line->NbPoints() >= 1)) { - - if(!bOutOfTangentZone) { - aSeqOfNewPoint.Append(line->Value(1)); // line end - } - nbIterWithoutAppend = 0; - } - else { - ChoixIso = myIntersectionOn2S.Perform(Param, Rsnld, theChoixIso); - - if(myIntersectionOn2S.IsEmpty()) { - bStop = Standard_True;// !myIntersectionOn2S.IsTangent(); - bOutOfTangentZone = Standard_False; // !myIntersectionOn2S.IsTangent(); - } - else { - Standard_Boolean bAddPoint = Standard_True; - Standard_Boolean pointisvalid = Standard_False; - - previousPoint = myIntersectionOn2S.Point(); - Standard_Real u1,v1,u2,v2; - previousPoint.Parameters(u1,v1,u2,v2); - - if(u1 <= UM1 && u2 <= UM2 && v1 <= VM1 && - v2 <= VM2 && u1 >= Um1 && u2 >= Um2 && - v1 >= Vm1 && v2 >= Vm2) - pointisvalid = Standard_True; - - if(pointisvalid) { - - if(line->NbPoints() >= 1) { - gp_Pnt pf = line->Value(1).Value(); - gp_Pnt pl = previousPoint.Value(); - - if(pf.Distance(pl) < Precision::Confusion()) { - dIncKey++; - if(dIncKey == 5000) return bOutOfTangentZone; - else bAddPoint = Standard_False; - } - } - - if(bAddPoint && !bOutOfTangentZone) { - aSeqOfNewPoint.Append(previousPoint); - nbIterWithoutAppend = 0; - } - } - } - } - } - break; - } - default: - { - break; - } - } - } - } - Standard_Boolean bExtendLine = Standard_False; - Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; - - Standard_Integer pit = 0; - - for(pit = 0; !bExtendLine && (pit < 2); pit++) { - if(pit == 0) - previousPoint.Parameters(u1,v1,u2,v2); - else { - if(aSeqOfNewPoint.Length() > 0) - aSeqOfNewPoint.Value(aSeqOfNewPoint.Length()).Parameters(u1,v1,u2,v2); - else - break; - } - - if(((u1 - Um1) < ResoU1) || - ((UM1 - u1) < ResoU1) || - ((u2 - Um2) < ResoU2) || - ((UM2 - u2) < ResoU2) || - ((v1 - Vm1) < ResoV1) || - ((VM1 - v1) < ResoV1) || - ((v2 - Vm2) < ResoV2) || - ((VM2 - v2) < ResoV2)) - bExtendLine = Standard_True; - } - - if(!bExtendLine) { - // if(aStatus == IntWalk_OK || aStatus == IntWalk_ArretSurPoint) { - if(aStatus == IntWalk_OK) { - bExtendLine = Standard_True; - - if(aSeqOfNewPoint.Length() > 1) { - TColStd_Array1OfReal FirstParams(0, 3), LastParams(0, 3), Resolutions(0, 3); - Resolutions(0) = ResoU1; Resolutions(1) = ResoV1; Resolutions(2) = ResoU2; Resolutions(3) = ResoV2; - - aSeqOfNewPoint(1).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), - FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); - aSeqOfNewPoint(aSeqOfNewPoint.Length()).Parameters(LastParams.ChangeValue(0), - LastParams.ChangeValue(1), - LastParams.ChangeValue(2), - LastParams.ChangeValue(3)); - Standard_Integer indexofiso = 0; - - if(theChoixIso == IntImp_UIsoparametricOnCaro1) indexofiso = 0; - if(theChoixIso == IntImp_VIsoparametricOnCaro1) indexofiso = 1; - if(theChoixIso == IntImp_UIsoparametricOnCaro2) indexofiso = 2; - if(theChoixIso == IntImp_VIsoparametricOnCaro2) indexofiso = 3; - - Standard_Integer afirstindex = (indexofiso < 2) ? 0 : 2; - gp_Vec2d aTangentZoneDir(gp_Pnt2d(FirstParams.Value(afirstindex), FirstParams.Value(afirstindex + 1)), - gp_Pnt2d(LastParams.Value(afirstindex), LastParams.Value(afirstindex + 1))); - - gp_Dir2d anIsoDir(0, 1); - - if((indexofiso == 1) || (indexofiso == 3)) - anIsoDir = gp_Dir2d(1, 0); - - if(aTangentZoneDir.SquareMagnitude() > gp::Resolution()) { - Standard_Real piquota = M_PI*0.25; - - if(fabs(aTangentZoneDir.Angle(anIsoDir)) > piquota) { - Standard_Integer ii = 1, nextii = 2; - gp_Vec2d d1(0, 0); - Standard_Real asqresol = gp::Resolution(); - asqresol *= asqresol; - - do { - aSeqOfNewPoint(ii).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), - FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); - aSeqOfNewPoint(ii + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1), - LastParams.ChangeValue(2), LastParams.ChangeValue(3)); - d1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex), - FirstParams.Value(afirstindex + 1)), - gp_Pnt2d(LastParams.Value(afirstindex), - LastParams.Value(afirstindex + 1))); - ii++; - } - while((d1.SquareMagnitude() < asqresol) && - (ii < aSeqOfNewPoint.Length())); - - nextii = ii; - - while(nextii < aSeqOfNewPoint.Length()) { - - gp_Vec2d nextd1(0, 0); - Standard_Integer jj = nextii; - - do { - aSeqOfNewPoint(jj).Parameters(FirstParams.ChangeValue(0), FirstParams.ChangeValue(1), - FirstParams.ChangeValue(2), FirstParams.ChangeValue(3)); - aSeqOfNewPoint(jj + 1).Parameters(LastParams.ChangeValue(0), LastParams.ChangeValue(1), - LastParams.ChangeValue(2), LastParams.ChangeValue(3)); - nextd1 = gp_Vec2d(gp_Pnt2d(FirstParams.Value(afirstindex), - FirstParams.Value(afirstindex + 1)), - gp_Pnt2d(LastParams.Value(afirstindex), - LastParams.Value(afirstindex + 1))); - jj++; - - } - while((nextd1.SquareMagnitude() < asqresol) && - (jj < aSeqOfNewPoint.Length())); - nextii = jj; - - if(fabs(d1.Angle(nextd1)) > piquota) { - bExtendLine = Standard_False; - break; - } - d1 = nextd1; - } - } - // end if(fabs(aTangentZoneDir.Angle(anIsoDir) - } - } - } - } - - if(!bExtendLine) { - return Standard_False; - } - Standard_Integer i = 0; - - for(i = 1; i <= aSeqOfNewPoint.Length(); i++) { - AddAPoint(line, aSeqOfNewPoint.Value(i)); - } - - return bOutOfTangentZone; -} //======================================================================= //function : DistanceMinimizeByGradient diff --git a/src/IntWalk/IntWalk_PWalking.hxx b/src/IntWalk/IntWalk_PWalking.hxx index e4dab8ed9a..b6a1067f4f 100644 --- a/src/IntWalk/IntWalk_PWalking.hxx +++ b/src/IntWalk/IntWalk_PWalking.hxx @@ -199,9 +199,6 @@ protected: const Standard_Real the3DTol, TColStd_Array1OfReal &thePnt); - Standard_EXPORT Standard_Boolean ExtendLineInCommonZone (const IntImp_ConstIsoparametric theChoixIso, - const Standard_Boolean theDirectionFlag); - private: Standard_Boolean done; Handle(IntSurf_LineOn2S) line; diff --git a/tests/perf/modalg/bug29093 b/tests/perf/modalg/bug29093 new file mode 100644 index 0000000000..10face3f4b --- /dev/null +++ b/tests/perf/modalg/bug29093 @@ -0,0 +1,47 @@ +puts "========" +puts "OCC29093" +puts "========" +puts "" +################################# +# BOP PaveFiller hungs and constantly consumes memory +################################# + +puts "TODO OCC28989 ALL : Error! Big tolerance value!" + +set mem_max_wsetpeak 100000000 + +bclearobjects; +bcleartools; + +restore [locate_data_file bug29093_hung.brep] a +explode a So +baddobjects a_1 +baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9 a_10 a_11 a_12 a_13 a_14 + +dchrono cr restart + +bfillds +bbop result 4 + +dchrono cr stop counter bbuild + +set mem_wsetpeak [meminfo wsetpeak] + +if { ${mem_wsetpeak} > ${mem_max_wsetpeak}} { + puts "Error : there is memory problem (${mem_wsetpeak} MBytes has been allocated)" +} + +regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance result] full MaxTol + +# Maximal tolerance value must be updated after the fix. +# Current tolerance value is 803.89403359886296. + +if {${MaxTol} > 1.0e-4} { + puts "Error! Big tolerance value!" +} + +smallview +donly result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file -- 2.39.5