0027692: Visualization, AIS_AngleDimension - exterior angle and arrows visibility...
authornds <nds@opencascade.com>
Tue, 11 Oct 2016 05:46:42 +0000 (08:46 +0300)
committerapn <apn@opencascade.com>
Thu, 27 Oct 2016 14:48:30 +0000 (17:48 +0300)
Extension of angle presentation to provide this functionality

dox/user_guides/draw_test_harness/draw_test_harness.md
src/AIS/AIS_AngleDimension.cxx
src/AIS/AIS_AngleDimension.hxx
src/AIS/AIS_TypeOfAngle.hxx [new file with mode: 0644]
src/AIS/AIS_TypeOfAngleArrowVisibility.hxx [new file with mode: 0644]
src/AIS/FILES
src/ViewerTest/ViewerTest_RelationCommands.cxx
tests/bugs/vis/bug27692 [new file with mode: 0644]

index 14800ee..176ea17 100644 (file)
@@ -2483,7 +2483,28 @@ vdimparam dim1 -textvalue "w_1"
 vdimparam dim1 -autovalue
 ~~~~~
 
-@subsubsection occt_draw_4_4_22 vmovedim
+@subsubsection occt_draw_4_4_22 vdimangleparam
+
+Syntax:
+~~~~~
+vangleparam name [-type interior|exterior]
+                 [-showarrow first|second|both|none]
+~~~~~
+
+Sets parameters for angle dimension **name**.
+
+**Example:** 
+~~~~~
+vinit
+vpoint p1 0 0 0
+vpoint p2 10 0 0
+vpoint p3 10 5 0
+vdimension dim1 -angle -plane xoy -shapes p1 p2 p3
+vfit
+vangleparam dim1 -type exterior -showarrow first
+~~~~~
+
+@subsubsection occt_draw_4_4_23 vmovedim
 
 Syntax:
 ~~~~~
index 4bb905d..3d0dd98 100644 (file)
@@ -279,6 +279,8 @@ void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
 //=======================================================================
 void AIS_AngleDimension::Init()
 {
+  SetType (AIS_TOA_Interior);
+  SetArrowsVisibility (AIS_TOAV_Both);
   SetSpecialSymbol (THE_DEGREE_SYMBOL);
   SetDisplaySpecialSymbol (AIS_DSS_After);
   SetFlyout (15.0);
@@ -300,6 +302,14 @@ gp_Pnt AIS_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach,
   }
   
   gp_Pln aPlane = aConstructPlane.Value();
+  // to have an exterior angle presentation, a plane for further constructed circle should be reversed
+  if (myType == AIS_TOA_Exterior)
+  {
+    gp_Ax1 anAxis = aPlane.Axis();
+    gp_Dir aDir = anAxis.Direction();
+    aDir.Reverse();
+    aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
+  }
 
   Standard_Real aRadius = theFirstAttach.Distance (theCenter);
 
@@ -348,6 +358,15 @@ void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentat
 {
   gp_Pln aPlane (myCenterPoint, GetNormalForMinAngle());
 
+  // to have an exterior angle presentation, a plane for further constructed circle should be reversed
+  if (myType == AIS_TOA_Exterior)
+  {
+    gp_Ax1 anAxis = aPlane.Axis();
+    gp_Dir aDir = anAxis.Direction();
+    aDir.Reverse();
+    aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
+  }
+
   // construct circle forming the arc
   gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius);
   if (!aConstructCircle.IsDone())
@@ -372,7 +391,10 @@ void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentat
   // compute number of discretization elements in old-fanshioned way
   gp_Vec aCenterToFirstVec  (theCenter, theFirstAttach);
   gp_Vec aCenterToSecondVec (theCenter, theSecondAttach);
-  const Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec);
+  Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec);
+  if (myType == AIS_TOA_Exterior)
+    anAngle = 2.0 * M_PI - anAngle;
+  // it sets 50 points on PI, and a part of points if angle is less
   const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI));
 
   GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints);
@@ -705,8 +727,8 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
       if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
       {
         DrawArc (thePresentation,
-                 isArrowsExternal ? aFirstAttach : aFirstArrowEnd,
-                 isArrowsExternal ? aSecondAttach : aSecondArrowEnd,
+                 (isArrowsExternal || !isArrowVisible(AIS_TOAV_First)) ? aFirstAttach : aFirstArrowEnd,
+                 (isArrowsExternal || !isArrowVisible(AIS_TOAV_Second)) ? aSecondAttach : aSecondArrowEnd,
                  myCenterPoint,
                  Abs (GetFlyout()),
                  theMode);
@@ -718,7 +740,7 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
     {
       DrawExtension (thePresentation,
                      anExtensionSize,
-                     isArrowsExternal ? aFirstArrowEnd : aFirstAttach,
+                     (isArrowsExternal && isArrowVisible(AIS_TOAV_First)) ? aFirstArrowEnd : aFirstAttach,
                      aFirstExtensionDir,
                      aLabelString,
                      aLabelWidth,
@@ -731,7 +753,7 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
     {
       DrawExtension (thePresentation,
                      anExtensionSize,
-                     isArrowsExternal ? aSecondArrowEnd : aSecondAttach,
+                     (isArrowsExternal && isArrowVisible(AIS_TOAV_Second)) ? aSecondArrowEnd : aSecondAttach,
                      aSecondExtensionDir,
                      aLabelString,
                      aLabelWidth,
@@ -747,8 +769,8 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
     Prs3d_Root::NewGroup (thePresentation);
 
     DrawArc (thePresentation,
-             isArrowsExternal ? aFirstAttach  : aFirstArrowEnd,
-             isArrowsExternal ? aSecondAttach : aSecondArrowEnd,
+             (isArrowsExternal || !isArrowVisible(AIS_TOAV_First)) ? aFirstAttach  : aFirstArrowEnd,
+             (isArrowsExternal || !isArrowVisible(AIS_TOAV_Second)) ? aSecondAttach : aSecondArrowEnd,
              myCenterPoint,
              Abs(GetFlyout ()),
              theMode);
@@ -759,15 +781,17 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
   {
     Prs3d_Root::NewGroup (thePresentation);
 
-    DrawArrow (thePresentation, aFirstArrowBegin,  gp_Dir (aFirstArrowVec));
-    DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
+    if (isArrowVisible(AIS_TOAV_First))
+      DrawArrow (thePresentation, aFirstArrowBegin,  gp_Dir (aFirstArrowVec));
+    if (isArrowVisible(AIS_TOAV_Second))
+      DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
   }
 
   if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal)
   {
     Prs3d_Root::NewGroup (thePresentation);
 
-    if (aHPosition != LabelPosition_Left)
+    if (aHPosition != LabelPosition_Left && isArrowVisible(AIS_TOAV_First))
     {
       DrawExtension (thePresentation,
                      aDimensionAspect->ArrowTailSize(),
@@ -779,7 +803,7 @@ void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*
                      LabelPosition_None);
     }
 
-    if (aHPosition != LabelPosition_Right)
+    if (aHPosition != LabelPosition_Right && isArrowVisible(AIS_TOAV_Second))
     {
       DrawExtension (thePresentation,
                      aDimensionAspect->ArrowTailSize(),
@@ -1158,6 +1182,26 @@ Standard_Boolean AIS_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
            gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
 }
 
+//=======================================================================
+//function : isArrowVisible
+//purpose  : compares given and internal arrows types, returns true if the the type should be shown
+//=======================================================================
+Standard_Boolean AIS_AngleDimension::isArrowVisible(const AIS_TypeOfAngleArrowVisibility& theArrowType) const
+{
+  switch (theArrowType)
+  {
+    case AIS_TOAV_Both:
+      return myArrowsVisibility == AIS_TOAV_Both;
+    case AIS_TOAV_First:
+      return myArrowsVisibility == AIS_TOAV_Both || myArrowsVisibility == AIS_TOAV_First;
+    case AIS_TOAV_Second:
+      return myArrowsVisibility == AIS_TOAV_Both || myArrowsVisibility == AIS_TOAV_Second;
+    case AIS_TOAV_None:
+      return false;
+  }
+  return false;
+}
+
 //=======================================================================
 //function : GetTextPosition
 //purpose  : 
index bc1b7b5..ede9761 100755 (executable)
@@ -16,6 +16,9 @@
 #define _AIS_AngleDimension_HeaderFile
 
 #include <AIS_Dimension.hxx>
+#include <AIS_TypeOfAngle.hxx>
+#include <AIS_TypeOfAngleArrowVisibility.hxx>
+
 #include <Geom_Plane.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Transformation.hxx>
@@ -208,6 +211,32 @@ public:
 
   Standard_EXPORT virtual const gp_Pnt GetTextPosition () const Standard_OVERRIDE;
 
+  //! Sets angle type.
+  //! @param theType [in] the type value.
+  void SetType(const AIS_TypeOfAngle theType)
+  {
+    myType = theType;
+  }
+
+  //! @return the current angle type.
+  AIS_TypeOfAngle GetType() const
+  {
+    return myType;
+  }
+
+  //! Sets visible arrows type
+  //! @param theType [in] the type of visibility of arrows.
+  void SetArrowsVisibility(const AIS_TypeOfAngleArrowVisibility& theType)
+  {
+    myArrowsVisibility = theType;
+  }
+
+  //! @return the type of visibility of arrows.
+  AIS_TypeOfAngleArrowVisibility GetArrowsVisibility() const
+  {
+    return myArrowsVisibility;
+  }
+
 public:
 
   DEFINE_STANDARD_RTTIEXT(AIS_AngleDimension,AIS_Dimension)
@@ -340,7 +369,15 @@ protected:
                                                   const gp_Pnt& theCenterPoint,
                                                   const gp_Pnt& theSecondPoint) const;
 
+
+  //! Returns true if the arrow should be visible
+  //! @param theArrowType an arrow type
+  //! @return TRUE if the arrow should be visible
+  Standard_EXPORT Standard_Boolean isArrowVisible(const AIS_TypeOfAngleArrowVisibility& theArrowType) const;
+
 private:
+  AIS_TypeOfAngle myType; //!< type of angle
+  AIS_TypeOfAngleArrowVisibility myArrowsVisibility; //!< type of arrows visibility
 
   gp_Pnt myFirstPoint;
   gp_Pnt mySecondPoint;
diff --git a/src/AIS/AIS_TypeOfAngle.hxx b/src/AIS/AIS_TypeOfAngle.hxx
new file mode 100644 (file)
index 0000000..2d28c32
--- /dev/null
@@ -0,0 +1,27 @@
+// Created on: 1996-12-11
+// Created by: Robert COUBLANC
+// Copyright (c) 1996-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_TypeOfAngle_HeaderFile
+#define _AIS_TypeOfAngle_HeaderFile
+
+//! Declares the type of angle.
+enum AIS_TypeOfAngle
+{
+AIS_TOA_Interior, //!< the angle between two lines built on geometry parameters
+AIS_TOA_Exterior  //!< the angle equal 2 PI minus the interior angle
+};
+
+#endif // _AIS_TypeOfAngle_HeaderFile
diff --git a/src/AIS/AIS_TypeOfAngleArrowVisibility.hxx b/src/AIS/AIS_TypeOfAngleArrowVisibility.hxx
new file mode 100644 (file)
index 0000000..8915bce
--- /dev/null
@@ -0,0 +1,29 @@
+// Created on: 1996-12-11
+// Created by: Robert COUBLANC
+// Copyright (c) 1996-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_TypeOfAngleArrowVisibility_HeaderFile
+#define _AIS_TypeOfAngleArrowVisibility_HeaderFile
+
+//! Declares what arrows are visible on angle presentation
+enum AIS_TypeOfAngleArrowVisibility
+{
+AIS_TOAV_Both,   //!< both arrows of the first and the second angle tips
+AIS_TOAV_First,  //!< only first point arrow
+AIS_TOAV_Second, //!< only second point arrow
+AIS_TOAV_None    //!< arrows are not visible
+};
+
+#endif // _AIS_TypeOfAngleArrowVisibility_HeaderFile
index aa6d72c..4c878ef 100644 (file)
@@ -181,6 +181,8 @@ AIS_Trihedron.hxx
 AIS_Trihedron.lxx
 AIS_TypeFilter.cxx
 AIS_TypeFilter.hxx
+AIS_TypeOfAngle.hxx
+AIS_TypeOfAngleArrowVisibility.hxx
 AIS_TypeOfAttribute.hxx
 AIS_TypeOfAxis.hxx
 AIS_TypeOfDist.hxx
index 2d62d78..64103dd 100644 (file)
@@ -515,6 +515,122 @@ static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
   }
 }
 
+//=======================================================================
+//function : ParseAngleDimensionParams
+//purpose  : Auxilliary function: sets custom parameters for angle dimension.
+//
+//draw args: -type [interior|exterior]
+//           -showarrow [first|second|both|none]
+//=======================================================================
+static int ParseAngleDimensionParams (Standard_Integer  theArgNum,
+                               const char**      theArgVec,
+                               Standard_Integer  theStartIndex,
+                               NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
+{
+  theStringParams.Clear();
+
+  // Begin from the second parameter: the first one is dimension name
+  for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
+  {
+    TCollection_AsciiString aParam (theArgVec[anIt]);
+    aParam.LowerCase();
+
+    if (aParam.Search ("-") == -1)
+    {
+      std::cerr << "Error: wrong parameter '" << aParam << "'.\n";
+      return 1;
+    }
+
+    // Before all non-boolean flags parsing check if a flag have at least one value.
+    if (anIt + 1 >= theArgNum)
+    {
+      std::cerr << "Error: "<< aParam <<" flag should have value.\n";
+      return 1;
+    }
+
+    if (aParam.IsEqual ("-type"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+
+      theStringParams.Bind ("type", aLocalParam);
+    }
+    else if (aParam.IsEqual ("-showarrow"))
+    {
+      TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
+
+      theStringParams.Bind ("showarrow", aLocalParam);
+    }
+    else
+    {
+      std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+//=======================================================================
+//function : SetAngleDimensionParams
+//purpose  : Sets parameters for angle dimension
+//=======================================================================
+static void SetAngleDimensionParams (const Handle(AIS_Dimension)& theDim,
+                                     const NCollection_DataMap<TCollection_AsciiString,
+                                     TCollection_AsciiString>& theStringParams)
+{
+  Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (theDim);
+  if (anAngleDim.IsNull())
+  {
+    return;
+  }
+
+  if (theStringParams.IsBound ("type"))
+  {
+    AIS_TypeOfAngle anAngleType = AIS_TOA_Interior;
+    TCollection_AsciiString anAngleTypeStr = theStringParams.Find ("type");
+    if (anAngleTypeStr.IsEqual("interior"))
+    {
+      anAngleType = AIS_TOA_Interior;
+    }
+    else if (anAngleTypeStr.IsEqual("exterior"))
+    {
+      anAngleType = AIS_TOA_Exterior;
+    }
+    else
+    {
+      std::cerr << "Error: wrong angle type.\n";
+    }
+    anAngleDim->SetType(anAngleType);
+  }
+
+  if (theStringParams.IsBound ("showarrow"))
+  {
+    AIS_TypeOfAngleArrowVisibility anArrowType = AIS_TOAV_Both;
+    TCollection_AsciiString anArrowTypeStr = theStringParams.Find ("showarrow");
+    if (anArrowTypeStr.IsEqual("both"))
+    {
+      anArrowType = AIS_TOAV_Both;
+    }
+    else if (anArrowTypeStr.IsEqual("first"))
+    {
+      anArrowType = AIS_TOAV_First;
+    }
+    else if (anArrowTypeStr.IsEqual("second"))
+    {
+      anArrowType = AIS_TOAV_Second;
+    }
+    else if (anArrowTypeStr.IsEqual("none"))
+    {
+      anArrowType = AIS_TOAV_None;
+    }
+    else
+    {
+      std::cerr << "Error: wrong showarrow type.\n";
+    }
+    anAngleDim->SetArrowsVisibility(anArrowType);
+  }
+}
+
 //=======================================================================
 //function : VDimBuilder
 //purpose  : Command for building dimension presentations: angle,
@@ -2584,6 +2700,62 @@ static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const
   return 0;
 }
 
+//=======================================================================
+//function : VAngleParam
+//purpose  : Sets aspect parameters to angle dimension.
+//=======================================================================
+static int VAngleParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
+{
+  if (theArgNum < 3)
+  {
+    theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
+    return 1;
+  }
+
+
+  TCollection_AsciiString aName (theArgVec[1]);
+  gp_Pln aWorkingPlane;
+  Standard_Boolean toUpdate = Standard_True;
+
+  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
+
+  if (!GetMapOfAIS().IsBound2 (aName))
+  {
+    theDi << theArgVec[0] << "error: no object with this name.\n";
+    return 1;
+  }
+
+  Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
+  if (anObject->Type() != AIS_KOI_Dimension)
+  {
+    theDi << theArgVec[0] << "error: no dimension with this name.\n";
+    return 1;
+  }
+
+  Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
+  Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
+
+  if (ParseAngleDimensionParams (theArgNum, theArgVec, 2, aStringParams))
+  {
+    return 1;
+  }
+
+  SetAngleDimensionParams (aDim, aStringParams);
+
+  if (!aDim->IsValid())
+  {
+    std::cerr << "Error: Dimension geometry or plane is not valid.\n";
+    return 1;
+  }
+
+  // Redisplay a dimension after parameter changing.
+  if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
+  {
+    ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
+  }
+  return 0;
+}
+
 //=======================================================================
 //function : VMoveDim
 //purpose  : Moves dimension or relation text label to defined or picked
@@ -2800,6 +2972,12 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
   theCommands.Add("vangledim",
                  "vangledim Name:Selection in the viewer only ",
                  __FILE__,VAngleDimBuilder,group);
+
+  theCommands.Add("vangleparam",
+    "vangleparam name"
+    "[-type interior|exterior]\n"
+    "[-showarrow first|second|both|none]\n",
+    __FILE__,VAngleParam,group);
   
   theCommands.Add("vdiameterdim",
                  "vdiameterdim Name : Selection in the viewer only ",
diff --git a/tests/bugs/vis/bug27692 b/tests/bugs/vis/bug27692
new file mode 100644 (file)
index 0000000..baa3e02
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "Visualization, AIS_AngleDimension - exterior angle and arrows visibility improvements"
+puts "========"
+
+# Test case creates three angle dimensions with exterior/interior presentation for the angle
+# and different visual state of presentation arrows
+
+pload MODELING VISUALIZATION
+
+vinit
+vpoint p1 0 0 0
+vpoint p2 10 0 0
+vpoint p3 10 5 0
+vdimension dim1 -angle -plane xoy -shapes p1 p2 p3
+vangleparam dim1 -type exterior -showarrow first
+
+vpoint p4 50 0 0
+vpoint p5 60 0 0
+vpoint p6 60 5 0
+vdimension dim2 -angle -plane xoy -shapes p4 p5 p6
+vangleparam dim2 -type interior -showarrow none
+
+vpoint p7 30 -40 0
+vpoint p8 40 -40 0
+vpoint p9 50 -35 0
+vdimension dim3 -angle -plane xoy -shapes p7 p8 p9
+vangleparam dim3 -type exterior -showarrow second
+
+vfit
+vdump $imagedir/${casename}.png