From: apl Date: Mon, 26 Sep 2016 17:01:28 +0000 (+0300) Subject: Annotation presentation + Displayer code X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d9b3ca3f0ca2b798cfd9b9e1bf209dbef442e138;p=modules%2Fgeom.git Annotation presentation + Displayer code --- diff --git a/src/GEOMGUI/GEOM_Displayer.cxx b/src/GEOMGUI/GEOM_Displayer.cxx old mode 100644 new mode 100755 index 3ed44e128..65a75bb13 --- a/src/GEOMGUI/GEOM_Displayer.cxx +++ b/src/GEOMGUI/GEOM_Displayer.cxx @@ -1359,6 +1359,106 @@ void GEOM_Displayer::updateDimensions( const Handle(SALOME_InteractiveObject)& t } } +//================================================================= +/*! + * GEOM_Displayer::updateShapeAnnotations + * Creates or renews shape annotation presentation for the IO. + */ +//================================================================= +void GEOM_Displayer::updateShapeAnnotations( const Handle(SALOME_InteractiveObject)& theIO, + SALOME_OCCPrs* thePrs, + const gp_Ax3& theShapeLCS ) +{ + SalomeApp_Study* aStudy = getStudy(); + if ( !aStudy ) + { + return; + } + + if ( theIO.IsNull() ) + { + return; + } + + SOCC_Prs* anOccPrs = dynamic_cast( thePrs ); + AIS_ListOfInteractive aListOfIO; + anOccPrs->GetObjects( aListOfIO ); + AIS_ListIteratorOfListOfInteractive aIterateIO( aListOfIO ); + + // remove existing presentations of shape annotations + for ( ; aIterateIO.More(); aIterateIO.Next() ) + { + const Handle(AIS_InteractiveObject)& anIO = aIterateIO.Value(); + if ( !anIO->IsKind( STANDARD_TYPE( GEOM_Annotation ) ) ) + continue; + + aListOfIO.Remove( aIterateIO ); + if ( !aIterateIO.More() ) + break; + } + + // read annotation preferences + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + + QColor aQColor = aResMgr->colorValue ( "Geometry", "shape_annotation_color", QColor( 0, 0, 0 ) ); + int aLineWidth = aResMgr->integerValue( "Geometry", "shape_annotation_line_width", 1 ); + QFont aFont = aResMgr->fontValue ( "Geometry", "shape_annotation_font", QFont("Arial", 14) ); + bool aAutoHide = aResMgr->fontValue ( "Geometry", "shape_annotation_autohide", true ); + + // create shape annotations using data from the attribute of a study + QVariant aProperty = aStudy->getObjectProperty( GEOM::sharedPropertiesId(), + theIO->getEntry(), + GEOM::propertyName( GEOM::ShapeAnnotations ), + QVariant() ); + + GEOMGUI_ShapeAnnotationProperty aStudyAnnotations; + + if ( aProperty.isValid() && aProperty.canConvert() ) + { + aStudyAnnotations = aProperty.value(); + } + else + { + aStudyAnnotations.LoadFromAttribute( getStudy(), theIO->getEntry() ); + } + + // create up-to-date shape annotation presentations + for ( int aPrsIt = 0; aPrsIt < aStudyAnnotations.GetNumber(); ++aPrsIt ) + { + if ( !aStudyAnnotations.IsVisible( aPrsIt ) ) + { + continue; + } + + Handle(GEOM_Annotation) aPrs = new GEOM_Annotation(); + + aStudyAnnotations.GetRecord( aPrsIt )->Update( aPrs ); + + gp_Trsf aToLCS; + aToLCS.SetTransformation( theLCS, gp_Ax3() ); + aPrs->SetLocalTransformation( aToLCS ); + aPrs->SetOwner( theIO ); + + Quantity_Color aColor( aQColor.redF(), aQColor.greenF(), aQColor.blueF(), Quantity_TOC_RGB ); + + Standard_Real aFontHeight = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize(); + aPrs->SetColor( aColor ); + aPrs->SetTextHeight( aFontHeight ); + aPrs->SetFont( aFont.family().toLatin1().data() ); + aPrs->SetLineWidth( aLineWidth ); + + aListOfIO.Append( aPrs ); + } + + // update presentation + anOccPrs->Clear(); + + for ( aIterateIO.Initialize( aListOfIO ); aIterateIO.More(); aIterateIO.Next() ) + { + anOccPrs->AddObject( aIterateIO.Value() ); + } +} + //================================================================= /*! * GEOM_Displayer::Erase @@ -1549,6 +1649,7 @@ void GEOM_Displayer::Update( SALOME_OCCPrs* prs ) } updateDimensions( myIO, occPrs, gp_Ax3().Transformed( myShape.Location().Transformation() ) ); + updateAnnotations( myIO, occPrs, gp_Ax3().Transformed( myShape.Location().Transformation() ) ); } } diff --git a/src/GEOMGUI/GEOM_Displayer.h b/src/GEOMGUI/GEOM_Displayer.h old mode 100644 new mode 100755 index cf5a9df55..1ae652870 --- a/src/GEOMGUI/GEOM_Displayer.h +++ b/src/GEOMGUI/GEOM_Displayer.h @@ -263,6 +263,7 @@ protected: void updateShapeProperties( const Handle(GEOM_AISShape)&, bool ); void updateActorProperties( GEOM_Actor*, bool ); void updateDimensions( const Handle(SALOME_InteractiveObject)&, SALOME_OCCPrs*, const gp_Ax3& ); + void updateShapeAnnotations( const Handle(SALOME_InteractiveObject)&, SALOME_OCCPrs*, const gp_Ax3& ); PropMap getObjectProperties( SalomeApp_Study*, const QString&, SALOME_View* = 0 ); PropMap getDefaultPropertyMap(); diff --git a/src/OBJECT/CMakeLists.txt b/src/OBJECT/CMakeLists.txt index 900552cb6..2bc3e3f81 100755 --- a/src/OBJECT/CMakeLists.txt +++ b/src/OBJECT/CMakeLists.txt @@ -76,6 +76,7 @@ SET(OBJECT_HEADERS GEOM_DeviceActor.h GEOM_Constants.h GEOM_AISDimension.hxx + GEOM_Annotation.hxx ) # --- sources --- @@ -93,6 +94,7 @@ SET(OBJECT_SOURCES GEOM_DeviceActor.cxx GEOM_Constants.cxx GEOM_AISDimension.cxx + GEOM_Annotation.cxx ) # --- rules --- diff --git a/src/OBJECT/GEOM_Annotation.cxx b/src/OBJECT/GEOM_Annotation.cxx new file mode 100755 index 000000000..9eddb7cf6 --- /dev/null +++ b/src/OBJECT/GEOM_Annotation.cxx @@ -0,0 +1,426 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GEOM OBJECT : interactive object for Geometry entities visualization +// File : GEOM_Annotation.hxx +// Module : GEOM +// +#include + +// OCCT includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT (GEOM_Annotation, AIS_InteractiveObject) + +// ======================================================================= +// function : Constructor +// purpose : +// ======================================================================= +GEOM_Annotation::GEOM_Annotation() : AIS_InteractiveObject() +{ + SetPosition (gp_Pnt (0.0, 0.0, 0.0)); + SetScreenFixed (Standard_False); + SetAttachPoint (gp_Pnt (0.0, 0.0, 0.0)); + SetDisplayMode (0); + SetZLayer (Graphic3d_ZLayerId_Top); + SetAutoHide (Standard_True); + SetHilightMode (HighlightAll); + + Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect(); + aTextAspect->SetHeight (20.0); + aTextAspect->SetColor (Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB)); + myDrawer->SetTextAspect (aTextAspect); + + Handle(Prs3d_LineAspect) aLineAspect = + new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0); + myDrawer->SetLineAspect (aLineAspect); +} + +// ======================================================================= +// function : SetText +// purpose : +// ======================================================================= +void GEOM_Annotation::SetText (const TCollection_ExtendedString& theText) +{ + if (myText != theText) + SetToUpdate(); + + myText = theText; +} + +// ======================================================================= +// function : SetPosition +// purpose : +// ======================================================================= +void GEOM_Annotation::SetPosition (const gp_Pnt& thePosition) +{ + myPosition = thePosition; + + AIS_InteractiveObject::SetTransformPersistence (Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers, thePosition); +} + +// ======================================================================= +// function : SetScreenFixed +// purpose : +// ======================================================================= +void GEOM_Annotation::SetScreenFixed (const Standard_Boolean theIsFixed) +{ + myIsScreenFixed = theIsFixed; +} + +// ======================================================================= +// function : SetAttachPoint +// purpose : +// ======================================================================= +void GEOM_Annotation::SetAttachPoint (const gp_Pnt& thePoint) +{ + myAttach = thePoint; +} + +// ======================================================================= +// function : SetColor +// purpose : +// ======================================================================= +void GEOM_Annotation::SetColor (const Quantity_Color& theColor) +{ + myDrawer->TextAspect()->SetColor (theColor); + myDrawer->LineAspect()->SetColor (theColor); + AIS_InteractiveObject::SetColor (theColor); +} + +// ======================================================================= +// function : SetTextHeight +// purpose : +// ======================================================================= +void GEOM_Annotation::SetTextHeight (const Standard_Real theHeight) +{ + if (GetTextHeight() != theHeight) + { + myDrawer->TextAspect()->SetHeight (theHeight); + SetToUpdate (); + } +} + +// ======================================================================= +// function : SetFontAspect +// purpose : +// ======================================================================= +void GEOM_Annotation::SetFontAspect (const Font_FontAspect theFontAspect) +{ + if (GetFontAspect() != theFontAspect) + { + myDrawer->TextAspect()->Aspect()->SetTextFontAspect (theFontAspect); + SetToUpdate(); + } +} + +// ======================================================================= +// function : SetFont +// purpose : +// ======================================================================= +void GEOM_Annotation::SetFont (const TCollection_AsciiString& theFont) +{ + if (GetFont() != theFont) + { + myDrawer->TextAspect()->Aspect()->SetFont (theFont); + SetToUpdate(); + } +} + +// ======================================================================= +// function : SetLineWidth +// purpose : +// ======================================================================= +void GEOM_Annotation::SetLineWidth (const Standard_Real theLineWidth) +{ + myDrawer->LineAspect()->SetWidth (theLineWidth); +} + +// ======================================================================= +// function : Compute +// purpose : +// ======================================================================= +void GEOM_Annotation::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode) +{ + thePresentation->Clear(); + + if (theMode < 0) + { + return; + } + + Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast (Prs3d_Root::NewGroup (thePresentation)); + if (aGroup.IsNull()) + { + return; + } + + Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect(); + NCollection_String aUtfText (myText.ToExtString()); + OpenGl_Annotation* aAnnotationDraw = + new OpenGl_Annotation (this, static_cast(anAsp->Height()), aGroup->GlStruct()->GlDriver()); + + aGroup->AddElement (aAnnotationDraw); + aGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect()); + aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect()); + + NCollection_Handle aBoundingBox = TextBoundingBox(); + gp_Pnt aBoxMin = aBoundingBox->CornerMin(); + gp_Pnt aBoxMax = aBoundingBox->CornerMax(); + aGroup->ChangeBoundingBox() = Graphic3d_BndBox4f ( + Graphic3d_Vec4 (static_cast (aBoxMin.X()), + static_cast (aBoxMin.Y()), + static_cast (aBoxMin.Z()), 1.0F), + Graphic3d_Vec4 (static_cast (aBoxMax.X()), + static_cast (aBoxMax.Y()), + static_cast (aBoxMax.Z()), 1.0F)); +} + +// ======================================================================= +// function : ComputeSelection +// purpose : +// ======================================================================= +void GEOM_Annotation::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, + const Standard_Integer theMode) +{ + if (theMode != 0) + { + return; + } + + theSelection->Clear(); + + NCollection_Handle aBoundingBox = TextBoundingBox(); + Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 10); + Handle(Select3D_SensitiveBox) aSensitive = new Select3D_SensitiveBox (anEntityOwner, *aBoundingBox.get()); + theSelection->Add (aSensitive); +} + +// ======================================================================= +// function : TextBoundingBox +// purpose : +// ======================================================================= +NCollection_Handle GEOM_Annotation::TextBoundingBox() const +{ + Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect(); + Bnd_Box aBox; + Font_FTFont aFont; + unsigned int aResolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution; + if (aFont.Init (anAsp->Aspect()->Font().ToCString(), + anAsp->Aspect()->GetTextFontAspect(), (unsigned int)anAsp->Height(), aResolution)) + { + const NCollection_String aText ((Standard_Utf16Char* )myText.ToExtString()); + Font_Rect aFontRect = aFont.BoundingBox (aText, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM); + NCollection_Handle aBox = new Bnd_Box(); + aBox->Add (gp_Pnt (0.0, 0.0, 0.0)); + aBox->Add (gp_Pnt (aFontRect.Width(), aFontRect.Height(), 0.0)); + return aBox; + } + + return NCollection_Handle(); +} + +// ======================================================================= +// subclass : OpenGl_Annotation +// function : Constructor +// purpose : +// ======================================================================= +GEOM_Annotation::OpenGl_Annotation::OpenGl_Annotation (GEOM_Annotation* theAnnotation, + const Standard_Integer theTextHeight, + const OpenGl_GraphicDriver* theDriver) +: OpenGl_Element(), + myAISObject (theAnnotation), + myText (theAnnotation->myText.ToExtString()), + myTextLineY (0.f), + myTextDPI (0) +{ + // graphical resources for drawing text and underline + myTextParams.Height = theTextHeight; + myTextParams.HAlign = Graphic3d_HTA_LEFT; + myTextParams.VAlign = Graphic3d_VTA_BOTTOM; + myTextDraw = new OpenGl_Text (myText.ToCString(), OpenGl_Vec3(), myTextParams); + myTextLineDraw = new OpenGl_PrimitiveArray (theDriver); + + // graphical resources for drawing extension line and marker + Handle(Graphic3d_ArrayOfSegments) + aExtVertexArray = new Graphic3d_ArrayOfSegments(2); + aExtVertexArray->AddVertex (0.0, 0.0, 0.0); + aExtVertexArray->AddVertex (0.0, 0.0, 1.0); + myExtLineDraw = new OpenGl_PrimitiveArray (theDriver, Graphic3d_TOPA_SEGMENTS, + aExtVertexArray->Indices(), aExtVertexArray->Attributes(), aExtVertexArray->Bounds()); + + Handle(Graphic3d_ArrayOfPoints) + aExtMakerArray = new Graphic3d_ArrayOfPoints(1); + aExtMakerArray->AddVertex (0.0, 0.0, 1.0); + myExtMarkerDraw = new OpenGl_PrimitiveArray (theDriver, Graphic3d_TOPA_POINTS, + aExtMakerArray->Indices(), aExtMakerArray->Attributes(), aExtMakerArray->Bounds()); +} + +// ======================================================================= +// subclass : OpenGl_Annotation +// function : Destructor +// purpose : +// ======================================================================= +GEOM_Annotation::OpenGl_Annotation::~OpenGl_Annotation() +{ + Release (NULL); +} + +// ======================================================================= +// subclass : OpenGl_Annotation +// function : Release +// purpose : Releases GL resources with the given GL context. +// ======================================================================= +void GEOM_Annotation::OpenGl_Annotation::Release (OpenGl_Context* theCtx) +{ + if (myTextDraw) + { + myTextDraw->Release (theCtx); + myTextLineDraw->Release (theCtx); + myExtLineDraw->Release (theCtx); + myExtMarkerDraw->Release (theCtx); + } + myTextDraw = NULL; + myTextLineDraw = NULL; + myExtLineDraw = NULL; + myExtMarkerDraw = NULL; +} + +// ======================================================================= +// subclass : OpenGl_Annotation +// function : Render +// purpose : Renders the annotation graphical elements. +// ======================================================================= +void GEOM_Annotation::OpenGl_Annotation::Render (const Handle(OpenGl_Workspace)& theWorkspace) const +{ + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + + // --------------------------------------------------------------------- + // initialize text's font and configure some properties when DPI changes + // --------------------------------------------------------------------- + const unsigned int aDPI = theWorkspace->View()->RenderingParams().Resolution; + if (myTextDPI != aDPI) + { + const OpenGl_AspectText* anAspect = theWorkspace->AspectText(); + + // getting string size will also initialize font library + Standard_ShortReal aWidth, aHeight, aDescent; + myTextDraw->StringSize (aContext, myText, *anAspect, myTextParams, aDPI, aWidth, aHeight, aDescent); + myTextDPI = aDPI; + myTextLineY = ceil (aHeight * -0.2f); + + Handle(Graphic3d_ArrayOfSegments) + aVertexArray = new Graphic3d_ArrayOfSegments (2); + aVertexArray->AddVertex (0.0f, myTextLineY, 0.0f); + aVertexArray->AddVertex (aWidth, myTextLineY, 0.0f); + myTextLineDraw->InitBuffers (aContext, Graphic3d_TOPA_SEGMENTS, + aVertexArray->Indices(), aVertexArray->Attributes(), aVertexArray->Bounds()); + } + + // --------------------------------------------- + // perform view culling test by attachment point + // --------------------------------------------- + const OpenGl_Vec4 aAttach (static_cast(myAISObject->myAttach.X()), + static_cast(myAISObject->myAttach.Y()), + static_cast(myAISObject->myAttach.Z()), 1.F); + + const Handle(Graphic3d_Camera) aCamera = theWorkspace->View()->Camera(); + const OpenGl_Mat4& aCameraProjMat = aCamera->ProjectionMatrixF(); + const OpenGl_Mat4& aCameraViewMat = aCamera->OrientationMatrixF(); + const OpenGl_Vec4 aAttachView = aCameraViewMat * aAttach; + if (myAISObject->myIsAutoHide) + { + const OpenGl_Vec4 aAttachClip = aCameraProjMat * aAttachView; + if (abs (aAttachClip.x()) > aAttachClip.w() + || abs (aAttachClip.y()) > aAttachClip.w() + || abs (aAttachClip.z()) > aAttachClip.w()) + { + return; + } + } + + // ------------------------------------------------------------- + // render text label in current persistence matrix and underline + // ------------------------------------------------------------- + myTextDraw->Render (theWorkspace); + + // ---------------------------------------------- + // render underline in current persistence matrix + // ---------------------------------------------- + const bool toHighlight = theWorkspace->ToHighlight(); + if (toHighlight && myAISObject->myHilightMode == HighlightLabel) + { + theWorkspace->SetHighlight (false); + theWorkspace->ApplyAspectLine(); + } + myTextLineDraw->Render (theWorkspace); + + // ------------------------------------------------------------ + // render dynamic extension line using synthetic transformation + // ------------------------------------------------------------ + const OpenGl_Mat4& aViewMat = aContext->WorldViewState.Current(); + const OpenGl_Vec4 aHingeView = aViewMat * OpenGl_Vec4 (0.0f, myTextLineY, 0.0f, 1.0f); + + // prepare matrix to specify geometry of extension line in view space + // by multiplication of unit z coordinate vector on given matrix. + OpenGl_Mat4 aExtGeometryMat; + aExtGeometryMat.SetColumn (2, aAttachView - aHingeView); + aExtGeometryMat.SetColumn (3, aHingeView); + + aContext->ModelWorldState.Push(); + aContext->ModelWorldState.SetIdentity(); + aContext->WorldViewState.Push(); + aContext->WorldViewState.SetCurrent (aExtGeometryMat); + aContext->ApplyModelViewMatrix(); + + myExtLineDraw->Render (theWorkspace); + myExtMarkerDraw->Render (theWorkspace); + + aContext->ModelWorldState.Pop(); + aContext->WorldViewState.Pop(); + aContext->ApplyModelViewMatrix(); + + if (toHighlight != theWorkspace->ToHighlight()) + { + theWorkspace->SetHighlight (toHighlight); + } +} diff --git a/src/OBJECT/GEOM_Annotation.hxx b/src/OBJECT/GEOM_Annotation.hxx new file mode 100755 index 000000000..ddeafd98c --- /dev/null +++ b/src/OBJECT/GEOM_Annotation.hxx @@ -0,0 +1,226 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// GEOM OBJECT : interactive object for Geometry entities visualization +// File : GEOM_Annotation.hxx +// Module : GEOM +// +#ifndef GEOM_Annotation_HeaderFile +#define GEOM_Annotation_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + * \class GEOM_Annotation + * \brief Interactive object, representating annotation entity + */ +class GEOM_Annotation : public AIS_InteractiveObject +{ +public: + + DEFINE_STANDARD_RTTIEXT (GEOM_Annotation, AIS_InteractiveObject) + + //! Enumerates supported highlighting modes. + //! - HighlightAll : all elements of the annotation are highlighted. + //! - HighlightLabel : only annotation label is highlighted. + enum HighlightMode + { + HighlightAll = 0, + HighlightLabel = 1 + }; + +public: + + //! Constructor. + Standard_EXPORT GEOM_Annotation(); + + //! Destructor. + virtual ~GEOM_Annotation() {} + + //! Sets annotation text string. + //! \param theText [in] the string displayed in annotation label. + Standard_EXPORT void SetText (const TCollection_ExtendedString& theText); + + //! Returns annotation text string. + const TCollection_ExtendedString& GetText() const { return myText; } + + //! Sets position of the annotation text label. + //! \param thePosition [in] the cartesian point defining the position of lower left + //! corner of the text label. When displayed in fixed screen position mode + //! (\sa SetScreenFixed) the position is defined as {x,y} pixel coordinate + //! of window space, otherwise 3D point defined in world's coordinate system + //! is used. + Standard_EXPORT void SetPosition (const gp_Pnt& thePosition); + + //! Returns position of the annotation text label. + const gp_Pnt& GetPosition() const { return myPosition; } + + //! Sets or disables "2D screen fixed" positioning mode. In this mode the annotation + //! is fixed at predefined pixel location in the window coordinate space. Other mode + //! is "3D screen aligned" positioning, when the label is aligned in plane of the + //! screen, while its position is a 3D point defined in world's coordinate system. + Standard_EXPORT void SetScreenFixed (const Standard_Boolean theIsFixed); + + //! Retuns value of "screen fixed" positioning mode. + Standard_Boolean GetIsScreenFixed() const { return myIsScreenFixed; } + + //! Sets attachment point of extension line. + //! \param thePoint [in] the 3D cartesian point defined in world's coordinate system + //! (a point on annotated geometry). + Standard_EXPORT void SetAttachPoint (const gp_Pnt& thePoint); + + //! Returns attachment point of extension line. + const gp_Pnt& GetAttachPoint() const { return myAttach; } + +public: + + //! Sets color for the presentation. + Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE; + + //! Returns color for the text's label. + Quantity_Color GetColor() const { return myDrawer->TextAspect()->Aspect()->Color(); } + + //! Sets text height in pixels. + Standard_EXPORT void SetTextHeight (const Standard_Real theHeight); + + //! Returns text's height in pixels. + Standard_Real GetTextHeight() const { return myDrawer->TextAspect()->Height(); } + + //! Sets font aspect for label. + Standard_EXPORT void SetFontAspect (const Font_FontAspect theFontAspect); + + //! Returns label's font aspect. + Font_FontAspect GetFontAspect() const { return myDrawer->TextAspect()->Aspect()->GetTextFontAspect(); } + + //! Sets font used for drawing the label. + Standard_EXPORT void SetFont (const TCollection_AsciiString& theFont); + + //! Returns font used for drawing the label. + TCollection_AsciiString GetFont() const { return myDrawer->TextAspect()->Aspect()->Font(); } + + //! Sets line width to be used for drawing the annotation's extension line and underline. + Standard_EXPORT void SetLineWidth (const Standard_Real theLineWidth); + + //! Returns line width for drawing the annotation's extension line and underline. + Standard_Real LineWidth() const { return myDrawer->LineAspect()->Aspect()->Width(); } + + //! Sets annotation auto-hiding option. + //! \param theIsEnable [in] the option flag. If passed true, the annotation + //! will be automatically hidden in the view if the attachment point + //! goes outside of the view. + void SetAutoHide (const Standard_Boolean theIsEnable) { myIsAutoHide = theIsEnable; } + + //! Returns current state of the auto-hiding option. + Standard_Boolean GetAutoHide() const { return myIsAutoHide; } + + //! Sets highlight mode used for display of presentation. + //! \param theMode [in] the one of the supported highlight modes. + void SetHighlightMode (const HighlightMode theMode) { myHilightMode = theMode; } + + //! Returns highlight mode + HighlightMode GetHilightMode() const { return myHilightMode; } + +private: + + Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode = 0) Standard_OVERRIDE; + + Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, + const Standard_Integer theMode) Standard_OVERRIDE; + + virtual void SetLocalTransformation (const gp_Trsf& theTransformation) Standard_OVERRIDE {} + + virtual void SetTransformPersistence (const Graphic3d_TransModeFlags& theFlag, + const gp_Pnt& thePoint = gp_Pnt (0.0, 0.0, 0.0)) Standard_OVERRIDE {} + + NCollection_Handle TextBoundingBox() const; + +private: + + gp_Pnt myAttach; //!< Attachment point of extension line. + gp_Pnt myPosition; //!< Position of text label. + Standard_Boolean myIsScreenFixed; //!< Flag indicating whether "screen fixed" positioning mode is turned on or off. + Standard_Boolean myIsAutoHide; //!< Flag indicating whether "auto-hiding" option is turned on. + HighlightMode myHilightMode; //!< Highlight mode for presentation. + TCollection_ExtendedString myText; //!< Text string of the label presentation. + +private: + + //! Custom element implementing dynamic rendering of 3D annotation + //! and invoking dynamic callback in presentation class. + class OpenGl_Annotation : public OpenGl_Element + { + public: + + //! Constructor. Some of the input properties are assigned by reference for dynamic draw + //! (it is not likely that GL element will ever outlive the interactive object). + //! \param theAnnotation [in] the instance of interactive presentation class. + //! \param theTextHeight [in] the height of the text label. + //! \param theDriver [in] the instance of graphical driver required for initialization. + OpenGl_Annotation (GEOM_Annotation* theAnnotation, + const Standard_Integer theTextHeight, + const OpenGl_GraphicDriver* theDriver); + + //! Destructor. Releases GL resources with NULL context. + virtual ~OpenGl_Annotation(); + + //! Releases GL resources with the given GL context. + virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE; + + //! Renders the annotation graphical elements. + virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const Standard_OVERRIDE; + + private: + + GEOM_Annotation* myAISObject; //!< Instance of presentation class. + NCollection_String myText; //!< Text string of annotation label. + OpenGl_TextParam myTextParams; //!< Text draw parameters. + OpenGl_Text* myTextDraw; //!< Text draw element. + OpenGl_PrimitiveArray* myTextLineDraw; //!< Text underline draw element. + OpenGl_PrimitiveArray* myExtLineDraw; //!< Extension line draw element. + OpenGl_PrimitiveArray* myExtMarkerDraw; //!< Extension marker draw element. + mutable float myTextLineY; //!< Text's underlines relative position. + mutable unsigned int myTextDPI; //!< Text's DPI scale used for last rendering. + }; + + friend class OpenGl_Annotation; // allow opengl element to get private data and invoke callback methods +}; + +DEFINE_STANDARD_HANDLE (GEOM_Annotation, AIS_InteractiveObject) + +#endif