diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index dc234e3bc8..c557f70930 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -149,7 +149,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, default: { IntPatch_PrmPrmIntersection interpp; - interpp.Perform(S1,D1,TolArc,TolTang,myFleche,myUVMaxStep); + interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep); if (interpp.IsDone()) { done = Standard_True; @@ -1237,10 +1237,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)& Standard_Boolean ClearFlag = Standard_True; if(!ListOfPnts.IsEmpty()) { - interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine); + interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine); ClearFlag = Standard_False; } - interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!! + interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!! } else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())) { @@ -1253,7 +1253,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)& const Standard_Real AP = Max(MU, MV); Handle(Adaptor3d_HSurface) SS; FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS); - interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep); + interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep); } else { @@ -1263,7 +1263,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)& const Standard_Real AP = Max(MU, MV); Handle(Adaptor3d_HSurface) SS; FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS); - interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep); + interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep); } }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()) else @@ -1302,7 +1302,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)& Handle(Adaptor3d_HSurface) nS1 = theS1; Handle(Adaptor3d_HSurface) nS2 = theS2; FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2); - interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep); + interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep); }// 'NON - COLLINEAR LINES' }// both domains are infinite @@ -1652,7 +1652,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, else { IntPatch_PrmPrmIntersection interpp; - interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolArc,TolTang,myFleche,myUVMaxStep); + interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolTang,TolArc,myFleche,myUVMaxStep); if (interpp.IsDone()) { done = Standard_True; diff --git a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx index c68e8d5a86..e717aa85be 100644 --- a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx +++ b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx @@ -77,6 +77,8 @@ static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1, const IntSurf_TypeTrans theTrans1, const IntSurf_TypeTrans theTrans2, const Standard_Real theTol, + const Standard_Real theMaxStepS1, + const Standard_Real theMaxStepS2, Handle(IntPatch_WLine)& theWLline) { if(theSLin.Length() == 0) @@ -84,7 +86,6 @@ static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1, Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; - const Standard_Real aTol2D = 1.e-4; Standard_Integer cnbV = theWLline->NbVertex(); Standard_Integer ciV; for( ciV = 1; ciV <= cnbV; ciV++ ) @@ -119,11 +120,14 @@ static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1, Standard_Real vRs2 = theSurf2->Surface().VResolution(tDistance); Standard_Real RmaxS1 = Max(uRs1,vRs1); Standard_Real RmaxS2 = Max(uRs2,vRs2); - if((aPCS1.SquareDistance(aPTS1) < RmaxS1*RmaxS1) && (aPCS2.SquareDistance(aPTS2) < RmaxS2*RmaxS2)) + + if(RmaxS1 < theMaxStepS1 && RmaxS2 < theMaxStepS2) { - if(RmaxS1 < aTol2D && RmaxS2 < aTol2D) + if( pntDMin > tDistance && tDistance > Precision::PConfusion()) { - if( pntDMin > tDistance && tDistance > 1.e-9) + const Standard_Real aSqDist1 = aPCS1.SquareDistance(aPTS1), + aSqDist2 = aPCS2.SquareDistance(aPTS2); + if((aSqDist1 < RmaxS1*RmaxS1) && (aSqDist2 < RmaxS2*RmaxS2)) { pntDMin = tDistance; VDMin = tiV; @@ -1790,7 +1794,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& wline->AddVertex(vtx); } - SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, wline); + SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, + TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)), + Max(PW.MaxStep(2), PW.MaxStep(3)), wline); AddWLine(SLin, wline, Deflection); empt = Standard_False; @@ -2470,7 +2476,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur lignetrouvee = Standard_True; - SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, wline); + SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, + TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)), + Max(PW.MaxStep(2), PW.MaxStep(3)), wline); AddWLine(SLin, wline, Deflection); empt = Standard_False; diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index abbca82257..34c895cb89 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -34,61 +34,63 @@ #include //================================================================================== -// function : IntWalk_PWalking::IntWalk_PWalking -// purpose : -// estimate of max step : To avoid abrupt changes -// during change of isos +// function : ComputePasInit +// purpose : estimate of max step : To avoid abrupt changes during change of isos //================================================================================== -void ComputePasInit(Standard_Real *pasuv, - Standard_Real Um1,Standard_Real UM1, - Standard_Real Vm1,Standard_Real VM1, - Standard_Real Um2,Standard_Real UM2, - Standard_Real Vm2,Standard_Real VM2, - Standard_Real _Um1,Standard_Real _UM1, - Standard_Real _Vm1,Standard_Real _VM1, - Standard_Real _Um2,Standard_Real _UM2, - Standard_Real _Vm2,Standard_Real _VM2, - const Handle(Adaptor3d_HSurface)& Caro1, - const Handle(Adaptor3d_HSurface)& Caro2, - const Standard_Real Increment, - const Standard_Real tolconf) -{ - Standard_Real du1=Abs(UM1-Um1); - Standard_Real dv1=Abs(VM1-Vm1); - Standard_Real du2=Abs(UM2-Um2); - Standard_Real dv2=Abs(VM2-Vm2); +void IntWalk_PWalking::ComputePasInit(const Standard_Real theDeltaU1, + const Standard_Real theDeltaV1, + const Standard_Real theDeltaU2, + const Standard_Real theDeltaV2) +{ + const Standard_Real aRangePart = 0.01; + const Standard_Real Increment = 2.0*pasMax; + const Handle(Adaptor3d_HSurface)& + Caro1 = myIntersectionOn2S.Function().AuxillarSurface1(); + const Handle(Adaptor3d_HSurface)& + Caro2 = myIntersectionOn2S.Function().AuxillarSurface2(); - Standard_Real _du1=Abs(_UM1-_Um1); - Standard_Real _dv1=Abs(_VM1-_Vm1); - Standard_Real _du2=Abs(_UM2-_Um2); - Standard_Real _dv2=Abs(_VM2-_Vm2); + const Standard_Real aDeltaU1=Abs(UM1-Um1); + const Standard_Real aDeltaV1=Abs(VM1-Vm1); + const Standard_Real aDeltaU2=Abs(UM2-Um2); + const Standard_Real aDeltaV2=Abs(VM2-Vm2); //-- limit the reduction of uv box estimate to 0.01 natural box - //-- du1 : On box of Inter - //-- _du1 : On parametric space - if(_du1<1e50 && du1<0.01*_du1) du1=0.01*_du1; - if(_dv1<1e50 && dv1<0.01*_dv1) dv1=0.01*_dv1; - if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2; - if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2; + //-- theDeltaU1 : On box of Inter + //-- aDeltaU1 : On parametric space + if(!Precision::IsInfinite(aDeltaU1)) + pasuv[0]=Max(Increment*Max(theDeltaU1, aRangePart*aDeltaU1), pasuv[0]); + else + pasuv[0]=Max(Increment*theDeltaU1, pasuv[0]); - pasuv[0]=Increment*du1; - pasuv[1]=Increment*dv1; - pasuv[2]=Increment*du2; - pasuv[3]=Increment*dv2; + if(!Precision::IsInfinite(aDeltaV1)) + pasuv[1]=Max(Increment*Max(theDeltaV1, aRangePart*aDeltaV1), pasuv[1]); + else + pasuv[1]=Max(Increment*theDeltaV1, pasuv[1]); - Standard_Real ResoU1tol = Adaptor3d_HSurfaceTool::UResolution(Caro1, tolconf); - Standard_Real ResoV1tol = Adaptor3d_HSurfaceTool::VResolution(Caro1, tolconf); - Standard_Real ResoU2tol = Adaptor3d_HSurfaceTool::UResolution(Caro2, tolconf); - Standard_Real ResoV2tol = Adaptor3d_HSurfaceTool::VResolution(Caro2, tolconf); + if(!Precision::IsInfinite(aDeltaU2)) + pasuv[2]=Max(Increment*Max(theDeltaU2, aRangePart*aDeltaU2), pasuv[2]); + else + pasuv[2]=Max(Increment*theDeltaU2, pasuv[2]); - if (pasuv[0] < 2*ResoU1tol) - pasuv[0] = 2*ResoU1tol; - if (pasuv[1] < 2*ResoV1tol) - pasuv[1] = 2*ResoV1tol; - if (pasuv[2] < 2*ResoU2tol) - pasuv[2] = 2*ResoU2tol; - if (pasuv[3] < 2*ResoV2tol) - pasuv[3] = 2*ResoV2tol; + if(!Precision::IsInfinite(aDeltaV2)) + pasuv[3]=Max(Increment*Max(theDeltaV2, aRangePart*aDeltaV2), pasuv[3]); + else + pasuv[3]=Max(Increment*theDeltaV2, pasuv[3]); + + const Standard_Real ResoU1tol = Adaptor3d_HSurfaceTool::UResolution(Caro1, tolconf); + const Standard_Real ResoV1tol = Adaptor3d_HSurfaceTool::VResolution(Caro1, tolconf); + const Standard_Real ResoU2tol = Adaptor3d_HSurfaceTool::UResolution(Caro2, tolconf); + const Standard_Real ResoV2tol = Adaptor3d_HSurfaceTool::VResolution(Caro2, tolconf); + + myStepMin[0] = Max(myStepMin[0], 2.0*ResoU1tol); + myStepMin[1] = Max(myStepMin[1], 2.0*ResoV1tol); + myStepMin[2] = Max(myStepMin[2], 2.0*ResoU2tol); + myStepMin[3] = Max(myStepMin[3], 2.0*ResoV2tol); + + for(Standard_Integer i = 0; i < 4; i++) + { + pasuv[i]=Max(myStepMin[i], pasuv[i]); + } } //======================================================================= @@ -267,6 +269,7 @@ done(Standard_True), close(Standard_False), fleche(Deflection), tolconf(Epsilon), +myTolTang(TolTangency), sensCheminement(1), myIntersectionOn2S(Caro1,Caro2,TolTangency), STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0), @@ -377,6 +380,11 @@ STATIC_PRECEDENT_INFLEXION(0) } } + myStepMin[0] = 100.0*ResoU1; + myStepMin[1] = 100.0*ResoV1; + myStepMin[2] = 100.0*ResoU2; + myStepMin[3] = 100.0*ResoV2; + //-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2); for (Standard_Integer i = 0; i<=3;i++) { @@ -407,6 +415,7 @@ done(Standard_True), close(Standard_False), fleche(Deflection), tolconf(Epsilon), +myTolTang(TolTangency), sensCheminement(1), myIntersectionOn2S(Caro1,Caro2,TolTangency), STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0), @@ -543,6 +552,12 @@ STATIC_PRECEDENT_INFLEXION(0) if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1]; if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2]; if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3]; + + myStepMin[0] = 100.0*ResoU1; + myStepMin[1] = 100.0*ResoV1; + myStepMin[2] = 100.0*ResoU2; + myStepMin[3] = 100.0*ResoV2; + // TColStd_Array1OfReal Par(1,4); Par(1) = U1; @@ -622,6 +637,7 @@ static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theS const Standard_Real theV10, const Standard_Real theU20, const Standard_Real theV20, + const Standard_Real theToler, const Standard_Real theArrStep[]) { { @@ -645,7 +661,8 @@ static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theS } } - const Standard_Real aSQToler = 4.0e-14; + //For two faces (2^2 = 4) + const Standard_Real aSQToler = 4.0*theToler*theToler; const Standard_Integer aNbItems = 4; const Standard_Real aParUS1[aNbItems] = { theU10 + theArrStep[0], theU10 - theArrStep[0], @@ -717,22 +734,8 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2); const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2); // - ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max, - Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax,tolconf); - // - if(pasuv[0]<100.0*ResoU1) { - pasuv[0]=100.0*ResoU1; - } - if(pasuv[1]<100.0*ResoV1) { - pasuv[1]=100.0*ResoV1; - } - if(pasuv[2]<100.0*ResoU2) { - pasuv[2]=100.0*ResoU2; - } - if(pasuv[3]<100.0*ResoV2) { - pasuv[3]=100.0*ResoV2; - } - // + ComputePasInit(u1max - u1min,v1max - v1min,u2max - u2min,v2max - v2min); + for (Standard_Integer i=0; i<4; ++i) { if(pasuv[i]>10) @@ -806,7 +809,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4)); - if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), pasuv)) + if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), myTolTang, pasuv)) return; AddAPoint(line,previousPoint); @@ -1165,28 +1168,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, { pastroppetit=Standard_True; - if(pasuv[0] pasuv[i]) + { + pasuv[i] = aNewStep; + hasStepBeenIncreased = Standard_True; + } + } + + if(hasStepBeenIncreased) + { + Param(1)=SvParam[0]; + Param(2)=SvParam[1]; + Param(3)=SvParam[2]; + Param(4)=SvParam[3]; + + LevelOfIterWithoutAppend = 0; + + break; + } + } case IntWalk_OK: case IntWalk_ArretSurPoint://006 { @@ -1298,6 +1312,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if(RejectIndex >= RejectIndexMAX) { + Arrive = Standard_True; break; } @@ -1385,6 +1400,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if(RejectIndex >= RejectIndexMAX) { + Arrive = Standard_True; break; } @@ -1618,6 +1634,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if(RejectIndex >= RejectIndexMAX) { + Arrive = Standard_True; break; } @@ -2803,7 +2820,7 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso } IntWalk_StatusDeflection Status = IntWalk_OK; - Standard_Real FlecheCourante ,Ratio; + Standard_Real FlecheCourante , Ratio = 1.0; // Caro1 and Caro2 const Handle(Adaptor3d_HSurface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1(); @@ -2819,10 +2836,12 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso const gp_Dir& TgCourante = myIntersectionOn2S.Direction(); + const Standard_Real aCosBetweenTangent = TgCourante.Dot(previousd); + //================================================================================== //========= R i s k o f i n f l e x i o n p o i n t ============ //================================================================================== - if (TgCourante.Dot(previousd)<0) { + if (aCosBetweenTangent < 0) { //------------------------------------------------------------ //-- Risk of inflexion point : Divide the step by 2 //-- Initialize STATIC_PRECEDENT_INFLEXION so that @@ -2840,7 +2859,6 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso else return IntWalk_PasTropGrand; } - else { if(STATIC_PRECEDENT_INFLEXION > 0) { STATIC_PRECEDENT_INFLEXION -- ; @@ -2852,15 +2870,20 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso //========= D e t e c t c o n f u s e d P o in t s =========== //================================================================================== - Standard_Real Dist = previousPoint.Value(). + const Standard_Real aSqDist = previousPoint.Value(). SquareDistance(CurrentPoint.Value()); - if (Dist < tolconf*tolconf ) { - pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0])); - pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1])); - pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2])); - pasuv[3] = Max(5.*ResoV2,Min(1.5*pasuv[3],pasInit[3])); + if (aSqDist < tolconf*tolconf) { + pasInit[0] = Max(pasInit[0], 5.0*ResoU1); + pasInit[1] = Max(pasInit[1], 5.0*ResoV1); + pasInit[2] = Max(pasInit[2], 5.0*ResoU2); + pasInit[3] = Max(pasInit[3], 5.0*ResoV2); + + for(Standard_Integer i = 0; i < 4; i++) + { + pasuv[i] = Max(pasuv[i], Min(1.5*pasuv[i], pasInit[i])); + } //Compute local resolution: for OCC26717 if (Abs(pasuv[choixIso] - pasInit[choixIso]) <= Precision::Confusion()) { @@ -3029,7 +3052,7 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso //-- Estimate of the vector -- //--------------------------------------- FlecheCourante = - Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.; + Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*aSqDist))/8.; if ( FlecheCourante<= fleche*0.5) { //-- Current step too small if(FlecheCourante>1e-16) { @@ -3096,10 +3119,114 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso Ratio = 0.75 * (fleche / FlecheCourante); } } - pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0])); - pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1])); - pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2])); - pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3])); + + if(Status != IntWalk_PointConfondu) + { + //Here, aCosBetweenTangent >= 0.0 definitely. + + /* + Brief algorithm description. + We have two (not-coincindent) intersection point (P1 and P2). In every point, + vector of tangent (to the intersection curve) is known (vectors T1 and T2). + Basing on these data, we create osculating circle. + + * - arc of osculating circle + * * + P1 x----------x P2 + / \ + / \ + Vec(T1) Vec(T2) + + Let me draw your attention to the following facts: + 1. Vectors T1 and T2 direct FROM (not TO) points P1 and P2. Therefore, + one of previously computed vector should be reversed. + + In this case, the absolute (!) value of the deflection between the arc of + the osculating circle and the P1P2 segment can be computed as follows: + e = d*(1-sin(B/2))/(2*cos(B/2)), (1) + where d is the length of P1P2 segment, B is the angle between vectors T1 and T2. + At that, + pi/2 <= B <= pi, + cos(B/2) >= 0, + sin(B/2) > 0, + sin(B) > 0, + cos(B) < 0. + + Later, the normal state of algorithm work is (as we apply) + tolconf/2 <= e <= tolconf. + In this case, we keep previous step. + + If e < tolconf/2 then the local curvature of the intersection curve is small. + As result, the step should be increased. + + If e > tolconf then the step is too big. Therefore, we should decrease one. + + Condition (1) is equivalent to + sin(B/2) = 1 - 2/(1+(d/(2*e))^2) = Fs(e), + cos(B) = 1 - 2*Fs(e)^2 = Fd(e), + where Fs(e)and Fd(e) are some function with parameter "deflection". + + Let mean that Fs(e) is decreasing function. Fd(e) is increasing function, + in the range, where Fs(e) > 0.0 (i.e. when e < d/2). + + Now, let substitute required deflection (tolconf or tolconf/2) to z. Then + it is necessary to check if e < z or if e > z. + + In this case, it is enough to comapare Fs(e) and Fs(z). + At that Fs(e) > 0 because sin(B/2) > 0 always. + + Therefore, if Fs(z) < 0.0 then Fs(e) > Fs(z) ==> e < z definitely. + If Fs(z) > 0.0 then we can compare Fs(z)^2 and Fs(e)^2 or, in substance, + values Fd(e) and Fd(z). If Fd(e) > Fd(z) then e > z and vice versa. + */ + + //Fd(e) is already known (Fd(e) == -aCosBetweenTangent) + + const Standard_Real anInvSqAbsArcDeflMax = 0.25*aSqDist/(tolconf*tolconf); + const Standard_Real aSinB2Max = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMax); + + if(aSinB2Max >= 0.0 && (aCosBetweenTangent <= 2.0 * aSinB2Max * aSinB2Max - 1.0)) + {//Real deflection is greater or equal than tolconf + Status = IntWalk_PasTropGrand; + } + else + {//Real deflection is less than tolconf + const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax; + const Standard_Real aSinB2Min = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin); + + if((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0)) + {//Real deflection is less than tolconf/2.0 + Status = IntWalk_StepTooSmall; + } + } + + if(Status == IntWalk_PasTropGrand) + { + pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5; + return Status; + } + + if(Status == IntWalk_StepTooSmall) + { + pasuv[0] = Max(pasuv[0], AbsDu1); + pasuv[1] = Max(pasuv[1], AbsDv1); + pasuv[2] = Max(pasuv[2], AbsDu2); + pasuv[3] = Max(pasuv[3], AbsDv2); + + pasInit[0] = Max(pasInit[0], AbsDu1); + pasInit[1] = Max(pasInit[1], AbsDv1); + pasInit[2] = Max(pasInit[2], AbsDu2); + pasInit[3] = Max(pasInit[3], AbsDv2); + + return Status; + } + } + + pasuv[0] = Max(myStepMin[0],Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0])); + pasuv[1] = Max(myStepMin[1],Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1])); + pasuv[2] = Max(myStepMin[2],Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2])); + pasuv[3] = Max(myStepMin[3],Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3])); + if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0; return Status; } diff --git a/src/IntWalk/IntWalk_PWalking.hxx b/src/IntWalk/IntWalk_PWalking.hxx index 35b4aea5e0..81d8261d63 100644 --- a/src/IntWalk/IntWalk_PWalking.hxx +++ b/src/IntWalk/IntWalk_PWalking.hxx @@ -138,10 +138,19 @@ public: Standard_EXPORT Standard_Boolean SeekAdditionalPoints (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Integer theMinNbPoints); + Standard_Real MaxStep(Standard_Integer theIndex) + { + Standard_OutOfRange_Raise_if((theIndex < 0) || (theIndex > 3), ""); + return pasInit[theIndex]; + } protected: + Standard_EXPORT void ComputePasInit(const Standard_Real theDeltaU1, + const Standard_Real theDeltaV1, + const Standard_Real theDeltaU2, + const Standard_Real theDeltaV2); @@ -169,7 +178,9 @@ private: Standard_Real fleche; Standard_Real pasMax; Standard_Real tolconf; + Standard_Real myTolTang; Standard_Real pasuv[4]; + Standard_Real myStepMin[4]; Standard_Real pasSav[4]; Standard_Real pasInit[4]; Standard_Real Um1; diff --git a/src/IntWalk/IntWalk_StatusDeflection.hxx b/src/IntWalk/IntWalk_StatusDeflection.hxx index 93ad6ea2e6..9c18ffbab2 100644 --- a/src/IntWalk/IntWalk_StatusDeflection.hxx +++ b/src/IntWalk/IntWalk_StatusDeflection.hxx @@ -21,6 +21,7 @@ enum IntWalk_StatusDeflection { IntWalk_PasTropGrand, +IntWalk_StepTooSmall, IntWalk_PointConfondu, IntWalk_ArretSurPointPrecedent, IntWalk_ArretSurPoint, diff --git a/tests/blend/simple/X4 b/tests/blend/simple/X4 index b10849fb1f..d7df290b71 100644 --- a/tests/blend/simple/X4 +++ b/tests/blend/simple/X4 @@ -4,8 +4,6 @@ ## Comment : From CV tests serie page 25/26 ## =========================================== -puts "TODO #OCC26740 ALL: Faulty shapes in variables faulty_1 to faulty_" - restore [locate_data_file CCV_1_h1_gsk.rle] s explode s E blend result s 30 s_14 diff --git a/tests/bugs/modalg_5/bug24585_1 b/tests/bugs/modalg_5/bug24585_1 index 331e6c4be3..892c758e0e 100644 --- a/tests/bugs/modalg_5/bug24585_1 +++ b/tests/bugs/modalg_5/bug24585_1 @@ -6,7 +6,7 @@ puts "" # Wrong pcurve of the section curve ########################################################### -set MaxTol 3.0e-5 +set ExpectedTol 5.6061116035240048e-005 set NbCurv_OK 1 restore [locate_data_file bug24585_b1.brep] b1 @@ -23,9 +23,9 @@ if {${NbCurv} != ${NbCurv_OK}} { puts "Error: ${NbCurv_OK} curve(s) expected, but ${NbCurv} found." } -if {${Toler} > ${MaxTol}} { - puts "Error: Tolerance is too big!" -} +set tol_abs 0.0 +set tol_rel 0.01 +checkreal "Tolerance Reached" ${Toler} ${ExpectedTol} ${tol_abs} ${tol_rel} bounds c2d1_1 U1 U2 2dcvalue c2d1_1 U1 U_begin V_begin diff --git a/tests/bugs/modalg_5/bug25193 b/tests/bugs/modalg_5/bug25193 index 920dfd77f9..e401b254b6 100755 --- a/tests/bugs/modalg_5/bug25193 +++ b/tests/bugs/modalg_5/bug25193 @@ -1,3 +1,6 @@ +puts "TODO OCC27116 ALL: Error: Summary length =" +puts "TODO OCC27116 ALL: Error: 1 intersection curve\\(s\\) expected but" + puts "================" puts "OCC25193" puts "================" @@ -6,18 +9,97 @@ puts "" # Bad Intersection curveobtained by Surface/Surface Intersection Algorithm. ####################################################################### +puts "" + +pload QAcommands + +set GoodNbCurv 1 +set GoodTol 3.6570868343352305e-005 +set NbControlPts 10 + restore [locate_data_file bug25193_s1t.draw] s1 restore [locate_data_file bug25193_s4t.draw] s4 -set CurveNumb [intersect i s1 s4 3.6570868343352305e-005] +#Ethalon of intersection curve +bounds s1 us1 us2 vs1 vs2 +uiso cc s1 us1 -if { [llength ${CurveNumb}] != 6 } { - puts "Error : Bad Intersection curveobtained by Surface/Surface Intersection Algorithm" -} else { - puts "OK : Good Intersection curveobtained by Surface/Surface Intersection Algorithm" +regexp {is ([-0-9.+eE]+)} [length cc 1.0e-4] full ExpLength +puts "Expected length = $ExpLength" + +intersect res s1 s4 $GoodTol +set che [whatis res] +set ind [string first "3d curve" $che] + +set AllowRepeate 1 +set ic 1 + +if {${ind} >= 0} { + #Only variable "res" exists + renamevar res res_1 } +set SumLength 0 + +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 + break + } + + for {set jc 1} {$jc < $ic} {incr jc} { + mkedge e1 res_$ic + mkedge e2 res_$jc + set coe [checkoverlapedges e1 e2] + + puts "res_$ic <-> res_$jc: $coe" + if { [regexp "Edges is not overlaped" $coe] != 1 } { + puts "Error: Overlapped intersection curves" + } + } + + regexp {is ([-0-9.+eE]+)} [length res_$ic 1.0e-4] full ll + + set SumLength [ expr $SumLength+$ll ] + + bounds res_$ic U1 U2 + + set step [ dval (U2-U1)/$NbControlPts ] + + if { $step < 1.0e-9*$NbControlPts } { + puts "Error: Wrong curve's range!" + } + + set DPPrev 0 + for {set par [dval U1]} {$par <= [dval U2]} {set par [expr $par+$step]} { + cvalue res_$ic $par xx yy zz dx1 dy1 dz1 + regexp " parameter 1 = +(\[-0-9*\.+eE\]+)" [proj cc xx yy zz] full cpar + cvalue cc $cpar xx yy zz dx2 dy2 dz2 + + set DP [dval dx1*dx2+dy1*dy2+dz1*dz2] + + if {$DPPrev*$DP < 0.0} { + puts "Error: Curve res_$ic changes its direction" + } + + set DPPrev $DP + } + + incr ic +} + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm" +} else { + puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found" +} + +checkreal "Summary length " ${SumLength} $ExpLength 0.0 1.0e-6 + smallview +donly res_* s1 s4 fit checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug26980 b/tests/bugs/modalg_6/bug26980 new file mode 100644 index 0000000000..9816fcb810 --- /dev/null +++ b/tests/bugs/modalg_6/bug26980 @@ -0,0 +1,62 @@ +puts "========" +puts "OCC26980" +puts "========" +puts "" +################################# +# Intersection part of Boolean algorithm spends much system time and system memory +################################# + +set max_time 120 +set mem_max_wsetpeak 500000000 + + +bclearobjects; +bcleartools; + +restore [locate_data_file bug26980-cmp.brep] cmp + +puts [nbshapes cmp -t] + +eval baddobjects [explode cmp] + +dchrono cr reset +dchrono cr start + +bfillds +bbuild result + +dchrono cr stop + +set mem_wsetpeak [meminfo wsetpeak] + +if { ${mem_wsetpeak} > ${mem_max_wsetpeak}} { + puts "Error : there is memory problem (${mem_wsetpeak} MBytes has been allocated)" +} + +set chrono_info [dchrono cr show] +regexp {CPU user time: ([-0-9.+eE]+) seconds} $chrono_info full CPU_time +if { $CPU_time > ${max_time} } { + puts "CPU user time of Boolean operation is more than ${max_time} seconds - Error" +} else { + puts "CPU user time of Boolean operation is less than ${max_time} seconds - OK" +} + +set nbshapes_expected " + VERTEX : 365 + EDGE : 793 + WIRE : 531 + FACE : 531 + SHELL : 102 + SOLID : 101 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 2424 +" + +checknbshapes result -ref ${nbshapes_expected} -t + +smallview +donly result +fit + +set 2dviewer 1 diff --git a/tests/offset/shape/A1 b/tests/offset/shape/A1 index 624a00d47d..61adf130be 100644 --- a/tests/offset/shape/A1 +++ b/tests/offset/shape/A1 @@ -1,5 +1,5 @@ -puts "TODO OCC23068 Linux: ERROR. offsetperform operation not done." -puts "TODO OCC23068 Linux: Error : The volume of result shape is" +puts "TODO OCC23068 All: ERROR. offsetperform operation not done." +puts "TODO OCC23068 All: Error : The volume of result shape is" # Original bug : hkg60144 # Date : 17Juillet98