]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Fix of the bug
authorjgv <jgv@opencascade.com>
Wed, 14 Sep 2022 18:39:42 +0000 (21:39 +0300)
committerjfa <jfa@opencascade.com>
Fri, 4 Nov 2022 10:11:07 +0000 (13:11 +0300)
src/GEOMImpl/GEOMImpl_IProximity.hxx
src/GEOMImpl/GEOMImpl_ShapeProximityDriver.cxx

index 48b0854e8f29df24584c18d1166f9bd456c12fde..c32a5fdb716a68cb766eda45359079b55b68565a 100644 (file)
@@ -26,6 +26,8 @@
 #define PROXIMITY_ARG_POINT1   5
 #define PROXIMITY_ARG_POINT2   6
 #define PROXIMITY_ARG_VALUE    7
+#define PROXIMITY_ARG_STATUS1  8
+#define PROXIMITY_ARG_STATUS2  9
 
 class GEOMImpl_IProximity
 {
@@ -61,12 +63,24 @@ public:
     setPoint(PROXIMITY_ARG_POINT2, thePoint2);
   }
 
+  void SetStatusOfPoints(const Standard_Integer theStatus1, const Standard_Integer theStatus2)
+  {
+    setStatus(PROXIMITY_ARG_STATUS1, theStatus1);
+    setStatus(PROXIMITY_ARG_STATUS2, theStatus2);
+  }
+
   void GetProximityPoints(gp_Pnt& thePoint1, gp_Pnt& thePoint2)
   {
     thePoint1 = getPoint(PROXIMITY_ARG_POINT1);
     thePoint2 = getPoint(PROXIMITY_ARG_POINT2);
   }
 
+  void GetStatusOfPoints(Standard_Integer& theStatus1, Standard_Integer& theStatus2)
+  {
+    theStatus1 = getStatus(PROXIMITY_ARG_STATUS1);
+    theStatus2 = getStatus(PROXIMITY_ARG_STATUS2);
+  }
+
   void SetValue(const Standard_Real theValue)
   {
     _func->SetReal(PROXIMITY_ARG_VALUE, theValue);
@@ -87,12 +101,22 @@ private:
     _func->SetRealArray(thePosition, aCoords);
   }
 
+  void setStatus(const Standard_Integer thePosition, const Standard_Integer theStatus)
+  {
+    _func->SetInteger(thePosition, theStatus);
+  }
+
   gp_Pnt getPoint(const Standard_Integer thePosition)
   {
     Handle(TColStd_HArray1OfReal) aCoords = _func->GetRealArray(thePosition);
     return gp_Pnt(aCoords->Value(1), aCoords->Value(2), aCoords->Value(3));
   }
 
+  Standard_Integer getStatus(const Standard_Integer thePosition)
+  {
+    return _func->GetInteger(thePosition);
+  }
+
 private:
   Handle(GEOM_Function) _func;
 };
index c8cd2e459b256a94d7fba8b082be2ae8e61e963d..99a7431087dee482d5bb421f131feea9555d2327 100644 (file)
@@ -30,7 +30,9 @@
 #include <Extrema_ExtPS.hxx>
 #include <Extrema_GenLocateExtCS.hxx>
 #include <Extrema_GenLocateExtSS.hxx>
+#include <Extrema_GenLocateExtPS.hxx>
 #include <Extrema_LocateExtCC.hxx>
+#include <Extrema_LocateExtPC.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 
@@ -138,6 +140,60 @@ namespace {
     return aValue;
   }
 
+  static Standard_Real extremaPE(const gp_Pnt&      thePoint,
+                                 const TopoDS_Edge& theEdge,
+                                 gp_Pnt&            thePointOnEdge)
+  {
+    BRepAdaptor_Curve aCurve (theEdge);
+    
+    TopLoc_Location aLoc;
+    Standard_Real aTol = BRep_Tool::Tolerance(theEdge);
+    Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D (theEdge, aLoc);
+    if (!aPoly.IsNull())
+      aTol = Max (aTol, aPoly->Deflection());
+    
+    Standard_Real aParam = paramOnCurve (aCurve, thePointOnEdge, 2*aTol);
+    
+    Standard_Real aValue = -1.0;
+    Extrema_LocateExtPC anExtr (thePoint, aCurve, aParam, Precision::PConfusion());
+    if (anExtr.IsDone())
+    {
+      aValue = Sqrt(anExtr.SquareDistance());
+      
+      Extrema_POnCurv aPointOnCurve = anExtr.Point();
+      thePointOnEdge = aPointOnCurve.Value();
+    }
+    return aValue;
+  }
+  
+  static Standard_Real extremaPF(const gp_Pnt&      thePoint,
+                                 const TopoDS_Face& theFace,
+                                 gp_Pnt&            thePointOnFace)
+  {
+    BRepAdaptor_Surface aSurf (theFace);
+    
+    TopLoc_Location aLoc;
+    Standard_Real aTol = BRep_Tool::Tolerance(theFace);
+    Handle(Poly_Triangulation) aTria = BRep_Tool::Triangulation (theFace, aLoc);
+    if (!aTria.IsNull())
+      aTol = Max (aTol, aTria->Deflection());
+    
+    Standard_Real aU, aV;
+    paramsOnSurf(aSurf, thePointOnFace, 2*aTol, aU, aV);
+    
+    Standard_Real aValue = -1.0;
+    Extrema_GenLocateExtPS anExtr (aSurf);
+    anExtr.Perform (thePoint, aU, aV);
+    if (anExtr.IsDone())
+    {
+      aValue = Sqrt(anExtr.SquareDistance());
+      
+      Extrema_POnSurf aPointOnSurf = anExtr.Point();
+      thePointOnFace = aPointOnSurf.Value();
+    }
+    return aValue;
+  }
+
   static Standard_Real extremaEF(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
                                  gp_Pnt& thePonE, gp_Pnt& thePonF)
   {
@@ -253,6 +309,8 @@ Standard_Integer GEOMImpl_ShapeProximityDriver::Execute(Handle(TFunction_Logbook
       aValue = aCalcProx.Proximity();
       aProximity.SetProximityPoints(aCalcProx.ProximityPoint1(),
                                     aCalcProx.ProximityPoint2());
+      aProximity.SetStatusOfPoints((Standard_Integer)aCalcProx.ProxPntStatus1(),
+                                   (Standard_Integer)aCalcProx.ProxPntStatus2());
     }
     else
       Standard_ConstructionError::Raise("Failed to compute coarse proximity");
@@ -262,26 +320,99 @@ Standard_Integer GEOMImpl_ShapeProximityDriver::Execute(Handle(TFunction_Logbook
     TopAbs_ShapeEnum aType1 = aShape1.ShapeType();
     TopAbs_ShapeEnum aType2 = aShape2.ShapeType();
 
-    gp_Pnt aP1, aP2;
-    aProximity.GetProximityPoints(aP1, aP2);
+    gp_Pnt aPnt1, aPnt2;
+    BRepExtrema_ProximityDistTool::ProxPnt_Status aStatus1, aStatus2;
+    Standard_Integer intStatus1, intStatus2;
+    aProximity.GetProximityPoints(aPnt1, aPnt2);
+    aProximity.GetStatusOfPoints(intStatus1, intStatus2);
+    aStatus1 = (BRepExtrema_ProximityDistTool::ProxPnt_Status)intStatus1;
+    aStatus2 = (BRepExtrema_ProximityDistTool::ProxPnt_Status)intStatus2;
 
+    Standard_Real anExactValue = -1;
     if (aType1 == TopAbs_EDGE)
     {
       if (aType2 == TopAbs_EDGE)
-        aValue = extremaEE(TopoDS::Edge(aShape1), TopoDS::Edge(aShape2), aP1, aP2);
+      {
+        if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+            aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaEE(TopoDS::Edge(aShape1), TopoDS::Edge(aShape2), aPnt1, aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaPE(aPnt1, TopoDS::Edge(aShape2), aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER)
+        {
+          anExactValue = extremaPE(aPnt2, TopoDS::Edge(aShape1), aPnt1);
+        }
+      }
       else if (aType2 == TopAbs_FACE)
-        aValue = extremaEF(TopoDS::Edge(aShape1), TopoDS::Face(aShape2), aP1, aP2);
+      {
+        if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+            aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaEF(TopoDS::Edge(aShape1), TopoDS::Face(aShape2), aPnt1, aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaPF(aPnt1, TopoDS::Face(aShape2), aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER)
+        {
+          anExactValue = extremaPE(aPnt2, TopoDS::Edge(aShape1), aPnt1);
+        }
+      }
     }
     else if (aType1 == TopAbs_FACE)
     {
       if (aType2 == TopAbs_EDGE)
-        aValue = extremaEF(TopoDS::Edge(aShape2), TopoDS::Face(aShape1), aP2, aP1);
+      {
+        if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+            aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaEF(TopoDS::Edge(aShape2), TopoDS::Face(aShape1), aPnt2, aPnt1);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaPE(aPnt1, TopoDS::Edge(aShape2), aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER)
+        {
+          anExactValue = extremaPF(aPnt2, TopoDS::Face(aShape1), aPnt1);
+        }
+      }
       else if (aType2 == TopAbs_FACE)
-        aValue = extremaFF(TopoDS::Face(aShape1), TopoDS::Face(aShape2), aP1, aP2);
+      {
+        if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+            aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaFF(TopoDS::Face(aShape1), TopoDS::Face(aShape2), aPnt1, aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE)
+        {
+          anExactValue = extremaPF(aPnt1, TopoDS::Face(aShape2), aPnt2);
+        }
+        else if (aStatus1 == BRepExtrema_ProximityDistTool::ProxPnt_Status_MIDDLE &&
+                 aStatus2 == BRepExtrema_ProximityDistTool::ProxPnt_Status_BORDER)
+        {
+          anExactValue = extremaPF(aPnt2, TopoDS::Face(aShape1), aPnt1);
+        }
+      }
     }
 
+    if (anExactValue != -1)
+      aValue = anExactValue;
+
     if (aValue >= 0)
-      aProximity.SetProximityPoints(aP1, aP2);
+      aProximity.SetProximityPoints(aPnt1, aPnt2);
     else
       Standard_ConstructionError::Raise("Failed to compute precise proximity");
   }