]> OCCT Git - occt-copy.git/commitdiff
Patch for CR26980_1 fix CR26980_1_691
authornbv <nbv@opencascade.com>
Thu, 28 Jan 2016 10:43:08 +0000 (13:43 +0300)
committernbv <nbv@opencascade.com>
Fri, 29 Jan 2016 08:30:48 +0000 (11:30 +0300)
src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_PrmPrmIntersection.cxx
src/IntWalk/IntWalk.cdl
src/IntWalk/IntWalk_PWalking.cdl
src/IntWalk/IntWalk_PWalking.cxx
src/IntWalk/IntWalk_PWalking.lxx
tests/bugs/modalg_6/bug26980 [new file with mode: 0644]

index fb0107e33301c42496a03b82153ca806bb72fc4a..7cdb4daf11a8479019fef94dabe42cfefb568ddb 100644 (file)
@@ -524,7 +524,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;
@@ -1329,7 +1329,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
                         TolTang, ListOfPnts, RestrictLine, typs1, typs2);
   }
-}
+  }
 
 //=======================================================================
 //function : Perform
@@ -1548,7 +1548,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
               TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
     }
   }
-}
+  }
 
 //=======================================================================
 //function : ParamParamPerfom
@@ -1571,10 +1571,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()))
   {
@@ -1587,7 +1587,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
     {
@@ -1597,7 +1597,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
@@ -1636,7 +1636,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
 
@@ -1906,10 +1906,10 @@ void IntPatch_Intersection::
         }
 
         JoinWLines( slin, spnt, theTolTang,
-                    theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
-                    theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
-                    theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
-                    theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
+                                        theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
+                                        theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
+                                        theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
+                                        theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
                     theS1->FirstUParameter(), theS1->LastUParameter(),
                     theS1->FirstVParameter(), theS1->LastVParameter(),
                     theS2->FirstUParameter(), theS2->LastUParameter(),
@@ -1982,7 +1982,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;
@@ -1993,7 +1993,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
     }
   }
-}
+  }
 //======================================================================
 #include <IntPatch_IType.hxx>
 #include <IntPatch_LineConstructor.hxx>
@@ -2053,7 +2053,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
     NR1[nbR1]=0;
     nbR1++;
   }
-  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) { 
+  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
     R2[nbR2]=D2->Value();
     NR2[nbR2]=0;
     nbR2++;
index 8d07c7b2df76033b1ce0af1203f794c52b66e153..a0bc4144a8c876270989336ff9d9c1c977f8affb 100644 (file)
@@ -68,6 +68,192 @@ static void AddWLine(IntPatch_SequenceOfLine      &theLines,
                      const Handle(IntPatch_WLine) &theWLine,
                      const Standard_Real           Deflection);
 
+static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1,
+                                    const Handle(Adaptor3d_HSurface)& theSurf2,
+                                    const IntPatch_SequenceOfLine& theSLin,
+                                    const Standard_Real* const thePeriodsArr,
+                                    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)
+    return;
+
+  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
+
+  Standard_Integer cnbV = theWLline->NbVertex();
+  Standard_Integer ciV;
+  for( ciV = 1; ciV <= cnbV; ciV++ )
+  {
+    Standard_Real pntDMin = 1.e+100;
+    Standard_Integer VDMin = 0;
+    Standard_Integer WLDMin = 0;
+    gp_Pnt cPV = theWLline->Vertex(ciV).Value();
+    theWLline->Vertex(ciV).Parameters(aU1, aV1, aU2, aV2);
+    const gp_Pnt2d aPCS1(aU1, aV1), aPCS2(aU2, aV2);
+    Standard_Integer iL;
+    for( iL = 1; iL <= theSLin.Length(); iL++)
+    {
+      const Handle(IntPatch_Line)& aSLine = theSLin.Value(iL);
+      IntPatch_IType aType = aSLine->ArcType();
+      if( aType != IntPatch_Walking)
+        continue;
+      const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
+      Standard_Integer tnbV = aWLine->NbVertex();
+      Standard_Integer tiV;
+      for( tiV = 1; tiV <= tnbV; tiV++ )
+      {
+        gp_Pnt tPV = aWLine->Vertex(tiV).Value();
+
+        aWLine->Vertex(tiV).Parameters(aU1, aV1, aU2, aV2);
+        const gp_Pnt2d aPTS1(aU1, aV1), aPTS2(aU2, aV2);
+
+        Standard_Real tDistance = cPV.Distance(tPV);
+        Standard_Real uRs1 = theSurf1->Surface().UResolution(tDistance);
+        Standard_Real vRs1 = theSurf1->Surface().VResolution(tDistance);
+        Standard_Real uRs2 = theSurf2->Surface().UResolution(tDistance);
+        Standard_Real vRs2 = theSurf2->Surface().VResolution(tDistance);
+        Standard_Real RmaxS1 = Max(uRs1,vRs1);
+        Standard_Real RmaxS2 = Max(uRs2,vRs2);
+        
+        if(RmaxS1 < theMaxStepS1 && RmaxS2 < theMaxStepS2)
+        {
+          if( pntDMin > tDistance && tDistance > Precision::PConfusion())
+          {
+            const Standard_Real aSqDist1 = aPCS1.SquareDistance(aPTS1),
+                                aSqDist2 = aPCS2.SquareDistance(aPTS2);
+            if((aSqDist1 < RmaxS1*RmaxS1) && (aSqDist2 < RmaxS2*RmaxS2))
+            {
+              pntDMin = tDistance;
+              VDMin = tiV;
+              WLDMin = iL;
+            }
+          }
+        }
+      }
+    }
+
+    if( VDMin != 0 )
+    {
+      const Handle(IntPatch_Line)& aSLine = theSLin.Value(WLDMin);
+      const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
+      Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
+      Standard_Integer ciVpar = (Standard_Integer)theWLline->Vertex(ciV).ParameterOnLine();
+      Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
+      Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
+      theWLline->Point(ciVpar).Parameters(u11,v11,u12,v12);
+      aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
+
+      Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
+      IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
+      Standard_Integer cNbP = theWLline->NbPnts();
+
+      TColStd_SequenceOfInteger VPold;
+      Standard_Integer iPo;
+      for( iPo = 1; iPo <= cnbV; iPo++ )
+      {
+        Standard_Real Po = theWLline->Vertex(iPo).ParameterOnLine();
+        Standard_Integer IPo = (Standard_Integer) Po;
+        VPold.Append(IPo);
+      }
+
+      Standard_Boolean removeNext = Standard_False;
+      Standard_Boolean removePrev = Standard_False;
+      if( ciV == 1)
+      {
+        Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
+        if(dPar > 10)
+        {
+          removeNext = Standard_True;
+          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+        }
+      }
+      else if( ciV == cnbV)
+      {
+        Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
+        if(dPar > 10)
+        {
+          removePrev = Standard_True;
+          VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
+        }
+      }
+      else
+      {
+        Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
+        Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
+        if(dParMi > 10)
+        {
+          removePrev = Standard_True;
+          VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
+        }
+
+        if(dParMa > 10)
+        {
+          removeNext = Standard_True;
+          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+          {
+            if(dParMi > 10)
+              VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
+            else
+              VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+          }
+        }
+        else
+        {
+          if(dParMi > 10)
+            for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
+              VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
+        } 
+      }
+
+      Standard_Integer pI = ciVpar;
+
+      Standard_Integer iP;
+      for( iP = 1; iP <= cNbP; iP++)
+      {
+        if( pI == iP )
+        {
+          IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, theWLline->Point(iP), thePeriodsArr);
+          newL2s->Add(newPnt);
+        }
+        else if(removeNext && iP == (pI + 1))
+          continue;
+        else if(removePrev && iP == (pI - 1))
+          continue;
+        else
+          newL2s->Add(theWLline->Point(iP));
+      }
+
+      IntPatch_Point newVtx;
+      gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
+      newVtx.SetValue(Pnt3dV,theTol,Standard_False);
+      newVtx.SetParameters(u21,v21,u22,v22);
+      newVtx.SetParameter(VPold.Value(ciV));
+
+      Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,theTrans1,theTrans2);
+
+      Standard_Integer iV;
+      for( iV = 1; iV <= cnbV; iV++ )
+      {
+        if( iV == ciV )
+          NWLine->AddVertex(newVtx);
+        else
+        {
+          IntPatch_Point theVtx = theWLline->Vertex(iV);
+          theVtx.SetParameter(VPold.Value(iV));
+          NWLine->AddVertex(theVtx);
+        }
+      }
+
+      theWLline = NWLine;
+    }//if( VDMin != 0 )
+  }//for( ciV = 1; ciV <= cnbV; ciV++ )
+}
+
 //=======================================================================
 //function : DublicateOfLinesProcessing
 //purpose  : Decides, if rejecting current line is necessary
@@ -1606,144 +1792,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
                 wline->AddVertex(vtx);
               }              
 
-              Standard_Integer slinlen = SLin.Length();
-              if( slinlen > 0 ) {
-                Standard_Integer cnbV = wline->NbVertex();
-                Standard_Integer ciV;
-                for( ciV = 1; ciV <= cnbV; ciV++ ) {
-                  Standard_Real pntDMin = 1.e+100;
-                  Standard_Integer VDMin = 0;
-                  Standard_Integer WLDMin = 0;
-                  gp_Pnt cPV = wline->Vertex(ciV).Value();
-                  Standard_Integer iL;
-                  for( iL = 1; iL <= slinlen; iL++) {
-                    const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
-                    IntPatch_IType aType = aSLine->ArcType();
-                    if( aType != IntPatch_Walking)
-                      continue;
-                    const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                    Standard_Integer tnbV = aWLine->NbVertex();
-                    Standard_Integer tiV;
-                    for( tiV = 1; tiV <= tnbV; tiV++ ) {
-                      gp_Pnt tPV = aWLine->Vertex(tiV).Value();
-                      Standard_Real tDistance = cPV.Distance(tPV);
-                      Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
-                      Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
-                      Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
-                      Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
-                      Standard_Real RmaxS1 = Max(uRs1,vRs1);
-                      Standard_Real RmaxS2 = Max(uRs2,vRs2);
-                      if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4) {
-                        if( pntDMin > tDistance && tDistance > 1.e-9) {
-                          pntDMin = tDistance;
-                          VDMin = tiV;
-                          WLDMin = iL;
-                        }
-                      }
-                    }
-                  }
-
-                  if( VDMin != 0 ) {
-                    const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
-                    const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                    Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
-                    Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
-                    Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
-                    Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
-                    wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
-                    aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
-
-                    Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
-                    IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
-                    Standard_Integer cNbP = wline->NbPnts();
-
-                    TColStd_SequenceOfInteger VPold;
-                    Standard_Integer iPo;
-                    for( iPo = 1; iPo <= cnbV; iPo++ ) {
-                      Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
-                      Standard_Integer IPo = (Standard_Integer) Po;
-                      VPold.Append(IPo);
-                    }
-
-                    Standard_Boolean removeNext = Standard_False;
-                    Standard_Boolean removePrev = Standard_False;
-                    if( ciV == 1) {
-                      Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                      if(dPar > 10) {
-                        removeNext = Standard_True;
-                        for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                          VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                      }
-                    }
-                    else if( ciV == cnbV) {
-                      Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                      if(dPar > 10) {
-                        removePrev = Standard_True;
-                        VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                      }
-                    }
-                    else {
-                      Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                      Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                      if(dParMi > 10) {
-                        removePrev = Standard_True;
-                        VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                      }
-                      if(dParMa > 10) {
-                        removeNext = Standard_True;
-                        for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) {
-                          if(dParMi > 10)
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
-                          else
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                        }
-                      }
-                      else {
-                        if(dParMi > 10)
-                          for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                            VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                      } 
-                    }
-                    Standard_Integer pI = (Standard_Integer) ciVpar;
-
-                    Standard_Integer iP;
-                    for( iP = 1; iP <= cNbP; iP++) {
-                      if( pI == iP )
-                      {
-                        IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
-                        newL2s->Add(newPnt);
-                      }
-                      else if(removeNext && iP == (pI + 1))
-                        continue;
-                      else if(removePrev && iP == (pI - 1))
-                        continue;
-                      else
-                        newL2s->Add(wline->Point(iP));
-                    }
-
-                    IntPatch_Point newVtx;
-                    gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
-                    newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
-                    newVtx.SetParameters(u21,v21,u22,v22);
-                    newVtx.SetParameter(VPold.Value(ciV));
-
-                    Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
-
-                    Standard_Integer iV;
-                    for( iV = 1; iV <= cnbV; iV++ ) {
-                      if( iV == ciV )
-                        NWLine->AddVertex(newVtx);
-                      else {
-                        IntPatch_Point theVtx = wline->Vertex(iV);
-                        theVtx.SetParameter(VPold.Value(iV));
-                        NWLine->AddVertex(theVtx);
-                      }
-                    }
-
-                    wline = NWLine;
-                  }
-                }
-              }// SLin.Length > 0
+              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;
@@ -2423,166 +2474,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
                       lignetrouvee = Standard_True;
 
-                      Standard_Integer slinlen = SLin.Length();
-                      if( slinlen > 0 )
-                      {
-                        Standard_Integer cnbV = wline->NbVertex();
-                        Standard_Integer ciV;
-                        for( ciV = 1; ciV <= cnbV; ciV++ )
-                        {
-                          Standard_Real pntDMin = 1.e+100;
-                          Standard_Integer VDMin = 0;
-                          Standard_Integer WLDMin = 0;
-                          gp_Pnt cPV = wline->Vertex(ciV).Value();
-                          Standard_Integer iL;
-                          for( iL = 1; iL <= slinlen; iL++)
-                          {
-                            const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
-                            IntPatch_IType aType = aSLine->ArcType();
-                            if( aType != IntPatch_Walking)
-                              continue;
-                            const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                            Standard_Integer tnbV = aWLine->NbVertex();
-                            Standard_Integer tiV;
-                            for( tiV = 1; tiV <= tnbV; tiV++ )
-                            {
-                              gp_Pnt tPV = aWLine->Vertex(tiV).Value();
-                              Standard_Real tDistance = cPV.Distance(tPV);
-                              Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
-                              Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
-                              Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
-                              Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
-                              Standard_Real RmaxS1 = Max(uRs1,vRs1);
-                              Standard_Real RmaxS2 = Max(uRs2,vRs2);
-                              if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4)
-                              {
-                                if( pntDMin > tDistance && tDistance > 1.e-9)
-                                {
-                                  pntDMin = tDistance;
-                                  VDMin = tiV;
-                                  WLDMin = iL;
-                                }
-                              }
-                            }
-                          }
-
-                          if( VDMin != 0 )
-                          {
-                            const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
-                            const Handle(IntPatch_WLine)&  aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
-                            Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
-                            Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
-                            Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
-                            Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
-                            wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
-                            aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
-
-                            Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
-                            IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
-                            Standard_Integer cNbP = wline->NbPnts();
-
-                            TColStd_SequenceOfInteger VPold;
-                            Standard_Integer iPo;
-                            for( iPo = 1; iPo <= cnbV; iPo++ )
-                            {
-                              Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
-                              Standard_Integer IPo = (Standard_Integer) Po;
-                              VPold.Append(IPo);
-                            }
-
-                            Standard_Boolean removeNext = Standard_False;
-                            Standard_Boolean removePrev = Standard_False;
-                            if( ciV == 1)
-                            {
-                              Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                              if(dPar > 10)
-                              {
-                                removeNext = Standard_True;
-                                for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                  VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                              }
-                            }
-                            else if( ciV == cnbV)
-                            {
-                              Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                              if(dPar > 10)
-                              {
-                                removePrev = Standard_True;
-                                VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                              }
-                            }
-                            else
-                            {
-                              Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
-                              Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
-                              if(dParMi > 10)
-                              {
-                                removePrev = Standard_True;
-                                VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
-                              }
-
-                              if(dParMa > 10)
-                              {
-                                removeNext = Standard_True;
-                                for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                {
-                                  if(dParMi > 10)
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
-                                  else
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                                }
-                              }
-                              else
-                              {
-                                if(dParMi > 10)
-                                  for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
-                                    VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
-                              } 
-                            }
-
-                            Standard_Integer pI = ciVpar;
-
-                            Standard_Integer iP;
-                            for( iP = 1; iP <= cNbP; iP++)
-                            {
-                              if( pI == iP )
-                              {
-                                IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
-                                newL2s->Add(newPnt);
-                              }
-                              else if(removeNext && iP == (pI + 1))
-                                continue;
-                              else if(removePrev && iP == (pI - 1))
-                                continue;
-                              else
-                                newL2s->Add(wline->Point(iP));
-                            }
-
-                            IntPatch_Point newVtx;
-                            gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
-                            newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
-                            newVtx.SetParameters(u21,v21,u22,v22);
-                            newVtx.SetParameter(VPold.Value(ciV));
-
-                            Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
-
-                            Standard_Integer iV;
-                            for( iV = 1; iV <= cnbV; iV++ )
-                            {
-                              if( iV == ciV )
-                                NWLine->AddVertex(newVtx);
-                              else
-                              {
-                                IntPatch_Point theVtx = wline->Vertex(iV);
-                                theVtx.SetParameter(VPold.Value(iV));
-                                NWLine->AddVertex(theVtx);
-                              }
-                            }
-
-                            wline = NWLine;
-                          }//if( VDMin != 0 )
-                        }//for( ciV = 1; ciV <= cnbV; ciV++ )
-                      }// SLin.Length > 0
+                      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 5aa4e72566caef857e1c5da8b7081c4ce25d30c5..eb9c3217014f5bf04e6ef90ac2b15cb934aeb66f 100644 (file)
@@ -34,10 +34,10 @@ uses
 is
 
     enumeration StatusDeflection is 
-                PasTropGrand, PointConfondu, ArretSurPointPrecedent,
+                PasTropGrand, StepTooSmall, PointConfondu, ArretSurPointPrecedent,
                 ArretSurPoint, OK;
 
--- StepTooGreat, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
+-- StepTooGreat, StepTooSmall, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
     
 --class of result objects marching on a biparametric surface
 
index 99b7bcd6442797f4bc38d98d5d3112ff14dab9c4..bb5721f202ef54441f69dd0e382f1a76837fc5ec 100644 (file)
@@ -210,7 +210,21 @@ is
        
        raises NotDone from StdFail
        is static;
+      
+      
+    MaxStep(me ; Index : Integer from Standard)
+    
+       ---Purpose: Returns the point of range Index on the polyline. 
+       --          An exception is raised if IsDone returns False.
+       --          An exception is raised if Index<=0 or Index>NbPoints.
 
+       returns  Real from Standard
+       ---C++: inline
+
+       raises OutOfRange from Standard
+       
+       is static;
+       
 
     TangentAtLine(me; Index: out Integer from Standard)
     
@@ -250,6 +264,12 @@ is
     POn2S :          PntOn2S   from  IntSurf  ) ;
     ---C++: inline
     
+  ComputePasInit(me          : in out;
+                 Um1, UM1, Vm1, VM1, Um2, UM2, Vm2, VM2, Um1p, UM1p, Vm1p, VM1p, Um2p, UM2p, Vm2p, VM2p, Increment, tolconf: Real from Standard)
+
+  is protected;
+
+    
     ExtendLineInCommonZone(me: in out; theChoixIso: ConstIsoparametric  from IntImp;
 theDirectionFlag: Boolean from Standard)
     returns Boolean from Standard
@@ -317,9 +337,11 @@ fields
     fleche             : Real     from Standard;   -- max possible vector
     pasMax             : Real     from Standard;   -- max possible uv ratio
     tolconf            : Real     from Standard;   -- tol of confusion of 2 points
+    myTolTang          : Real     from Standard;
     pasuv              : Real     from Standard[4];-- uv step on squares 
     pasSav             : Real     from Standard[4];-- first saved step
     pasInit            : Real     from Standard[4];-- saving of steps  
+    myStepMin          : Real     from Standard[4];
 
     Um1                : Real from Standard;
     UM1                : Real from Standard;
index ae9e675e82b2a9fbde0a63bc634cd6c97541186c..cca5be548c08be5e23f56ac8c303bd4717ec67a3 100644 (file)
 // 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)
-{ 
+void IntWalk_PWalking::ComputePasInit(const Standard_Real Um1,
+                                      const Standard_Real UM1,
+                                      const Standard_Real Vm1,
+                                      const Standard_Real VM1,
+                                      const Standard_Real Um2,
+                                      const Standard_Real UM2,
+                                      const Standard_Real Vm2,
+                                      const Standard_Real VM2,
+                                      const Standard_Real _Um1,
+                                      const Standard_Real _UM1,
+                                      const Standard_Real _Vm1,
+                                      const Standard_Real _VM1,
+                                      const Standard_Real _Um2,
+                                      const Standard_Real _UM2,
+                                      const Standard_Real _Vm2,
+                                      const Standard_Real _VM2,
+                                      const Standard_Real Increment,
+                                      const Standard_Real tolconf)
+{
+  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);
@@ -72,24 +80,25 @@ void ComputePasInit(Standard_Real *pasuv,
   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;
+  pasuv[0]=Max(Increment*du1, pasuv[0]);
+  pasuv[1]=Max(Increment*dv1, pasuv[1]);
+  pasuv[2]=Max(Increment*du2, pasuv[2]);
+  pasuv[3]=Max(Increment*dv2, pasuv[3]);
 
   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;
+  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]);
+  }
 }
 
 //=======================================================================
@@ -268,6 +277,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),
@@ -378,6 +388,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++) {
@@ -408,6 +423,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),
@@ -544,6 +560,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;
@@ -623,6 +645,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[])
 {
   {
@@ -646,7 +669,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],
@@ -718,22 +742,9 @@ 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(u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
+                 Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,pasMax+pasMax,tolconf);
+
   for (Standard_Integer i=0; i<4; ++i)
   {
     if(pasuv[i]>10)
@@ -807,7 +818,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);
@@ -1166,27 +1177,9 @@ 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])
+                for(Standard_Integer i = 0; i < 4; i++)
                 {
-                  pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
-                  pastroppetit=Standard_False; 
-                }
-
-                if(pasuv[3]<pasInit[3])
-                {
-                  pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
+                  pasuv[i]+=(pasInit[i]-pasuv[i])*0.25;
                   pastroppetit=Standard_False;
                 }
 
@@ -1211,6 +1204,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
           {
@@ -1299,6 +1318,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
                     if(RejectIndex >= RejectIndexMAX)
                     {
+                      Arrive = Standard_True;
                       break;
                     }
 
@@ -1386,6 +1406,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
                       if(RejectIndex >= RejectIndexMAX)
                       {
+                        Arrive = Standard_True;
                         break;
                       }
 
@@ -1619,6 +1640,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
                         if(RejectIndex >= RejectIndexMAX)
                         {
+                          Arrive = Standard_True;
                           break;
                         }
 
@@ -2104,7 +2126,7 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
     aS1 = theASurf1->Surface().BSpline();
     break;
   default:
-    return Standard_True;
+      return Standard_True;
   }
 
   switch(theASurf2->GetType())
@@ -2116,7 +2138,7 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
     aS2 = theASurf2->Surface().BSpline();
     break;
   default:
-    return Standard_True;
+      return Standard_True;
   }
 
   Standard_Boolean aStatus = Standard_False;
@@ -2821,7 +2843,7 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
   }
 
   IntWalk_StatusDeflection Status = IntWalk_OK;
-  Standard_Real FlecheCourante ,Ratio;
+  Standard_Real FlecheCourante , Ratio = 1.0;
 
 
   const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point(); 
@@ -2834,10 +2856,12 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
 
   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 
@@ -2855,7 +2879,6 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
     else 
       return IntWalk_PasTropGrand;
   }
-
   else {
     if(STATIC_PRECEDENT_INFLEXION  > 0) { 
       STATIC_PRECEDENT_INFLEXION -- ;
@@ -2867,11 +2890,11 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
   //=========  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 ) { 
+  if (aSqDist < 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]));
@@ -2994,7 +3017,7 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
   //-- 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) { 
@@ -3061,10 +3084,94 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection()
       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
+              cos(B) = 1 - 2*(1-2/(1+(d/(2*e))^2))^2 = Fd(e),
+    where Fd(e) is some function with parameter "deflection".
+
+    Let mean that Fd(e) is increasing function, i.e. the greater cos(B)
+    the greater real deflection e.
+    */
+
+    //When Deflection is equal to tolconf
+    const Standard_Real anInvSqAbsArcDeflMax = 0.25*aSqDist/(tolconf*tolconf);
+  
+    //When Deflection is equal to tolconf/2
+    const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax;
+    const Standard_Real aThresholdCosMin = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin);
+    const Standard_Real aThresholdCosMax = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMax);
+
+    if((Status != IntWalk_PasTropGrand) && (aCosBetweenTangent < 2.0*aThresholdCosMax*aThresholdCosMax - 1.0))
+    { // I.e. cos(B) >= Fd(tolconf).
+      // Consequently, real deflection is greater than tolconf (too big) ==> decrease step
+      pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
+      return IntWalk_PasTropGrand;
+    }
+
+    if(aCosBetweenTangent > 2.0*aThresholdCosMin*aThresholdCosMin - 1.0)
+    { //I.e. cos(B) <= Fd(tolconf/2)
+      // Consequently, real deflection is less than tolconf/2 (too small) ==> increase step
+
+      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 IntWalk_StepTooSmall;
+    }
+  }
+
+  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 e1614170c9be5a0b4f397a5bd4e933bb9cd0edcf..430d1bf1246053431efa3aedbbd1a18463745c3d 100644 (file)
@@ -62,6 +62,12 @@ inline const gp_Dir& IntWalk_PWalking::TangentAtLine
   return tgdir;
 }
 
+inline Standard_Real IntWalk_PWalking::MaxStep(Standard_Integer theIndex) const
+{
+  Standard_OutOfRange_Raise_if((theIndex < 0) || (theIndex > 3), "");
+  return pasInit[theIndex];
+}
+
 #define REGLAGE 0
 
 inline void IntWalk_PWalking::AddAPoint(Handle(IntSurf_LineOn2S)& theLine,
diff --git a/tests/bugs/modalg_6/bug26980 b/tests/bugs/modalg_6/bug26980
new file mode 100644 (file)
index 0000000..2c2e452
--- /dev/null
@@ -0,0 +1,64 @@
+puts "========"
+puts "OCC26980"
+puts "========"
+puts ""
+#################################
+# Intersection part of Boolean algorithm spends much system time and system memory
+#################################
+
+cpulimit 5000 
+
+set max_time 120
+set mem_max_wsetpeak 700000000
+
+
+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