]> OCCT Git - occt.git/commitdiff
0032644: Modeling Algorithms - Empty result of section operation IR-2021-12-24
authoremv <emv@opencascade.com>
Thu, 28 Oct 2021 08:07:05 +0000 (11:07 +0300)
committersmoskvin <smoskvin@opencascade.com>
Thu, 23 Dec 2021 16:19:11 +0000 (19:19 +0300)
Use distance criteria additionally to parameter criteria when verifying the extrema solution to belong to the edge boundary.
Refactor the BRepExtrema_DistanceSS class to remove the excessive methods with mirrored parameters.

dox/upgrade/upgrade.md
src/BRepExtrema/BRepExtrema_DistanceSS.cxx
src/BRepExtrema/BRepExtrema_DistanceSS.hxx
tests/bugs/modalg_7/bug32644 [new file with mode: 0644]

index 5caa102205a9a83e76f63a2f368146b2f77fb455..72720303c3eda287803ab6aaa90ceea03869fd2a 100644 (file)
@@ -2300,6 +2300,10 @@ void Perform(const Handle(Adaptor3d_CurveOnSurface)& theCurveOnSurface,
 Building OCCT now requires C++11-compliant compiler, so that some legacy compilers (Visual Studio 2010 and 2012) are no more supported.
 It is recommended using Visual Studio 2015 or newer for building OCCT on Windows platform.
 
+@subsection upgrade_770_removed_features Removed features
+
+* One of the constructors of the BRepExtrema_DistanceSS class (the one without deflection parameter) has been removed as excessive. The remaining constructor has to be used instead.
+
 @subsection upgrade_occt770_parallel_flag_removed Removed parameter theIsParallel from Put/Compute/Perform
 
 theIsParallel parameter has been removed from Put/Compute/Perform from the next classes:
index 7cbd701f3b802d686fd0321b56ebfa28918f858c..0031e66a71b3c3345450ebcb22fab748abcddda2 100644 (file)
@@ -73,7 +73,7 @@ static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, c
     }
   }
   return Standard_True;
-}  
+}
 
 //------------------------------------------------------------------------------
 // function: MIN_SOLUTION
@@ -85,16 +85,16 @@ static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
                           BRepExtrema_SeqOfSolution& seqSol1,
                           BRepExtrema_SeqOfSolution& seqSol2)
 {
-  for (BRepExtrema_SeqOfSolution::iterator anIt1 = SeqSol1.begin(), anIt2 = SeqSol2.begin(); 
-       anIt1 != SeqSol1.end(); 
+  for (BRepExtrema_SeqOfSolution::iterator anIt1 = SeqSol1.begin(), anIt2 = SeqSol2.begin();
+       anIt1 != SeqSol1.end();
        anIt1++, anIt2++)
   {
     const Standard_Real dst1 = anIt1->Dist();
     if (fabs(dst1 - DstRef) < Eps)
-         {       
+    {
       seqSol1.Append(*anIt1);
       seqSol2.Append(*anIt2);
-         }
+    }
   }
 }
 
@@ -104,7 +104,7 @@ static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
                               Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
 {
-  if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
+  if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
     return;
 
   aResEdge = S2;
@@ -113,17 +113,17 @@ static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, Topo
   Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
 
   if (Precision::IsInfinite(aFirst1) &&
-      Precision::IsInfinite(aLast1)  &&
+      Precision::IsInfinite(aLast1) &&
       Precision::IsInfinite(aFirst2) &&
       Precision::IsInfinite(aLast2))
     return;
-  
+
   Standard_Real Umin = 0., Umax = 0.;
   Standard_Boolean bUmin, bUmax;
   bUmin = bUmax = Standard_False;
 
   Handle(Geom_Curve) pCurv;
-  if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
+  if (!pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)))
   {
     pCurv = pCurv1;
     bIsTrim1 = Standard_True;
@@ -138,7 +138,7 @@ static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, Topo
       Umax = aLast1;
     }
   }
-  else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
+  else if (!pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)))
   {
     pCurv = pCurv2;
     bIsTrim2 = Standard_True;
@@ -172,7 +172,7 @@ static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, Topo
     const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
     const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
 
-       Standard_Real arrU[8];
+    Standard_Real arrU[8];
     GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
     /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
     aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
@@ -182,22 +182,22 @@ static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, Topo
     aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
     aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
     aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
-    
+
     if (!bUmin)
       Umin = arrU[0];
-       
+
     if (!bUmax)
       Umax = arrU[0];
 
     Standard_Integer i = 0;
     while (i < 8)
-       {
+    {
       const Standard_Real aU = arrU[i++];
-         if (aU < Umin)
-           Umin = aU;
-         else if (aU > Umax)
-           Umax = aU;
-       }
+      if (aU < Umin)
+        Umin = aU;
+      else if (aU > Umax)
+        Umax = aU;
+    }
 
     Standard_Real tol = Precision::Confusion();
     if (bIsTrim1)
@@ -205,7 +205,7 @@ static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, Topo
     else if (bIsTrim2)
       tol = BRep_Tool::Tolerance(S2);
 
-    const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
+    const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3. * tol);
     if (fabs(Umin - Umax) < EpsU)
     {
       Umin -= EpsU;
@@ -225,23 +225,23 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 {
   bIsInfinit = Standard_False;
 
-  TopAbs_ShapeEnum Type1 = S1.ShapeType();     
+  TopAbs_ShapeEnum Type1 = S1.ShapeType();
   TopAbs_ShapeEnum Type2 = S2.ShapeType();
 
   TopoDS_Edge aE;
   TopoDS_Face aF;
-  
+
   if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
   {
     aE = TopoDS::Edge(S1);
-    if ( BRep_Tool::Degenerated(aE) )
+    if (BRep_Tool::Degenerated(aE))
       return;
     aF = TopoDS::Face(S2);
   }
   else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
   {
     aE = TopoDS::Edge(S2);
-    if ( BRep_Tool::Degenerated(aE) )
+    if (BRep_Tool::Degenerated(aE))
       return;
     aF = TopoDS::Face(S1);
   }
@@ -253,7 +253,7 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 
   aResFace = aF;
   Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
+
   const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
 
   Standard_Real U1, V1, U2, V2;
@@ -284,15 +284,15 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
     if (Precision::IsInfinite(V1))
       bIsTrim = Standard_True;
     else
-       {
+    {
       Vmin = V1;
       bVmin = Standard_True;
-       }
-      
+    }
+
     if (Precision::IsInfinite(V2))
       bIsTrim = Standard_True;
     else
-       {
+    {
       Vmax = V2;
       bVmax = Standard_True;
     }
@@ -308,11 +308,11 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
   }
 
   if (bIsTrim)
-  {      
+  {
     Bnd_Box aEdgeBox;
     BRepBndLib::Add(aE, aEdgeBox);
 
-    if(aEdgeBox.IsWhole())
+    if (aEdgeBox.IsWhole())
       return;
 
     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
@@ -329,14 +329,14 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 
     Standard_Real arrU[8], arrV[8];
     GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
-    /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
-    aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
-    aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
-    aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
-    aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
-    aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
-    aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
-    aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
+    /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0], arrV[0]);
+    aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1], arrV[1]);
+    aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2], arrV[2]);
+    aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3], arrV[3]);
+    aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4], arrV[4]);
+    aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5], arrV[5]);
+    aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6], arrV[6]);
+    aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7], arrV[7]);
 
     if (!bUmin)
       Umin = arrU[0];
@@ -349,33 +349,33 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 
     Standard_Integer i = 0;
     while (i < 8)
-       {
+    {
       const Standard_Real aU = arrU[i];
-         if (aU < Umin)
-           Umin = aU;
-         else if (aU > Umax)
-           Umax = aU;
+      if (aU < Umin)
+        Umin = aU;
+      else if (aU > Umax)
+        Umax = aU;
 
       const Standard_Real aV = arrV[i];
-         if (aV < Vmin)
-           Vmin = aV;
-         else if (aV > Vmax)
-           Vmax = aV;
+      if (aV < Vmin)
+        Vmin = aV;
+      else if (aV > Vmax)
+        Vmax = aV;
 
       i++;
-       }
-      
+    }
+
     GeomAdaptor_Surface aGAS(pSurf);
     const Standard_Real tol = BRep_Tool::Tolerance(aF);
 
-    const Standard_Real EpsU = aGAS.UResolution(3.*tol);
+    const Standard_Real EpsU = aGAS.UResolution(3. * tol);
     if (fabs(Umin - Umax) < EpsU)
     {
       Umin -= EpsU;
       Umax += EpsU;
     }
 
-    const Standard_Real EpsV = aGAS.VResolution(3.*tol);
+    const Standard_Real EpsV = aGAS.VResolution(3. * tol);
     if (fabs(Vmin - Vmax) < EpsV)
     {
       Vmin -= EpsV;
@@ -394,14 +394,14 @@ static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
 //------------------------------------------------------------------------------
 // static function: PERFORM_C0
 //------------------------------------------------------------------------------
-static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
+static void PERFORM_C0(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
                        BRepExtrema_SeqOfSolution& SeqSol1,
                        BRepExtrema_SeqOfSolution& SeqSol2,
                        const Standard_Real DstRef,
                        Standard_Real& mDstRef,
                        const Standard_Real Eps)
 {
-  if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
+  if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
     return;
 
   Standard_Integer iE;
@@ -409,15 +409,15 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
   {
     TopoDS_Edge E, Eother;
     if (iE == 0)
-       {
-         E      = S1;
-         Eother = S2;
-       }
+    {
+      E = S1;
+      Eother = S2;
+    }
     else
-       {
-         E      = S2;
-         Eother = S1;
-       }
+    {
+      E = S2;
+      Eother = S1;
+    }
 
     Standard_Real aFirst, aLast;
     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
@@ -426,25 +426,25 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
     Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
 
     if (pCurv->Continuity() == GeomAbs_C0)
-       {
+    {
       const Standard_Real epsP = Precision::PConfusion();
 
       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
 
-      TColStd_Array1OfReal arrInter(1,1+nbIntervals);
+      TColStd_Array1OfReal arrInter(1, 1 + nbIntervals);
       aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
 
       GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
       const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
-      TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
+      TColStd_Array1OfReal arrInterOther(1, 1 + nbIntervalsOther);
       aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
 
-      Standard_Real Udeb,Ufin;
-      BRep_Tool::Range(Eother,Udeb,Ufin);
+      Standard_Real Udeb, Ufin;
+      BRep_Tool::Range(Eother, Udeb, Ufin);
 
-      gp_Pnt P1,Pt;
-      Standard_Integer i, ii;  
+      gp_Pnt P1, Pt;
+      Standard_Integer i, ii;
       BRepClass_FaceClassifier classifier;
       for (i = 1; i <= arrInter.Length(); i++)
       {
@@ -452,36 +452,36 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
         const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
         const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
 
-        BRepExtrema_ExtPC Ext(V1,Eother);
-        const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
-        if ( NbExtrema > 0 )
-               { 
+        BRepExtrema_ExtPC Ext(V1, Eother);
+        const Standard_Integer NbExtrema = Ext.IsDone() ? Ext.NbExt() : 0;
+        if (NbExtrema > 0)
+        {
           // Search minimum distance dstmin
           Standard_Real Dstmin = Ext.SquareDistance(1);
           for (ii = 2; ii <= NbExtrema; ii++)
           {
             const Standard_Real sDst = Ext.SquareDistance(ii);
-            if (sDst<Dstmin)
-              Dstmin=sDst;
+            if (sDst < Dstmin)
+              Dstmin = sDst;
           }
           Dstmin = sqrt(Dstmin);
 
-          if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
+          if ((Dstmin < DstRef - Eps) || (fabs(Dstmin - DstRef) < Eps))
             for (ii = 1; ii <= NbExtrema; ii++)
             {
-              if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
+              if (fabs(Dstmin - sqrt(Ext.SquareDistance(ii))) < Eps)
               {
-                Pt=Ext.Point(ii);
-                if (TRI_SOLUTION(SeqSol2,Pt))
+                Pt = Ext.Point(ii);
+                if (TRI_SOLUTION(SeqSol2, Pt))
                 {
                   // Check if the parameter does not correspond to a vertex
                   const Standard_Real t = Ext.Parameter(ii);
-                  if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
+                  if ((fabs(t - Udeb) >= epsP) && (fabs(t - Ufin) > epsP))
                   {
                     if (mDstRef > Dstmin)
-                      mDstRef=Dstmin;
-                    const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
-                    const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
+                      mDstRef = Dstmin;
+                    const BRepExtrema_SolutionElem Sol1(Dstmin, aPnt, BRepExtrema_IsOnEdge, E, aParameter);
+                    const BRepExtrema_SolutionElem Sol2(Dstmin, Pt, BRepExtrema_IsOnEdge, Eother, t);
                     SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
                     SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
                   }
@@ -489,58 +489,90 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
               }
             }
         }
-        for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
+        for (Standard_Integer i2 = 1; i2 <= arrInterOther.Length(); i2++)
         {
           const Standard_Real aParameterOther = arrInterOther(i2);
           const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
           const Standard_Real Dst = aPnt.Distance(aPntOther);
-          if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
-          {            
+          if ((Dst < DstRef - Eps) || (fabs(Dst - DstRef) < Eps))
+          {
             if (mDstRef > Dst)
-              mDstRef=Dst;
-            const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
-            const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
+              mDstRef = Dst;
+            const BRepExtrema_SolutionElem Sol1(Dst, aPnt, BRepExtrema_IsOnEdge, E, aParameter);
+            const BRepExtrema_SolutionElem Sol2(Dst, aPntOther, BRepExtrema_IsOnEdge, Eother, aParameterOther);
             SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
             SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
-          }              
+          }
         }
       }
     }
   }
 }
 
-/*********************************************************************************/
+//=======================================================================
+//function : isOnBoundary
+//purpose  : Checks in 3d if the extrema point belongs to edge boundary
+//=======================================================================
+static Standard_Boolean isOnBoundary(const TopoDS_Edge& theEdge,
+                                     const gp_Pnt& theSol,
+                                     const Standard_Real theParam,
+                                     const Standard_Real thePTol)
+{
+  for (TopoDS_Iterator it(theEdge); it.More(); it.Next())
+  {
+    const TopoDS_Vertex& aV = TopoDS::Vertex (it.Value());
+    Standard_Real aVParam = BRep_Tool::Parameter(aV, theEdge);
+    if (Abs (aVParam - theParam) < thePTol &&
+        BRep_Tool::Pnt (aV).Distance (theSol) < BRep_Tool::Tolerance (aV))
+    {
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
+//=======================================================================
+//function : Perform
+//purpose  :
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2,
+                                     const Bnd_Box& theBox1, const Bnd_Box& theBox2)
 {
-  SeqSolShape1.Clear();
-  SeqSolShape2.Clear();
-  myModif=Standard_False;
+  mySeqSolShape1.Clear();
+  mySeqSolShape2.Clear();
+  myModif = Standard_False;
+
+  Standard_Real aBBDist = theBox1.Distance (theBox2);
+  if (aBBDist - myDstRef > myEps)
+  {
+    // The Box-Box distance is greater than the start distance.
+    // The solution cannot be improved further.
+    return;
+  }
 
-  switch (S1.ShapeType())
+  switch (theS1.ShapeType())
   {
-    case TopAbs_VERTEX :
+    case TopAbs_VERTEX:
     {
-      TopoDS_Vertex V1 = TopoDS::Vertex(S1);
-      switch (S2.ShapeType())
+      TopoDS_Vertex aV1 = TopoDS::Vertex (theS1);
+      switch (theS2.ShapeType())
       {
-        case TopAbs_VERTEX :
+        case TopAbs_VERTEX:
         {
-          TopoDS_Vertex V2 = TopoDS::Vertex(S2);
-          Perform( V1, V2 );
+          TopoDS_Vertex aV2 = TopoDS::Vertex (theS2);
+          Perform (aV1, aV2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
-        case TopAbs_EDGE :
+        case TopAbs_EDGE:
         {
-          TopoDS_Edge E2 = TopoDS::Edge(S2);
-          Perform( V1, E2, B1, B2 );
+          TopoDS_Edge aE2 = TopoDS::Edge (theS2);
+          Perform (aV1, aE2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
-        case TopAbs_FACE :
+        case TopAbs_FACE:
         {
-          TopoDS_Face F2 = TopoDS::Face(S2);
-          Perform( V1, F2, B1, B2 );
+          TopoDS_Face aF2 = TopoDS::Face (theS2);
+          Perform (aV1, aF2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
         default:
@@ -548,41 +580,40 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
       }
       break;
     }
-
-    case TopAbs_EDGE :
+    case TopAbs_EDGE:
     {
-      TopoDS_Edge E1 = TopoDS::Edge(S1);
-      switch (S2.ShapeType())
+      TopoDS_Edge aE1 = TopoDS::Edge (theS1);
+      switch (theS2.ShapeType())
       {
-        case TopAbs_VERTEX :
+        case TopAbs_VERTEX:
         {
-          TopoDS_Vertex V2 = TopoDS::Vertex(S2);
-          Perform( E1, V2, B1, B2 );
+          TopoDS_Vertex aV2 = TopoDS::Vertex (theS2);
+          Perform (aV2, aE1, mySeqSolShape2, mySeqSolShape1);
           break;
         }
-        case TopAbs_EDGE :
+        case TopAbs_EDGE:
         {
-          TopoDS_Edge E2 = TopoDS::Edge(S2);
+          TopoDS_Edge aE2 = TopoDS::Edge (theS2);
           TopoDS_Edge aTrimEdge;
           Standard_Boolean bIsTrim1 = Standard_False;
           Standard_Boolean bIsTrim2 = Standard_False;
-          TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
+          TRIM_INFINIT_EDGE (aE1, aE2, aTrimEdge, bIsTrim1, bIsTrim2);
           if (bIsTrim1)
-            E1 = aTrimEdge;
+            aE1 = aTrimEdge;
           if (bIsTrim2)
-            E2 = aTrimEdge;
-          Perform( E1, E2, B1, B2 );
+            aE2 = aTrimEdge;
+          Perform (aE1, aE2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
-        case TopAbs_FACE :
+        case TopAbs_FACE:
         {
-          TopoDS_Face F2 = TopoDS::Face(S2);
+          TopoDS_Face aF2 = TopoDS::Face (theS2);
           TopoDS_Face aTrimFace;
           Standard_Boolean bIsInfinit;
-          TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
+          TRIM_INFINIT_FACE (aE1, aF2, aTrimFace, bIsInfinit);
           if (bIsInfinit)
-            F2 = aTrimFace;
-          Perform( E1, F2, B1, B2 );
+            aF2 = aTrimFace;
+          Perform (aE1, aF2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
         default:
@@ -590,33 +621,32 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
       }
       break;
     }
-
-    case TopAbs_FACE :
+    case TopAbs_FACE:
     {
-      TopoDS_Face F1 = TopoDS::Face(S1);
-      switch (S2.ShapeType())
+      TopoDS_Face aF1 = TopoDS::Face (theS1);
+      switch (theS2.ShapeType())
       {
-        case TopAbs_VERTEX :
+        case TopAbs_VERTEX:
         {
-          TopoDS_Vertex V2 = TopoDS::Vertex(S2);
-          Perform( F1, V2, B1, B2 );
+          TopoDS_Vertex aV2 = TopoDS::Vertex (theS2);
+          Perform (aV2, aF1, mySeqSolShape2, mySeqSolShape1);
           break;
         }
-        case TopAbs_EDGE :
+        case TopAbs_EDGE:
         {
-          TopoDS_Edge E2 = TopoDS::Edge(S2);
+          TopoDS_Edge aE2 = TopoDS::Edge (theS2);
           TopoDS_Face aTrimFace;
           Standard_Boolean bIsInfinit;
-          TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
+          TRIM_INFINIT_FACE (aF1, aE2, aTrimFace, bIsInfinit);
           if (bIsInfinit)
-            F1 = aTrimFace;
-          Perform( F1, E2, B1, B2 );
+            aF1 = aTrimFace;
+          Perform (aE2, aF1, mySeqSolShape2, mySeqSolShape1);
           break;
         }
-        case TopAbs_FACE :
+        case TopAbs_FACE:
         {
-          TopoDS_Face F2 = TopoDS::Face(S2);
-          Perform( F1, F2, B1, B2 );
+          TopoDS_Face aF2 = TopoDS::Face (theS2);
+          Perform (aF1, aF2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
         default:
@@ -629,78 +659,80 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
   }
 }
 
-/*********************************************************************************/
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
-{     
-  const gp_Pnt P1 = BRep_Tool::Pnt(S1);
-  const gp_Pnt P2 = BRep_Tool::Pnt(S2);
+//=======================================================================
+//function : Perform
+//purpose  : Vertex-Vertex
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform (const TopoDS_Vertex& theS1,
+                                      const TopoDS_Vertex& theS2,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape2)
+{
+  const gp_Pnt aP1 = BRep_Tool::Pnt (theS1);
+  const gp_Pnt aP2 = BRep_Tool::Pnt (theS2);
 
-  const Standard_Real Dst = P1.Distance(P2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  { 
+  const Standard_Real Dst = aP1.Distance(aP2);
+  if ((Dst < myDstRef - myEps) || (fabs(Dst - myDstRef) < myEps))
+  {
     if (myDstRef > Dst)
-      myDstRef=Dst;
-    myModif=Standard_True;
-    const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
-    const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
-    SeqSolShape1.Append(Sol1);
-    SeqSolShape2.Append(Sol2);
+      myDstRef = Dst;
+    myModif = Standard_True;
+    const BRepExtrema_SolutionElem Sol1 (Dst, aP1, BRepExtrema_IsVertex, theS1);
+    const BRepExtrema_SolutionElem Sol2 (Dst, aP2, BRepExtrema_IsVertex, theS2);
+    theSeqSolShape1.Append (Sol1);
+    theSeqSolShape2.Append (Sol2);
   }
 }
 
-/*********************************************************************************/
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
-{ 
-  if (BRep_Tool::Degenerated(S2))
+//=======================================================================
+//function : Perform
+//purpose  : Vertex-Edge
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform (const TopoDS_Vertex& theS1,
+                                      const TopoDS_Edge& theS2,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape2)
+{
+  if (BRep_Tool::Degenerated(theS2))
     return;
 
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
+  BRepExtrema_ExtPC Ext(theS1, theS2);
+  const Standard_Integer NbExtrema = Ext.IsDone() ? Ext.NbExt() : 0;
+  if (NbExtrema > 0)
   {
-    BRepExtrema_ExtPC Ext(S1,S2);
-    const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
-    if ( NbExtrema > 0 )
+    // Search minimum distance Dstmin
+    Standard_Integer i;
+    Standard_Real Dstmin = Ext.SquareDistance(1);
+    for (i = 2; i <= NbExtrema; i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin)
-          Dstmin=sDst;
-         }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        Standard_Real Udeb,Ufin;
-        BRep_Tool::Range(S2,Udeb,Ufin);
-
-        gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
-        const Standard_Real epsP=Precision::PConfusion();
+      const Standard_Real sDst = Ext.SquareDistance(i);
+      if (sDst < Dstmin)
+        Dstmin = sDst;
+    }
+    Dstmin = sqrt(Dstmin);
+    if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
+    {
+      gp_Pnt Pt, P1 = BRep_Tool::Pnt(theS1);
+      const Standard_Real epsP = Precision::PConfusion();
 
-        for (i = 1; i <= NbExtrema; i++)
+      for (i = 1; i <= NbExtrema; i++)
+      {
+        if (fabs(Dstmin - sqrt(Ext.SquareDistance(i))) < myEps)
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          Pt = Ext.Point(i);
+          if (TRI_SOLUTION(theSeqSolShape2, Pt))
           {
-            Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape2,Pt))
+            // Check if the parameter does not correspond to a vertex
+            const Standard_Real t = Ext.Parameter(i);
+            if (!isOnBoundary(theS2, Pt, t, epsP))
             {
-              // Check if the parameter does not correspond to a vertex
-              const Standard_Real t = Ext.Parameter(i);
-              if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
-              {
-                if (myDstRef > Dstmin)
-                  myDstRef=Dstmin;
-                myModif=Standard_True;
-                const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
-                const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
-              }
+              if (myDstRef > Dstmin)
+                myDstRef = Dstmin;
+              myModif = Standard_True;
+              const BRepExtrema_SolutionElem Sol1(Dstmin, P1, BRepExtrema_IsVertex, theS1);
+              const BRepExtrema_SolutionElem Sol2(Dstmin, Pt, BRepExtrema_IsOnEdge, theS2, t);
+              theSeqSolShape1.Append(Sol1);
+              theSeqSolShape2.Append(Sol2);
             }
           }
         }
@@ -709,114 +741,56 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge&
   }
 }
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
-                                     const Bnd_Box& B1,const Bnd_Box& B2)
+//=======================================================================
+//function : Perform
+//purpose  : Vertex-Face
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& theS1,
+                                     const TopoDS_Face& theS2,
+                                     BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                     BRepExtrema_SeqOfSolution& theSeqSolShape2)
 {
-  if (BRep_Tool::Degenerated(S1))
-    return;
-
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
+  BRepExtrema_ExtPF Ext (theS1, theS2, myFlag, myAlgo);
+  const Standard_Integer NbExtrema = Ext.IsDone() ? Ext.NbExt() : 0;
+  if (NbExtrema > 0)
   {
-    BRepExtrema_ExtPC Ext(S2,S1);
-    const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
-    if ( NbExtrema > 0 )
+    // Search minimum distance Dstmin
+    Standard_Integer i;
+    Standard_Real Dstmin = Ext.SquareDistance(1);
+    for (i = 2; i <= NbExtrema; i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin)
-          Dstmin=sDst;
-         }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        Standard_Real Udeb,Ufin;
-        BRep_Tool::Range(S1,Udeb,Ufin);
-
-        gp_Pnt Pt, P2 = BRep_Tool::Pnt(S2);
-        const Standard_Real epsP=Precision::PConfusion();
-
-        for (i = 1; i <= NbExtrema; i++)
-        {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
-          {
-            Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt))
-            {
-              // Check if the parameter does not correspond to a vertex
-              const Standard_Real t = Ext.Parameter(i);
-              if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
-              {
-                if (myDstRef > Dstmin)
-                  myDstRef=Dstmin;
-                myModif=Standard_True;
-                const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
-                const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
-              }
-            }
-          }
-        }
-      }
+      const Standard_Real sDst = Ext.SquareDistance(i);
+      if (sDst < Dstmin)
+        Dstmin = sDst;
     }
-  }
-}
-
-/*********************************************************************************/
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2, 
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
-{
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  { 
-    BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
-    const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
-    if ( NbExtrema > 0 )
+    Dstmin = sqrt(Dstmin);
+    if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin) 
-          Dstmin=sDst;
-      }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
+      Standard_Real U, V;
+      gp_Pnt Pt, P1 = BRep_Tool::Pnt(theS1);
+      BRepClass_FaceClassifier classifier;
+      const Standard_Real tol = BRep_Tool::Tolerance(theS2);
+
+      for (i = 1; i <= NbExtrema; i++)
       {
-        Standard_Real U,V;
-        gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
-        BRepClass_FaceClassifier classifier;
-        const Standard_Real tol = BRep_Tool::Tolerance(S2);
-        for (i = 1; i <= NbExtrema; i++)
+        if (fabs(Dstmin - sqrt(Ext.SquareDistance(i))) < myEps)
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          Pt = Ext.Point(i);
+          if (TRI_SOLUTION(theSeqSolShape2, Pt))
           {
-            Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape2,Pt))
+            // Check if the parameter does not correspond to a vertex
+            Ext.Parameter(i, U, V);
+            const gp_Pnt2d PUV(U, V);
+            classifier.Perform(theS2, PUV, tol);
+            if (classifier.State() == TopAbs_IN)
             {
-              // Check if the parameter does not correspond to a vertex
-              Ext.Parameter(i,U,V);
-              const gp_Pnt2d PUV(U,V);
-              classifier.Perform(S2,PUV,tol);
-              if (classifier.State()==TopAbs_IN)
-              {
-                if (myDstRef > Dstmin)
-                  myDstRef=Dstmin;
-                myModif=Standard_True;
-                const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
-                const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);               
-              }
+              if (myDstRef > Dstmin)
+                myDstRef = Dstmin;
+              myModif = Standard_True;
+              const BRepExtrema_SolutionElem Sol1(Dstmin, P1, BRepExtrema_IsVertex, theS1);
+              const BRepExtrema_SolutionElem Sol2(Dstmin, Pt, BRepExtrema_IsInFace, theS2, U, V);
+              theSeqSolShape1.Append(Sol1);
+              theSeqSolShape2.Append(Sol2);
             }
           }
         }
@@ -825,206 +799,211 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face&
   }
 }
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2, 
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
+//=======================================================================
+//function : Perform
+//purpose  : Edge-Edge
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform (const TopoDS_Edge& theS1,
+                                      const TopoDS_Edge& theS2,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape2)
 {
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  { 
-    BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
-    const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
-    if ( NbExtrema > 0 )
+  if (BRep_Tool::Degenerated(theS1) || BRep_Tool::Degenerated(theS2))
+    return;
+
+  const Standard_Real DstRef = myDstRef;
+
+  BRepExtrema_ExtCC Ext(theS1, theS2);
+  const Standard_Integer NbExtrema = Ext.IsDone() ? (Ext.IsParallel() ? 0 : Ext.NbExt()) : 0;
+  if (NbExtrema > 0)
+  {
+    // Search minimum distance Dstmin
+    Standard_Integer i;
+    Standard_Real Dstmin = Ext.SquareDistance(1);
+    for (i = 2; i <= NbExtrema; i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin) 
-          Dstmin=sDst;
-      }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
+      const Standard_Real sDst = Ext.SquareDistance(i);
+      if (sDst < Dstmin)
+        Dstmin = sDst;
+    }
+    Dstmin = sqrt(Dstmin);
+    if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
+    {
+      gp_Pnt Pt1, Pt2;
+      const Standard_Real epsP = Precision::PConfusion();
+
+      for (i = 1; i <= NbExtrema; i++)
       {
-        Standard_Real U,V;
-        gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
-        BRepClass_FaceClassifier classifier;
-        const Standard_Real tol = BRep_Tool::Tolerance(S1);
-        for (i = 1; i <= NbExtrema; i++)
+        if (fabs(Dstmin - sqrt(Ext.SquareDistance(i))) < myEps)
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          Pt1 = Ext.PointOnE1(i);
+          Pt2 = Ext.PointOnE2(i);
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
           {
-            Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt))
+            // Check if the parameters do not correspond to a vertex
+            const Standard_Real t1 = Ext.ParameterOnE1(i);
+            const Standard_Real t2 = Ext.ParameterOnE2(i);
+
+            if (!isOnBoundary (theS1, Pt1, t1, epsP) && !isOnBoundary (theS2, Pt2, t2, epsP))
             {
-              // Check if the parameter does not correspond to a vertex
-              Ext.Parameter(i,U,V);
-              const gp_Pnt2d PUV(U,V);
-              classifier.Perform(S1,PUV,tol);
-              if (classifier.State()==TopAbs_IN)
-              {
-                if (myDstRef > Dstmin)
-                  myDstRef=Dstmin;
-                myModif=Standard_True;
-                const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
-                const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);               
-              }
+              if (myDstRef > Dstmin)
+                myDstRef = Dstmin;
+              myModif = Standard_True;
+              const BRepExtrema_SolutionElem Sol1(Dstmin, Pt1, BRepExtrema_IsOnEdge, theS1, t1);
+              const BRepExtrema_SolutionElem Sol2(Dstmin, Pt2, BRepExtrema_IsOnEdge, theS2, t2);
+              theSeqSolShape1.Append(Sol1);
+              theSeqSolShape2.Append(Sol2);
             }
           }
         }
       }
     }
   }
-}
 
-/*********************************************************************************/
+  BRepExtrema_SeqOfSolution SeqSolution1;
+  BRepExtrema_SeqOfSolution SeqSolution2;
+
+  PERFORM_C0(theS1, theS2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
+  BRepExtrema_SeqOfSolution seqSol1;
+  BRepExtrema_SeqOfSolution seqSol2;
+
+  if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
+    MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
+
+  if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
+  {
+    theSeqSolShape1.Append(seqSol1);
+    theSeqSolShape2.Append(seqSol2);
+    myModif = Standard_True;
+  }
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : Edge-Face
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform (const TopoDS_Edge& theS1, const TopoDS_Face& theS2,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape2)
 {
-  if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
+  if (BRep_Tool::Degenerated(theS1))
     return;
 
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
-    const Standard_Real DstRef = myDstRef;
+  BRepClass_FaceClassifier classifier;
 
-    BRepExtrema_ExtCC Ext(S1,S2);
-       const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
-    if ( NbExtrema > 0 )
+  BRepExtrema_ExtCF Ext(theS1, theS2);
+  const Standard_Integer NbExtrema = Ext.IsDone() ? (Ext.IsParallel() ? 0 : Ext.NbExt()) : 0;
+  if (NbExtrema > 0)
+  {
+    // Search minimum distance Dstmin
+    Standard_Integer i;
+    Standard_Real Dstmin = Ext.SquareDistance(1);
+    for (i = 2; i <= NbExtrema; i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin) 
-          Dstmin=sDst;
-         }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
-        BRep_Tool::Range(S1,Udeb1,Ufin1);
-        BRep_Tool::Range(S2,Udeb2,Ufin2);
+      const Standard_Real sDst = Ext.SquareDistance(i);
+      if (sDst < Dstmin)
+        Dstmin = sDst;
+    }
+    Dstmin = sqrt(Dstmin);
+    if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
+    {
+      Standard_Real U, V;
+      const Standard_Real tol = BRep_Tool::Tolerance(theS2);
 
-        gp_Pnt Pt1,Pt2;
-        const Standard_Real epsP=Precision::PConfusion();
+      gp_Pnt Pt1, Pt2;
+      const Standard_Real epsP = Precision::PConfusion();
 
-        for (i=1;i<=NbExtrema;i++)
+      for (i = 1; i <= NbExtrema; i++)
+      {
+        if (fabs(Dstmin - sqrt(Ext.SquareDistance(i))) < myEps)
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          Pt1 = Ext.PointOnEdge(i);
+          Pt2 = Ext.PointOnFace(i);
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
           {
-            Pt1=Ext.PointOnE1(i);
-            Pt2=Ext.PointOnE2(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+            // Check if the parameter does not correspond to a vertex
+            const Standard_Real t1 = Ext.ParameterOnEdge(i);
+            if (!isOnBoundary (theS1, Pt1, t1, epsP))
             {
-              // Check if the parameters do not correspond to a vertex
-              const Standard_Real t1 = Ext.ParameterOnE1(i);
-              const Standard_Real t2 = Ext.ParameterOnE2(i);
-              if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
+              Ext.ParameterOnFace(i, U, V);
+              const gp_Pnt2d PUV(U, V);
+              classifier.Perform(theS2, PUV, tol);
+              if (classifier.State() == TopAbs_IN)
               {
                 if (myDstRef > Dstmin)
-                  myDstRef=Dstmin;
-                myModif=Standard_True;
-                const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
-                const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
-                SeqSolShape1.Append(Sol1);
-                SeqSolShape2.Append(Sol2);
+                  myDstRef = Dstmin;
+                myModif = Standard_True;
+                const BRepExtrema_SolutionElem Sol1(Dstmin, Pt1, BRepExtrema_IsOnEdge, theS1, t1);
+                const BRepExtrema_SolutionElem Sol2(Dstmin, Pt2, BRepExtrema_IsInFace, theS2, U, V);
+                theSeqSolShape1.Append(Sol1);
+                theSeqSolShape2.Append(Sol2);
               }
             }
           }
         }
       }
     }
+  }
 
+  Standard_Real aFirst, aLast;
+  Handle(Geom_Curve) pCurv = BRep_Tool::Curve(theS1, aFirst, aLast);
+  if (pCurv->Continuity() == GeomAbs_C0)
+  {
     BRepExtrema_SeqOfSolution SeqSolution1;
     BRepExtrema_SeqOfSolution SeqSolution2;
 
-    PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
-     
-    BRepExtrema_SeqOfSolution seqSol1;
-    BRepExtrema_SeqOfSolution seqSol2;
-       
-    if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
-      MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
-     
-    if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
-    {
-      SeqSolShape1.Append(seqSol1);
-      SeqSolShape2.Append(seqSol2);    
-      myModif = Standard_True;
-    }
-  }
-}
+    GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
+    const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
 
-/*********************************************************************************/
+    TColStd_Array1OfReal arrInter(1, 1 + nbIntervals);
+    aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
-{
-  if (BRep_Tool::Degenerated(S1))
-    return;
-    
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
-    BRepClass_FaceClassifier classifier;
+    gp_Pnt Pt;
+    Standard_Real U, V;
+    const Standard_Real tol = BRep_Tool::Tolerance(theS2);
 
-    BRepExtrema_ExtCF Ext(S1,S2);
-       const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
-    if ( NbExtrema > 0 )
+    Standard_Integer i;
+    for (i = 1; i <= arrInter.Length(); i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin) 
-          Dstmin=sDst;
-      }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        Standard_Real Udeb,Ufin,U,V;
-        BRep_Tool::Range(S1,Udeb,Ufin);
-        const Standard_Real tol=BRep_Tool::Tolerance(S2);
+      const Standard_Real aParameter = arrInter(i);
+      gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
+      TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
 
-        gp_Pnt Pt1,Pt2;
-        const Standard_Real epsP=Precision::PConfusion();
+      BRepExtrema_ExtPF ExtPF(V1, theS2);
+      const Standard_Integer NbExtremaPF = ExtPF.IsDone() ? ExtPF.NbExt() : 0;
+      if (NbExtremaPF > 0)
+      {
+        // Search minimum distance Dstmin
+        Standard_Integer ii;
+        Standard_Real Dstmin = ExtPF.SquareDistance(1);
+        for (ii = 2; ii <= NbExtremaPF; ii++)
+        {
+          const Standard_Real sDst = ExtPF.SquareDistance(ii);
+          if (sDst < Dstmin)
+            Dstmin = sDst;
+        }
+        Dstmin = sqrt(Dstmin);
 
-        for (i = 1; i <= NbExtrema; i++)
+        if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          for (ii = 1; ii <= NbExtremaPF; ii++)
           {
-            Pt1=Ext.PointOnEdge(i);
-            Pt2=Ext.PointOnFace(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+            if (fabs(Dstmin - sqrt(ExtPF.SquareDistance(ii))) < myEps)
             {
               // Check if the parameter does not correspond to a vertex
-              const Standard_Real t1 = Ext.ParameterOnEdge(i);
-              if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
+              ExtPF.Parameter(ii, U, V);
+              const gp_Pnt2d PUV(U, V);
+              classifier.Perform(theS2, PUV, tol);
+              if (classifier.State() == TopAbs_IN)
               {
-                Ext.ParameterOnFace(i,U,V);
-                const gp_Pnt2d PUV(U,V);
-                classifier.Perform(S2,PUV,tol);
-                if (classifier.State()==TopAbs_IN)
-                {
-                  if (myDstRef > Dstmin)
-                    myDstRef=Dstmin;
-                  myModif=Standard_True;
-                  const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
-                  const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);             
-                }
+                if (myDstRef > Dstmin)
+                  myDstRef = Dstmin;
+                myModif = Standard_True;
+                const BRepExtrema_SolutionElem Sol1(Dstmin, aPnt, BRepExtrema_IsOnEdge, theS1, aParameter);
+                const BRepExtrema_SolutionElem Sol2(Dstmin, ExtPF.Point(ii), BRepExtrema_IsInFace, theS2, U, V);
+                SeqSolution1.Append(Sol1);
+                SeqSolution2.Append(Sol2);
               }
             }
           }
@@ -1032,289 +1011,78 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
       }
     }
 
-    Standard_Real aFirst, aLast;
-    Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
-    if (pCurv->Continuity() == GeomAbs_C0)
-    {
-      BRepExtrema_SeqOfSolution SeqSolution1;
-      BRepExtrema_SeqOfSolution SeqSolution2;
-
-      GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
-      const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
-
-      TColStd_Array1OfReal arrInter(1,1+nbIntervals);
-      aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
-
-      gp_Pnt Pt;
-      Standard_Real U,V;
-      const Standard_Real tol = BRep_Tool::Tolerance(S2);
-
-      Standard_Integer i;
-      for (i = 1; i <= arrInter.Length(); i++)
-      {
-        const Standard_Real aParameter = arrInter(i);
-        gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
-        TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
-
-        BRepExtrema_ExtPF ExtPF(V1,S2);
-        const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
-        if (NbExtremaPF > 0 )
-        {
-          // Search minimum distance Dstmin
-          Standard_Integer ii;
-          Standard_Real Dstmin = ExtPF.SquareDistance(1);
-          for (ii = 2; ii <= NbExtremaPF; ii++)
-          {
-            const Standard_Real sDst = ExtPF.SquareDistance(ii);
-            if (sDst<Dstmin)
-              Dstmin=sDst;
-          }
-          Dstmin = sqrt(Dstmin);
-
-          if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-          {
-            for (ii = 1; ii <= NbExtremaPF; ii++)
-            { 
-              if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
-              { 
-                // Check if the parameter does not correspond to a vertex
-                ExtPF.Parameter(ii,U,V);
-                const gp_Pnt2d PUV(U,V);
-                               classifier.Perform(S2,PUV,tol);
-                if (classifier.State()==TopAbs_IN)
-                {
-                  if (myDstRef > Dstmin)
-                    myDstRef=Dstmin;
-                  myModif=Standard_True;
-                  const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
-                  const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
-                  SeqSolution1.Append(Sol1);
-                  SeqSolution2.Append(Sol2);
-                }
-              }
-            }
-          }
-        }
-      }
+    BRepExtrema_SeqOfSolution seqSol1;
+    BRepExtrema_SeqOfSolution seqSol2;
+    if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
+      MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
 
-      BRepExtrema_SeqOfSolution seqSol1;
-      BRepExtrema_SeqOfSolution seqSol2;
-      if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
-        MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
-           
-      if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
-      {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
-      }
+    if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
+    {
+      theSeqSolShape1.Append(seqSol1);
+      theSeqSolShape2.Append(seqSol2);
     }
   }
 }
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
+//=======================================================================
+//function : Perform
+//purpose  : Face-Face
+//=======================================================================
+void BRepExtrema_DistanceSS::Perform (const TopoDS_Face& theS1,
+                                      const TopoDS_Face& theS2,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape1,
+                                      BRepExtrema_SeqOfSolution& theSeqSolShape2)
 {
-  if (BRep_Tool::Degenerated(S2))
-    return;
-    
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
+  BRepExtrema_ExtFF Ext(theS1, theS2);
+  const Standard_Integer NbExtrema = Ext.IsDone() ? (Ext.IsParallel() ? 0 : Ext.NbExt()) : 0;
+  if (NbExtrema > 0)
   {
-    BRepClass_FaceClassifier classifier;
-
-    BRepExtrema_ExtCF Ext(S2,S1);
-       const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
-    if ( NbExtrema > 0 )
+    // Search minimum distance Dstmin
+    Standard_Integer i;
+    Standard_Real Dstmin = Ext.SquareDistance(1);
+    for (i = 2; i <= NbExtrema; i++)
     {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
-      {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin) 
-          Dstmin=sDst;
-      }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        Standard_Real Udeb,Ufin,U,V;
-        BRep_Tool::Range(S2,Udeb,Ufin);
-        const Standard_Real tol=BRep_Tool::Tolerance(S1);
-
-        gp_Pnt Pt1,Pt2;
-        const Standard_Real epsP=Precision::PConfusion();
-
-        for (i = 1; i <= NbExtrema; i++)
-        {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
-          {
-            Pt1=Ext.PointOnEdge(i);
-            Pt2=Ext.PointOnFace(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
-            {
-              // Check if the parameter does not correspond to a vertex
-              const Standard_Real t1 = Ext.ParameterOnEdge(i);
-              if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
-              {
-                Ext.ParameterOnFace(i,U,V);
-                const gp_Pnt2d PUV(U,V);
-                classifier.Perform(S1,PUV,tol);
-                if (classifier.State()==TopAbs_IN)
-                {
-                  if (myDstRef > Dstmin)
-                    myDstRef=Dstmin;
-                  myModif=Standard_True;
-                  const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
-                  const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);             
-                }
-              }
-            }
-          }
-        }
-      }
+      const Standard_Real sDst = Ext.SquareDistance(i);
+      if (sDst < Dstmin)
+        Dstmin = sDst;
     }
-
-    Standard_Real aFirst, aLast;
-    Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
-    if (pCurv->Continuity() == GeomAbs_C0)
+    Dstmin = sqrt(Dstmin);
+    if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin - myDstRef) < myEps))
     {
-      BRepExtrema_SeqOfSolution SeqSolution1;
-      BRepExtrema_SeqOfSolution SeqSolution2;
-
-      GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
-      const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
-
-      TColStd_Array1OfReal arrInter(1,1+nbIntervals);
-      aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
+      const Standard_Real tol1 = BRep_Tool::Tolerance(theS1);
+      const Standard_Real tol2 = BRep_Tool::Tolerance(theS2);
 
-      gp_Pnt Pt;
-      Standard_Real U,V;
-      const Standard_Real tol = BRep_Tool::Tolerance(S1);
-
-      Standard_Integer i;
-      for (i = 1; i <= arrInter.Length(); i++)
-      {
-        const Standard_Real aParameter = arrInter(i);
-        gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
-        TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
-
-        BRepExtrema_ExtPF ExtPF(V1,S1);
-        const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
-        if (NbExtremaPF > 0 )
-        {
-          // Search minimum distance Dstmin
-          Standard_Integer ii;
-          Standard_Real Dstmin = ExtPF.SquareDistance(1);
-          for (ii = 2; ii <= NbExtremaPF; ii++)
-          {
-            const Standard_Real sDst = ExtPF.SquareDistance(ii);
-            if (sDst<Dstmin)
-              Dstmin=sDst;
-          }
-          Dstmin = sqrt(Dstmin);
-
-          if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-          {
-            for (ii = 1; ii <= NbExtremaPF; ii++)
-            { 
-              if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
-              { 
-                // Check if the parameter does not correspond to a vertex
-                ExtPF.Parameter(ii,U,V);
-                const gp_Pnt2d PUV(U,V);
-                               classifier.Perform(S1,PUV,tol);
-                if (classifier.State()==TopAbs_IN)
-                {
-                  if (myDstRef > Dstmin)
-                    myDstRef=Dstmin;
-                  myModif=Standard_True;
-                  const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
-                  const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
-                  SeqSolution1.Append(Sol1);
-                  SeqSolution2.Append(Sol2);
-                }
-              }
-            }
-          }
-        }
-      }
-
-      BRepExtrema_SeqOfSolution seqSol1;
-      BRepExtrema_SeqOfSolution seqSol2;
-      if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
-        MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
-           
-      if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
-      {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
-      }
-    }
-  }
-}
-
-/*********************************************************************************/
+      gp_Pnt Pt1, Pt2;
+      gp_Pnt2d PUV;
+      Standard_Real U1, V1, U2, V2;
+      BRepClass_FaceClassifier classifier;
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
-{
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  { 
-    BRepExtrema_ExtFF Ext(S1,S2);
-       const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
-    if ( NbExtrema > 0 )
-    {
-      // Search minimum distance Dstmin
-      Standard_Integer i;
-      Standard_Real Dstmin = Ext.SquareDistance(1);
-      for (i = 2; i <= NbExtrema; i++)
+      for (i = 1; i <= NbExtrema; i++)
       {
-        const Standard_Real sDst = Ext.SquareDistance(i);
-        if (sDst<Dstmin)
-          Dstmin=sDst;
-      }
-      Dstmin = sqrt(Dstmin);
-      if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
-      {
-        const Standard_Real tol1=BRep_Tool::Tolerance(S1);
-        const Standard_Real tol2=BRep_Tool::Tolerance(S2);
-
-        gp_Pnt Pt1,Pt2;
-        gp_Pnt2d PUV;
-        Standard_Real U1,V1,U2,V2;
-        BRepClass_FaceClassifier classifier;
-        for (i = 1; i <= NbExtrema; i++)
+        if (fabs(Dstmin - sqrt(Ext.SquareDistance(i))) < myEps)
         {
-          if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
+          Pt1 = Ext.PointOnFace1(i);
+          Pt2 = Ext.PointOnFace2(i);
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
           {
-            Pt1=Ext.PointOnFace1(i);
-            Pt2=Ext.PointOnFace2(i); 
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+            // Check if the parameter does not correspond to a vertex
+            Ext.ParameterOnFace1(i, U1, V1);
+            PUV.SetCoord(U1, V1);
+            classifier.Perform(theS1, PUV, tol1);
+            if (classifier.State() == TopAbs_IN)
             {
-              // Check if the parameter does not correspond to a vertex
-              Ext.ParameterOnFace1(i,U1,V1);
-              PUV.SetCoord(U1,V1);
-              classifier.Perform(S1,PUV,tol1);
-              if (classifier.State()==TopAbs_IN)
+              Ext.ParameterOnFace2(i, U2, V2);
+              PUV.SetCoord(U2, V2);
+              classifier.Perform(theS2, PUV, tol2);
+              if (classifier.State() == TopAbs_IN)
               {
-                Ext.ParameterOnFace2(i,U2,V2);
-                PUV.SetCoord(U2,V2);
-                classifier.Perform(S2,PUV,tol2);
-                if (classifier.State()==TopAbs_IN)
-                {
-                  if (myDstRef > Dstmin)
-                    myDstRef=Dstmin;
-                  myModif=Standard_True;
-                  const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
-                  const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
-                  SeqSolShape1.Append(Sol1);
-                  SeqSolShape2.Append(Sol2);
-                }
+                if (myDstRef > Dstmin)
+                  myDstRef = Dstmin;
+                myModif = Standard_True;
+                const BRepExtrema_SolutionElem Sol1(Dstmin, Pt1, BRepExtrema_IsInFace, theS1, U1, V1);
+                const BRepExtrema_SolutionElem Sol2(Dstmin, Pt2, BRepExtrema_IsInFace, theS2, U2, V2);
+                theSeqSolShape1.Append(Sol1);
+                theSeqSolShape2.Append(Sol2);
               }
             }
           }
@@ -1323,5 +1091,3 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
     }
   }
 }
-
-/*********************************************************************************/
index 1f7e6fc9e424ed5b55aadbd18fb056bd57062e5f..638bff0297929b8c031c9702985e3292929c2cde 100644 (file)
@@ -26,111 +26,116 @@ class TopoDS_Vertex;
 class TopoDS_Edge;
 class TopoDS_Face;
 
-
-//!  This class allows to compute minimum distance between two shapes <br>
-//! (face edge vertex) and is used in DistShapeShape class. <br>
+//! This class allows to compute minimum distance between two brep shapes
+//! (face edge vertex) and is used in DistShapeShape class.
 class BRepExtrema_DistanceSS
 {
- public:
+public:
 
   DEFINE_STANDARD_ALLOC
 
-  //! computes the distance between two Shapes ( face edge vertex). <br>
-  BRepExtrema_DistanceSS(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
-                                         const Bnd_Box& B1, const Bnd_Box& B2,
-                                         const Standard_Real DstRef,
-                                         const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
-                                         const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad)
-  : myDstRef(DstRef), myModif(Standard_False), myEps(Precision::Confusion()), myFlag(F), myAlgo(A)
-  {
-    Perform(S1, S2, B1, B2);
-  }
-  //! computes the distance between two Shapes ( face edge vertex). <br>
-  //! Parameter theDeflection is used to specify a maximum deviation <br>
-  //! of extreme distances from the minimum one. <br>
-  //! Default value is Precision::Confusion(). <br>
-  BRepExtrema_DistanceSS(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
-                                         const Bnd_Box& B1, const Bnd_Box& B2,
-                                         const Standard_Real DstRef, const Standard_Real aDeflection,
-                                         const Extrema_ExtFlag F = Extrema_ExtFlag_MINMAX,
-                                         const Extrema_ExtAlgo A = Extrema_ExtAlgo_Grad)
-  : myDstRef(DstRef), myModif(Standard_False), myEps(aDeflection), myFlag(F), myAlgo(A)
+public: //! @name Constructor from two shapes
+
+  //! Computes the distance between two Shapes (face edge vertex).
+  //! @param theS1 - First shape
+  //! @param theS2 - Second shape
+  //! @param theBox1 - Bounding box of first shape
+  //! @param theBox2 - Bounding box of second shape
+  //! @param theDstRef - Initial distance between the shapes to start with
+  //! @param theDeflection - Maximum deviation of extreme distances from the minimum
+  //!                        one (default is Precision::Confusion()).
+  //! @param theExtFlag - Specifies which extrema solutions to look for
+  //!                     (default is MINMAX, applied only to point-face extrema)
+  //! @param theExtAlgo - Specifies which extrema algorithm is to be used
+  //!                     (default is Grad algo, applied only to point-face extrema)
+  BRepExtrema_DistanceSS(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2,
+                         const Bnd_Box& theBox1, const Bnd_Box& theBox2,
+                         const Standard_Real theDstRef,
+                         const Standard_Real theDeflection = Precision::Confusion(),
+                         const Extrema_ExtFlag theExtFlag = Extrema_ExtFlag_MINMAX,
+                         const Extrema_ExtAlgo theExtAlgo = Extrema_ExtAlgo_Grad)
+  :
+    myDstRef(theDstRef),
+    myModif(Standard_False),
+    myEps(theDeflection),
+    myFlag(theExtFlag),
+    myAlgo(theExtAlgo)
   {
-    Perform(S1, S2, B1, B2);
+    Perform(theS1, theS2, theBox1, theBox2);
   }
-  //! True if the distance has been computed <br>
+
+public: //! @name Results
+
+  //! Returns true if the distance has been computed, false otherwise.
   Standard_Boolean IsDone() const
   {
     return myModif;
   }
-  //! returns the distance value <br>
+
+  //! Returns the distance value.
   Standard_Real DistValue() const
   {
     return myDstRef;
   }
-  //! returns the list of solutions on the first shape <br>
+
+  //! Returns the list of solutions on the first shape.
   const BRepExtrema_SeqOfSolution& Seq1Value() const
   {
-    return SeqSolShape1;
+    return mySeqSolShape1;
   }
-  //! returns the list of solutions on the second shape <br>
+
+  //! Returns the list of solutions on the second shape.
   const BRepExtrema_SeqOfSolution& Seq2Value() const
   {
-    return SeqSolShape2;
-  }
-  //! sets the flag controlling minimum and maximum search
-  void SetFlag(const Extrema_ExtFlag F)
-  {
-    myFlag = F;
-  }
-  //! sets the flag controlling ...
-  void SetAlgo(const Extrema_ExtAlgo A)
-  {
-    myAlgo = A;
+    return mySeqSolShape2;
   }
 
- private:
-
-  //! computes the distance between two Shapes ( face edge vertex) <br>
-  Standard_EXPORT void Perform(const TopoDS_Shape& S1,const TopoDS_Shape& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-
-  //! computes the distance between two vertices <br>
-  void Perform(const TopoDS_Vertex& S1,const TopoDS_Vertex& S2);
-  //! computes the minimum distance between a vertex and an edge <br>
-  void Perform(const TopoDS_Vertex& S1,const TopoDS_Edge& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-  //! computes the minimum distance between a vertex and a face <br>
-  void Perform(const TopoDS_Vertex& S1,const TopoDS_Face& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-
-  //! computes the minimum distance between an edge and a vertex <br>
-  void Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-  /*{
-    Perform(S2, S1, B2, B1);
-  }*/
-  //! computes the minimum distance between two edges <br>
-  void Perform(const TopoDS_Edge& S1,const TopoDS_Edge& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-  //! computes the minimum distance an edge and a face <br>
-  void Perform(const TopoDS_Edge& S1,const TopoDS_Face& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-
-  //! computes the minimum distance betwwen a face and a vertex <br>
-  void Perform(const TopoDS_Face& S1,const TopoDS_Vertex& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-  /*{
-    Perform(S2, S1, B2, B1);
-  }*/
-  //! computes the minimum distance between a face and an edge <br>
-  void Perform(const TopoDS_Face& S1,const TopoDS_Edge& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-  /*{
-    Perform(S2, S1, B2, B1);
-  }*/
-  //! computes the minimum distance between two faces <br>
-  void Perform(const TopoDS_Face& S1,const TopoDS_Face& S2,const Bnd_Box& B1,const Bnd_Box& B2);
-
-  BRepExtrema_SeqOfSolution SeqSolShape1;
-  BRepExtrema_SeqOfSolution SeqSolShape2;
-  Standard_Real myDstRef;
-  Standard_Boolean myModif;
-  Standard_Real myEps;
-  Extrema_ExtFlag myFlag;
-  Extrema_ExtAlgo myAlgo;
+private: //! @name private methods performing the search
+
+  //! Computes the distance between two Shapes (face edge vertex).
+  //! General method to sort out the shape types and call the specific method.
+  Standard_EXPORT void Perform(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2,
+                               const Bnd_Box& theBox1,    const Bnd_Box& theBox2);
+
+  //! Computes the distance between two vertices.
+  void Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+  //! Computes the minimum distance between a vertex and an edge.
+  void Perform(const TopoDS_Vertex& theS1, const TopoDS_Edge& theS2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+  //! Computes the minimum distance between a vertex and a face.
+  void Perform(const TopoDS_Vertex& theS1, const TopoDS_Face& theS2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+  //! Computes the minimum distance between two edges.
+  void Perform(const TopoDS_Edge& theS1, const TopoDS_Edge& theS2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+  //! Computes the minimum distance between an edge and a face.
+  void Perform(const TopoDS_Edge& theS1, const TopoDS_Face& theS2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+  //! Computes the minimum distance between two faces.
+  void Perform(const TopoDS_Face& theS1, const TopoDS_Face& theS2,
+               BRepExtrema_SeqOfSolution& theSeqSolShape1,
+               BRepExtrema_SeqOfSolution& theSeqSolShape2);
+
+private: //! @name Fields
+
+  BRepExtrema_SeqOfSolution mySeqSolShape1; //!< Solutions on the first shape
+  BRepExtrema_SeqOfSolution mySeqSolShape2; //!< Solutions on the second shape
+  Standard_Real myDstRef;   //!< The minimal distance found
+  Standard_Boolean myModif; //!< Flag indicating whether the solution was improved or not
+  Standard_Real myEps;      //!< Deflection
+  Extrema_ExtFlag myFlag;   //!< Extrema flag indicating what solutions to look for
+  Extrema_ExtAlgo myAlgo;   //!< Extrema algo to be used to look for solutions
 };
 
 #endif
diff --git a/tests/bugs/modalg_7/bug32644 b/tests/bugs/modalg_7/bug32644
new file mode 100644 (file)
index 0000000..6a69640
--- /dev/null
@@ -0,0 +1,22 @@
+puts "================================================="
+puts "OCC32644: Modeling Algorithms - Empty result of section operation"
+puts "================================================="
+puts ""
+
+restore [locate_data_file bug32644_face.brep] f
+restore [locate_data_file bug32644_wire.brep] w
+
+bclearobjects
+bcleartools
+baddobjects f
+baddtools w
+bfillds
+
+bbop result 4
+checkprops result -l 2.06
+checksection result -r 2
+checknbshapes result -edge 2
+
+bsplit rsplit
+checkshape rsplit
+checknbshapes rsplit -face 2