0026980: Intersection algorithm spends much system time and system memory
authornbv <nbv@opencascade.com>
Mon, 8 Feb 2016 07:01:22 +0000 (10:01 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Feb 2016 09:58:53 +0000 (12:58 +0300)
1. Step of Walking-line has been increased as possible and now computes by iteratively adaptive algorithm (every iteration checks if current step is too big/small and decreases/increases one).

2. Interface of IntWalk_PWalking class has been changed
2.1. Method MaxStep() has been added in order to know about maximal distance between 2D-points.
2.2. Method ComputePasInit(...) has been added in order to initial step value computation.
2.3. Fields myTolTang (tolerance for intersection algorithm) and myStepMin (minimal step value) have been added.

Correction of some test cases.
Creation test case for this issue.
Changes to eliminate compiler warnings.

src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_PrmPrmIntersection.cxx
src/IntWalk/IntWalk_PWalking.cxx
src/IntWalk/IntWalk_PWalking.hxx
src/IntWalk/IntWalk_StatusDeflection.hxx
tests/blend/simple/X4
tests/bugs/modalg_5/bug24585_1
tests/bugs/modalg_5/bug25193
tests/bugs/modalg_6/bug26980 [new file with mode: 0644]
tests/offset/shape/A1

index dc234e3..c557f70 100644 (file)
@@ -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;
index c68e8d5..e717aa8 100644 (file)
@@ -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;
index abbca82..34c895c 100644 (file)
 #include <TColStd_Array1OfReal.hxx>
 
 //==================================================================================
-// 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);
-
-  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();
+
+  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;
-
-  pasuv[0]=Increment*du1;
-  pasuv[1]=Increment*dv1;
-  pasuv[2]=Increment*du2;
-  pasuv[3]=Increment*dv2;
-
-  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 (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;
+  //--  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]);
+
+  if(!Precision::IsInfinite(aDeltaV1))
+    pasuv[1]=Max(Increment*Max(theDeltaV1, aRangePart*aDeltaV1), pasuv[1]);
+  else
+    pasuv[1]=Max(Increment*theDeltaV1, pasuv[1]);
+
+  if(!Precision::IsInfinite(aDeltaU2))
+    pasuv[2]=Max(Increment*Max(theDeltaU2, aRangePart*aDeltaU2), pasuv[2]);
+  else
+    pasuv[2]=Max(Increment*theDeltaU2, pasuv[2]);
+
+  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]<pasInit[0])
-                {
-                  pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
-                  pastroppetit=Standard_False;
-                }
-
-                if(pasuv[1]<pasInit[1])
-                {
-                  pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
-                  pastroppetit=Standard_False;
-                }
-
-                if(pasuv[2]<pasInit[2])
-                {
-                  pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
-                  pastroppetit=Standard_False; 
-                }
-
-                if(pasuv[3]<pasInit[3])
+                for(Standard_Integer i = 0; i < 4; i++)
                 {
-                  pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
-                  pastroppetit=Standard_False;
+                  if(pasuv[i]<pasInit[i])
+                  {
+                    pasuv[i]+=(pasInit[i]-pasuv[i])*0.25;
+                    pastroppetit=Standard_False;
+                  }
                 }
 
                 if(pastroppetit)
@@ -1210,6 +1198,32 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
             break;
           }
+        case IntWalk_StepTooSmall:
+          {
+            Standard_Boolean hasStepBeenIncreased = Standard_False;
+
+            for(Standard_Integer i = 0; i < 4; i++)
+            {
+              const Standard_Real aNewStep = Min(1.5*pasuv[i], pasInit[i]);
+              if(aNewStep > 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;
 }
index 35b4aea..81d8261 100644 (file)
@@ -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;
index 93ad6ea..9c18ffb 100644 (file)
@@ -21,6 +21,7 @@
 enum IntWalk_StatusDeflection
 {
 IntWalk_PasTropGrand,
+IntWalk_StepTooSmall,
 IntWalk_PointConfondu,
 IntWalk_ArretSurPointPrecedent,
 IntWalk_ArretSurPoint,
index b10849f..d7df290 100644 (file)
@@ -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
index 331e6c4..892c758 100644 (file)
@@ -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
index 920dfd7..e401b25 100755 (executable)
@@ -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"
+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 "OK : Good Intersection curveobtained by Surface/Surface Intersection Algorithm"
+  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 (file)
index 0000000..9816fcb
--- /dev/null
@@ -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
index 624a00d..61adf13 100644 (file)
@@ -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