]> OCCT Git - occt.git/commitdiff
0032644: Modeling Algorithms - Empty result of section operation
authoremv <emv@opencascade.com>
Thu, 28 Oct 2021 08:07:05 +0000 (11:07 +0300)
committeremv <emv@opencascade.com>
Fri, 29 Oct 2021 06:46:40 +0000 (09:46 +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.

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

index 61773dd80697ef634429d631194191cc6f58b3c3..c1b96db97a7918a5f0e960691ac96f2be1a5f740 100644 (file)
@@ -88,10 +88,10 @@ static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
   {
     const Standard_Real dst1 = SeqSol1.Value(i).Dist();
     if (fabs(dst1 - DstRef) < Eps)
-       {         
+    {
       seqSol1.Append(SeqSol1.Value(i));
       seqSol2.Append(SeqSol2.Value(i));
-       }
+    }
   }
 }
 
@@ -506,38 +506,70 @@ static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
   }
 }
 
-/*********************************************************************************/
+//=======================================================================
+//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 = Precision::PConfusion())
+{
+  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();
+  mySeqSolShape1.Clear();
+  mySeqSolShape2.Clear();
   myModif=Standard_False;
 
-  switch (S1.ShapeType())
+  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 (theS1.ShapeType())
   {
     case TopAbs_VERTEX :
     {
-      TopoDS_Vertex V1 = TopoDS::Vertex(S1);
-      switch (S2.ShapeType())
+      TopoDS_Vertex aV1 = TopoDS::Vertex (theS1);
+      switch (theS2.ShapeType())
       {
         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 :
         {
-          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 :
         {
-          TopoDS_Face F2 = TopoDS::Face(S2);
-          Perform( V1, F2, B1, B2 );
+          TopoDS_Face aF2 = TopoDS::Face (theS2);
+          Perform (aV1, aF2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
         default:
@@ -545,41 +577,40 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
       }
       break;
     }
-
     case TopAbs_EDGE :
     {
-      TopoDS_Edge E1 = TopoDS::Edge(S1);
-      switch (S2.ShapeType())
+      TopoDS_Edge aE1 = TopoDS::Edge (theS1);
+      switch (theS2.ShapeType())
       {
         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 :
         {
-          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 :
         {
-          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:
@@ -587,33 +618,32 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
       }
       break;
     }
-
     case TopAbs_FACE :
     {
-      TopoDS_Face F1 = TopoDS::Face(S1);
-      switch (S2.ShapeType())
+      TopoDS_Face aF1 = TopoDS::Face (theS1);
+      switch (theS2.ShapeType())
       {
         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 :
         {
-          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 :
         {
-          TopoDS_Face F2 = TopoDS::Face(S2);
-          Perform( F1, F2, B1, B2 );
+          TopoDS_Face aF2 = TopoDS::Face (theS2);
+          Perform (aF1, aF2, mySeqSolShape1, mySeqSolShape2);
           break;
         }
         default:
@@ -626,38 +656,44 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape&
   }
 }
 
-/*********************************************************************************/
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& 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 P1 = BRep_Tool::Pnt(S1);
-  const gp_Pnt P2 = BRep_Tool::Pnt(S2);
+  const gp_Pnt aP1 = BRep_Tool::Pnt (theS1);
+  const gp_Pnt aP2 = BRep_Tool::Pnt (theS2);
 
-  const Standard_Real Dst = P1.Distance(P2);
+  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);
+    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)
+//=======================================================================
+//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(S2))
+  if (BRep_Tool::Degenerated(theS2))
     return;
 
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
-    BRepExtrema_ExtPC Ext(S1,S2);
+  BRepExtrema_ExtPC Ext(theS1, theS2);
     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
     if ( NbExtrema > 0 )
     {
@@ -673,10 +709,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge&
       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);
+      gp_Pnt Pt, P1 = BRep_Tool::Pnt(theS1);
         const Standard_Real epsP=Precision::PConfusion();
 
         for (i = 1; i <= NbExtrema; i++)
@@ -684,19 +717,19 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge&
           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
           {
             Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape2,Pt))
+          if (TRI_SOLUTION(theSeqSolShape2, 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 (!isOnBoundary(theS2, Pt, t, 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);
+              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);
               }
             }
           }
@@ -704,18 +737,17 @@ 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_ExtPC Ext(S2,S1);
+  BRepExtrema_ExtPF Ext (theS1, theS2, myFlag, myAlgo);
     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
     if ( NbExtrema > 0 )
     {
@@ -730,145 +762,32 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex&
          }
       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);
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-/*********************************************************************************/
-
-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 )
-    {
-      // 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(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)
-          {
-            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(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);               
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& 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(S2,S1,myFlag,myAlgo);
-    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++)
-      {
-        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,P2=BRep_Tool::Pnt(S2);
+      gp_Pnt Pt, P1 = BRep_Tool::Pnt(theS1);
         BRepClass_FaceClassifier classifier;
-        const Standard_Real tol = BRep_Tool::Tolerance(S1);
+      const Standard_Real tol = BRep_Tool::Tolerance(theS2);
  
         for (i = 1; i <= NbExtrema; i++)
         {
           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
           {
             Pt=Ext.Point(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt))
+          if (TRI_SOLUTION(theSeqSolShape2, Pt))
             {
               // 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);
+            classifier.Perform(theS2, 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);               
+              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);
               }
             }
           }
@@ -876,22 +795,22 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex&
       }
     }
   }
-}
 
-/*********************************************************************************/
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& 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)
 {
-  if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
+  if (BRep_Tool::Degenerated(theS1) || BRep_Tool::Degenerated(theS2))
     return;
 
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
     const Standard_Real DstRef = myDstRef;
 
-    BRepExtrema_ExtCC Ext(S1,S2);
+  BRepExtrema_ExtCC Ext(theS1, theS2);
        const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
     if ( NbExtrema > 0 )
     {
@@ -907,10 +826,6 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
       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);
-
         gp_Pnt Pt1,Pt2;
         const Standard_Real epsP=Precision::PConfusion();
 
@@ -920,20 +835,21 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
           {
             Pt1=Ext.PointOnE1(i);
             Pt2=Ext.PointOnE2(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
             {
               // 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))
+
+            if (!isOnBoundary (theS1, Pt1, t1, epsP) && !isOnBoundary (theS2, Pt2, t2, epsP))
               {
                 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);
+              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);
               }
             }
           }
@@ -944,7 +860,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
     BRepExtrema_SeqOfSolution SeqSolution1;
     BRepExtrema_SeqOfSolution SeqSolution2;
 
-    PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
+  PERFORM_C0(theS1, theS2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
      
     BRepExtrema_SeqOfSolution seqSol1;
     BRepExtrema_SeqOfSolution seqSol2;
@@ -954,27 +870,26 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S
      
     if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
     {
-      SeqSolShape1.Append(seqSol1);
-      SeqSolShape2.Append(seqSol2);    
+    theSeqSolShape1.Append(seqSol1);
+    theSeqSolShape2.Append(seqSol2);
       myModif = Standard_True;
     }
   }
-}
-
-/*********************************************************************************/
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
+//=======================================================================
+//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))
+  if (BRep_Tool::Degenerated(theS1))
     return;
     
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
     BRepClass_FaceClassifier classifier;
 
-    BRepExtrema_ExtCF Ext(S1,S2);
+  BRepExtrema_ExtCF Ext(theS1, theS2);
        const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
     if ( NbExtrema > 0 )
     {
@@ -990,154 +905,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S
       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);
-
-        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(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);             
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-    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);
-           
-      if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
-      {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
-      }
-    }
-  }
-}
-
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
-                                     const Bnd_Box& B1, const Bnd_Box& B2)
-{
-  if (BRep_Tool::Degenerated(S2))
-    return;
-    
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  {
-    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++)
-      {
-        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);
+      const Standard_Real tol = BRep_Tool::Tolerance(theS2);
 
         gp_Pnt Pt1,Pt2;
         const Standard_Real epsP=Precision::PConfusion();
@@ -1148,24 +917,24 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
           {
             Pt1=Ext.PointOnEdge(i);
             Pt2=Ext.PointOnFace(i);
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, 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))
+            if (!isOnBoundary (theS1, Pt1, t1, epsP))
               {
                 Ext.ParameterOnFace(i,U,V);
                 const gp_Pnt2d PUV(U,V);
-                classifier.Perform(S1,PUV,tol);
+              classifier.Perform(theS2, 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 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);
                 }
               }
             }
@@ -1175,7 +944,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
     }
 
     Standard_Real aFirst, aLast;
-    Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
+  Handle(Geom_Curve) pCurv = BRep_Tool::Curve(theS1, aFirst, aLast);
     if (pCurv->Continuity() == GeomAbs_C0)
     {
       BRepExtrema_SeqOfSolution SeqSolution1;
@@ -1189,7 +958,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
 
       gp_Pnt Pt;
       Standard_Real U,V;
-      const Standard_Real tol = BRep_Tool::Tolerance(S1);
+    const Standard_Real tol = BRep_Tool::Tolerance(theS2);
 
       Standard_Integer i;
       for (i = 1; i <= arrInter.Length(); i++)
@@ -1198,7 +967,7 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
         gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
         TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
 
-        BRepExtrema_ExtPF ExtPF(V1,S1);
+      BRepExtrema_ExtPF ExtPF(V1, theS2);
         const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
         if (NbExtremaPF > 0 )
         {
@@ -1222,14 +991,14 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
                 // 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);
+              classifier.Perform(theS2, 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);
+                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);
                 }
@@ -1246,22 +1015,22 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S
            
       if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
       {
-        SeqSolShape1.Append(seqSol1);
-        SeqSolShape2.Append(seqSol2);
+      theSeqSolShape1.Append(seqSol1);
+      theSeqSolShape2.Append(seqSol2);
       }
     }
   }
-}
-
-/*********************************************************************************/
 
-void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& 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)
 {
-  const Standard_Real Dst=B1.Distance(B2);
-  if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
-  { 
-    BRepExtrema_ExtFF Ext(S1,S2);
+  BRepExtrema_ExtFF Ext(theS1, theS2);
        const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
     if ( NbExtrema > 0 )
     {
@@ -1277,8 +1046,8 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
       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);
+      const Standard_Real tol1 = BRep_Tool::Tolerance(theS1);
+      const Standard_Real tol2 = BRep_Tool::Tolerance(theS2);
 
         gp_Pnt Pt1,Pt2;
         gp_Pnt2d PUV;
@@ -1291,26 +1060,26 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
           {
             Pt1=Ext.PointOnFace1(i);
             Pt2=Ext.PointOnFace2(i); 
-            if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
+          if (TRI_SOLUTION(theSeqSolShape1, Pt1) || TRI_SOLUTION(theSeqSolShape2, Pt2))
             {
               // Check if the parameter does not correspond to a vertex
               Ext.ParameterOnFace1(i,U1,V1);
               PUV.SetCoord(U1,V1);
-              classifier.Perform(S1,PUV,tol1);
+            classifier.Perform(theS1, PUV, tol1);
               if (classifier.State()==TopAbs_IN)
               {
                 Ext.ParameterOnFace2(i,U2,V2);
                 PUV.SetCoord(U2,V2);
-                classifier.Perform(S2,PUV,tol2);
+              classifier.Perform(theS2, 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);
+                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);
                 }
               }
             }
@@ -1319,6 +1088,3 @@ void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S
       }
     }
   }
-}
-
-/*********************************************************************************/
index 1f7e6fc9e424ed5b55aadbd18fb056bd57062e5f..96667e6e56a25158d58a150195e97968b316fbb0 100644 (file)
@@ -26,111 +26,139 @@ 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)
+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(theS1, theS2, theBox1, theBox2);
+  }
+
+public: //! @name Setting the options for the algorithm
+
+  //! Sets the deflection - maximum deviation of extreme distances from the minimum one.
+  //! Default value is Precision::Confusion().
+  void SetDeflection (const Standard_Real theDeflection)
+  {
+    myEps = theDeflection;
+  }
+
+  //! Sets the flag controlling what type of search to perform.
+  //! Default value is MinMax. This option is applied to only Point-Face extrema search.
+  void SetFlag(const Extrema_ExtFlag theExtFlag)
   {
-    Perform(S1, S2, B1, B2);
+    myFlag = theExtFlag;
   }
-  //! 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)
+
+  //! Sets the algorithm to be used for the extrema search - Grad or Tree.
+  //! Default value is Grad. This option is applied to only Point-Face extrema search.
+  void SetAlgo(const Extrema_ExtAlgo theExtAlgo)
   {
-    Perform(S1, S2, B1, B2);
+    myAlgo = theExtAlgo;
   }
-  //! 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