]> 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>
Thu, 27 Sep 2018 14:32:03 +0000 (17:32 +0300)
Added new class AIS_ViewCube implementing interactive cube displaying orientation of the main axes of the model space in the viewer.
Each side, edge, or corner of the cube corresponds to particular orientation of the camera, and the class provides methods to move the camera to corresponding position (with animation if needed).

DRAW command vviewcube is added to use the cube in DRAW.

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..fb6b907
--- /dev/null
@@ -0,0 +1,2104 @@
+// 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());
+  Standard_Integer anIt = 1;
+  for (; anIt < SIDE_INDEX; anIt++)
+  {
+    Handle(Side) aPart = Handle(Side)::DownCast (myParts.ChangeFromIndex (anIt));
+    aPart->Display (thePrsMgr, aGroup, 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->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
+    {
+      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(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 (theGroup, 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..d8ccd82
--- /dev/null
@@ -0,0 +1,1059 @@
+// 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(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 57ad7727739b541cc9bfe2440d6bf82e66c94f6b..c7d6cca95f4a4e57d82079b1cbe914e93944901d 100644 (file)
@@ -172,3 +172,5 @@ AIS_TypeOfAxis.hxx
 AIS_TypeOfDist.hxx
 AIS_TypeOfIso.hxx
 AIS_TypeOfPlane.hxx
+AIS_ViewCube.hxx
+AIS_ViewCube.cxx
index f063bbf5326a922a22c45f42dfa131c000106da3..16777c848771adca3f7f634b0a88994fa7705da8 100644 (file)
@@ -26,6 +26,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>
@@ -286,6 +287,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
@@ -11859,6 +11879,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.AddDescription ("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  :
@@ -12557,4 +12786,39 @@ 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