diff --git a/doc/salome/gui/GEOM/images/annotation.png b/doc/salome/gui/GEOM/images/annotation.png
new file mode 100644
index 000000000..584104fc3
Binary files /dev/null and b/doc/salome/gui/GEOM/images/annotation.png differ
diff --git a/doc/salome/gui/GEOM/images/annotation_preview.png b/doc/salome/gui/GEOM/images/annotation_preview.png
new file mode 100644
index 000000000..0cb50206d
Binary files /dev/null and b/doc/salome/gui/GEOM/images/annotation_preview.png differ
diff --git a/doc/salome/gui/GEOM/input/annotation.doc b/doc/salome/gui/GEOM/input/annotation.doc
new file mode 100644
index 000000000..f1368188d
--- /dev/null
+++ b/doc/salome/gui/GEOM/input/annotation.doc
@@ -0,0 +1,48 @@
+/*!
+
+\page annotation_page Shape annotation
+
+ Annotation functionality allows showing in the viewer special user-defined text label connected to corresponding part of a CAD model with a line.
+
+\image html annotation_preview.png
+
+Shape annotation behavior are summarized below:
+
+ - Annotation text is always parallel to the screen and horizontal.
+ - Annotation text is not zoomed or rotated when a 3D scene is zoomed or rotated by the user.
+ - The user is able to modify the font, the style, the color and the size of the annotation text and the color, the width and the style of the connection line applied to all annotations.
+It can be accessed from the main menu via File -> Preferences. The Shape annotations group on Geometry Settings pane contains controls for it.
+
+ - The annotation text is defined using UTF-8 encoding and thus support any Unicode characters.
+ - Position of an annotation in a 3D view is defined by dragging it with the mouse.
+ - There are several algorithms for the annotation position calculation during the scene manipulations (panning, zooming, rotation):
+
+ - Algorithm 1: an annotation has fixed position in 2D screen coordinates (fixed screen position mode). In this mode, the annotations are always visible (appear as “topmost objects”), never hidden by the (annotated) geometry.
+ - Algorithm 2: an annotation has fixed position in 3D model space, this position is projected onto the screen just as normal point coordinates. In this mode, some annotations may be invisible depending on the camera (position, orientation, zoom).
+
+ - Annotations appear in an Annotations sub-tree in Text Browser.
+ - All annotations may be shown/hidden in a 3D view using corresponded popup menu on Annotations item in Text Browser.
+ - Annotations of a shape may be shown/hidden in a 3D view using corresponded popup menu on the shape item in Object Browser.
+ - Annotation is logically connected to the shape:
+
+ - Selection of an annotation will highlight corresponding shape/subshape in 3D view.
+ - When the shape is deleted, the annotation will be also deleted.
+
+
+
+It can be accessed from the main menu via Inspection -> Annotation
+
+\image html annotation.png "Create Annotation dialog"
+
+In this dialog you can:
+
+ - Set Text text shown in View 3d and a name of annotation presented in the Text Browser.
+ - Select a \b Shape to which the annotation will be assigned.
+ - Set Fixed screen position to select alogithm for the annotation position caldulation.
+ - Select a Shape Type to which the annotation will be assigned on the shape.
+ It contains "Whole shape", "Vertex", "Edge", "Face" and "Solid" choices.
+ - Select a sub shape to assign annotation to. Text control contains information about local selection in the viewer.
+ - Push \b Apply or Apply and Close button to commit creation of the field.
-
+
+
+*/
diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
index 515a94ce4..feca9e24f 100644
--- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc
+++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
@@ -17,6 +17,7 @@
\subpage angle_page "Angle"
\subpage tolerance_page "Tolerance"
\subpage managing_dimensions_page "Dimensions"
+\subpage annotation_page "Annotations"
\subpage whatis_page "WhatIs"
\subpage inspect_object_operation_page "Inspect Object"
\subpage shape_statistics_operation_page "Shape Statistics"
diff --git a/src/GEOMGUI/GEOMGUI_AnnotationMgr.cxx b/src/GEOMGUI/GEOMGUI_AnnotationMgr.cxx
index b7f4e9f9d..e1cecc0d1 100755
--- a/src/GEOMGUI/GEOMGUI_AnnotationMgr.cxx
+++ b/src/GEOMGUI/GEOMGUI_AnnotationMgr.cxx
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
@@ -144,7 +145,8 @@ bool GEOMGUI_AnnotationMgr::IsDisplayed( const QString& theEntry, const int theI
// purpose : Displays annotation shape presentation in view. It creates an annotation presentation
// and stores it in an internal container
//=======================================================================
-void GEOMGUI_AnnotationMgr::Display( const QString& theEntry, const int theIndex, SOCC_Viewer* theView )
+void GEOMGUI_AnnotationMgr::Display( const QString& theEntry, const int theIndex, SOCC_Viewer* theView,
+ const bool isStoreViewState, const bool isUpdateViewer )
{
SOCC_Viewer* aView = viewOrActiveView( theView );
if ( !aView )
@@ -161,7 +163,8 @@ void GEOMGUI_AnnotationMgr::Display( const QString& theEntry, const int theIndex
QString anEntry = QString("%1%2%3").arg(theEntry).arg(GetEntrySeparator()).arg(theIndex);
SALOME_Prs* aPrs = CreatePresentation( aProperty, anObject, aView, anEntry );
((SALOME_View*)aView)->Display( getDisplayer(), aPrs );
- getDisplayer()->UpdateViewer();
+ if ( isUpdateViewer )
+ getDisplayer()->UpdateViewer();
EntryToAnnotations anEntryToMap;
if ( myVisualized.contains( aView ) )
@@ -175,9 +178,11 @@ void GEOMGUI_AnnotationMgr::Display( const QString& theEntry, const int theIndex
anEntryToMap[theEntry] = anAnnotationToPrsMap;
myVisualized[aView] = anEntryToMap;
- // change persistent for the entry: set visible state in true for indices which presentations are shown
- storeVisibleState( theEntry, theView );
- storeFixedPosition( theEntry, theView );
+ if ( isStoreViewState ) {
+ // change persistent for the entry: set visible state in true for indices which presentations are shown
+ storeVisibleState( theEntry, theView );
+ storeFixedPosition( theEntry, theView );
+ }
}
void GEOMGUI_AnnotationMgr::Redisplay( const QString& theEntry, const int theIndex,
@@ -251,7 +256,8 @@ void GEOMGUI_AnnotationMgr::Redisplay( const QString& theEntry, const int theInd
}
}
-void GEOMGUI_AnnotationMgr::Erase( const QString& theEntry, const int theIndex, SOCC_Viewer* theView )
+void GEOMGUI_AnnotationMgr::Erase( const QString& theEntry, const int theIndex, SOCC_Viewer* theView,
+ const bool isUpdateViewer )
{
SOCC_Viewer* aView = viewOrActiveView( theView );
if ( !aView )
@@ -271,7 +277,8 @@ void GEOMGUI_AnnotationMgr::Erase( const QString& theEntry, const int theIndex,
// erase presentation from the viewer
SALOME_Prs* aPrs = anAnnotationToPrs[theIndex];
((SALOME_View*)aView)->Erase( getDisplayer(), aPrs );
- getDisplayer()->UpdateViewer();
+ if ( isUpdateViewer )
+ getDisplayer()->UpdateViewer();
// remove displayed parameters from an internal container
anAnnotationToPrs.remove( theIndex );
@@ -288,7 +295,8 @@ void GEOMGUI_AnnotationMgr::Erase( const QString& theEntry, const int theIndex,
storeVisibleState( theEntry, theView );
}
-void GEOMGUI_AnnotationMgr::DisplayVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView )
+void GEOMGUI_AnnotationMgr::DisplayVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView,
+ const bool isUpdateViewer )
{
SalomeApp_Study* aStudy = dynamic_cast( getApplication()->activeStudy() );
_PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( theEntry.toStdString() );
@@ -303,12 +311,13 @@ void GEOMGUI_AnnotationMgr::DisplayVisibleAnnotations( const QString& theEntry,
for ( int anIndex = 0; anIndex < aCount; ++anIndex )
{
if ( isVisible[anIndex] )
- Display( theEntry, anIndex, theView );
+ Display( theEntry, anIndex, theView, true, isUpdateViewer );
}
}
}
-void GEOMGUI_AnnotationMgr::EraseVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView )
+void GEOMGUI_AnnotationMgr::EraseVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView,
+ const bool isUpdateViewer )
{
SOCC_Viewer* aView = viewOrActiveView( theView );
if ( !myVisualized.contains( aView ) )
@@ -333,7 +342,8 @@ void GEOMGUI_AnnotationMgr::EraseVisibleAnnotations( const QString& theEntry, SO
SALOME_Prs* aPrs = anAnnotationToPrs[anIndex];
((SALOME_View*)aView)->Erase( getDisplayer(), aPrs );
}
- getDisplayer()->UpdateViewer();
+ if ( isUpdateViewer )
+ getDisplayer()->UpdateViewer();
anEntryToAnnotation.remove( theEntry );
myVisualized[aView] = anEntryToAnnotation;
}
@@ -436,6 +446,57 @@ void GEOMGUI_AnnotationMgr::UpdateVisibleAnnotations( const QString& theEntry, S
getDisplayer()->UpdateViewer();
}
+void GEOMGUI_AnnotationMgr::DisplayAllAnnotations( SOCC_Viewer* theView )
+{
+ SOCC_Viewer* aView = viewOrActiveView( theView );
+ if ( !myVisualized.contains( aView ) )
+ return;
+
+ GeometryGUI* aModule = dynamic_cast( getApplication()->activeModule() );
+ GEOMGUI_TextTreeWdg* aTextWidget = aModule->GetTextTreeWdg();
+ QList anEntries = aTextWidget->getAllEntries( GEOMGUI_TextTreeWdg::AnnotationShape );
+
+ SalomeApp_Study* aStudy = dynamic_cast( getApplication()->activeStudy() );
+ for ( int i = 0, aCount = anEntries.size(); i < aCount; i++ ) {
+ QString anEntry = anEntries[i];
+
+ _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( anEntry.toStdString() );
+ if ( !aSObj )
+ continue;
+
+ const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
+ if ( !aShapeAnnotations.IsNull() )
+ continue;
+
+ int anAnnotationsCount = aShapeAnnotations->GetNbAnnotation();
+ for ( int anIndex = 0; anIndex < anAnnotationsCount; ++anIndex )
+ {
+ Display( anEntry, anIndex, aView, false, false );
+ }
+ getDisplayer()->UpdateViewer();
+ storeVisibleState( anEntry, aView );
+ storeFixedPosition( anEntry, aView );
+ }
+}
+
+void GEOMGUI_AnnotationMgr::EraseAllAnnotations( SOCC_Viewer* theView )
+{
+ SOCC_Viewer* aView = viewOrActiveView( theView );
+ if ( !myVisualized.contains( aView ) )
+ return;
+
+ GeometryGUI* aModule = dynamic_cast( getApplication()->activeModule() );
+ GEOMGUI_TextTreeWdg* aTextWidget = aModule->GetTextTreeWdg();
+ QList anEntries = aTextWidget->getAllEntries( GEOMGUI_TextTreeWdg::AnnotationShape );
+
+ for ( int i = 0, aCount = anEntries.size(); i < aCount; i++ ) {
+ QString anEntry = anEntries[i];
+ EraseVisibleAnnotations( anEntry, aView, false );
+ storeVisibleState( anEntry, aView );
+ }
+ getDisplayer()->UpdateViewer();
+}
+
void GEOMGUI_AnnotationMgr::SetPreviewStyle( const QString& theEntry, const int theIndex, const bool theIsPreview )
{
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
diff --git a/src/GEOMGUI/GEOMGUI_AnnotationMgr.h b/src/GEOMGUI/GEOMGUI_AnnotationMgr.h
index 56a46acec..52d3b1260 100755
--- a/src/GEOMGUI/GEOMGUI_AnnotationMgr.h
+++ b/src/GEOMGUI/GEOMGUI_AnnotationMgr.h
@@ -59,17 +59,25 @@ public:
const QString& theEntry = QString() );
bool IsDisplayed( const QString& theEntry, const int theIndex, SOCC_Viewer* theView = 0 ) const;
- void Display( const QString& theEntry, const int theIndex, SOCC_Viewer* theView = 0 );
- void Erase( const QString& theEntry, const int theIndex, SOCC_Viewer* theView = 0 );
+ void Display( const QString& theEntry, const int theIndex, SOCC_Viewer* theView = 0,
+ const bool isStoreViewState = true, const bool isUpdateViewer = true );
+ void Erase( const QString& theEntry, const int theIndex, SOCC_Viewer* theView = 0,
+ const bool isUpdateViewer = true );
void EraseRemovedAnnotation( const QString& theEntry, const int theIndex );
void Redisplay( const QString& theEntry, const int theIndex,
const GEOMGUI_AnnotationAttrs::Properties& theProperties);
void Redisplay( const QString& theEntry, const int theIndex,
const GEOMGUI_AnnotationAttrs::Properties& theProperties, SOCC_Viewer* theView );
- void DisplayVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView = 0 );
- void EraseVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView = 0 );
+ void DisplayVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView = 0,
+ const bool isUpdateViewer = true );
+ void EraseVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView = 0,
+ const bool isUpdateViewer = true );
void UpdateVisibleAnnotations( const QString& theEntry, SOCC_Viewer* theView = 0 );
+
+ void DisplayAllAnnotations( SOCC_Viewer* theView = 0 );
+ void EraseAllAnnotations( SOCC_Viewer* theView = 0 );
+
void SetPreviewStyle( const QString& theEntry, const int theIndex, const bool theIsPreview );
void RemoveView( SOCC_Viewer* theView );
diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx
index 47dd3441e..b245a14f9 100755
--- a/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx
+++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.cxx
@@ -521,13 +521,14 @@ void GEOMGUI_TextTreeWdg::updateVisibilityColumn( const BranchType& theBranchTyp
//=================================================================================
void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos )
{
- if ( selectedItems().isEmpty() )
- return;
- QMenu aMenu;
- aMenu.addAction( myActions[GEOMOp::OpShow] );
- aMenu.addAction( myActions[GEOMOp::OpHide] );
+ CAM_Application* anApp = dynamic_cast(myStudy->application());
+ GeometryGUI* aModule = dynamic_cast(anApp->activeModule());
- if ( selectedItems().count() == 1 ) {
+ QMenu aMenu;
+ aMenu.addAction( aModule->action(GEOMOp::OpShowAllAnnotations) );
+ aMenu.addAction( aModule->action(GEOMOp::OpHideAllAnnotations) );
+
+ if ( !selectedItems().isEmpty() && selectedItems().count() == 1 ) {
QTreeWidgetItem* anItem = selectedItems().first();
QString anEntry = entryFromItem( anItem->parent() );
if ( !anEntry.isEmpty() ) {
@@ -539,8 +540,6 @@ void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos )
return;
aMenu.clear();
// Edit annotation action
- CAM_Application* anApp = dynamic_cast(myStudy->application());
- GeometryGUI* aModule = dynamic_cast(anApp->activeModule());
QAction* anEditAction = aModule->action(GEOMOp::OpEditAnnotation);
if ( anEditAction )
aMenu.addAction( anEditAction );
@@ -730,6 +729,15 @@ void GEOMGUI_TextTreeWdg::setSelected( const QMap >& theAnno
}
}
+//=================================================================================
+// function : getAllEntries
+// purpose :
+//=================================================================================
+QList GEOMGUI_TextTreeWdg::getAllEntries( const BranchType& theBranchType )
+{
+ return getObjects( theBranchType ).keys();
+}
+
//=================================================================================
// function : setShapeItemVisibility
// purpose :
diff --git a/src/GEOMGUI/GEOMGUI_TextTreeWdg.h b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h
index 2025a511e..d92a607b8 100644
--- a/src/GEOMGUI/GEOMGUI_TextTreeWdg.h
+++ b/src/GEOMGUI/GEOMGUI_TextTreeWdg.h
@@ -73,6 +73,8 @@ public:
void getSelected( QMap >& theAnnotations );
void setSelected( const QMap >& theAnnotations );
+ QList getAllEntries( const BranchType& theBranchType );
+
protected:
void createActions();
void redisplay( QString theEntry );
diff --git a/src/MeasureGUI/MeasureGUI.cxx b/src/MeasureGUI/MeasureGUI.cxx
index ea9758c95..084a9b61a 100755
--- a/src/MeasureGUI/MeasureGUI.cxx
+++ b/src/MeasureGUI/MeasureGUI.cxx
@@ -231,38 +231,44 @@ void MeasureGUI::ChangeAnnotationsVisibility( const bool theIsVisible )
return;
Handle(SALOME_InteractiveObject) anIObject = getSingleSelectedIO();
- if ( anIObject.IsNull()
- || !anIObject->hasEntry() )
- return;
+ if ( !anIObject.IsNull() && anIObject->hasEntry() ) {
+ const QString aEntry = anIObject->getEntry();
- const QString aEntry = anIObject->getEntry();
+ _PTR(SObject) aSObj = anActiveStudy->studyDS()->FindObjectID( aEntry.toStdString() );
- _PTR(SObject) aSObj = anActiveStudy->studyDS()->FindObjectID( aEntry.toStdString() );
+ const Handle(GEOMGUI_AnnotationAttrs)
+ aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
- const Handle(GEOMGUI_AnnotationAttrs)
- aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
-
- if ( aShapeAnnotations.IsNull() ) {
- return;
- }
-
- const int aCount = aShapeAnnotations->GetNbAnnotation();
-
- if ( aCount > 0 ) {
-
- SUIT_OverrideCursor wc;
-
- for ( int anI = 0; anI < aCount; ++anI ) {
-
- if ( !theIsVisible ) {
- getGeometryGUI()->GetAnnotationMgr()->Erase( aEntry, anI );
- }
- else {
- getGeometryGUI()->GetAnnotationMgr()->Display( aEntry , anI );
- }
+ if ( aShapeAnnotations.IsNull() ) {
+ return;
}
- getGeometryGUI()->emitAnnotationsUpdated( aEntry );
+ const int aCount = aShapeAnnotations->GetNbAnnotation();
+
+ if ( aCount > 0 ) {
+
+ SUIT_OverrideCursor wc;
+
+ for ( int anI = 0; anI < aCount; ++anI ) {
+
+ if ( !theIsVisible ) {
+ getGeometryGUI()->GetAnnotationMgr()->Erase( aEntry, anI );
+ }
+ else {
+ getGeometryGUI()->GetAnnotationMgr()->Display( aEntry , anI );
+ }
+ }
+
+ getGeometryGUI()->emitAnnotationsUpdated( aEntry );
+ }
+ }
+ else {
+ if ( theIsVisible ) {
+ getGeometryGUI()->GetAnnotationMgr()->DisplayAllAnnotations();
+ }
+ else {
+ getGeometryGUI()->GetAnnotationMgr()->EraseAllAnnotations();
+ }
}
}