From ee905e847d6b78658f6849b680102428cea9b2e1 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 11 Oct 2016 08:46:42 +0300 Subject: [PATCH] 0027692: Visualization, AIS_AngleDimension - exterior angle and arrows visibility improvements Extension of angle presentation to provide this functionality --- .../draw_test_harness/draw_test_harness.md | 23 ++- src/AIS/AIS_AngleDimension.cxx | 66 +++++-- src/AIS/AIS_AngleDimension.hxx | 37 ++++ src/AIS/AIS_TypeOfAngle.hxx | 27 +++ src/AIS/AIS_TypeOfAngleArrowVisibility.hxx | 29 +++ src/AIS/FILES | 2 + .../ViewerTest_RelationCommands.cxx | 178 ++++++++++++++++++ tests/bugs/vis/bug27692 | 30 +++ 8 files changed, 380 insertions(+), 12 deletions(-) create mode 100644 src/AIS/AIS_TypeOfAngle.hxx create mode 100644 src/AIS/AIS_TypeOfAngleArrowVisibility.hxx create mode 100644 tests/bugs/vis/bug27692 diff --git a/dox/user_guides/draw_test_harness/draw_test_harness.md b/dox/user_guides/draw_test_harness/draw_test_harness.md index 14800ee537..176ea176cf 100644 --- a/dox/user_guides/draw_test_harness/draw_test_harness.md +++ b/dox/user_guides/draw_test_harness/draw_test_harness.md @@ -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: ~~~~~ diff --git a/src/AIS/AIS_AngleDimension.cxx b/src/AIS/AIS_AngleDimension.cxx index 4bb905d332..3d0dd98db3 100644 --- a/src/AIS/AIS_AngleDimension.cxx +++ b/src/AIS/AIS_AngleDimension.cxx @@ -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 : diff --git a/src/AIS/AIS_AngleDimension.hxx b/src/AIS/AIS_AngleDimension.hxx index bc1b7b5682..ede97619b1 100755 --- a/src/AIS/AIS_AngleDimension.hxx +++ b/src/AIS/AIS_AngleDimension.hxx @@ -16,6 +16,9 @@ #define _AIS_AngleDimension_HeaderFile #include +#include +#include + #include #include #include @@ -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 index 0000000000..2d28c32578 --- /dev/null +++ b/src/AIS/AIS_TypeOfAngle.hxx @@ -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 index 0000000000..8915bced09 --- /dev/null +++ b/src/AIS/AIS_TypeOfAngleArrowVisibility.hxx @@ -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 diff --git a/src/AIS/FILES b/src/AIS/FILES index aa6d72cfe8..4c878ef9ff 100644 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -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 diff --git a/src/ViewerTest/ViewerTest_RelationCommands.cxx b/src/ViewerTest/ViewerTest_RelationCommands.cxx index 2d62d78217..64103dd67b 100644 --- a/src/ViewerTest/ViewerTest_RelationCommands.cxx +++ b/src/ViewerTest/ViewerTest_RelationCommands.cxx @@ -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& 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& 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 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 index 0000000000..baa3e02f60 --- /dev/null +++ b/tests/bugs/vis/bug27692 @@ -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 -- 2.39.5