diff --git a/src/AIS/AIS_ViewCube.cxx b/src/AIS/AIS_ViewCube.cxx new file mode 100644 index 0000000000..1f45ac2813 --- /dev/null +++ b/src/AIS/AIS_ViewCube.cxx @@ -0,0 +1,2076 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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.SetReflectionModeOff (Graphic3d_TOR_SPECULAR); + aShadingMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT); + 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->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); + + if (myPosition & Aspect_TOTP_CENTER) + { + return Graphic3d_Vec2i (aWidth / 2, aHeight / 2); + } + + Graphic3d_Vec2i aPosition; + 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) 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); + + // Set view affinity for child object + Handle(Graphic3d_ViewAffinity) anAffinity = GetContext()->CurrentViewer()->StructureManager()->RegisterObject (myFlatPart); + anAffinity->SetVisible (Standard_False); + + // View Affinity should be applied after Display + for (V3d_ListOfViewIterator aViewIter (theContext->CurrentViewer()->DefinedViewIterator()); aViewIter.More(); aViewIter.Next()) + { + theContext->SetViewAffinity (this, aViewIter.Value(), Standard_False); + aViewIter.Value()->View()->ChangeHiddenObjects()->Add (myFlatPart.get()); + + } + theContext->SetViewAffinity (this, theView, Standard_True); + anAffinity->SetVisible (theView->View()->Identification(), Standard_True); + theView->View()->ChangeHiddenObjects()->Remove (myFlatPart.get()); +} + +//======================================================================= +//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; + } + + 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& aTris = Triangulations(); + for (NCollection_Sequence::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.01))); + + 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& aTris = aPart->Triangulations(); + for (NCollection_Sequence::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 index 0000000000..78bc6747e1 --- /dev/null +++ b/src/AIS/AIS_ViewCube.hxx @@ -0,0 +1,1044 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +//! @code +//! aView->SetView (aView); +//! aContext->Display (aViewCube, 0, 0, Standard_False); +//! @endcode +//! But View Affinity should be taken into account here also. +//! 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. +//! +//! @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); + + //! 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(); + + Standard_EXPORT void setDefaultHighlightAttributes(); + +public: //! @name Geometry management API + + Standard_EXPORT void Position (Aspect_TypeOfTriedronPosition& thePosition, + Graphic3d_Vec2i& theOffset); + + 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& 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 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.0f); + + //! 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 + MapOfOwnerCameraState; + + typedef NCollection_IndexedDataMap + 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 diff --git a/src/AIS/FILES b/src/AIS/FILES index e424026e96..3a571058e6 100644 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -180,3 +180,5 @@ AIS_TypeOfAxis.hxx AIS_TypeOfDist.hxx AIS_TypeOfIso.hxx AIS_TypeOfPlane.hxx +AIS_ViewCube.hxx +AIS_ViewCube.cxx diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 8d59c8f4d1..60fdebe073 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -233,6 +234,25 @@ Standard_EXPORT Handle(AIS_Manipulator) GetActiveAISManipulator() return NULL; } +typedef NCollection_DataMap 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 @@ -11486,6 +11506,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 : @@ -12181,4 +12410,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 index 0000000000..f1ddd2f9fe --- /dev/null +++ b/tests/v3d/viewcube/default @@ -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 index 0000000000..f3f5a13d97 --- /dev/null +++ b/tests/v3d/viewcube/move @@ -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 index 0000000000..d94673598a --- /dev/null +++ b/tests/v3d/viewcube/part @@ -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 1"} { + 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 1" || [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 index 0000000000..46c5db999b --- /dev/null +++ b/tests/v3d/viewcube/style @@ -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.24705882352941178"} { + puts "ERROR: Errors in changing View Cube colors." +} +vdump $anImage1 + +# ------------------------------------- +# Transparency +# ------------------------------------- +vviewcube -reset +vviewcube -transparency 0.5 +if {[vreadpixel 118 273 name] != "GRAY17 0.37254901960784315" || [vreadpixel 270 260 name] != "GRAY48 0.24705882352941178"} { + 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.50588235294117645" || [vreadpixel 270 260 name] != "GRAY76 0.63921568627450975"} { + 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.24705882352941178"} { + puts "ERROR: Errors in changing View Cube arrow style." +} +vdump $anImage4 + +# ------------------------------------- +# Font +# ------------------------------------- +vviewcube -reset +vviewcube -font "Impact" -fontheight 16 +if {[vreadpixel 151 198 name] != "BLACK 1" || [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 + + + + + +