]> OCCT Git - occt-copy.git/commitdiff
0028954: Visualization - implement interactive object for camera manipulations
authoraba <aba@opencascade.com>
Fri, 8 Sep 2017 16:03:18 +0000 (19:03 +0300)
committernds <nds@opencascade.com>
Tue, 11 Jun 2019 10:22:00 +0000 (13:22 +0300)
src/AIS/AIS_ViewCube.cxx [new file with mode: 0644]
src/AIS/AIS_ViewCube.hxx [new file with mode: 0644]
src/AIS/FILES
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/viewcube/default [new file with mode: 0644]
tests/v3d/viewcube/move [new file with mode: 0644]
tests/v3d/viewcube/part [new file with mode: 0644]
tests/v3d/viewcube/style [new file with mode: 0644]
tests/v3d/viewcube/view [new file with mode: 0644]
tests/v3d/viewcube/view2 [new file with mode: 0644]

diff --git a/src/AIS/AIS_ViewCube.cxx b/src/AIS/AIS_ViewCube.cxx
new file mode 100644 (file)
index 0000000..6b4923b
--- /dev/null
@@ -0,0 +1,2106 @@
+// Created on: 2017-07-25
+// Created by: Anastasia BOBYLEVA
+// Copyright (c) 2017 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.
+
+#include <AIS_ViewCube.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_ManipulatorOwner.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <BRepPrim_Wedge.hxx>
+#include <BRepTools.hxx>
+#include <ElCLib.hxx>
+#include <gce_MakeDir.hxx>
+#include <GeomAPI_ExtremaCurveCurve.hxx>
+#include <GeomAPI_IntCS.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Transformation.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Prs3d.hxx>
+#include <Prs3d_Arrow.hxx>
+#include <Prs3d_ArrowAspect.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <Prs3d_Text.hxx>
+#include <Prs3d_ToolDisk.hxx>
+#include <Prs3d_ToolSphere.hxx>
+#include <Select3D_SensitiveCircle.hxx>
+#include <Select3D_SensitivePoint.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <Select3D_SensitiveTriangulation.hxx>
+#include <Select3D_SensitivePrimitiveArray.hxx>
+#include <SelectMgr_SequenceOfOwner.hxx>
+#include <StdSelect_BRepOwner.hxx>
+#include <StdSelect_BRepSelectionTool.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <V3d_View.hxx>
+
+#include <BRepPrimAPI_MakeBox.hxx>
+#include <StdPrs_ShadedShape.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCube, AIS_InteractiveObject)
+IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCubeFlat, AIS_ViewCube)
+
+namespace
+{
+  const Standard_Real ROUND_INTERVAL = 0.2;
+
+  const Standard_Integer SIDE_INDEX = 7;
+  const Standard_Integer EDGE_INDEX = 19;
+  const Standard_Integer VERTEX_INDEX = 27;
+  const Standard_Integer ARROW_INDEX = 31;
+  const Standard_Integer ROUND_ARROW_INDEX = 33;
+
+
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_ViewCube::AIS_ViewCube()
+: myPosition (Aspect_TOTP_LEFT_LOWER),
+  myOffset (Graphic3d_Vec2i (150, 150)),
+  mySize (100.0),
+  myBoxPadding (20.0),
+  myAxisPadding (10.0),
+  myCornerRadius (0.1),
+  myArrowPadding (0.0),
+  myToDisplayEdges (Standard_True),
+  myToDisplayVertices (Standard_True),
+  myStartState (new Graphic3d_Camera),
+  myEndState (new Graphic3d_Camera),
+  myDuration (0.5),
+  myIsAutoTransform (Standard_False)
+{
+  SetInfiniteState();
+  SetMutable (Standard_True);
+
+  myDrawer->SetArrowAspect (new Prs3d_ArrowAspect());
+  myDrawer->SetTextAspect (new Prs3d_TextAspect());
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myArrowAspect = new Prs3d_ShadingAspect;
+  myDynHilightDrawer = new Prs3d_Drawer;
+  myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+
+
+  setDefaultAttributes();
+  setDefaultHighlightAttributes();
+
+  // Set default size parameters that are stored in Drawer
+  myDrawer->ArrowAspect()->SetLength (mySize * 0.25);
+  myDrawer->TextAspect()->SetHeight (mySize * 0.2);
+
+
+  // Create parts
+  addPart (new Side (this, BRepPrim_YMin, TCollection_ExtendedString ("FRONT")),  gp::DY(), gp::DZ());
+  addPart (new Side (this, BRepPrim_YMax, TCollection_ExtendedString ("BACK")),  -gp::DY(), gp::DZ());
+  addPart (new Side (this, BRepPrim_XMin, TCollection_ExtendedString ("LEFT")),   gp::DX(), gp::DZ());
+  addPart (new Side (this, BRepPrim_XMax, TCollection_ExtendedString ("RIGHT")), -gp::DX(), gp::DZ());
+  addPart (new Side (this, BRepPrim_ZMin, TCollection_ExtendedString ("BOTTOM")), gp::DZ(), -gp::DY());
+  addPart (new Side (this, BRepPrim_ZMax, TCollection_ExtendedString ("TOP")),   -gp::DZ(), gp::DY());
+
+  for (Standard_Integer anX = 0; anX < 4; anX++)
+    for (Standard_Integer anY = anX < 2 ? 2 : 4 ; anY < 6; anY++)
+    {
+      gp_Dir aDir (direction (anX) + direction (anY));
+      gp_Dir anUp = Abs (aDir.Z()) < Precision::Confusion()
+                    ? gp_Dir (0.0, 0.0, 1.0)
+                    : (Abs (aDir.Y()) < Precision::Confusion()
+                       ? gp_Dir (0.0, -sign (aDir.Z()), 0.0)
+                       : gp_Dir (0.0, -1.0 * sign (aDir.Y() * aDir.Z()), 1.0) );
+      addPart (new Edge (this, (BRepPrim_Direction) anX, (BRepPrim_Direction) anY), aDir, anUp);
+    }
+
+  for (Standard_Integer anX = 0; anX < 2; anX++)
+    for (Standard_Integer anY = 2; anY < 4; anY++)
+      for (Standard_Integer aZ = 4; aZ < 6; aZ++)
+      {
+        gp_Dir aDir (direction (anX) + direction (anY) + direction (aZ));
+        gp_Dir anUp(-sign(aDir.X()) * sign (aDir.Z()), -sign (aDir.Y()) * sign (aDir.Z()), 2.0);
+        addPart (new Vertex (this, (BRepPrim_Direction) anX, (BRepPrim_Direction) anY, (BRepPrim_Direction) aZ), aDir, anUp);
+      }
+
+  addPart (new FlatArrow (this), -M_PI_4, 0.0, 0.0, 9);
+  addPart (new FlatArrow (this), 0.0, M_PI_4, 0.0, 9);
+  addPart (new FlatArrow (this), M_PI_4, 0.0, 0.0, 9);
+  addPart (new FlatArrow (this), 0.0, -M_PI_4, 0.0, 9);
+  addPart (new RoundedArrow (this), 0.0, 0.0, M_PI_4, 9);
+  addPart (new RoundedArrow (this), 0.0, 0.0, -M_PI_4, 9);
+
+  SetZLayer (Graphic3d_ZLayerId_Topmost);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_ViewCube::AIS_ViewCube (const Handle(PrsMgr_PresentableObject)& theParent)
+: myPosition (Aspect_TOTP_LEFT_LOWER),
+  myOffset (Graphic3d_Vec2i (150, 150)),
+  mySize (100.0),
+  myBoxPadding (20.0),
+  myAxisPadding (10.0),
+  myCornerRadius (0.1),
+  myArrowPadding (0.0),
+  myToDisplayEdges (Standard_True),
+  myToDisplayVertices (Standard_True),
+  myDuration (0.5),
+  myIsAutoTransform (Standard_False)
+{
+  // Do not add parts and camera state here
+
+  SetInfiniteState();
+  SetMutable (Standard_True);
+
+  // Inherit aspects
+  myDrawer = new Prs3d_Drawer;
+  myDrawer->SetLink (theParent->Attributes());
+  myDynHilightDrawer = new Prs3d_Drawer;
+  myDynHilightDrawer->SetLink (theParent->DynamicHilightAttributes());
+}
+
+//=======================================================================
+//function : setDefaultAttributes
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::setDefaultAttributes()
+{
+  myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_CENTER);
+  myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_CENTER);
+  myDrawer->TextAspect()->SetColor (Quantity_NOC_BLACK);
+  myDrawer->TextAspect()->SetFont (Font_NOF_GREEK_MONO);
+  myDrawer->TextAspect()->SetHeight (16.0);
+
+  myDrawer->ArrowAspect()->SetAngle (50.0 * M_PI / 180.0);
+  myDrawer->ArrowAspect()->SetLength (10.0);
+
+  Graphic3d_MaterialAspect aShadingMaterial;
+  aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
+  aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+  aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
+  aShadingMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
+  aShadingMaterial.SetTransparency (0.0);
+
+  Graphic3d_MaterialAspect aBackMaterial;
+  aBackMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+  aBackMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
+  aBackMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
+  aBackMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
+  aBackMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
+  aBackMaterial.SetTransparency (1.0);
+
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial, Aspect_TOFM_FRONT_SIDE);
+  myDrawer->ShadingAspect()->SetMaterial (aBackMaterial, Aspect_TOFM_BACK_SIDE);
+  myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE, Aspect_TOFM_FRONT_SIDE);
+  myDrawer->ShadingAspect()->SetColor (Quantity_NOC_GRAY40, Aspect_TOFM_BACK_SIDE);
+  myDrawer->ShadingAspect()->Aspect()->SetPolygonOffsets (Aspect_POM_Fill, 5.0, 10.0);
+  myDrawer->SetFaceBoundaryDraw (Standard_False);
+
+  myArrowAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myArrowAspect->SetMaterial (aShadingMaterial);
+  myArrowAspect->SetColor (Quantity_NOC_WHITE);
+  myArrowAspect->SetTransparency (0.5);
+}
+
+//=======================================================================
+//function : setDefaultHighlightAttributes
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::setDefaultHighlightAttributes()
+{
+  Graphic3d_MaterialAspect aHighlightMaterial;
+  aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
+  aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
+  aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
+  aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
+  aHighlightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
+  myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect);
+  myDynHilightDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDynHilightDrawer->ShadingAspect()->SetMaterial (aHighlightMaterial);
+  myDynHilightDrawer->ShadingAspect()->SetColor (Quantity_NOC_CYAN1);
+  myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
+  myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
+}
+
+//=======================================================================
+//function : UnsetAttributes
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::UnsetAttributes()
+{
+  setDefaultAttributes();
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : UnsetHilightAttributes
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::UnsetHilightAttributes()
+{
+  myHilightDrawer.Nullify();
+  setDefaultHighlightAttributes();
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : Reset
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Reset()
+{
+  UnsetAttributes();
+  UnsetHilightAttributes();
+
+  mySize = 100.0;
+  myBoxPadding = 20.0;
+  myAxisPadding = 10.0;
+  myCornerRadius = 0.1;
+  myArrowPadding = 0.0;
+  myToDisplayEdges = Standard_True;
+  myToDisplayVertices = Standard_True;
+  myDrawer->ArrowAspect()->SetLength (mySize * 0.25);
+  myDrawer->TextAspect()->SetHeight (mySize * 0.16);
+}
+
+//=======================================================================
+//function : SetPosition
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Position (Aspect_TypeOfTriedronPosition& thePosition,
+                             Graphic3d_Vec2i& theOffset)
+{
+  thePosition = myPosition;
+  theOffset = myOffset;
+}
+
+//=======================================================================
+//function : Position
+//purpose  :
+//=======================================================================
+Graphic3d_Vec2i AIS_ViewCube::Position() const
+{
+  if (myView.IsNull())
+  {
+    return Graphic3d_Vec2i();
+  }
+
+  Standard_Integer aWidth = 0;
+  Standard_Integer aHeight = 0;
+  myView->Window()->Size (aWidth, aHeight);
+
+  Graphic3d_Vec2i aPosition (aWidth / 2, aHeight / 2);
+  if (myPosition & Aspect_TOTP_TOP)
+  {
+    aPosition.y() = myOffset.y();
+  }
+  else if (myPosition & Aspect_TOTP_BOTTOM)
+  {
+    aPosition.y() = aHeight - myOffset.y();
+  }
+
+  if (myPosition & Aspect_TOTP_LEFT)
+  {
+    aPosition.x() = myOffset.x();
+  }
+  else if (myPosition & Aspect_TOTP_RIGHT)
+  {
+    aPosition.x() = aWidth - myOffset.x();
+  }
+  return aPosition;
+}
+
+//=======================================================================
+//function : SetPosition
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetPosition (const Aspect_TypeOfTriedronPosition thePosition,
+                                const Standard_Integer theXOffset,
+                                const Standard_Integer theYOffset)
+{
+  myPosition = thePosition;
+  myOffset = Graphic3d_Vec2i (theXOffset, theYOffset);
+}
+
+
+//=======================================================================
+//function : SetPosition
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::SetPosition (const Graphic3d_Vec2i& thePosition,
+                                            const Handle(V3d_View)& theView)
+{
+  if (theView.IsNull() || thePosition.x() < 0 || thePosition.y() < 0)
+  {
+    return Standard_False;
+  }
+
+  Standard_Integer aWidth = 0;
+  Standard_Integer aHeight = 0;
+  theView->Window()->Size (aWidth, aHeight);
+  if (thePosition.x() > aWidth || thePosition.y() > aHeight)
+  {
+    return Standard_False;
+  }
+
+  Standard_Integer aMask = 0;
+  Graphic3d_Vec2i anOffset (0, 0);
+
+  if (thePosition.x() < aWidth / 2)
+  {
+    aMask |= Aspect_TOTP_LEFT;
+    anOffset.x() = thePosition.x();
+  }
+  else if (thePosition.x() > aWidth / 2)
+  {
+    aMask |= Aspect_TOTP_RIGHT;
+    anOffset.x() = aWidth - thePosition.x();
+  }
+
+  if (thePosition.y() > aHeight / 2)
+  {
+    aMask |= Aspect_TOTP_BOTTOM;
+    anOffset.y() = aHeight - thePosition.y();
+  }
+  else if (thePosition.y() < aHeight / 2)
+  {
+    aMask |= Aspect_TOTP_TOP;
+    anOffset.y() = thePosition.y();
+  }
+
+  myPosition = Aspect_TypeOfTriedronPosition (aMask);
+  myOffset = anOffset;
+
+  SetToUpdate();
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : SetPosition
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::SetPosition (const Graphic3d_Vec2i& thePosition)
+{
+  return SetPosition (thePosition, myView);
+}
+
+//=======================================================================
+//function : Size
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::Size() const
+{
+  return mySize;
+}
+
+//=======================================================================
+//function : SetSize
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetSize (const Standard_Real theValue, const Standard_Boolean theToAdaptAnother)
+{
+  if (Abs (mySize - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  mySize = theValue;
+  if (theToAdaptAnother)
+  {
+    myBoxPadding = mySize * 0.2;
+    myAxisPadding = mySize * 0.1;
+    myDrawer->ArrowAspect()->SetLength (mySize * 0.25f);
+    myDrawer->TextAspect()->SetHeight (mySize * 0.16);
+  }
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : SetBoxPadding
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetBoxPadding (const Standard_Real theValue)
+{
+  if (Abs (myBoxPadding - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myBoxPadding = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : BoxPadding
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::BoxPadding() const
+{
+  return myBoxPadding;
+}
+
+//=======================================================================
+//function : SetAxisPadding
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetAxisPadding (const Standard_Real theValue)
+{
+  if (Abs (myAxisPadding - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myAxisPadding = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : AxisPadding
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::AxisPadding() const
+{
+  return myAxisPadding;
+}
+
+//=======================================================================
+//function : SetCornerRadius
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetCornerRadius (const Standard_Real theValue)
+{
+  Standard_OutOfRange_Raise_if (theValue < 0.0 || theValue > 0.5,
+                                "AIS_ViewCube::SetCornerRadius(): theValue should be in [0; 0.5]");
+  if (Abs (myCornerRadius - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myCornerRadius = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : CornerRadius
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::CornerRadius() const
+{
+  return myCornerRadius;
+}
+
+//=======================================================================
+//function : ToDrawVertices
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::ToDrawVertices() const
+{
+  return myToDisplayVertices;
+}
+
+//=======================================================================
+//function : SetDrawVertices
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetDrawVertices (const Standard_Boolean theValue)
+{
+  if (myToDisplayVertices == theValue)
+  {
+    return;
+  }
+  myToDisplayVertices = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : ToDrawEdges
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::ToDrawEdges() const
+{
+  return myToDisplayEdges;
+}
+
+//=======================================================================
+//function : SetDrawEdges
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetDrawEdges (const Standard_Boolean theValue)
+{
+  if (myToDisplayEdges == theValue)
+  {
+    return;
+  }
+  myToDisplayEdges = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : SetArrowAngle
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetArrowAngle (const Standard_Real theValue)
+{
+  if (Abs (myDrawer->ArrowAspect()->Angle() - theValue) < Precision::Angular())
+  {
+    return;
+  }
+  myDrawer->ArrowAspect()->SetAngle (theValue);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : ArrowAngle
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::ArrowAngle() const
+{
+  return myDrawer->ArrowAspect()->Angle();
+}
+
+//=======================================================================
+//function : SetArrowLength
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetArrowLength (const Standard_Real theValue)
+{
+  if (Abs (myDrawer->ArrowAspect()->Length() - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myDrawer->ArrowAspect()->SetLength (theValue);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : ArrowLength
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::ArrowLength() const
+{
+  return myDrawer->ArrowAspect()->Length();
+}
+
+//=======================================================================
+//function : SetArrowPadding
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetArrowPadding (const Standard_Real theValue)
+{
+  if (Abs (myArrowPadding - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myArrowPadding = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : ArrowPadding
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::ArrowPadding() const
+{
+  return myArrowPadding;
+}
+
+//=======================================================================
+//function : SetDuration
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetDuration (const Standard_Real theValue)
+{
+  if (Abs (myDuration - theValue) <Precision::Confusion())
+  {
+    return;
+  }
+
+  myDuration = theValue;
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : Duration
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::Duration() const
+{
+  return myDuration;
+}
+
+//=======================================================================
+//function : SetTextColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetTextColor (const Quantity_Color& theColor)
+{
+  myDrawer->TextAspect()->SetColor (theColor);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : TextColor
+//purpose  :
+//=======================================================================
+const Quantity_Color& AIS_ViewCube::TextColor() const
+{
+  return myDrawer->TextAspect()->Aspect()->Color();
+}
+
+//=======================================================================
+//function : SetFont
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetFont (const TCollection_AsciiString& theFont)
+{
+  myDrawer->TextAspect()->Aspect()->SetFont (theFont);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : Font
+//purpose  :
+//=======================================================================
+const TCollection_AsciiString& AIS_ViewCube::Font() const
+{
+  return myDrawer->TextAspect()->Aspect()->Font();
+}
+
+//=======================================================================
+//function : SetFontHeight
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetFontHeight (const Standard_Real theValue)
+{
+  myDrawer->TextAspect()->SetHeight (theValue);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : FontHeight
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::FontHeight() const
+{
+  return myDrawer->TextAspect()->Height();
+}
+
+//=======================================================================
+//function : SetArrowColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetArrowColor (const Quantity_Color& theColor)
+{
+  if (myArrowAspect->Color().IsEqual (theColor))
+  {
+    return;
+  }
+  myArrowAspect->SetColor (theColor);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : ArrowColor
+//purpose  :
+//=======================================================================
+const Quantity_Color& AIS_ViewCube::ArrowColor() const
+{
+  return myArrowAspect->Color();
+}
+
+//=======================================================================
+//function : SetArrowTransparency
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetArrowTransparency (const Standard_Real theValue)
+{
+  if (Abs (myArrowAspect->Transparency() - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myArrowAspect->SetTransparency (theValue);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : SetArrowTransparency
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::ArrowTransparency() const
+{
+  return myArrowAspect->Transparency();
+}
+
+//=======================================================================
+//function : SetInnerColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetInnerColor (const Quantity_Color& theColor)
+{
+  myDrawer->ShadingAspect()->SetColor (theColor, Aspect_TOFM_BACK_SIDE);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : InsideBoxColor
+//purpose  :
+//=======================================================================
+const Quantity_Color& AIS_ViewCube::InnerColor() const
+{
+  return myDrawer->ShadingAspect()->Color (Aspect_TOFM_BACK_SIDE);
+}
+
+//=======================================================================
+//function : SetBoxColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetBoxColor (const Quantity_Color& theColor)
+{
+  if (myDrawer->ShadingAspect()->Color().IsEqual (theColor))
+  {
+    return;
+  }
+  myDrawer->ShadingAspect()->SetColor (theColor, Aspect_TOFM_FRONT_SIDE);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : BoxColor
+//purpose  :
+//=======================================================================
+const Quantity_Color& AIS_ViewCube::BoxColor() const
+{
+  return myDrawer->ShadingAspect()->Color (Aspect_TOFM_FRONT_SIDE);
+}
+
+//=======================================================================
+//function : SetBoxTransparency
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetBoxTransparency (const Standard_Real theValue)
+{
+  if (Abs (myDrawer->ShadingAspect()->Transparency() - theValue) < Precision::Confusion())
+  {
+    return;
+  }
+  myDrawer->ShadingAspect()->SetTransparency (theValue);
+  SetToUpdate();
+}
+
+//=======================================================================
+//function : BoxTransparency
+//purpose  :
+//=======================================================================
+Standard_Real AIS_ViewCube::BoxTransparency() const
+{
+  return myDrawer->ShadingAspect()->Transparency();
+}
+
+//=======================================================================
+//function : SetColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetColor (const Quantity_Color& theColor)
+{
+  SetArrowColor (theColor);
+  SetBoxColor (theColor);
+}
+
+//=======================================================================
+//function : SetTransparency
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetTransparency (const Standard_Real theValue)
+{
+  SetArrowTransparency (theValue);
+  SetBoxTransparency (theValue);
+}
+
+//=======================================================================
+//function : SetTransformPersistence
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
+{
+  (void) theTrsfPers;
+}
+
+//=======================================================================
+//function : setTransformPersistence
+//purpose  : 
+//=======================================================================
+void AIS_ViewCube::setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
+{
+  AIS_InteractiveObject::SetTransformPersistence (theTrsfPers);
+}
+
+//=======================================================================
+//function : setTransformPersistence
+//purpose  : 
+//=======================================================================
+void AIS_ViewCube::AddChild (const Handle(PrsMgr_PresentableObject)& theObject)
+{
+  (void) theObject;
+}
+
+//=======================================================================
+//function : setTransformPersistence
+//purpose  : 
+//=======================================================================
+void AIS_ViewCube::RemoveChild (const Handle(PrsMgr_PresentableObject)& theObject)
+{
+  (void) theObject;
+}
+
+//=======================================================================
+//function : addChild
+//purpose  : 
+//=======================================================================
+void AIS_ViewCube::addChild (const Handle(PrsMgr_PresentableObject)& theObject)
+{
+  AIS_InteractiveObject::AddChild (theObject);
+}
+
+//=======================================================================
+//function : addChild
+//purpose  : 
+//=======================================================================
+void AIS_ViewCube::removeChild (const Handle(PrsMgr_PresentableObject)& theObject)
+{
+  AIS_InteractiveObject::RemoveChild (theObject);
+}
+
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                            const Handle(Prs3d_Presentation)& thePrs,
+                            const Standard_Integer theMode)
+{
+  if (theMode != 0)
+  {
+    return;
+  }
+
+  // View cube is to be attached to view, otherwise it isn't displayed
+  Standard_ProgramError_Raise_if (myView.IsNull(),
+                                  "AIS_ViewCube::Compute() - view cube isn't attached to any view.");
+
+  if (myFlatPart.IsNull())
+  {
+    myFlatPart = new AIS_ViewCubeFlat (this);
+    addChild (myFlatPart);
+    myFlatPart->SetContext (GetContext());
+  }
+
+  thePrs->SetMutable (Standard_True);
+  thePrs->SetZLayer (ZLayer());
+  Handle(Graphic3d_Group) aGroup;
+  Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
+  anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  gp_Pnt aLocation = (mySize * 0.5 + myBoxPadding + myAxisPadding) * gp_XYZ (-1.0, -1.0, -1.0);
+
+  setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, myPosition, myOffset));
+
+  // Display axes
+  // Create axis in the default coordinate system. The custom position is applied in local transformation.
+  Axis anAxes[3];
+  const Standard_Real aSize = mySize + 2 * myBoxPadding + myAxisPadding;
+  anAxes[0] = Axis (gp_Ax1 (aLocation, gp::DX()), Quantity_NOC_RED, L'X', aSize);
+  anAxes[1] = Axis (gp_Ax1 (aLocation, gp::DY()), Quantity_NOC_GREEN, L'Y', aSize);
+  anAxes[2] = Axis (gp_Ax1 (aLocation, gp::DZ()), Quantity_NOC_BLUE1, L'Z', aSize);
+  for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
+  {
+    aGroup = Prs3d_Root::NewGroup (thePrs);
+    Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d (*anAspect->Aspect()));
+    anAspectAx->SetColor (anAxes[anIt].Color());
+    aGroup->SetGroupPrimitivesAspect (anAspectAx->Aspect());
+    Handle(Prs3d_TextAspect) aTextAspectAx = new Prs3d_TextAspect (new Graphic3d_AspectText3d (*myDrawer->TextAspect()->Aspect()));
+    aTextAspectAx->SetColor (anAxes[anIt].Color());
+    aTextAspectAx->SetHeight (myDrawer->TextAspect()->Height());
+    anAxes[anIt].Compute (aGroup, anAspectAx, aTextAspectAx);
+  }
+
+  // Display center
+  aGroup = Prs3d_Root::NewGroup (thePrs);
+  Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d (*anAspect->Aspect()));
+  anAspectCen->SetColor (Quantity_NOC_WHITE);
+  aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
+  Prs3d_ToolSphere aTool (4.0, 20, 20);
+  gp_Trsf aTrsf;
+  aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
+  Handle(Graphic3d_ArrayOfTriangles) aCenterArray;
+  aTool.FillArray (aCenterArray, aTrsf);
+  aGroup->AddPrimitiveArray (aCenterArray);
+
+  // Display box
+  aGroup = Prs3d_Root::NewGroup (thePrs);
+  aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+  Handle(Graphic3d_Group) aTextGroup = Prs3d_Root::NewGroup (thePrs);
+  Standard_Integer anIt = 1;
+  for (; anIt < SIDE_INDEX; anIt++)
+  {
+    Handle(Side) aPart = Handle(Side)::DownCast (myParts.ChangeFromIndex (anIt));
+    aPart->Display (thePrsMgr, aGroup, aTextGroup, myDrawer->TextAspect());
+    aPart->SetTransformPersistence (TransformPersistence());
+  }
+
+  if (myToDisplayEdges)
+  {
+    const Standard_Real aThickness = myBoxPadding > 0 ? Sqrt (myBoxPadding * myBoxPadding + myBoxPadding * myBoxPadding) - 2.0 : 2.0;
+    for (anIt = SIDE_INDEX; anIt < EDGE_INDEX; anIt++)
+    {
+      Handle(Edge) aPart = Handle(Edge)::DownCast (myParts.ChangeFromIndex (anIt));
+      aPart->Display (thePrsMgr, aGroup, aThickness);
+      aPart->SetTransformPersistence (TransformPersistence());
+    }
+  }
+
+  if (myToDisplayVertices)
+  {
+    Standard_Real aRadius = myBoxPadding > 0 ? myBoxPadding * 0.5f / Cos (M_PI_4) : 2.0f;
+    for (anIt = EDGE_INDEX; anIt < VERTEX_INDEX; anIt++)
+    {
+      Handle(Vertex) aPart = Handle(Vertex)::DownCast (myParts.ChangeFromIndex (anIt));
+      aPart->Display (thePrsMgr, aGroup, aRadius);
+      aPart->SetTransformPersistence (TransformPersistence());
+    }
+  }
+}
+
+//=======================================================================
+//function : HasTransformation
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::HasTransformation() const
+{
+  return !myAnimation->IsStopped();
+}
+
+//=======================================================================
+//function : Add
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::AddTo (const Handle(AIS_InteractiveContext)& theContext,
+                          const Handle(V3d_View)& theView)
+{
+  SetView (theView);
+
+  theContext->Display (this, 0, 0, Standard_False);
+  SetViewAffinity (theView);
+}
+
+//=======================================================================
+//function : SetViewAffinity
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetViewAffinity (const Handle(V3d_View)& theView)
+{
+  const Handle(AIS_InteractiveContext)& aContext = GetContext();
+  if (aContext.IsNull())
+  {
+    return;
+  }
+
+  // Set view affinity for child object
+  myFlatPart->Presentation()->CStructure()->ViewAffinity = new Graphic3d_ViewAffinity;
+  myFlatPart->Presentation()->CStructure()->ViewAffinity->SetVisible (Standard_False);
+
+  Handle(Graphic3d_ViewAffinity) anAffinity = aContext->CurrentViewer()->StructureManager()->ObjectAffinity (this);
+  anAffinity->SetVisible (Standard_False);
+
+  // View Affinity should be applied after Display
+  /*for (V3d_ListOfViewIterator aViewIter (aContext->CurrentViewer()->DefinedViewIterator()); aViewIter.More(); aViewIter.Next())
+  {
+    aContext->SetViewAffinity (this, aViewIter.Value(), Standard_False);
+  }
+  aContext->SetViewAffinity (this, theView, Standard_True);
+  */
+
+  anAffinity->SetVisible (theView->View()->Identification(), Standard_True);
+  myFlatPart->Presentation()->CStructure()->ViewAffinity->SetVisible (theView->View()->Identification(), Standard_True);
+
+}
+
+//=======================================================================
+//function : Hide
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Hide()
+{
+  GetContext()->SetViewAffinity (this, myView, Standard_False);
+  GetContext()->SetViewAffinity (myFlatPart, myView, Standard_False);
+}
+
+//=======================================================================
+//function : Show
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Show()
+{
+  GetContext()->SetViewAffinity (this, myView, Standard_True);
+  GetContext()->SetViewAffinity (myFlatPart, myView, Standard_True);
+}
+
+//=======================================================================
+//function : SetView
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetView (const Handle(V3d_View)& theView)
+{
+  myView = theView;
+  myAnimation = new AIS_AnimationCamera ("ViewCube", theView);
+}
+
+//=======================================================================
+//function : View
+//purpose  :
+//=======================================================================
+const Handle(V3d_View)& AIS_ViewCube::View() const
+{
+  return myView;
+}
+
+//=======================================================================
+//function : Transform
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::StartTransform (const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  // Make camera changings
+  if (theOwner.IsNull())
+  {
+    return;
+  }
+
+  myStartState->Copy (myView->Camera());
+  myEndState->Copy (myView->Camera());
+
+  const Handle(CameraState)& aState = myStates.FindFromKey (theOwner);
+  aState->FillCamera (myView, myEndState);
+
+  myAnimation->SetCameraStart (myStartState);
+  myAnimation->SetCameraEnd (myEndState);
+  myAnimation->SetStartPts (0.0);
+  myAnimation->SetOwnDuration (myDuration);
+  myAnimation->StartTimer (0.0, 1.0, Standard_True, Standard_False);
+}
+
+//=======================================================================
+//function : transform
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::transform()
+{
+  const Standard_Real aPts = myAnimation->UpdateTimer();
+
+  if (aPts >= myDuration)
+  {
+    myAnimation->Stop();
+    onFinishTransformation();
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Transform
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::Transform (const Standard_Boolean theToUpdate)
+{
+  if (!HasTransformation())
+  {
+    return Standard_False;
+  }
+
+  if (!transform())
+  {
+    return Standard_False;
+  }
+
+  if (theToUpdate)
+  {
+    myView->IsInvalidated() ? myView->Redraw() : myView->RedrawImmediate();
+  }
+
+  onAfterTransform();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Transform
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Transform (const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  StartTransform (theOwner);
+  while (HasTransformation())
+  {
+    if (!transform())
+    {
+      return;
+    }
+
+    myView->IsInvalidated() ? myView->Redraw() : myView->RedrawImmediate();
+    onAfterTransform();
+  }
+}
+
+//=======================================================================
+//function : SetAutoTransform
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::SetAutoTransform (const Standard_Boolean theValue)
+{
+  myIsAutoTransform = theValue;
+}
+
+//=======================================================================
+//function : IsAutoTransform
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_ViewCube::IsAutoTransform() const
+{
+  return myIsAutoTransform;
+}
+
+//=======================================================================
+//function : addPart
+//purpose  :
+//=======================================================================
+Standard_Integer AIS_ViewCube::addPart (const Handle(Part)& thePart,
+                                        const gp_Dir& theDir, const gp_Dir& theUp,
+                                        const Standard_Integer thePriority)
+{
+  Handle(SelectMgr_EntityOwner) anOwner = new AIS_ViewCubeOwner (this, thePriority);
+  myStates.Add (anOwner, new CameraStateReplace (theDir, theUp));
+  return myParts.Add (anOwner, thePart);
+}
+
+//=======================================================================
+//function : addPart
+//purpose  :
+//=======================================================================
+Standard_Integer AIS_ViewCube::addPart (const Handle(Part)& thePart,
+                                        const Standard_Real theAngleX, const Standard_Real theAngleY, const Standard_Real theAngleZ,
+                                        const Standard_Integer thePriority)
+{
+  Handle(SelectMgr_EntityOwner) anOwner = new AIS_ViewCubeOwner (this, thePriority);
+  myStates.Add (anOwner, new CameraStateRotate (theAngleX, theAngleY, theAngleZ));
+  return myParts.Add (anOwner, thePart);
+}
+
+// =======================================================================
+// function : direction
+// purpose  :
+// =======================================================================
+gp_XYZ AIS_ViewCube::direction (const Standard_Integer theDir)
+{
+  BRepPrim_Direction aDir = (BRepPrim_Direction)theDir;
+  switch (aDir)
+  {
+    case BRepPrim_XMax:
+    {
+      return gp::DX().XYZ().Reversed();
+    }
+    case BRepPrim_XMin:
+    {
+      return gp::DX().XYZ();
+    }
+    case BRepPrim_YMax:
+    {
+      return gp::DY().XYZ().Reversed();
+    }
+    case BRepPrim_YMin:
+    {
+      return gp::DY().XYZ();
+    }
+    case BRepPrim_ZMax:
+    {
+      return gp::DZ().XYZ().Reversed();
+    }
+    case BRepPrim_ZMin:
+    {
+      return gp::DZ().XYZ();
+    }
+  }
+  return gp_XYZ();
+}
+
+// =======================================================================
+// function : sign
+// purpose  :
+// =======================================================================
+Standard_Real AIS_ViewCube::sign (const Standard_Real theValue)
+{
+  return theValue > 0.0 ? 1.0 : -1.0;
+}
+
+//=======================================================================
+//function : setLocalTransformation
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::setLocalTransformation (const Handle(Geom_Transformation)& /*theTrsf*/)
+{
+  Standard_ASSERT_INVOKE ("AIS_ViewCube::setLocalTransformation: "
+                          "Custom transformation is not supported by this class");
+}
+
+//=======================================================================
+//function : HilightOwnerWithColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                          const Handle(Prs3d_Drawer)& theStyle,
+                                          const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  if (theOwner.IsNull())
+  {
+    return;
+  }
+
+  const Handle(Part)& aPart = myParts.FindFromKey (theOwner);
+  const Handle(Prs3d_Presentation)& aPresentation = aPart->HighlightPresentation();
+  if (aPresentation.IsNull())
+  {
+    return;
+  }
+
+  // Manage view affinity if it is enabled for object
+  Handle(Graphic3d_ViewAffinity) anAffinity = GetContext()->CurrentViewer()->StructureManager()->ObjectAffinity (this);
+  if (anAffinity->IsVisible (View()->View()->Identification()))
+  {
+    if (aPresentation->CStructure()->ViewAffinity.IsNull())
+    {
+      aPresentation->CStructure()->ViewAffinity = new Graphic3d_ViewAffinity;
+    }
+    aPresentation->CStructure()->ViewAffinity->SetVisible (Standard_False);
+    aPresentation->CStructure()->ViewAffinity->SetVisible (View()->View()->Identification(), Standard_True);
+  }
+
+  aPresentation->Highlight (theStyle);
+  for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
+       aGroupIter.More(); aGroupIter.Next())
+  {
+    Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
+    if (!aGrp.IsNull())
+    {
+      aGrp->SetGroupPrimitivesAspect (myDynHilightDrawer->ShadingAspect()->Aspect());
+    }
+  }
+  aPresentation->SetZLayer (theStyle->ZLayer());
+  thePM->AddToImmediateList (aPresentation);
+}
+
+//=======================================================================
+//function : HilightSelected
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                    const SelectMgr_SequenceOfOwner& theSeq)
+{
+  (void) thePM;
+
+  if (!myIsAutoTransform)
+  {
+    return;
+  }
+  Transform (theSeq (1));
+}
+
+//=======================================================================
+//function : HilightOwnerWithColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                      const Standard_Integer theMode)
+{
+  if (theMode != 0)
+  {
+    return;
+  }
+
+  theSelection->Clear();
+  Standard_Integer anIt = 1;
+  for (; anIt < SIDE_INDEX; anIt++)
+  {
+    const Handle(SelectMgr_EntityOwner)& anOwner = myStates.FindKey (anIt);
+    myParts.FindFromKey (anOwner)->ComputeSelection (anOwner, theSelection);
+  }
+
+  if (myToDisplayEdges)
+  {
+    for (anIt = SIDE_INDEX; anIt < EDGE_INDEX; anIt++)
+    {
+      const Handle(SelectMgr_EntityOwner)& anOwner = myStates.FindKey (anIt);
+      myParts.FindFromKey (anOwner)->ComputeSelection (anOwner, theSelection);
+    }
+  }
+
+  if (myToDisplayVertices)
+  {
+    for (anIt = EDGE_INDEX; anIt < VERTEX_INDEX; anIt++)
+    {
+      const Handle(SelectMgr_EntityOwner)& anOwner = myStates.FindKey (anIt);
+      myParts.FindFromKey (anOwner)->ComputeSelection (anOwner, theSelection);
+    }
+  }
+
+  // Compute selection of flat part
+  if (!myFlatPart->HasSelection (theMode))
+  {
+    myFlatPart->RecomputePrimitives (theMode);
+  }
+  Handle(SelectMgr_Selection) aSelection = new SelectMgr_Selection (theMode);
+  myFlatPart->ComputeSelection (aSelection, theMode);
+}
+
+// =======================================================================
+// class    : CameraStateReplace
+// function : FillCamera
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::CameraStateReplace::FillCamera (const Handle(V3d_View)& theView, const Handle(Graphic3d_Camera)& theCamera)
+{
+  Handle(Graphic3d_Camera) aBackupCamera = new Graphic3d_Camera (theView->Camera());
+  theCamera->SetDirection (Direction);
+  theCamera->SetUp (Up);
+
+  theView->SetCamera (theCamera);
+  theView->FitAll (0.01, Standard_False);
+  theView->SetCamera (aBackupCamera);
+}
+
+// =======================================================================
+// class    : CameraStateRotate
+// function : FillCamera
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::CameraStateRotate::FillCamera (const Handle(V3d_View)& theView, const Handle(Graphic3d_Camera)& theCamera)
+{
+  // Do not use View for camera manipulation
+  (void) theView;
+
+  gp_Dir aBackDir (gp_Vec (theCamera->Center(), theCamera->Eye()));
+  gp_Dir aXAxis (theCamera->Up().Crossed (aBackDir));
+  gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
+  gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
+
+  gp_Trsf aRot[3], aTrsf;
+  aRot[0].SetRotation (gp_Ax1 (theCamera->Center(), aYAxis), -AngleX);
+  aRot[1].SetRotation (gp_Ax1 (theCamera->Center(), aXAxis), AngleY);
+  aRot[2].SetRotation (gp_Ax1 (theCamera->Center(), aZAxis), AngleZ);
+  aTrsf.Multiply (aRot[0]);
+  aTrsf.Multiply (aRot[1]);
+  aTrsf.Multiply (aRot[2]);
+
+  theCamera->Transform (aTrsf);
+}
+
+// =======================================================================
+// class    : Part
+// function : Reset
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::Part::Reset()
+{
+  myTriangulations.Clear();
+  if (!myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation->Clear();
+  }
+}
+
+// =======================================================================
+// class    : Part
+// function : ComputeSelection
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::Part::ComputeSelection (const Handle(SelectMgr_EntityOwner)& theOwner,
+                                           const Handle(SelectMgr_Selection)& theSelection)
+{
+  const NCollection_Sequence<Handle(Poly_Triangulation)>& aTris = Triangulations();
+  for (NCollection_Sequence<Handle(Poly_Triangulation)>::Iterator aTriIt (aTris); aTriIt.More(); aTriIt.Next())
+  {
+    Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (theOwner, aTriIt.Value(), TopLoc_Location(), Standard_True);
+    theSelection->Add (aTri);
+  }
+}
+
+// =======================================================================
+// class    : Part
+// function : SetTransformPersistence
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::Part::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
+{
+  if (!myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation->SetTransformPersistence (theTrsfPers);
+  }
+}
+
+// =======================================================================
+// class    : Part
+// function : Direction
+// purpose  :
+// =======================================================================
+gp_XYZ AIS_ViewCube::Part::Direction (const BRepPrim_Direction theDir)
+{
+  switch (theDir)
+  {
+    case BRepPrim_XMax:
+    {
+      return gp::DX().XYZ();
+    }
+    case BRepPrim_XMin:
+    {
+      return gp::DX().XYZ().Reversed();
+    }
+    case BRepPrim_YMax:
+    {
+      return gp::DY().XYZ();
+    }
+    case BRepPrim_YMin:
+    {
+      return gp::DY().XYZ().Reversed();
+    }
+    case BRepPrim_ZMax:
+    {
+      return gp::DZ().XYZ();
+    }
+    case BRepPrim_ZMin:
+    {
+      return gp::DZ().XYZ().Reversed();
+    }
+  }
+  return gp_XYZ();
+}
+
+//=======================================================================
+//function : Location
+//purpose  :
+//=======================================================================
+gp_XYZ AIS_ViewCube::Part::Location()
+{
+  const Standard_Real anOffset = myParent->Size() * 0.5 + myParent->BoxPadding();
+  return gp_XYZ (-anOffset, -anOffset, -anOffset);
+}
+
+// =======================================================================
+// function : NumberOfTriangleVerices
+// purpose  :
+// =======================================================================
+Standard_Integer AIS_ViewCube::ToolRectangle::NumberOfTriangleVerices() const
+{
+   // Compute number of triangles
+   return (myRadius > 0 ? 3 * ((Standard_Integer)(M_PI_2 / ROUND_INTERVAL + 1) * 4 + 6) : 6);
+}
+
+// =======================================================================
+// function : FillCorner
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::ToolRectangle::FillCorner (const gp_Circ& theCircle,
+                                               const Standard_Real theStartParameter,
+                                               const Standard_Real theEndParameter,
+                                               const Handle(Graphic3d_ArrayOfTriangles)& theArray)
+{
+  for (Standard_Real anIt = theStartParameter; anIt < theEndParameter; anIt += ROUND_INTERVAL)
+  {
+      theArray->AddVertex (ElCLib::Value (anIt, theCircle), theCircle.Position().Direction());
+      theArray->AddVertex (ElCLib::Value (anIt + ROUND_INTERVAL, theCircle), theCircle.Position().Direction());
+      theArray->AddVertex (theCircle.Location(), theCircle.Position().Direction());
+  }
+}
+
+//=======================================================================
+//class    : ToolRectangle
+//function : FillArray
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::ToolRectangle::FillArray (Handle(Graphic3d_ArrayOfTriangles)& theArray,
+                                                    Handle(Poly_Triangulation)& theTriangulation)
+{
+    theArray = new Graphic3d_ArrayOfTriangles (NumberOfTriangleVerices(), 0, Standard_True);
+    const Standard_Real aCornerRadius = myRadius;
+    gp_Ax2 aPosition = myPosition;
+    if (aCornerRadius > 0.0f)
+    {
+        // Corners
+        aPosition.SetLocation (gp_Pnt (myTopLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius - aPosition.YDirection().XYZ() * aCornerRadius));
+        FillCorner (gp_Circ (aPosition, aCornerRadius), M_PI_2, M_PI, theArray);
+        aPosition.SetLocation (gp_Pnt (myBottomLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius));
+        FillCorner (gp_Circ (aPosition, aCornerRadius), M_PI, M_PI * 1.5, theArray);
+        aPosition.SetLocation (gp_Pnt (myBottomRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius));
+        FillCorner (gp_Circ (aPosition, aCornerRadius), M_PI * 1.5, M_PI * 2, theArray);
+        aPosition.SetLocation (gp_Pnt (myTopRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius - aPosition.YDirection().XYZ() * aCornerRadius));
+        FillCorner (gp_Circ (aPosition, aCornerRadius), 0, M_PI_2, theArray);
+
+        // Side parts
+        theArray->AddVertex (myTopLeft.XYZ() - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomLeft.XYZ() + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myTopLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myTopLeft.XYZ() - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomRight.XYZ() + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myTopRight.XYZ() - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myTopRight.XYZ() - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myTopRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius - aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+        theArray->AddVertex (myBottomRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius + aPosition.YDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    }
+
+    theArray->AddVertex (myTopLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    theArray->AddVertex (myBottomLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    theArray->AddVertex (myBottomRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    theArray->AddVertex (myTopLeft.XYZ() + aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    theArray->AddVertex (myBottomRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+    theArray->AddVertex (myTopRight.XYZ() - aPosition.XDirection().XYZ() * aCornerRadius, aPosition.Direction());
+
+    theTriangulation = new Poly_Triangulation (4, 2, 0);
+    theTriangulation->ChangeNodes().SetValue (1, myBottomLeft);
+    theTriangulation->ChangeNodes().SetValue (2, myTopLeft);
+    theTriangulation->ChangeNodes().SetValue (3, myTopRight);
+    theTriangulation->ChangeNodes().SetValue (4, myBottomRight);
+    theTriangulation->ChangeTriangles().SetValue (1, Poly_Triangle (1, 2, 3));
+    theTriangulation->ChangeTriangles().SetValue (2, Poly_Triangle (1, 3, 4));
+}
+
+//=======================================================================
+//class    : Side
+//function : Init
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Side::Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                  const Handle(Graphic3d_Group)& theGroup,
+                                  const Handle(Graphic3d_Group)& theTextGroup,
+                                  const Handle(Prs3d_TextAspect)& theTextAspect)
+{
+  Reset();
+
+  gp_Pnt aTopLeft, aTopRight, aBottomLeft, aBottomRight;
+  const gp_Ax2& aSystem = gp::XOY();
+
+  const Standard_Real aPadding = myParent->BoxPadding();
+  const Standard_Real aSize = myParent->Size();
+  const Standard_Real aCornerRadius = myParent->CornerRadius() * aSize;
+  const gp_XYZ aLoc = Location();
+  const gp_XYZ& anX = aSystem.XDirection().XYZ();
+  const gp_XYZ& anY = aSystem.YDirection().XYZ();
+  const gp_XYZ& aZ = aSystem.Direction().XYZ();
+  gp_Ax2 aPosition;
+
+  switch (myDirection)
+  {
+    case BRepPrim_XMax:
+    {
+      aPosition = gp_Ax2 (aLoc + anX * (aSize + 2 * aPadding) +  anY * aPadding + aZ * aPadding, anX, anY);
+      break;
+    }
+    case BRepPrim_XMin:
+    {
+      aPosition = gp_Ax2 (aLoc + anY * (aSize + aPadding) + aZ * aPadding, anX * (-1), anY * (-1));
+      break;
+    }
+    case BRepPrim_YMax:
+    {
+      aPosition = gp_Ax2 (aLoc + anX * (aSize + aPadding) + anY * (aSize + 2 * aPadding) + aZ * aPadding, anY, anX * (-1));
+      break;
+    }
+    case BRepPrim_YMin:
+    {
+      aPosition = gp_Ax2 (aLoc + anX * aPadding + aZ * aPadding, anY * (-1), anX);
+      break;
+    }
+    case BRepPrim_ZMax:
+    {
+      aPosition = gp_Ax2 (aLoc + anX * aPadding + anY * aPadding + aZ * (aSize + 2 * aPadding), aZ, anX);
+      break;
+    }
+    case BRepPrim_ZMin:
+    {
+      aPosition = gp_Ax2 (aLoc + anX * aPadding + anY * (aSize + aPadding), aZ * (-1), anX);
+      break;
+    }
+  }
+  aBottomLeft = aPosition.Location();
+  aTopLeft = aBottomLeft.XYZ() + aPosition.YDirection().XYZ() * aSize;
+  aTopRight = aTopLeft.XYZ() + aPosition.XDirection().XYZ() * aSize;
+  aBottomRight = aBottomLeft.XYZ() + aPosition.XDirection().XYZ() * aSize;
+  const Standard_Real aCoef = aSize * 0.5;
+  gp_Ax2 aTextPosition (aPosition.Translated (gp_Vec (aPosition.XDirection().XYZ() * aCoef + aPosition.YDirection().XYZ() * aCoef + aPosition.Direction().XYZ() * aSize * 0.02)));
+
+  Handle(Graphic3d_ArrayOfTriangles) anArray;
+  Handle(Poly_Triangulation) aTri;
+  ToolRectangle aTool (aPosition, aBottomLeft, aTopLeft, aBottomRight, aTopRight, aCornerRadius);
+  aTool.FillArray (anArray, aTri);
+  theGroup->AddPrimitiveArray (anArray);
+
+  Prs3d_Text::Draw (theTextGroup, theTextAspect, myText, aTextPosition);
+
+  if (myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation = new Prs3d_Presentation (thePrsMgr->StructureManager());
+  }
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightPresentation);
+  aGroup->AddPrimitiveArray (anArray);
+
+  myTriangulations.Append (aTri);
+}
+
+// =======================================================================
+// class    : Vertex
+// function : Display
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::Vertex::Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                     const Handle(Graphic3d_Group)& theGroup,
+                                     const Standard_Real theRadius,
+                                     const Standard_Integer theSlicesNb)
+{
+  Reset();
+
+  gp_XYZ anX = Direction (myDirection1);
+  gp_XYZ anY = Direction (myDirection2);
+  gp_XYZ aZ = Direction (myDirection3);
+  const gp_Ax2& aParentPosition = gp::XOY();
+  const Standard_Real aPadding = myParent->BoxPadding();
+  gp_Pnt aPos (Location() + (aParentPosition.XDirection().XYZ() * aPadding
+                             + aParentPosition.YDirection().XYZ() * aPadding
+                             + aParentPosition.Direction().XYZ() * aPadding)* 0.75);
+  const Standard_Real aSize = myParent->Size() + aPadding * 0.5;
+  gp_XYZ aT;
+  if (myDirection1 == BRepPrim_XMax)
+  {
+    aT += aParentPosition.XDirection().XYZ() * aSize;
+  }
+  if (myDirection2 == BRepPrim_YMax)
+  {
+    aT += aParentPosition.YDirection().XYZ() * aSize;
+  }
+  if (myDirection3 == BRepPrim_ZMax)
+  {
+    aT += aParentPosition.Direction().XYZ() * aSize;
+  }
+  aPos.Translate (aT);
+
+  gp_Ax2 aPosition (aPos, gp_Dir (anX + anY + aZ).Reversed());
+
+  Prs3d_ToolDisk aTool (0.0, theRadius, theSlicesNb, 1);
+  gp_Ax3 aSystem (aPosition);
+  gp_Trsf aTrsf;
+  aTrsf.SetTransformation (aSystem, gp_Ax3());
+  Handle(Graphic3d_ArrayOfTriangles) anArray;
+  Handle(Poly_Triangulation) aTri;
+  aTool.FillArray (anArray, aTri, aTrsf);
+
+  theGroup->AddPrimitiveArray (anArray);
+
+  if (myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation = new Prs3d_Presentation (thePrsMgr->StructureManager());
+  }
+
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightPresentation);
+  aGroup->AddPrimitiveArray (anArray);
+
+  myTriangulations.Append (aTri);
+}
+
+// =======================================================================
+// class    : Edge
+// function : Display
+// purpose  :
+// =======================================================================
+void AIS_ViewCube::Edge::Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                   const Handle(Graphic3d_Group)& theGroup,
+                                   const Standard_Real theThickness)
+{
+  Reset();
+
+  gp_XYZ aDir1 = Direction (myDirection1);
+  gp_XYZ aDir2 = Direction (myDirection2);
+  const gp_Ax2& aParentPosition = gp::XOY();
+  const Standard_Real aSize = (1 - 2 * myParent->CornerRadius()) * myParent->Size() * 0.5;
+  if (aSize < Precision::Confusion())
+  {
+    return;
+  }
+
+  // Center of edge
+  gp_XYZ aPos (aDir1 * (myParent->Size() + myParent->BoxPadding()) * 0.5 + aDir2 * (myParent->Size() + myParent->BoxPadding()) * 0.5);
+
+  // Prepare vertices for edge rectangle
+  gp_Dir aDir = aDir1 ^ aDir2;
+  gp_Dir anX (aDir.IsParallel (aParentPosition.Direction(), Precision::Angular())
+              ? aParentPosition.Direction()
+              : (aDir.IsParallel(aParentPosition.XDirection(), Precision::Angular())
+                  ? aParentPosition.XDirection()
+                  : aParentPosition.YDirection()));
+  gp_Dir aN (aDir1 + aDir2);
+  gp_Dir anY (aN ^ anX);
+  gp_Pnt aTopLeft, aTopRight, aBottomLeft, aBottomRight;
+  aBottomLeft = aPos - anX.XYZ() * aSize - anY.XYZ() * theThickness * 0.5;
+  aTopLeft = aPos - anX.XYZ() * aSize + anY.XYZ() * theThickness * 0.5;
+  aTopRight = aPos + anX.XYZ() * aSize + anY.XYZ() * theThickness * 0.5;
+  aBottomRight = aPos + anX.XYZ() * aSize - anY.XYZ() * theThickness * 0.5;
+
+  //* Fill graphical structures
+  Handle(Graphic3d_ArrayOfTriangles) anArray;
+  Handle(Poly_Triangulation) aTri;
+  ToolRectangle aTool (gp_Ax2 (gp::Origin(), aN, anX), aBottomLeft, aTopLeft, aBottomRight, aTopRight, theThickness * 0.5f);
+  aTool.FillArray (anArray, aTri);
+
+  theGroup->AddPrimitiveArray (anArray);
+  if (myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation = new Prs3d_Presentation (thePrsMgr->StructureManager());
+  }
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightPresentation);
+  aGroup->AddPrimitiveArray (anArray);
+
+  myTriangulations.Append (aTri);
+}
+
+//=======================================================================
+//class    : Axis
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_ViewCube::Axis::Axis (const gp_Ax1& theAxis,
+                          const Quantity_Color& theColor,
+                          const Standard_ExtCharacter& theSymbol,
+                          const Standard_Real theLength)
+: myPosition (theAxis),
+  myColor (theColor),
+  myLength (theLength),
+  mySymbol (theSymbol)
+{
+  //
+}
+
+//=======================================================================
+//class    : Axis
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::Axis::Compute (const Handle(Graphic3d_Group)& theGroup,
+                                  const Handle(Prs3d_ShadingAspect)& theAspect,
+                                  const Handle(Prs3d_TextAspect)& theTextAspect)
+{
+
+  const Standard_Real anArrowLength   = 0.2 * myLength;
+  Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (myPosition, 1.0, myLength, 3.0, anArrowLength, 20);
+
+  theGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
+  theGroup->AddPrimitiveArray (aTriangleArray);
+
+
+  gp_Pnt aTextOrigin = myPosition.Location().Translated (gp_Vec (myPosition.Direction().X() * (myLength + anArrowLength),
+                                                                 myPosition.Direction().Y() * (myLength + anArrowLength),
+                                                                 myPosition.Direction().Z() * (myLength + anArrowLength)));
+  Prs3d_Text::Draw (theGroup, theTextAspect, TCollection_ExtendedString (mySymbol), aTextOrigin);
+}
+
+//=======================================================================
+//class    : ToolArrow
+//function : FillArray
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::ToolArrow::FillArray (Handle(Graphic3d_ArrayOfTriangles)& theArray,
+                                          Handle(Poly_Triangulation)& theTriangulation)
+{
+  theArray = new Graphic3d_ArrayOfTriangles (4, 0, Standard_True);
+  const gp_Dir aDir = gp::DZ();
+  gp_Pnt aPointer = myAxis.Location().XYZ() + myAxis.Direction().XYZ() * myLength;
+  gp_XYZ aBotDir = myAxis.Direction().Crossed (aDir).XYZ();
+  Standard_Real anEdgeLength = Tan (myAngle * 0.5) * myLength;
+
+  theArray->AddVertex (aPointer, aDir);
+  theArray->AddVertex (gp_Pnt (myAxis.Location().XYZ() - aBotDir * anEdgeLength), aDir);
+  theArray->AddVertex (gp_Pnt (myAxis.Location().XYZ() + aBotDir * anEdgeLength), aDir);
+  theArray->AddVertex (aPointer, aDir);
+
+  theTriangulation = new Poly_Triangulation (3, 1, 0);
+  theTriangulation->ChangeNodes().SetValue (1, aPointer);
+  theTriangulation->ChangeNodes().SetValue (2, myAxis.Location().XYZ() + aBotDir * anEdgeLength);
+  theTriangulation->ChangeNodes().SetValue (3, myAxis.Location().XYZ() - aBotDir * anEdgeLength);
+  theTriangulation->ChangeTriangles().SetValue (1, Poly_Triangle (1, 2, 3));
+}
+
+//=======================================================================
+//class    : FlatArrow
+//function : Init
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::FlatArrow::Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                        const Handle(Graphic3d_Group)& theGroup,
+                                        const gp_Ax1& theAxis,
+                                        const Standard_Real theLength,
+                                        const Standard_Real theAngle)
+{
+  Reset();
+
+  Handle(Poly_Triangulation) aTri;
+  Handle(Graphic3d_ArrayOfTriangles) anArray;
+
+  ToolArrow anArrow (theAxis, theLength, theAngle);
+  anArrow.FillArray (anArray, aTri);
+  theGroup->AddPrimitiveArray (anArray);
+
+  if (myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation = new Prs3d_Presentation (thePrsMgr->StructureManager());
+  }
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightPresentation);
+  aGroup->AddPrimitiveArray (anArray);
+
+  myTriangulations.Append (aTri);
+}
+
+//=======================================================================
+//class    : DiskSegment
+//function : Init
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::RoundedArrow::Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                          const Handle(Graphic3d_Group)& theGroup,
+                                          const gp_Pnt& theCenter,
+                                          const Standard_Real theArrowLength,
+                                          const Standard_Real theArrowAngle,
+                                          const Standard_Real theInnerRadius,
+                                          const Standard_Real theStartAngle,
+                                          const Standard_Real theEndAngle,
+                                          const Standard_Boolean theIsClockwise,
+                                          const Standard_Integer theSlicesNb)
+{
+  Reset();
+
+  // Make thickness of arrow tail depended from arrow length and angle
+  const Standard_Real anInnerRadius = theInnerRadius;
+  const Standard_Real anOuterRadius = theInnerRadius + Tan (theArrowAngle * 0.5) * theArrowLength * 0.6;
+  const Standard_Real aRadius = (anInnerRadius + anOuterRadius) * 0.5;
+  const Standard_Real aStartAngle = theIsClockwise ? theStartAngle + theArrowLength / aRadius : theStartAngle;
+  const Standard_Real anEndAngle = theIsClockwise ? theEndAngle : theEndAngle - theArrowLength / aRadius;
+
+  // Draw tail
+  ToolDiskSegment aTool (anInnerRadius, anOuterRadius, aStartAngle, anEndAngle, theSlicesNb);
+  gp_Ax3 aSystem (theCenter, gp::DZ(), gp::DX());
+  gp_Trsf aTrsf;
+  aTrsf.SetTransformation (aSystem, gp_Ax3());
+  Handle(Poly_Triangulation) aTri1, aTri2;
+  Handle(Graphic3d_ArrayOfTriangles) anArray1, anArray2;
+  aTool.FillArray (anArray1, aTri1, aTrsf);
+  AddTriangulation (aTri1);
+
+  // Draw arrow
+  gp_Pnt anArrowPos = ElCLib::CircleValue (theIsClockwise ? aStartAngle : anEndAngle, aSystem.Ax2(), aRadius);
+  gp_Dir aRadiusDir (theCenter.XYZ() - anArrowPos.XYZ());
+  ToolArrow anArrow (gp_Ax1 (anArrowPos, theIsClockwise ? aSystem.Direction() ^ aRadiusDir : aRadiusDir ^ aSystem.Direction()), theArrowLength, theArrowAngle);
+  anArrow.FillArray (anArray2, aTri2);
+  AddTriangulation (aTri2);
+
+  theGroup->AddPrimitiveArray (anArray1);
+  theGroup->AddPrimitiveArray (anArray2);
+
+  if (myHighlightPresentation.IsNull())
+  {
+    myHighlightPresentation = new Prs3d_Presentation (thePrsMgr->StructureManager());
+  }
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (myHighlightPresentation);
+  aGroup->AddPrimitiveArray (anArray1);
+  aGroup->AddPrimitiveArray (anArray2);
+}
+//=======================================================================
+//class    : ToolDiskSegment
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_ViewCube::ToolDiskSegment::ToolDiskSegment (const Standard_Real    theInnerRadius,
+                                                 const Standard_Real    theOuterRadius,
+                                                 const Standard_Real    theStartAngle,
+                                                 const Standard_Real    theEndAngle,
+                                                 const Standard_Integer theNbFacettes)
+: Prs3d_ToolDisk (theInnerRadius, theOuterRadius, theNbFacettes, 20),
+  myStartAngle (theStartAngle),
+  myEndAngle (theEndAngle)
+{
+}
+
+//=======================================================================
+//class    : ToolDiskSegment
+//function : Vertex
+//purpose  :
+//=======================================================================
+gp_Pnt AIS_ViewCube::ToolDiskSegment::Vertex (const Standard_Real theU, const Standard_Real theV)
+{
+  const Standard_Real aU      = myStartAngle + theU * (myEndAngle - myStartAngle);
+  const Standard_Real aRadius = myInnerRadius + (myOuterRadius - myInnerRadius) * theV;
+  return gp_Pnt (Cos (aU) * aRadius, Sin (aU) * aRadius,  0.0);
+}
+
+//=======================================================================
+//function : ComputeFlat
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::ComputeFlat (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, const Handle(Prs3d_Presentation)& thePrs)
+{
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
+  aGroup->SetGroupPrimitivesAspect (myArrowAspect->Aspect());
+
+  gp_XYZ aCenter (gp::Origin().XYZ());
+  const gp_Ax2& aPosition = gp::XOY();
+
+  // Here minimal radius of arrow circle is computed: (Size + 2*BoxPadding + 2*AxisPadding) * Cos (M_PI_4) / 2
+  //                                                   + AxisPadding + AxisDiameter + ArrowPadding
+  // Additionally arrow padding is apply for customization
+  Standard_Real aRadius = (mySize + 2 * myBoxPadding + 2 * myAxisPadding) * Sqrt(2.0) / 2.0 + 2.0 + myArrowPadding;
+  gp_Ax1 aPositions[4] = {
+    gp_Ax1 (aCenter - aPosition.XDirection().XYZ() * (aRadius), aPosition.XDirection().Reversed()),
+    gp_Ax1 (aCenter + aPosition.YDirection().XYZ() * (aRadius), aPosition.YDirection()),
+    gp_Ax1 (aCenter + aPosition.XDirection().XYZ() * (aRadius), aPosition.XDirection()),
+    gp_Ax1 (aCenter - aPosition.YDirection().XYZ() * (aRadius), aPosition.YDirection().Reversed())
+  };
+
+  Standard_Integer aPosIndex = 0;
+  for (Standard_Integer anIt = VERTEX_INDEX; anIt < ARROW_INDEX; anIt++)
+  {
+    Handle(FlatArrow) aPart = Handle(FlatArrow)::DownCast (myParts.ChangeFromIndex (anIt));
+    aPart->Display (thePrsMgr, aGroup, aPositions[aPosIndex++], myDrawer->ArrowAspect()->Length(), myDrawer->ArrowAspect()->Angle());
+    aPart->SetTransformPersistence (myFlatPart->TransformPersistence());
+  }
+
+  aRadius += myDrawer->ArrowAspect()->Length() * 0.3;
+  Handle(RoundedArrow) anArrow = Handle(RoundedArrow)::DownCast (myParts.ChangeFromIndex (ARROW_INDEX));
+  anArrow->Display (thePrsMgr, aGroup, gp_Pnt (aCenter), myDrawer->ArrowAspect()->Length(), myDrawer->ArrowAspect()->Angle(), aRadius, M_PI_4, M_PI_2 - 0.3, Standard_True);
+  anArrow = Handle(RoundedArrow)::DownCast (myParts.ChangeFromIndex (ARROW_INDEX + 1));
+  anArrow->Display (thePrsMgr, aGroup, gp_Pnt (aCenter), myDrawer->ArrowAspect()->Length(), myDrawer->ArrowAspect()->Angle(), aRadius, M_PI_2 + 0.3, M_PI - M_PI_4);
+  for (Standard_Integer anIt = ARROW_INDEX; anIt < ROUND_ARROW_INDEX; anIt++)
+  {
+    myParts.ChangeFromIndex (anIt)->SetTransformPersistence (myFlatPart->TransformPersistence());
+  }
+}
+
+//=======================================================================
+//function : ComputeFlat
+//purpose  :
+//=======================================================================
+void AIS_ViewCube::ComputeSelectionFlat (const Handle(SelectMgr_Selection)& theSelection)
+{
+  for (Standard_Integer anIt = VERTEX_INDEX; anIt < ROUND_ARROW_INDEX; anIt++)
+  {
+    const Handle(SelectMgr_EntityOwner)& anOwner = myStates.FindKey (anIt);
+    anOwner->SetSelectable (myFlatPart);
+    const Handle(Part)& aPart = myParts.FindFromKey (anOwner);
+    const NCollection_Sequence<Handle(Poly_Triangulation)>& aTris = aPart->Triangulations();
+    for (NCollection_Sequence<Handle(Poly_Triangulation)>::Iterator aTriIt (aTris); aTriIt.More(); aTriIt.Next())
+    {
+      Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation (anOwner, aTriIt.Value(), TopLoc_Location(), Standard_True);
+      theSelection->Add (aTri);
+    }
+  }
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_ViewCubeFlat::AIS_ViewCubeFlat (const Handle(AIS_ViewCube)& theParent)
+  : AIS_ViewCube (theParent)
+{
+  //
+}
+
+//=======================================================================
+//function : parent
+//purpose  :
+//=======================================================================
+Handle(AIS_ViewCube) AIS_ViewCubeFlat::parent() const
+{
+  Handle(PrsMgr_PresentableObject) aParent (Parent());
+  return Handle(AIS_ViewCube)::DownCast (aParent);
+}
+
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_ViewCubeFlat::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                const Handle(Prs3d_Presentation)& thePrs,
+                                const Standard_Integer theMode)
+{
+  if (theMode != 0)
+  {
+    return;
+  }
+
+  Handle(AIS_ViewCube) aParent = parent();
+
+  thePrs->SetMutable (Standard_True);
+  thePrs->SetZLayer (aParent->ZLayer());
+
+  // Set transform persistance options
+  Aspect_TypeOfTriedronPosition aPersPos;
+  Graphic3d_Vec2i aPersOffset;
+  aParent->Position (aPersPos, aPersOffset);
+  setTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, aPersPos, aPersOffset));
+
+  aParent->ComputeFlat (thePrsMgr, thePrs);
+}
+
+//=======================================================================
+//function : ComputeSelection
+//purpose  :
+//=======================================================================
+void AIS_ViewCubeFlat::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                          const Standard_Integer theMode)
+{
+  if (theMode != 0)
+  {
+    return;
+  }
+
+  parent()->ComputeSelectionFlat (theSelection);
+}
+
+//=======================================================================
+//function : HilightOwnerWithColor
+//purpose  :
+//=======================================================================
+void AIS_ViewCubeFlat::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                              const Handle(Prs3d_Drawer)& theStyle,
+                                              const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  (void) theStyle;
+  parent()->HilightOwnerWithColor (thePM, parent()->DynamicHilightAttributes(), theOwner);
+}
+
+//=======================================================================
+//function : HilightSelected
+//purpose  :
+//=======================================================================
+void AIS_ViewCubeFlat::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                        const SelectMgr_SequenceOfOwner& theSeq)
+{
+  parent()->HilightSelected (thePM, theSeq);
+}
diff --git a/src/AIS/AIS_ViewCube.hxx b/src/AIS/AIS_ViewCube.hxx
new file mode 100644 (file)
index 0000000..b8be300
--- /dev/null
@@ -0,0 +1,1060 @@
+// Created on: 2017-07-25
+// Created by: Anastasia BOBYLEVA
+// Copyright (c) 2017 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_ViewCube_HeaderFile
+#define _AIS_ViewCube_HeaderFile
+
+#include <AIS_AnimationCamera.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <BRepPrim_Direction.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_Camera.hxx>
+#include <Graphic3d_Group.hxx>
+#include <Graphic3d_Vec2.hxx>
+#include <NCollection_DataMap.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Prs3d_ToolDisk.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <TColStd_MapTransientHasher.hxx>
+#include <V3d_View.hxx>
+
+class AIS_ViewCubeFlat;
+
+//! Interactive object for displaying the view manipulation cube.
+//! It allows to manage view camera with more convenient way than manual manipulation of camera with mouse or touches.
+//! View cube consists of several parts that are responsible for different camera manipulations:
+//! @li Cube sides represent main views: top, bottom, left, right, front and back.
+//! @li Edges represent rotation of one of main views on 45 degrees.
+//! @li Vertices represent rotation of one of man views in two directions.
+//! @li Arrows represent rotation of view around X, Y, and Z axes on 45 degrees.
+//!
+//! Sides, edges, vertices and axes form 3D part of object that rotates with view camera, but doesn't respond on panning and scaling.
+//! This is made with trigedron transform persistence on 3D part of View Cube. Note that th eobject does not support
+//! changing of transform persistance option outside the object, as well as local transformation and childs attaching and deletion.
+//!
+//! Arrows form 2D part of objects. This part is fully 2D and but doesn't respond on camera manipulations. This part has 2D transform persistance applied,
+//! and for this purpose it is separated from 3D part into child interactive object.
+//! Interation of View Cube is represented with StartTransform(), Transform() and HasTransformation() methods.
+//!
+//! AIS_ViewCube can be simply added to the target view with method AddTo(). It uses View Affinity option to display object in the application.
+//! @code
+//! Handle(AIS_ViewCube) aViewCube = new AIS_ViewCube();
+//! aViewCube->AddTo (aContext, aView);
+//! @endcode
+//! or it can be just be displayed without iew affinity option (in this case it will be displayed in all views):
+//! @code
+//! Handle(AIS_ViewCube) aViewCube = new AIS_ViewCube();
+//! Handle(AIS_InteractiveContext) aContext;
+//! aContext->Display (aViewCube, Standard_False);
+//! @endcode
+//!
+//! View Cube parts are sensitive to detection, or dynamic highlighting (but not selection), and every its owner corresponds to camera transformation.
+//! So, once one of the owners of View Cube is detected, application is to be call StartTransform (anOwner) and Transform (anOwner) for starting
+//! animation of transformation.
+//! @code
+//! aViewCube->StartTransform (aDetectedOwner);
+//! while (aViewCube->HasTransformation())
+//! {
+//!   aViewCube->Transform();
+//!   // Updating of application window
+//!   ...
+//! }
+//! @endcode
+//! or
+//! @code aViewCube->Transform (aDetectedOwner); @endcode
+//! that includes transformation loop.
+//! This loop allows external actions like application updating. For this purpose AIS_ViewCube has virtual interface onAfterTransform(),
+//! that is to be redefined on application level.
+//! Note that after modification end no highlighting is restored by default.
+//! This means that after transformation of box if mouse pointer still points to box, it will not be highlighted. 
+//! Highlighting restoring of box is to be made on application level with AIS_InteracitveContext::MoveTo() method.
+//!
+//! @b Positioning:
+//! View Cube is attached to one defined point in the view plane. This point of attachment is placed in the center of view
+//! and can be changed with SetPosition() methods.
+//!
+//! @b Functionality:
+//! View cube structure is customizable. It can be done with SetDrawVertices() and SetDrawEdges(). They make edges and vertices fully invisible
+//! and insensitive.
+//! 
+//! @b Appearance management:
+//! The class has API for:
+//! @li Changing color of 3D part with SetBoxColor()
+//! @li Changing color of 2D part with SetArrowColor()
+//! @li Changing color of the whole object with SetColor()
+//! @li Changing transparency with SetBoxTransparency(), SetArrowTransparency(), SetTransparency
+//! @li Changing font for sides and axes text with SetText()
+//! @li Changing arrow parameters with SetArrowAngle(), SetArrowLength()
+//! By default arrows are semi-transparent.
+class AIS_ViewCube : public AIS_InteractiveObject
+{
+public:
+
+  DEFINE_STANDARD_RTTIEXT(AIS_ViewCube, AIS_InteractiveObject)
+
+  Standard_EXPORT AIS_ViewCube();
+
+  ~AIS_ViewCube() {}
+
+  //! Add View Cube to defined context and displays it in the input view only.
+  //! @param theContext [in] interactive context.
+  //! @param theView [in] 3D view.
+  Standard_EXPORT void AddTo (const Handle(AIS_InteractiveContext)& theContext, const Handle(V3d_View)& theView);
+
+  //! Make view cube visible only in the input view
+  //! @param theView [in] V3d View object
+  //! @warning This method should be called after View Cube is displayed in context
+  //!          or it will have no effect
+  Standard_EXPORT void SetViewAffinity (const Handle(V3d_View)& theView);
+
+  //! Hide View Cube in view
+  Standard_EXPORT void Hide();
+
+  //! Show View Cube in view
+  Standard_EXPORT void Show();
+
+  //! Set view for View Cube.
+  //! It can be used as alternative of AddTo() method.
+  Standard_EXPORT void SetView (const Handle(V3d_View)& theView);
+
+  Standard_EXPORT const Handle(V3d_View)& View() const;
+
+  //! Set default parameters for visual attributes
+  //! @sa Attributes()
+  Standard_EXPORT virtual void UnsetAttributes() Standard_OVERRIDE;
+
+  //! Set default parameters for dynamic highlighting attributes, reset highlight attributes
+  Standard_EXPORT virtual void UnsetHilightAttributes() Standard_OVERRIDE;
+
+  //! Reset all size and style parameters to default.
+  //! @warning It doesn't reset position of View Cube
+  Standard_EXPORT void Reset();
+
+protected:
+
+  //! Internal constructor for child objects
+  Standard_EXPORT AIS_ViewCube (const Handle(PrsMgr_PresentableObject)& theParent);
+
+  //! Set default visual attributes
+  Standard_EXPORT void setDefaultAttributes();
+
+  //! Set default dynamic highlight properties
+  Standard_EXPORT void setDefaultHighlightAttributes();
+
+public: //! @name Geometry management API
+
+  //! @return position of center of View Cube in terms of 2d trandform  persistence.
+  //! @sa Aspect_TypeOfTriedronPosition, Graphic3d_Vec2i
+  Standard_EXPORT void Position (Aspect_TypeOfTriedronPosition& thePosition,
+                                 Graphic3d_Vec2i& theOffset);
+
+  //! @return position of center of View Cube in screen cooordinates
+  //! (origin of system if topleft corner). 
+  Standard_EXPORT Graphic3d_Vec2i Position() const;
+
+  //! Set position of center of View Cube in view plane depending on size of view.
+  //! @warning this method works only if object is already attahed to the view.
+  Standard_EXPORT Standard_Boolean SetPosition (const Graphic3d_Vec2i& thePosition);
+
+  //! Set position of center of View Cube in view plane.
+  //! Note that this method can be used before AddTo() method call (and therefore attaching of View Cube to the V3d_View),
+  //! and therefore no Redisplay() will be called.
+  //! Position is complex and consists of part of view where object will be attached
+  //! and offset in pixels from the corner of view.
+  //! @warning vertical/horizontal offsets are applied only if object is placed not in center. 
+  //! @param thePosition [in] relative position of the view.
+  //! @param theOffset [in] offset from the corner.
+  //! Usage case:
+  //! @code aViewCube->SetPosition (Aspect_TOTP_LEFT_LOWER, 200, 200); @endcode
+  //! @sa Aspect_TypeOfTriedronPosition
+  Standard_EXPORT void SetPosition (const Aspect_TypeOfTriedronPosition thePosition,
+                                    const Standard_Integer theXOffset,
+                                    const Standard_Integer theYOffset);
+
+  //! Set position of center of View Cube in view plane depending on size of input view.
+  //! Note that this method can be used before AddTo() method call (and therefore attaching of View Cube to the V3d_View),
+  //! and therefore no Redisplay() will be called.
+  //! @param thePosition [in] Position in view plane from top left corner.
+  //! @param theView [in] input view.
+  Standard_EXPORT Standard_Boolean SetPosition (const Graphic3d_Vec2i& thePosition,
+                                                const Handle(V3d_View)& theView);
+
+  //! @return size (width and height) of View cube sides.
+  Standard_EXPORT Standard_Real Size() const;
+
+  //! Sets size (width and height) of View cube sides.
+  //! @param theToAdaptAnother [in] if is TRUE another parameters are adapted with the size.
+  Standard_EXPORT void SetSize (const Standard_Real theValue,
+                                const Standard_Boolean theToAdaptAnother = Standard_False);
+
+  //! Set new value of padding between box sides.
+  Standard_EXPORT void SetBoxPadding (const Standard_Real theValue);
+
+  //! @return padding between box sides.
+  Standard_EXPORT Standard_Real BoxPadding() const;
+
+  //! Set new value of padding between axis and 3D part (box).
+  Standard_EXPORT void SetAxisPadding (const Standard_Real theValue);
+
+  //! @return padding between axes and 3D part (box).
+  Standard_EXPORT Standard_Real AxisPadding() const;
+
+  //! Set corner radius of View Cube sides.
+  //! @param theValue [in] value in [0, 0.5] that show ration between box size and corner radius
+  //! i.e. theValue = CornerRadius / Size();
+  //! @warning throw Program Error if value is out of bounds.
+  Standard_EXPORT void SetCornerRadius (const Standard_Real theValue);
+
+  //! @return radius of side corners.
+  Standard_EXPORT Standard_Real CornerRadius() const;
+
+  //! @return TRUE if vertices (vertex) of View Cube is drawn.
+  Standard_EXPORT Standard_Boolean ToDrawVertices() const;
+
+  //! Enable/disable drawing of vertices (corners) of View Cube.
+  Standard_EXPORT void SetDrawVertices (const Standard_Boolean theValue);
+
+  //! @return TRUE if edges of View Cube is drawn.
+  Standard_EXPORT Standard_Boolean ToDrawEdges() const;
+
+  //! Enable/disable drawing of edges of View Cube.
+  Standard_EXPORT void SetDrawEdges (const Standard_Boolean theValue);
+
+  //! Set new value of arrow angle.
+  //! @param theValue [in] the input angle in radians
+  //! @code Attributes()->ArrowAspect()->SetAngle() @endcode
+  //! can be used instead.
+  Standard_EXPORT void SetArrowAngle (const Standard_Real theValue);
+
+  //! @return angle on the pointer of arrow in radians.
+  //! @code Attributes()->ArrowAspect()->Angle() @endcode
+  //! can be used instead.
+  Standard_EXPORT Standard_Real ArrowAngle() const;
+
+  //! Set new value of arrow length.
+  //! @param theValue [in] new value of arrow length.
+  //! @code Attributes()->ArrowAspect()->SetLength() @endcode
+  //! can be used instead.
+  Standard_EXPORT void SetArrowLength (const Standard_Real theValue);
+
+  //! @return length of arrows.
+  //! @code Attributes()->ArrowAspect()->Length() @endcode
+  //! can be used instead.
+  Standard_EXPORT Standard_Real ArrowLength() const;
+
+  //! Set new value of additional arrow padding between 3D box of View Cube and circle of 2D arrows.
+  //! @param theValue [in] the input value of arrow padding.
+  Standard_EXPORT void SetArrowPadding (const Standard_Real theValue);
+
+  //! @return additional arrow padding between 3D box of View Cube and circle of 2D arrows.
+  //! By default it is 0.
+  Standard_EXPORT Standard_Real ArrowPadding() const;
+
+  //! Set duration of animation.
+  //! @param theValue [in] input value of duration in seconds.
+  Standard_EXPORT void SetDuration (const Standard_Real theValue);
+
+  //! @return duration of animation.
+  Standard_EXPORT Standard_Real Duration() const;
+
+public: //! @name Style management API
+
+  //! Set color of text labels on box sides. By default it is black.
+  //! @code Attributes()->TextAspect()->SetColor() @endcode can be used instead
+  //! @param theColor [in] new color of text
+  Standard_EXPORT void SetTextColor (const Quantity_Color& theColor);
+
+  //! @return text color of labels of box sides. By default it is black.
+  Standard_EXPORT const Quantity_Color& TextColor() const;
+
+  //! Set font name that is used for displaying of sides and axes text.
+  //! @param theFont [in] input name of font.
+  //! @code Attributes()->TextAspect()->SetFont() @endcode
+  //! can be used instead.
+  Standard_EXPORT void SetFont (const TCollection_AsciiString& theFont);
+
+  //! @return font name that is used for displaying of sides and axes text.
+  //! @code Attributes()->TextAspect()->Aspect()->SetFont() @endcode
+  //! can be used instead.
+  Standard_EXPORT const TCollection_AsciiString& Font() const;
+
+  //! Change font height
+  //! @param theValue [in] new height of font.
+  //! @code Attributes()->TextAspect()->SetHeight() @endcode
+  //! can be used instead.
+  Standard_EXPORT void SetFontHeight (const Standard_Real theValue);
+
+  //! @return height of font
+  Standard_EXPORT Standard_Real FontHeight() const;
+
+  //! Set new value of color for the 2D part of object.
+  //! @param theColor [in] input color value.
+  Standard_EXPORT void SetArrowColor (const Quantity_Color& theColor);
+
+  //! @return value of color for the 2D part of object.
+  Standard_EXPORT const Quantity_Color& ArrowColor() const;
+
+  //! Set new value of transparency for 2D part of object.
+  //! @param theValue [in] input transparency value.
+  Standard_EXPORT void SetArrowTransparency (const Standard_Real theValue);
+
+  //! @return value of transparency for 2D part of object.
+  Standard_EXPORT Standard_Real ArrowTransparency() const;
+
+  //! Set color of sides back material.
+  //! @code Attributes()->ShadingAspect()->Aspect()->ChangeBackMaterial().SetColor() @endcode
+  //! can be used instead
+  //! @param theColor [in] the color
+  Standard_EXPORT void SetInnerColor (const Quantity_Color& theColor);
+
+  //! @return color of sides back material.
+  Standard_EXPORT const Quantity_Color& InnerColor() const;
+
+  //! Set new value of front color for the 3D part of object.
+  //! @param theColor [in] input color value.
+  Standard_EXPORT void SetBoxColor (const Quantity_Color& theColor);
+
+  //! @return value of front color for the 3D part of object.
+  Standard_EXPORT const Quantity_Color& BoxColor() const;
+
+  //! Set new value of transparency for 3D part of object.
+  //! @param theValue [in] input transparency value.
+  Standard_EXPORT void SetBoxTransparency (const Standard_Real theValue);
+
+  //! @return transparency for 3D part of object.
+  Standard_EXPORT Standard_Real BoxTransparency() const;
+
+  //! Set new value of color for the whole object.
+  //! @param theColor [in] input color value.
+  Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
+
+  //! Set new value of transparency for the whole object.
+  //! @param theValue [in] input transparency value.
+  Standard_EXPORT virtual void SetTransparency (const Standard_Real theValue) Standard_OVERRIDE;
+
+public: //! @name Transformation methods
+
+  //! @return TRUE if View Cube has unfinished transformation of view camera.
+  Standard_EXPORT Standard_Boolean HasTransformation() const;
+
+  //! Start camera transformation corresponding to the input detected owner.
+  //! @param theOwner [in] detected owner.
+  Standard_EXPORT virtual void StartTransform (const Handle(SelectMgr_EntityOwner)& theOwner);
+
+  //! Perform one step of current camera transformation.
+  //! theToUpdate [in] enable/disable update of view.
+  //! @return TRUE if animation is not stopped.
+  Standard_EXPORT virtual Standard_Boolean Transform (const Standard_Boolean theToUpdate = Standard_False);
+
+  //! Perform camera transformation loop corresponding to the input detected owner.
+  //! @param theOwner [in] detected owner.
+  Standard_EXPORT virtual void Transform (const Handle(SelectMgr_EntityOwner)& theOwner);
+
+  //! Set transformation of View Cube and view Redraw() on HilightSelected() method (on mouse click).
+  //! By defualt it is disabled.
+  //! @param theValue [in] enable/disable flag
+  Standard_EXPORT void SetAutoTransform (const Standard_Boolean theValue);
+
+  //! @return TRUE if View Cube is automatically transformated and redraws view on HilightSelected() method.
+  Standard_EXPORT Standard_Boolean IsAutoTransform() const;
+
+protected:
+
+  //! Perform internal single step of transformation.
+  Standard_EXPORT Standard_Boolean transform();
+
+protected: //! @name protected vitrual API
+
+  //! Method that is called after one step of transformation.
+  Standard_EXPORT virtual void onAfterTransform()
+  {}
+
+  //! Method that is called after transformation finish.
+  Standard_EXPORT virtual void onFinishTransformation()
+  {}
+
+public: //! @name Presentation computation
+
+  //! Compute 3D part of View Cube.
+  //! @param thePrsMgr [in] presentation manager.
+  //! @param thePrs [in] input presentation that is to be filled with flat presentation primitives.
+  //! @param theMode [in] display mode.
+  //! @warning this object accept only 0 display mode.
+  Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                        const Handle(Prs3d_Presentation)& thePrs,
+                                        const Standard_Integer theMode = 0) Standard_OVERRIDE;
+
+  //! Disables auto highlighting to use HilightSelected() and HilightOwnerWithColor() overriden methods.
+  Standard_EXPORT virtual Standard_Boolean IsAutoHilight() const Standard_OVERRIDE
+  {
+    return Standard_False;
+  }
+
+  //! Method which clear all selected owners belonging to this selectable object.
+  //! @warning this object does not support selection.
+  virtual void ClearSelected() Standard_OVERRIDE
+  {}
+
+  //! Method which hilghights inputowner belonging to this selectable object.
+  //! @param thePM [in] presentation manager
+  //! @param theStyle [in] style for dymnamic highlighting.
+  //! @param theOwner [in] input entity owner.
+  Standard_EXPORT virtual void HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                                      const Handle(Prs3d_Drawer)& theStyle,
+                                                      const Handle(SelectMgr_EntityOwner)& theOwner) Standard_OVERRIDE;
+
+  //! Method which draws selected owners.
+  Standard_EXPORT virtual void HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                                const SelectMgr_SequenceOfOwner& theSeq) Standard_OVERRIDE;
+
+
+  //! Redefine computing of sensitive entites for View Cube.
+  //! @param theSelection [in] input selection object that is to be filled wtih sensitive entities.
+  //! @param theMode [in] selection mode.
+  //! @warning object accepts only 0 selection mode.
+  Standard_EXPORT void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                         const Standard_Integer theMode);
+
+public: //! @name Managing of child object oresentation and selection.
+
+  //! Compute presentation with flat parts of View Cube.
+  //! @param thePrsMgr [in] presentation manager.
+  //! @param thePrs [in] input presentation that is to be filled with flat presentation primitives.
+  Standard_EXPORT void ComputeFlat (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, const Handle(Prs3d_Presentation)& thePrs);
+
+  //! Compute sensitive entities for flat parts of View Cube.
+  //! @param theSelection [in] input selection object that is to be filled wtih sensitive entities.
+  Standard_EXPORT void ComputeSelectionFlat (const Handle(SelectMgr_Selection)& theSelection);
+
+public:
+
+  //! Redefines transform persistence management to setup transformation for sub-presentation of axes.
+  //! @warning this interactive object does not support custom transformation persistence when.
+  Standard_EXPORT virtual void SetTransformPersistence (const  Handle(Graphic3d_TransformPers)& theTrsfPers) Standard_OVERRIDE;
+
+  //! Makes theObject child of current object in scene hierarchy.
+  Standard_EXPORT virtual void AddChild (const Handle(PrsMgr_PresentableObject)& theObject) Standard_OVERRIDE;
+
+  //! Removes theObject from children of current object in scene hierarchy.
+  Standard_EXPORT virtual void RemoveChild (const Handle(PrsMgr_PresentableObject)& theObject) Standard_OVERRIDE;
+
+protected:
+
+  Standard_EXPORT void setTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers);
+
+  Standard_EXPORT void addChild (const Handle(PrsMgr_PresentableObject)& theObject);
+
+  Standard_EXPORT void removeChild (const Handle(PrsMgr_PresentableObject)& theObject);
+
+  //! Redefines local transformation management method to inform user of inproper use.
+  //! @warning this interactive object does not support setting custom local transformation.
+  Standard_EXPORT virtual void setLocalTransformation (const Handle(Geom_Transformation)& theTrsf) Standard_OVERRIDE;
+
+  //! Hide methods
+  using AIS_InteractiveObject::SetLocalTransformation;
+  using SelectMgr_SelectableObject::SetZLayer;
+
+protected: //! @name Auxilliary classes to fill presentation with proper primitives
+
+  //! Base object that represent transformation of view camera.
+  class CameraState : public Standard_Transient
+  {
+  public:
+    DEFINE_STANDARD_RTTI_INLINE (CameraState, Standard_Transient)
+    CameraState() {}
+    virtual void FillCamera (const Handle(V3d_View)& theView, const Handle(Graphic3d_Camera)& theCamera) = 0;
+  };
+
+  //! Object that defines new orientation of camera.
+  class CameraStateReplace : public CameraState
+  {
+  public:
+
+    DEFINE_STANDARD_RTTI_INLINE (CameraStateReplace, CameraState)
+
+    //! @param theDir [in] Direction from eye to center of camera.
+    //! @param theUp [in] Up direction of camera.
+    CameraStateReplace (const gp_Dir& theDir, const gp_Dir& theUp)
+      : Up (theUp),
+        Direction (theDir)
+    {}
+
+    //! Apply new state to the camera.
+    //! @param theCamera [in] input camera object.
+    virtual void FillCamera (const Handle(V3d_View)& theView, const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE;
+
+  protected:
+
+    gp_Dir Up; //!< Up direction of camera
+    gp_Dir Direction; //!< Direction from eye to center of camera.
+  };
+
+  //! Object that defines rotation of camera on defined axis angles
+  class CameraStateRotate : public CameraState
+  {
+  public:
+
+    DEFINE_STANDARD_RTTI_INLINE (CameraStateRotate, CameraState)
+
+    //! @param theAngleX [in] Angle for rotation of X Axis.
+    //! @param theAngleY [in] Angle for rotation of Y Axis.
+    //! @param theAngleZ [in] Angle for rotation of Z Axis.
+    CameraStateRotate (const Standard_Real theAngleX, const Standard_Real theAngleY, const Standard_Real theAngleZ)
+      : AngleX (theAngleX),
+        AngleY (theAngleY),
+        AngleZ (theAngleZ)
+    {}
+
+    //! Apply rotate object state to the camera.
+    //! @param theCamera [in] input camera object.
+    virtual void FillCamera (const Handle(V3d_View)& theView, const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE;
+
+  protected:
+
+    Standard_Real AngleX; //!< Angle for rotation of X Axis
+    Standard_Real AngleY; //!< Angle for rotation of Y Axis
+    Standard_Real AngleZ; //!< Angle for rotation of Z Axis
+  };
+
+  //! Triangular part of view cube
+  class Part : public Standard_Transient
+  {
+  public:
+
+    DEFINE_STANDARD_RTTI_INLINE (Part, Standard_Transient)
+
+    Part() {}
+
+    Part (const Handle(AIS_ViewCube)& theParent)
+    : myParent (theParent)
+    {}
+
+    ~Part()
+    {
+      Reset();
+    }
+
+    //! Reset part fields.
+    void Reset();
+
+    void ComputeSelection (const Handle(SelectMgr_EntityOwner)& theOwner,
+                           const Handle(SelectMgr_Selection)& theSelection);
+
+    //! Set transform persistance for highlighting presentation.
+    void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers);
+
+    //! @return presentation for highlighting.
+    const Handle(Prs3d_Presentation)& HighlightPresentation() const
+    {
+      return myHighlightPresentation;
+    }
+
+    //! @return triangulations of the part.
+    const NCollection_Sequence<Handle(Poly_Triangulation)>& Triangulations() const
+    {
+      return myTriangulations;
+    }
+
+    //! Append triangulation to part.
+    void AddTriangulation (const Handle(Poly_Triangulation)& theTri)
+    {
+      myTriangulations.Append (theTri);
+    }
+
+    //! @return direction corresponding to the input direction identifier.
+    //! @param theDir [in] direction identifier.
+    //! @sa BRepPrim_Direction
+    gp_XYZ Direction (const BRepPrim_Direction theDir);
+
+    //! @return absolute location of left bottom corner of parent cube.
+    gp_XYZ Location();
+
+  protected:
+
+    //! Set of triangulations of sensitive entities.
+    NCollection_Sequence<Handle(Poly_Triangulation)> myTriangulations;
+    Handle(Prs3d_Presentation) myHighlightPresentation;
+    Handle(AIS_ViewCube) myParent;
+  };
+  
+  //! Tool to fill primitive array for rectangle with rounded corners.
+  class ToolRectangle
+  {
+  public:
+
+
+    //! @param thePosition [in] a plane for rectangle.
+    //! @param theBottomLeft [in] bottom left corner.
+    //! @param theTopLeft [in] top left corner.
+    //! @param theBottomRight [in] bottom right corner.
+    //! @param theTopRight [in] top right corner.
+    //! @param theRadius [in] radius of rounded corners.
+    ToolRectangle (const gp_Ax2& thePosition, const gp_Pnt& theBottomLeft, const gp_Pnt& theTopLeft,
+                   const gp_Pnt& theBottomRight, const gp_Pnt& theTopRight, const Standard_Real theRadius)
+    : myPosition (thePosition),
+      myBottomLeft (theBottomLeft),
+      myTopLeft (theTopLeft),
+      myBottomRight (theBottomRight),
+      myTopRight (theTopRight),
+      myRadius (theRadius)
+    {}
+
+    //! Fill primitive array and triangulation for sentitve entity.
+    void FillArray (Handle(Graphic3d_ArrayOfTriangles)& theArray,
+                    Handle(Poly_Triangulation)& theTriangulation);
+
+  protected:
+
+    //! Compute number of vertices  for triangular array.
+    Standard_Integer NumberOfTriangleVerices() const;
+
+    //! Fill primitive array with triangles for rounded corner of rectnagle.
+    //! @param theCircle [in] defines position and radius of corner.
+    //! @param theStartParameter [in] start circular parameter of corner arc.
+    //! @param theendParameter [in] end circular parameter of corner arc.
+    //! @param theArray [in] primitive array.
+    void FillCorner (const gp_Circ& theCircle,
+                     const Standard_Real theStartParameter,
+                     const Standard_Real theEndParameter,
+                     const Handle(Graphic3d_ArrayOfTriangles)& theArray);
+
+  protected:
+
+    gp_Ax2 myPosition;      //!< Position of plane where rectangle lies.
+    gp_Pnt myBottomLeft;    //!< Bottom left corner. 
+    gp_Pnt myTopLeft;       //!< Top left corner.
+    gp_Pnt myBottomRight;   //!< Bottom right corner.
+    gp_Pnt myTopRight;      //!< Top right corner.
+    Standard_Real myRadius; //!< Radius of corners.
+  };
+
+  //! Part to display side of cube with rounded corners.
+  class Side : public Part
+  {
+  public:
+    DEFINE_STANDARD_RTTI_INLINE (Side, Part)
+
+    Side() : Part() {}
+
+    //! @param theParent [in] AIS_ViewCube parent object.
+    //! @param theDirection [in] Defines cube face.
+    //! @param theText [in] Text drawn in the middle of face.
+    Side (const Handle(AIS_ViewCube)& theParent,
+          const BRepPrim_Direction theDirection,
+          const TCollection_ExtendedString theText)
+      : Part (theParent),
+        myDirection (theDirection),
+        myText (theText)
+    {}
+
+    ~Side() {}
+
+    //! Fill graphic group with primitives, fills internal triangulation and highlight presentation.
+    //! @param thePrsMgr [in] presentation manager.
+    //! @param theGroup [in] the graphic group.
+    //! @param theTextAspect [in] text style.
+    void Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                  const Handle(Graphic3d_Group)& theGroup,
+                  const Handle(Graphic3d_Group)& theTextGroup,
+                  const Handle(Prs3d_TextAspect)& theTextAspect);
+
+  protected:
+
+    BRepPrim_Direction myDirection; //!< Defines cube face.
+    TCollection_ExtendedString myText; //!< Text drawn in the middle of face.
+  };
+
+  //! Part to display vertex of cube as circle with defined radius.
+  class Vertex : public Part
+  {
+  public:
+    DEFINE_STANDARD_RTTI_INLINE (Vertex, Part)
+
+    Vertex() : Part() {}
+
+    //! @param theParent [in] AIS_ViewCube parent object
+    //! @param theDirection1 [in] Defines cube face tangent to vertex.
+    //! @param theDirection2 [in] Defines cube face tangent to vertex.
+    //! @param theDirection3 [in] Defines cube face tangent to vertex.
+    Vertex (const Handle(AIS_ViewCube)& theParent,
+            const BRepPrim_Direction theDirection1,
+            const BRepPrim_Direction theDirection2,
+            const BRepPrim_Direction theDirection3)
+    : Part (theParent),
+      myDirection1 (theDirection1),
+      myDirection2 (theDirection2),
+      myDirection3 (theDirection3)
+    {}
+
+    ~Vertex() {}
+
+    //! Fill graphic group with primitives, fills internal triangulation and highlight presentation.
+    //! @param thePrsMgr [in] presentation manager
+    //! @param theGroup [in] the graphic group
+    //! @param theRadius [in] radius of rounded vertex
+    //! @param theSlicesNb [in] number of facettes for Prs3d_ToolDisk
+    void Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                  const Handle(Graphic3d_Group)& theGroup,
+                  const Standard_Real theRadius,
+                  const Standard_Integer theSlicesNb = 20);
+
+  protected:
+
+    BRepPrim_Direction myDirection1; //!< Defines cube face tangent to vertex.
+    BRepPrim_Direction myDirection2; //!< Defines cube face tangent to vertex.
+    BRepPrim_Direction myDirection3; //!< Defines cube face tangent to vertex.
+  };
+
+  //! Part that defines rectangular edge with rounded corners.
+  class Edge : public Part
+  {
+  public:
+    DEFINE_STANDARD_RTTI_INLINE (Edge, Part)
+
+    Edge(): Part() {}
+
+    //! Constructor
+    //! @param theParent [in] AIS_ViewCube parent object
+    //! @param theDirection1 [in] Defines cube face tangent to edge.
+    //! @param theDirection2 [in] Defines cube face tangent to edge.
+    Edge (const Handle(AIS_ViewCube)& theParent,
+          const BRepPrim_Direction theDirection1,
+          const BRepPrim_Direction theDirection2)
+      : Part (theParent),
+        myDirection1 (theDirection1),
+        myDirection2 (theDirection2)
+    {}
+
+    //! Fill graphic group with primitives, fills internal triangulation and highlight presentation.
+    //! @param thePrsMgr [in] presentation manager
+    //! @param theGroup [in] the graphic group
+    //! @param theThickness [in] thickness of edge
+    void Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                  const Handle(Graphic3d_Group)& theGroup,
+                  const Standard_Real theThickness);
+
+  protected:
+
+    BRepPrim_Direction myDirection1; //!< Defines cube face tangent to edge.
+    BRepPrim_Direction myDirection2; //!< Defines cube face tangent to edge.
+  };
+
+  //! Tool to fill primitive array for flat triangular arrow.
+  //!      ^
+  //!     /|   <-theDir
+  //!    / |
+  //!   /--*  <- thePosition
+  class ToolArrow
+  {
+  public:
+
+    //! @param theAxis [in] Axis from the base of arrow to the pointer.
+    //! @param theLength [in] Length from the pointer ot base of arrow.
+    //! @param theAngle [in] Value of pointer angle in radians.
+    ToolArrow (const gp_Ax1& theAxis, const Standard_Real theLength, const Standard_Real theAngle)
+      : myAxis (theAxis),
+        myLength (theLength),
+        myAngle (theAngle)
+    {}
+
+    //! Fill primitive array and triangulation for sentitve entity.
+    void FillArray (Handle(Graphic3d_ArrayOfTriangles)& theArray,
+                    Handle(Poly_Triangulation)& theTriangulation);
+
+  protected:
+
+    gp_Ax1 myAxis; //!< Axis from the base of arrow to the pointer.
+    Standard_Real myLength; //!< Length from the pointer ot base of arrow.
+    Standard_Real myAngle; //!< Value of pointer angle in radians.
+  };
+
+  //! Part to display triangular flat arrow.
+  class FlatArrow : public Part
+  {
+  public:
+
+    DEFINE_STANDARD_RTTI_INLINE (FlatArrow, Part)
+  public:
+
+    FlatArrow() : Part() {}
+
+    FlatArrow (const Handle(AIS_ViewCube)& theParent)
+    : Part (theParent)
+    {}
+
+   ~FlatArrow() {}
+
+    //! @param thePrsMgr [in] presentation manager
+    //! @param theGroup [in] the graphic group
+    //! @param theAxis [in] bottom center of arrow, direction from bottom line to the pointer of arrow
+    //! @param theLength [in] length of the arrow from the pointer to the base of arrow
+    //! @param theAngle [in] value of pointer angle in radians
+    void Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                  const Handle(Graphic3d_Group)& theGroup,
+                  const gp_Ax1& theAxis,
+                  const Standard_Real theLength,
+                  const Standard_Real theAngle);
+  };
+
+  //! Tool to fill triangle primitive array corresponding to disk segment.
+  class ToolDiskSegment : public Prs3d_ToolDisk
+  {
+  public:
+
+    //! @param theInnerRadius [in] small radius of disk segment.
+    //! @param theOuterRadius [in] big radius of disk segment.
+    //! @param theStartAngle [in] Start angle in counter clockwise order.
+    //! @param theEndAngle [in] End angle in counter clockwise order.
+    //! @param theNbSlides [in] Number of facettes.
+    Standard_EXPORT ToolDiskSegment (const Standard_Real    theInnerRadius,
+                                     const Standard_Real    theOuterRadius,
+                                     const Standard_Real    theStartAngle,
+                                     const Standard_Real    theEndAngle,
+                                     const Standard_Integer theNbFacettes);
+
+  protected:
+
+    Standard_EXPORT virtual gp_Pnt Vertex (const Standard_Real theU, const Standard_Real theV) Standard_OVERRIDE;
+
+    Standard_Real myStartAngle; //!< Start angle in counter clockwise order.
+    Standard_Real myEndAngle; //!< End angle in counter clockwise order.
+  };
+
+  //! Displays rounded arrow consisted of disk segment and triangular arrow
+  class RoundedArrow : public Part
+  {
+  public:
+
+    DEFINE_STANDARD_RTTI_INLINE (RoundedArrow, Part)
+
+    //! Empty constructor
+    RoundedArrow() : Part() {}
+
+    RoundedArrow (const Handle(AIS_ViewCube)& theParent)
+    : Part (theParent)
+    {}
+
+    //! Destructor
+    ~RoundedArrow() {}
+
+    //! @param thePrsMgr [in] presentation manager
+    //! @param theGroup [in] the graphic group
+    //! @param theCenter [in] location of circle that lies on the center axis of rounded arrow 
+    //! @param theArrowAngle [in] arrow angle
+    //! @param theArrowLength [in] arrow length
+    //! @param theInnerRadius [in] inner radius
+    //! @param theStartAngle [in] start angle
+    //! @param theEndAngle [in] end angle
+    //! @param theIsClockwise [in] the direction of angle, be default
+    //! angle is counted in couner clockwise order, from start to end angle
+    //! @param theSlicesNb [in] number of slices for triangulation of arrow tail segment
+    void Display (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                  const Handle(Graphic3d_Group)& theGroup,
+                  const gp_Pnt& theCenter,
+                  const Standard_Real theArrowLength,
+                  const Standard_Real theArrowAngle,
+                  const Standard_Real theInnerRadius,
+                  const Standard_Real theStartAngle,
+                  const Standard_Real theEndAngle,
+                  const Standard_Boolean theIsClockwise = Standard_False,
+                  const Standard_Integer theSlicesNb = 20);
+  };
+
+  //! The class displays axis presentation with text.
+  class Axis
+  {
+  public:
+
+    Axis (const gp_Ax1& theAxis = gp_Ax1(),
+          const Quantity_Color& theColor = Quantity_Color(),
+          const Standard_ExtCharacter& theSymbol = L' ',
+          const Standard_Real theLength = 10.);
+
+    //! Compute presentation of axis.
+    //! @param theGroup [in] graphic group.
+    //! @param theAspect [in] shading style.
+    //! @param theTextAspect [in] text style.
+    void Compute (const Handle(Graphic3d_Group)& theGroup,
+                  const Handle(Prs3d_ShadingAspect)& theAspect,
+                  const Handle(Prs3d_TextAspect)& theTextAspect);
+
+    //! @return color of axis.
+    Quantity_Color Color() const { return myColor; }
+
+    //! Set position of axis.
+    void SetPosition (const gp_Ax1& thePosition) { myPosition = thePosition; }
+
+    //! @return position of axis.
+    const gp_Ax1& Position() const { return myPosition; }
+
+    //! @return lenght of axis.
+    Standard_Real Length() const { return myLength; }
+
+    //! Set length of axis including arrows.
+    void SetLength (const Standard_Real theValue)
+    {
+      myLength = theValue;
+    }
+
+    //! @return text symbol of the axis.
+    const Standard_ExtCharacter Symbol() const { mySymbol; }
+
+    //! Set text symbol of axis: 'X', 'Y' or 'Z' are used.
+    void SetSymbol (const Standard_ExtCharacter& theValue) { mySymbol = theValue; }
+
+  protected:
+
+    gp_Ax1 myPosition; //!< Position of the axis including local transformation.
+    Quantity_Color myColor; //!< Color of axis.
+    Standard_Real myLength; //!< Length of translation axis.
+    Standard_ExtCharacter mySymbol; //!< Symbol attached to the axis.
+  };
+
+protected:
+
+  Standard_EXPORT Standard_Integer addPart (const Handle(Part)& thePart,
+                                            const gp_Dir& theDir, const gp_Dir& theUp,
+                                            const Standard_Integer thePriority = 7);
+
+  Standard_EXPORT Standard_Integer addPart (const Handle(Part)& thePart,
+                                            const Standard_Real theAngleX, const Standard_Real theAngleY, const Standard_Real theAngleZ,
+                                            const Standard_Integer thePriority = 7);
+
+  Standard_EXPORT gp_XYZ direction (const Standard_Integer theDir);
+
+  Standard_EXPORT Standard_Real sign (const Standard_Real theValue);
+
+protected: //! @name Map definitions
+
+  typedef NCollection_IndexedDataMap<Handle(SelectMgr_EntityOwner), Handle(CameraState),TColStd_MapTransientHasher>
+  MapOfOwnerCameraState;
+
+  typedef NCollection_IndexedDataMap<Handle(SelectMgr_EntityOwner), Handle(Part), TColStd_MapTransientHasher>
+  MapOfOwnerPart;
+
+private:
+
+  
+  Aspect_TypeOfTriedronPosition myPosition; //!< Presisted position of cube.
+  Graphic3d_Vec2i myOffset; //!< Offset to the position. It is needed to set needed position.
+  Standard_Real mySize; //!< Size of box side, length of one axis.
+  Standard_Real myBoxPadding; //!< Padding between box elements.
+  Standard_Real myAxisPadding; //!< Padding between box and axis.
+  Standard_Real myCornerRadius; //!< Value of corner radius in value of ratio to Size, is in [0; 0.5].
+  Standard_Real myArrowPadding; //!< Additional padding for arrows and box, by default it is equal to 0.
+  Standard_Boolean myToDisplayEdges; //!< Flag that shows if edges of box are to be displayed.
+  Standard_Boolean myToDisplayVertices; //!< Flag that shows if vertices (corners) of box are to be displayed.
+  
+  Handle(V3d_View) myView; //!< Reference to view.
+  Handle(Prs3d_ShadingAspect) myArrowAspect; //!< Style for 2D arrows presentations.
+  MapOfOwnerPart myParts; //!< Map of graphical parts: box sides, edges, vertices, arrows.
+
+private: //! @name Animation options
+
+  Handle(Graphic3d_Camera) myStartState; //!< Start state of view camera.
+  Handle(Graphic3d_Camera) myEndState; //!< End state of view camera.
+  Handle(AIS_AnimationCamera) myAnimation; //!< Camera animation object.
+  Standard_Real myDuration; //!< Duration of animation. By default it is half a second.
+  MapOfOwnerCameraState myStates; //! Map of linked owners and camera states: positions or angles to rotate.
+  Standard_Boolean myIsAutoTransform; //!< Means that transformation is performed in HilightSelected() method.
+
+private:
+
+  Handle(AIS_ViewCubeFlat) myFlatPart; //!< Reference to the child interactive object for 2D part.
+};
+
+//! @brief Auxilliary class for defining flat part of View Cube.
+//! It is created to display arrows with 2D transform persistance
+//! and amange sensitive entites with the same persistance.
+//! This object does not manage any View Cube options, camera manipulations.
+class AIS_ViewCubeFlat : public AIS_ViewCube
+{
+public:
+
+  DEFINE_STANDARD_RTTIEXT(AIS_ViewCubeFlat, AIS_ViewCube)
+
+  //! Constructs dependent interactive object for View Cube flat part
+  AIS_ViewCubeFlat (const Handle(AIS_ViewCube)& theParent);
+
+  //! Destructor
+  ~AIS_ViewCubeFlat() {}
+
+protected:
+
+  //! @return parent object: AIS_ViewCube instance
+  Handle(AIS_ViewCube) parent() const;
+
+public:
+
+  //! Fill flat presentation.
+  //! @param thePrsMgr [in] presentation manager
+  //! @param thePrs [in] reference to the presentation that is to be filled with graphic groups. It is mutable here.
+  //! @param theMode [in] display mode.
+  //! @warning Only 0 display mode is acceptable.
+  Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                        const Handle(Prs3d_Presentation)& thePrs,
+                                        const Standard_Integer theMode = 0) Standard_OVERRIDE;
+
+  //! Fill sensitive primitives.
+  //! @param theSelection [in] selection obejct to be filled
+  //! @param theMode [in] input selection mode
+  //! @warning Only zero seelction mode is acceptable.
+  Standard_EXPORT void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                         const Standard_Integer theMode) Standard_OVERRIDE;
+
+  //! Manage custom dynamic highlighting. It is calls as IsAutoHilight() method is redefined for thids object
+  //! and always return Standard_False.
+  //! @param thePM [in] presentation manager
+  //! @param theStyle [in] graphical attributes for dynamic highlighting. Here DynamicHilightAttributes() of parent
+  //! interactive object is used.
+  //! @param theOwner [in] owner of detected sensitive entity.
+  Standard_EXPORT virtual void HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                                      const Handle(Prs3d_Drawer)& theStyle,
+                                                      const Handle(SelectMgr_EntityOwner)& theOwner) Standard_OVERRIDE;
+
+  //! Method which draws selected owners.
+  Standard_EXPORT virtual void HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                                const SelectMgr_SequenceOfOwner& theSeq) Standard_OVERRIDE;
+
+};
+
+//! Redefined entity owner that is highglighted when owner is detected,
+//! even if Interactive Context highlighted on last detection procedure.
+//! This owner is needed for View Cube to highlight arrows once more after tranformation.
+class AIS_ViewCubeOwner : public SelectMgr_EntityOwner
+{
+public:
+
+  DEFINE_STANDARD_RTTI_INLINE (AIS_ViewCubeOwner, SelectMgr_EntityOwner)
+
+  AIS_ViewCubeOwner (const Handle(SelectMgr_SelectableObject)& theObject, const Standard_Integer thePriority = 0)
+  : SelectMgr_EntityOwner (theObject, thePriority)
+  {}
+
+  //! @return TRUE. This owner will always call method
+  //! Hilight for its Selectable Object when the owner is detected.
+  Standard_EXPORT virtual Standard_Boolean IsForcedHilight() const Standard_OVERRIDE
+  {
+    return Standard_True;
+  }
+};
+
+
+#endif
index 9a173099698903270ef3de843cbe3106691a9066..b8555d373fb4ef39e3bd7feb7d8bd7dfb157004a 100644 (file)
@@ -175,3 +175,5 @@ AIS_TypeOfAxis.hxx
 AIS_TypeOfDist.hxx
 AIS_TypeOfIso.hxx
 AIS_TypeOfPlane.hxx
+AIS_ViewCube.hxx
+AIS_ViewCube.cxx
index 523c03bab2de6cb920122b65d8cdeb049a2ef04a..21363ee22eb3415862b6f52fda95633594c885e0 100644 (file)
@@ -27,6 +27,7 @@
 #include <AIS_InteractiveObject.hxx>
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <AIS_ViewCube.hxx>
 #include <Aspect_Grid.hxx>
 #include <DBRep.hxx>
 #include <Draw_ProgressIndicator.hxx>
@@ -1313,6 +1314,25 @@ Standard_EXPORT Handle(AIS_Manipulator) GetActiveAISManipulator()
   return NULL;
 }
 
+typedef NCollection_DataMap<Handle(V3d_View), Handle(AIS_ViewCube)> ViewerTest_MapOfViewCube;
+
+Standard_EXPORT ViewerTest_MapOfViewCube& MapOfViewCube()
+{
+  static ViewerTest_MapOfViewCube aViewMap;
+  return aViewMap;
+}
+
+Standard_EXPORT Handle(AIS_ViewCube) ActiveViewCube()
+{
+  Handle(AIS_ViewCube) aCube;
+  if (MapOfViewCube().Find (ViewerTest::CurrentView(), aCube))
+  {
+    return aCube;
+  }
+
+  return NULL;
+}
+
 //==============================================================================
 
 #ifdef _WIN32
@@ -13700,6 +13720,215 @@ static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
   return 0;
 }
 
+//===============================================================================================
+//function : VViewCube
+//purpose  :
+//===============================================================================================
+static int VViewCube (Draw_Interpretor& theDi,
+                      Standard_Integer  theArgsNb,
+                      const char**      theArgVec)
+{
+  if (theArgsNb < 2)
+  {
+    std::cout << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'\n";
+    return 1;
+  }
+
+  const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
+  const Handle(V3d_View)& aView = ViewerTest::CurrentView();
+  if (aContext.IsNull() || aView.IsNull())
+  {
+    std::cout << "Error: no active view.\n";
+    return 1;
+  }
+
+  ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
+  Standard_Integer anArgIter = 1;
+  for (; anArgIter < theArgsNb; ++anArgIter)
+  {
+    anUpdateTool.parseRedrawMode (theArgVec[anArgIter]);
+  }
+
+  Handle(AIS_ViewCube) aViewCube;
+  ViewerTest_CmdParser aCmd;
+  aCmd.SetDescription ("vviewcube Name [options]. Commmand manages View Cube object:");
+  aCmd.AddOption ("enable", "enables view cube");
+  aCmd.AddOption ("disable", "disables view cube");
+  aCmd.AddOption ("remove", "removes view cube presentation from context and view");
+  aCmd.AddOption ("remove", "removes view cube presentation from context and view");
+  aCmd.AddOption ("reset", "reset geomertical and visual attributes");
+  aCmd.AddOption ("size", "... size - set size of View Cube");
+  aCmd.AddOption ("adaptsize", " - adapt all another parameters to input size");
+  aCmd.AddOption ("color", "... r g b - set color of View Cube ");
+  aCmd.AddOption ("boxcolor", "... r g b - set box color of view cube");
+  aCmd.AddOption ("arrowcolor", "... r g b - set arrow color of view cube");
+  aCmd.AddOption ("textcolor", "... r g b - set side text color of view cube");
+  aCmd.AddOption ("innercolor", "... r g b - set inner box color of view cube");
+  aCmd.AddOption ("arrowangle", "... value - set pointer angle of arrows in radians");
+  aCmd.AddOption ("arrowlength", "... value - set length of arrows");
+  aCmd.AddOption ("arrowpadding", "... value - set padding between axis and arrows");
+  aCmd.AddOption ("transparency", "... [0;1] - set transparency of object");
+  aCmd.AddOption ("boxtransparency", "... [0;1] - set transparency of box in View Cube");
+  aCmd.AddOption ("arrowtransparency", "... [0;1] - set transparency of arrows in View Cube");
+  aCmd.AddOption ("font", "... string - set font name");
+  aCmd.AddOption ("fontheight", "... value - set font height");
+  aCmd.AddOption ("boxpadding", "... value - set padding between box sides");
+  aCmd.AddOption ("axispadding", "... value - set padding between box and arrows");
+  aCmd.AddOption ("cornerradius", "... value - set radius of side corners in [0;0.5] (0-50% of box side size)");
+  aCmd.AddOption ("hideedges", " - hide edges of View Cube");
+  aCmd.AddOption ("showedges", " - show edges of View Cube");
+  aCmd.AddOption ("hidevertices", " - hide vertices ov View Cube");
+  aCmd.AddOption ("showvertices", " - show vertices ov View Cube");
+  aCmd.AddOption ("position", "... PixX PixY - 2D position of View Cube from top left corner");
+
+  aCmd.Parse (theArgsNb, theArgVec);
+
+  if (aCmd.HasOption ("help"))
+  {
+    theDi.PrintHelp (theArgVec[0]);
+    return 0;
+  }
+
+  // Get current view cube entity
+  aViewCube = ActiveViewCube();
+  if (aViewCube.IsNull())
+  {
+    aViewCube = new AIS_ViewCube();
+    MapOfViewCube().Bind (aView, aViewCube);
+    aViewCube->SetAutoTransform (Standard_True);
+  }
+
+  if (aCmd.HasOption ("color"))
+  {
+    aViewCube->SetColor (Quantity_Color (aCmd.ArgVec3f ("color")));
+  }
+  if (aCmd.HasOption ("boxcolor"))
+  {
+    aViewCube->SetBoxColor (Quantity_Color (aCmd.ArgVec3f ("boxcolor")));
+  }
+  if (aCmd.HasOption ("arrowcolor"))
+  {
+    aViewCube->SetArrowColor (Quantity_Color (aCmd.ArgVec3f ("arrowcolor")));
+  }
+  if (aCmd.HasOption ("textcolor"))
+  {
+    aViewCube->SetTextColor (Quantity_Color (aCmd.ArgVec3f ("textcolor")));
+  }
+  if (aCmd.HasOption ("innercolor"))
+  {
+    aViewCube->SetInnerColor (Quantity_Color (aCmd.ArgVec3f ("innercolor")));
+  }
+  if (aCmd.HasOption ("arrowangle"))
+  {
+    aViewCube->SetArrowAngle (aCmd.ArgDouble ("arrowangle") * M_PI / 180.0);
+  }
+  if (aCmd.HasOption ("arrowlength"))
+  {
+    aViewCube->SetArrowLength (aCmd.ArgDouble ("arrowlength"));
+  }
+  if (aCmd.HasOption ("arrowpadding"))
+  {
+    aViewCube->SetArrowPadding (aCmd.ArgDouble ("arrowpadding"));
+  }
+  if (aCmd.HasOption ("transparency"))
+  {
+    aViewCube->SetTransparency (aCmd.ArgDouble ("transparency"));
+  }
+  if (aCmd.HasOption ("boxtransparency"))
+  {
+    aViewCube->SetBoxTransparency (aCmd.ArgDouble ("boxtransparency"));
+  }
+  if (aCmd.HasOption ("arrowtransparency"))
+  {
+    aViewCube->SetArrowTransparency (aCmd.ArgDouble ("arrowtransparency"));
+  }
+  if (aCmd.HasOption ("font"))
+  {
+    aViewCube->SetFont (aCmd.Arg ("font", 0).c_str());
+  }
+  if (aCmd.HasOption ("fontheight"))
+  {
+    aViewCube->SetFontHeight (aCmd.ArgDouble ("fontheight", 0));
+  }
+  if (aCmd.HasOption ("boxpadding"))
+  {
+    aViewCube->SetBoxPadding (aCmd.ArgDouble ("boxpadding"));
+  }
+  if (aCmd.HasOption ("axispadding"))
+  {
+    aViewCube->SetAxisPadding (aCmd.ArgDouble ("axispadding"));
+  }
+  if (aCmd.HasOption ("cornerradius"))
+  {
+    aViewCube->SetCornerRadius (aCmd.ArgDouble ("cornerradius"));
+  }
+  if (aCmd.HasOption ("hideedges"))
+  {
+    aViewCube->SetDrawEdges (Standard_False);
+  }
+  if (aCmd.HasOption ("showedges"))
+  {
+    aViewCube->SetDrawEdges (Standard_True);
+  }
+  if (aCmd.HasOption ("hidevertices"))
+  {
+    aViewCube->SetDrawVertices (Standard_False);
+  }
+  if (aCmd.HasOption ("showvertices"))
+  {
+    aViewCube->SetDrawVertices (Standard_True);
+  }
+  if (aCmd.HasOption ("position", 2))
+  {
+    aViewCube->SetPosition (Graphic3d_Vec2i (aCmd.ArgInt ("position", 0), aCmd.ArgInt ("position", 1)),
+                            aView);
+  }
+  if (aCmd.HasOption ("size"))
+  {
+    aViewCube->SetSize (aCmd.ArgDouble ("size", 0), aCmd.HasOption ("adaptsize"));
+  }
+  if (aCmd.HasOption ("reset"))
+  {
+    aViewCube->Reset();
+  }
+
+  // Enable View Cube for current view
+  if (aCmd.HasOption ("enable") && !aContext->IsDisplayed (aViewCube))
+  {
+    aContext->MainSelector()->SetPickClosest (Standard_False);
+    if (aViewCube->View().IsNull())
+    {
+      aViewCube->SetView (aView);
+      aViewCube->AddTo (aContext, aView);
+    }
+    else
+    {
+      aViewCube->Show();
+    }
+  }
+  else if (aCmd.HasOption ("disable") && aContext->IsDisplayed (aViewCube))
+  {
+    ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_True);
+    aViewCube->Hide();
+  }
+  else if (aCmd.HasOption ("remove") && aContext->IsDisplayed (aViewCube))
+  {
+    ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_True);
+    MapOfViewCube().UnBind (aViewCube->View());
+    aContext->Remove (aViewCube, Standard_False);
+  }
+  else
+  {
+    TColStd_ListOfInteger aModes;
+    aViewCube->ToBeUpdated (aModes);
+    if (!aModes.IsEmpty())
+    {
+      aContext->Redisplay (aViewCube, Standard_False);
+    }
+  }
+
+  return 0;
+}
 //=======================================================================
 //function : ViewerCommands
 //purpose  :
@@ -14498,5 +14727,40 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "vprogressive",
     __FILE__, VProgressiveMode, group);
 #endif
+
+  theCommands.Add ("vviewcube",
+    "\n vviewcube [-enable|-disable]"
+    "\n Warning: after end pf test please call vviewcube -remove, otherwise View Cube will hold down active view from closing"
+    "\n    tool to create and manage interactive view manipualtion object for active view."
+    "\n    Options: "
+    "\n      '-enable|disable'         display/erase view cube with defined visual options"
+    "\n      '-reset                   reset geomertical and visual attributes'"
+    "\n      '-size Value'             adjust position when attaching"
+    "\n      '-adaptSize'              call with -size to adapt all part to size of 3D box"
+    "\n      'remove'                  removes view cube presentation from context and view"
+    "\n      'size Size'               set size of View Cube"
+    "\n      'color R G B'             set color of View Cube in limits [0;1]"
+    "\n      'boxcolor R G B'          set box color of view cube in limits [0;1]"
+    "\n      'arrowcolor R G B'        set arrow color of view cube in limits [0;1]"
+    "\n      'textcolor R G B'         set color of side text of view cube in limits [0;1]"
+    "\n      'innercolor R G B'        set inner box color of view cube in limits [0;1]"
+    "\n      'arrowangle Value'        set pointer angle of arrows in radians"
+    "\n      'arrowlength Value'       set length of arrows"
+    "\n      'arrowpadding Value'      set padding between axis and arrows"
+    "\n      'transparency [0;1]'      set transparency of object"
+    "\n      'boxtransparency [0;1]'   set transparency of box in View Cube"
+    "\n      'arrowtransparency [0;1]' set transparency of arrows in View Cube"
+    "\n      'font Name'               set font name"
+    "\n      'fontheight value'        set font height"
+    "\n      'boxpadding Value'        set padding between box sides"
+    "\n      'axispadding Value'       set padding between box and arrows"
+    "\n      'cornerradius Value'      set radius of corners of sides"
+    "\n      'hideedges'               hide edges of View Cube"
+    "\n      'showedges'               show edges of View Cube"
+    "\n      'hidevertices'            hide vertices ov View Cube"
+    "\n      'showvertices'            show vertices ov View Cube"
+    "\n      'position XPix YPix'      2D position of View Cube from top left corner",
+    __FILE__, VViewCube, group);
+
 }
 
diff --git a/tests/v3d/viewcube/default b/tests/v3d/viewcube/default
new file mode 100644 (file)
index 0000000..f1ddd2f
--- /dev/null
@@ -0,0 +1,64 @@
+puts "=================================="
+puts "AIS_ViewCube - display and erase with default settings"
+puts "=================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+set anImage3 $imagedir/${casename}_3.png
+set anImage4 $imagedir/${casename}_4.png
+
+vclear
+vclose ALL
+vinit
+# -------------------------------------
+# create helper object
+# -------------------------------------
+box aBox1 15 20 70
+vdisplay aBox1 -dispMode 1
+vaxo
+vfit
+
+# -------------------------------------
+# display view cube object
+# -------------------------------------
+vviewcube -enable -size 70 -adaptsize -position 120 250
+
+vmoveto 118 230
+if {[vreadpixel 118 230 name] != "DARKTURQUOISE 1"} {
+  puts "ERROR: Highlighting of view cube side is wrong."
+}
+vmoveto 0 0
+vdump $anImage1
+
+# -------------------------------------
+# Check side
+# -------------------------------------
+vselect 125 200
+if {[vreadpixel 115 233 name] != "GRAY95 1"} {
+  puts "ERROR: Display of view cube is wrong."
+}
+if {[vreadpixel 190 136 name] != "IVORY 1"} {
+  puts "ERROR: Position of TOP camera is wrong."
+}
+vdump $anImage2
+
+# -------------------------------------
+# Check edge
+# -------------------------------------
+vselect 163 242
+if {[vreadpixel 141 234 name] != "GRAY76 1"} {
+  puts "ERROR: Position of TOP-RIGHT camera is wrong."
+}
+vdump $anImage3
+
+# -------------------------------------
+# Check vertex
+# -------------------------------------
+vselect 121 213
+if {[vreadpixel 120 250 name] != "GRAY95 1"} {
+  puts "ERROR: Position of TOP-RIGHT-BACK camera is wrong."
+}
+vdump $anImage4
+
+vviewcube -remove
+vclear
\ No newline at end of file
diff --git a/tests/v3d/viewcube/move b/tests/v3d/viewcube/move
new file mode 100644 (file)
index 0000000..f3f5a13
--- /dev/null
@@ -0,0 +1,46 @@
+puts "=================================="
+puts "AIS_ViewCube - check positioning of View Cube"
+puts "=================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+set anImage3 $imagedir/${casename}_3.png
+set anImage4 $imagedir/${casename}_4.png
+
+vclear
+vclose ALL
+vinit
+
+# -------------------------------------
+# display view cube object
+# -------------------------------------
+vviewcube -enable -size 70 -adaptsize
+
+# -------------------------------------
+# check positioning of view cube object
+# -------------------------------------
+if {[vreadpixel 96 285 name] != "GRAY68 1"} {
+  puts "ERROR: Bottom left View Cube fails."
+}
+vdump $anImage1
+
+vviewcube -position 200 200
+if {[vreadpixel 200 176 name] != "GRAY68 1"} {
+  puts "ERROR: Center View Cube fails."
+}
+vdump $anImage2
+
+vviewcube -position 310 100
+if {[vreadpixel 310 73 name] != "GRAY68 1"} {
+  puts "ERROR: Top right View Cube fails."
+}
+vdump $anImage3
+
+vviewcube -position 140 240
+if {[vreadpixel 140 217 name] != "GRAY68 1"} {
+  puts "ERROR: Custom View Cube fails."
+}
+vdump $anImage4
+
+vviewcube -remove
+vclear
\ No newline at end of file
diff --git a/tests/v3d/viewcube/part b/tests/v3d/viewcube/part
new file mode 100644 (file)
index 0000000..0b9f053
--- /dev/null
@@ -0,0 +1,33 @@
+puts "====================================="
+puts "AIS_ViewCube - test custom appearance"
+puts "====================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+set anImage3 $imagedir/${casename}_3.png
+
+vclear
+vclose ALL
+vinit
+
+vviewcube -enable -hideedges
+if {[vreadpixel 186 236 name] != "BLACK 0"} {
+  puts "ERROR: Invalid display of View Cube without edges."
+}
+vdump $anImage1
+
+vviewcube -showedges -hidevertices
+if {[vreadpixel 150 258 name] != "BLACK 0"} {
+  puts "ERROR: Invalid display of View Cube without vertices."
+}
+vdump $anImage2
+
+vviewcube -hideedges -hidevertices
+
+if {[vreadpixel 186 236 name] != "BLACK 0" || [vreadpixel 150 258 name] != "BLACK 0"} {
+  puts "ERROR: Invalid display of View Cube without edges & vertices."
+}
+vdump $anImage3
+
+vviewcube -remove
+vclear
\ No newline at end of file
diff --git a/tests/v3d/viewcube/style b/tests/v3d/viewcube/style
new file mode 100644 (file)
index 0000000..6cb16c0
--- /dev/null
@@ -0,0 +1,84 @@
+puts "=================================="
+puts "AIS_ViewCube - display custom styled View Cube"
+puts "=================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+set anImage3 $imagedir/${casename}_3.png
+set anImage4 $imagedir/${casename}_4.png
+set anImage5 $imagedir/${casename}_5.png
+set anImage6 $imagedir/${casename}_6.png
+set anImage7 $imagedir/${casename}_7.png
+vclear
+vclose ALL
+vinit
+
+# -------------------------------------
+# Color
+# -------------------------------------
+vviewcube -enable -boxcolor 0.69 0.88 1 -arrowcolor 0 0.4 0.54 -textcolor 0 0.4 0.54
+if {[vreadpixel 118 273 name] != "LIGHTSLATEGRAY 1" || [vreadpixel 270 260 name] != "GRAY15 0.24705882370471954"} {
+  puts "ERROR: Errors in changing View Cube colors."
+}
+vdump $anImage1
+
+# -------------------------------------
+# Transparency
+# -------------------------------------
+vviewcube -reset
+vviewcube -transparency 0.5
+if {[vreadpixel 118 273 name] != "GRAY17 0.37254902720451355" || [vreadpixel 270 260 name] != "GRAY48 0.24705882370471954"} {
+  puts "ERROR: Errors in changing View Cube common transparency."
+}
+vdump $anImage2
+
+vviewcube -reset
+vviewcube -boxtransparency 0.4 -arrowtransparency 0.2
+if {[vreadpixel 118 273 name] != "GRAY16 0.5058823823928833" || [vreadpixel 270 260 name] != "GRAY76 0.63921570777893066"} {
+  puts "ERROR: Errors in changing View Cube separate transparency."
+}
+vdump $anImage3
+
+# -------------------------------------
+# Arrows
+# -------------------------------------
+vviewcube -reset
+vviewcube -arrowangle 30 -arrowlength 30
+if {[vreadpixel 270 268 name] != "BLACK 0" || [vreadpixel 291 259 name] != "GRAY48 0.24705882370471954"} {
+  puts "ERROR: Errors in changing View Cube arrow style."
+}
+vdump $anImage4
+
+# -------------------------------------
+# Font
+# -------------------------------------
+vviewcube -reset
+vviewcube -font "Impact" -fontheight 16
+if {[vreadpixel 150 200 name] != "BLACK 0.729411780834198" || [vreadpixel 168 391 name] != "RED 1"} {
+  puts "ERROR: Errors in changing View Cube font."
+}
+vdump $anImage5
+# -------------------------------------
+# Padding
+# -------------------------------------
+vviewcube -reset
+vviewcube -boxpadding 10 -axispadding 20 -arrowpadding 10
+if {[vreadpixel 71 263 name] != "BLACK 0" || [vreadpixel 37 266 name] != "BLUE2 1"} {
+  puts "ERROR: Errors in changing View Cube padding."
+}
+vdump $anImage6
+# -------------------------------------
+# Corner radius
+# -------------------------------------
+vviewcube -reset
+vviewcube -cornerradius 0.2
+vdump $anImage7
+
+vviewcube -remove
+vclear
+
+
+
+
+
+
diff --git a/tests/v3d/viewcube/view b/tests/v3d/viewcube/view
new file mode 100644 (file)
index 0000000..c978565
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=================================="
+puts "AIS_ViewCube - check view affinity"
+puts "=================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+
+vclear
+vclose ALL
+vinit view1
+vinit view2
+
+vviewcube -enable
+
+if {[vreadpixel 150 220 name] != "GRAY68 1"} {
+  puts "ERROR: display of View Cube in view2 fails."
+}
+vdump $anImage1
+
+vactivate view1
+
+if {[vreadpixel 150 220 name] != "BLACK 0"} {
+  puts "ERROR: View Cube should not be displayed in view1."
+}
+vdump $anImage2
+
+vactivate view2
+vviewcube -remove
\ No newline at end of file
diff --git a/tests/v3d/viewcube/view2 b/tests/v3d/viewcube/view2
new file mode 100644 (file)
index 0000000..27c277f
--- /dev/null
@@ -0,0 +1,25 @@
+puts "=================================="
+puts "AIS_ViewCube - check view affinity"
+puts "=================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+
+vclear
+vclose ALL
+vinit view1
+
+vviewcube -enable
+if {[vreadpixel 150 220 name] != "GRAY68 1"} {
+  puts "ERROR: display of View Cube in view1 fails."
+}
+vdump $anImage1
+vviewcube -remove
+
+vinit view2
+vviewcube -enable
+if {[vreadpixel 150 220 name] != "GRAY68 1"} {
+  puts "ERROR: View Cube should not be displayed in view1."
+}
+vdump $anImage2
+vviewcube -remove
\ No newline at end of file