0027915: Foundation Classes - remove the class NCollection_QuickSort
[occt.git] / src / AIS / AIS_LengthDimension.cxx
index ebbba29..cd35bf3 100755 (executable)
@@ -19,6 +19,7 @@
 #include <AIS.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepLib_MakeVertex.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <BRepTools.hxx>
@@ -26,8 +27,8 @@
 #include <ElSLib.hxx>
 #include <gce_MakeDir.hxx>
 #include <gce_MakePln.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAPI_ExtremaCurveCurve.hxx>
-#include <GeomAPI_ExtremaCurveSurface.hxx>
 #include <GeomAPI_ExtremaSurfaceSurface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Line.hxx>
@@ -35,6 +36,8 @@
 #include <TopExp_Explorer.hxx>
 
 
+IMPLEMENT_STANDARD_RTTIEXT(AIS_LengthDimension,AIS_Dimension)
+
 //=======================================================================
 //function : Constructor
 //purpose  : Dimension between two faces
@@ -269,7 +272,6 @@ void AIS_LengthDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /
                                    const Handle(Prs3d_Presentation)& thePresentation,
                                    const Standard_Integer theMode)
 {
-  thePresentation->Clear();
   mySelectionGeom.Clear (theMode);
 
   if (!IsValid())
@@ -433,28 +435,44 @@ Standard_Boolean AIS_LengthDimension::InitEdgeFaceLength (const TopoDS_Edge& the
                                                           const TopoDS_Face& theFace,
                                                           gp_Dir& theEdgeDir)
 {
-  Handle(Geom_Curve) aCurve;
-  gp_Pnt aFirstPoint, aSecondPoint;
-  Standard_Boolean isInfinite = Standard_False;
+  theEdgeDir = gp::DX();
 
-  if (!AIS::ComputeGeometry (theEdge, aCurve, aFirstPoint, aSecondPoint, isInfinite))
+  // Find attachment points (closest distance between the edge and the face)
+  BRepExtrema_DistShapeShape aDistAdaptor (theEdge, theFace, Extrema_ExtFlag_MIN);
+  if (!aDistAdaptor.IsDone() || aDistAdaptor.NbSolution() <1)
   {
     return Standard_False;
   }
-  theEdgeDir = gce_MakeDir (aFirstPoint, aSecondPoint);
-  gp_Pln aPlane;
-  Handle(Geom_Surface) aSurface;
-  AIS_KindOfSurface aSurfType;
-  Standard_Real anOffset;
+  myFirstPoint = aDistAdaptor.PointOnShape1 (1);
+  mySecondPoint = aDistAdaptor.PointOnShape2 (1);
 
-  if (!AIS::GetPlaneFromFace (theFace, aPlane, aSurface, aSurfType, anOffset))
+  // Take direction for dimension line (will be orthogonalized later) parallel to edge
+  BRepAdaptor_Curve aCurveAdaptor (theEdge);
+  Standard_Real aParam;
+  if (aDistAdaptor.SupportOnShape1 (1).ShapeType() == TopAbs_EDGE)
   {
-    return Standard_False;
+    aDistAdaptor.ParOnEdgeS1 (1, aParam);
+  }
+  else
+  {
+    Standard_Real aD1 = aCurveAdaptor.Value(aCurveAdaptor.FirstParameter()).SquareDistance (myFirstPoint);
+    Standard_Real aD2 = aCurveAdaptor.Value(aCurveAdaptor.LastParameter()).SquareDistance (myFirstPoint);
+    aParam = (aD1 < aD2 ? aCurveAdaptor.FirstParameter() : aCurveAdaptor.LastParameter());
+  }
+  gp_Pnt aP;
+  gp_Vec aV;
+  aCurveAdaptor.D1 (aParam, aP, aV);
+  if (aV.SquareMagnitude() > gp::Resolution())
+  {
+    theEdgeDir = aV;
   }
 
-  GeomAPI_ExtremaCurveSurface aDistAdaptor (aCurve, aSurface);
-
-  aDistAdaptor.NearestPoints (myFirstPoint, mySecondPoint);
+  // reverse direction if parameter is close to the end of the curve,
+  // to reduce chances to have overlapping between dimension line and edge
+  if (Abs (aParam - aCurveAdaptor.FirstParameter()) < Abs (aParam - aCurveAdaptor.LastParameter()))
+  {
+    theEdgeDir.Reverse();
+  }
 
   return IsValidPoints (myFirstPoint, mySecondPoint);
 }
@@ -578,11 +596,11 @@ Standard_Boolean AIS_LengthDimension::InitTwoShapesPoints (const TopoDS_Shape& t
 
         return isSuccess && IsValidPoints (myFirstPoint, mySecondPoint);
       }
-      else if (theFirstShape.ShapeType() == TopAbs_EDGE)
+      else if (theSecondShape.ShapeType() == TopAbs_EDGE)
       {
         myGeometryType = GeometryType_EdgeFace;
-        isSuccess = InitEdgeFaceLength (TopoDS::Edge (theFirstShape),
-                                        TopoDS::Face (theSecondShape),
+        isSuccess = InitEdgeFaceLength (TopoDS::Edge (theSecondShape),
+                                        TopoDS::Face (theFirstShape),
                                         aDirAttach);
 
         if (isSuccess)
@@ -627,6 +645,21 @@ Standard_Boolean AIS_LengthDimension::InitTwoShapesPoints (const TopoDS_Shape& t
           theIsPlaneComputed = Standard_True;
         }
 
+        return isSuccess;
+      }
+      else if (theSecondShape.ShapeType() == TopAbs_FACE)
+      {
+        myGeometryType = GeometryType_EdgeFace;
+        isSuccess = InitEdgeFaceLength (TopoDS::Edge (theFirstShape),
+                                        TopoDS::Face (theSecondShape),
+                                        aDirAttach);
+
+        if (isSuccess)
+        {
+          theComputedPlane = ComputePlane (aDirAttach);
+          theIsPlaneComputed = Standard_True;
+        }
+
         return isSuccess;
       }
     }