From 44ae4b9dbd4634d7cc643334e899e33343ec1521 Mon Sep 17 00:00:00 2001 From: ouv Date: Mon, 30 Jan 2012 12:34:05 +0000 Subject: [PATCH] Improvement of the highlighting/selection mechanism for the case of several coincident actors. --- src/SVTK/SALOME_Actor.cxx | 35 ++++++- src/SVTK/SALOME_Actor.h | 12 +++ src/SVTK/SVTK_InteractorStyle.cxx | 166 ++++++++++++++++++------------ src/SVTK/SVTK_Selector.cxx | 27 +---- src/SVTK/SVTK_Selector.h | 3 +- src/SVTK/SVTK_SelectorDef.h | 2 +- src/VTKViewer/VTKViewer_Actor.cxx | 10 ++ src/VTKViewer/VTKViewer_Actor.h | 5 + 8 files changed, 165 insertions(+), 95 deletions(-) diff --git a/src/SVTK/SALOME_Actor.cxx b/src/SVTK/SALOME_Actor.cxx index 624495948..589dee0aa 100644 --- a/src/SVTK/SALOME_Actor.cxx +++ b/src/SVTK/SALOME_Actor.cxx @@ -123,6 +123,29 @@ namespace } +namespace SVTK +{ + /*! + Make picker work with this actor only + */ + TPickLimiter::TPickLimiter( vtkAbstractPicker* thePicker, + SALOME_Actor* theActor ) : myPicker( thePicker ) + { + myPicker->InitializePickList(); + myPicker->AddPickList( theActor ); + myPicker->SetPickFromList( true ); + } + + /*! + Unlimit picking + */ + TPickLimiter::~TPickLimiter() + { + myPicker->SetPickFromList( false ); + myPicker->InitializePickList(); + } +} + bool IsThisActorPicked(SALOME_Actor *theActor, vtkActor *anAct) { if( anAct == theActor ) return true; if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( anAct ) ) @@ -453,6 +476,7 @@ SALOME_Actor switch(aSelectionMode){ case NodeSelection: { + SVTK::TPickLimiter aPickLimiter( myPointPicker, this ); myPointPicker->Pick( x, y, z, aRenderer ); int aVtkId = myPointPicker->GetPointId(); @@ -483,6 +507,7 @@ SALOME_Actor case FaceSelection: case VolumeSelection: { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); myCellPicker->Pick( x, y, z, aRenderer ); int aVtkId = myCellPicker->GetCellId(); @@ -512,6 +537,7 @@ SALOME_Actor } case EdgeOfCellSelection: { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); myCellPicker->Pick( x, y, z, aRenderer ); int aVtkId = myCellPicker->GetCellId(); @@ -601,6 +627,7 @@ SALOME_Actor if( !theSelectionEvent->myIsRectangle ) { switch(aSelectionMode){ case NodeSelection: { + SVTK::TPickLimiter aPickLimiter( myPointPicker, this ); myPointPicker->Pick( x, y, z, aRenderer ); int aVtkId = myPointPicker->GetPointId(); @@ -619,6 +646,7 @@ SALOME_Actor case FaceSelection: case VolumeSelection: { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); myCellPicker->Pick( x, y, z, aRenderer ); int aVtkId = myCellPicker->GetCellId(); @@ -636,6 +664,7 @@ SALOME_Actor } case EdgeOfCellSelection: { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); myCellPicker->Pick( x, y, z, aRenderer ); int aVtkId = myCellPicker->GetCellId(); @@ -679,8 +708,7 @@ SALOME_Actor switch(aSelectionMode){ case NodeSelection: { - myPointRectPicker->InitializePickList(); - myPointRectPicker->AddPickList(this); + SVTK::TPickLimiter aPickLimiter( myPointRectPicker, this ); myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer ); const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap(); @@ -740,8 +768,7 @@ SALOME_Actor case FaceSelection: case VolumeSelection: { - myCellRectPicker->InitializePickList(); - myCellRectPicker->AddPickList(this); + SVTK::TPickLimiter aPickLimiter( myCellRectPicker, this ); myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer ); const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap(); diff --git a/src/SVTK/SALOME_Actor.h b/src/SVTK/SALOME_Actor.h index 5af43aa51..e51d4eb43 100644 --- a/src/SVTK/SALOME_Actor.h +++ b/src/SVTK/SALOME_Actor.h @@ -44,6 +44,7 @@ class Handle(SALOME_InteractiveObject); #include +class vtkAbstractPicker; class vtkPointPicker; class vtkCellPicker; class vtkOutlineSource; @@ -235,6 +236,17 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor vtkSmartPointer myOutline; }; +namespace SVTK +{ + class SVTK_EXPORT TPickLimiter + { + vtkAbstractPicker* myPicker; + public: + TPickLimiter( vtkAbstractPicker*, SALOME_Actor* ); + ~TPickLimiter(); + }; +} + #ifdef WIN32 //#pragma warning ( default:4251 ) #endif diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index 937c0129f..5c59da5c8 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -457,48 +457,48 @@ void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, { SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY(); - SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + bool isPicked = false; + vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); - if ( anActor ) + if ( anActorCollection ) { - myPointPicker->Pick( aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer() ); - int aVtkId = myPointPicker->GetPointId(); - if ( aVtkId >= 0 ) - { - int anObjId = anActor->GetNodeObjId( aVtkId ); - vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId); - - if (myCurrRotationPointType == SVTK::StartPointSelection) { - myCurrRotationPointType = SVTK::SetRotateSelected; - - // invoke event for update coordinates in SVTK_SetRotationPointDlg - InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords); - } - else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) { - myCurrFocalPointType = SVTK::SetFocalPointSelected; - - // invoke event for update coordinates in SVTK_ViewParameterDlg - InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords); - } - } - else - { - if (myCurrRotationPointType == SVTK::StartPointSelection) { - // invoke event with no data (for SVTK_SetRotationPointDlg) - InvokeEvent(SVTK::RotationPointChanged,0); - myCurrRotationPointType = myPrevRotationPointType; - } - else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) { - // invoke event with no data (for SVTK_ViewParameterDlg) - InvokeEvent(SVTK::FocalPointChanged,0); - myCurrFocalPointType = myPrevFocalPointType; - } + anActorCollection->InitTraversal(); + while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) + { + if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) + { + SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor ); + myPointPicker->Pick( aSelectionEvent->myX, + aSelectionEvent->myY, + 0.0, + GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) + { + int anObjId = anActor->GetNodeObjId( aVtkId ); + vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId); + + if (myCurrRotationPointType == SVTK::StartPointSelection) { + myCurrRotationPointType = SVTK::SetRotateSelected; + + // invoke event for update coordinates in SVTK_SetRotationPointDlg + InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords); + } + else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) { + myCurrFocalPointType = SVTK::SetFocalPointSelected; + + // invoke event for update coordinates in SVTK_ViewParameterDlg + InvokeEvent(SVTK::FocalPointChanged,(void*)aCoords); + } + + isPicked = true; + break; + } + } } } - else + + if( !isPicked ) { if (myCurrRotationPointType == SVTK::StartPointSelection) { // invoke event with no data (for SVTK_SetRotationPointDlg) @@ -1037,23 +1037,36 @@ void SVTK_InteractorStyle::onFinishOperation() this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY); Interactor->StartPickCallback(); - SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + SALOME_Actor* aHighlightedActor = NULL; + vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); aSelectionEvent->myIsRectangle = false; if(!myShiftState) GetSelector()->ClearIObjects(); - if(anActor) - { - anActor->Highlight( this, aSelectionEvent, true ); + if( anActorCollection ) + { + anActorCollection->InitTraversal(); + while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) + { + if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) + { + if( anActor->Highlight( this, aSelectionEvent, true ) ) + { + aHighlightedActor = anActor; + break; + } + } } - else - { - if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor) - myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); - } - myLastHighlitedActor = anActor; + } + + if( !aHighlightedActor ) + { + if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor) + myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); + } + myLastHighlitedActor = aHighlightedActor; } else { @@ -1167,40 +1180,63 @@ void SVTK_InteractorStyle::onCursorMove(QPoint mousePos) bool anIsChanged = false; - SALOME_Actor *anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + SALOME_Actor* aPreHighlightedActor = NULL; + vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); if ( myCurrRotationPointType == SVTK::StartPointSelection || myCurrFocalPointType == SVTK::StartFocalPointSelection ) { myHighlightSelectionPointActor->SetVisibility( false ); - if ( anActor ) + if( anActorCollection ) { - myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() ); - int aVtkId = myPointPicker->GetPointId(); - if ( aVtkId >= 0 ) { - int anObjId = anActor->GetNodeObjId( aVtkId ); - - TColStd_IndexedMapOfInteger aMapIndex; - aMapIndex.Add( anObjId ); - myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex ); - - myHighlightSelectionPointActor->SetVisibility( true ); - anIsChanged = true; + anActorCollection->InitTraversal(); + while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) + { + if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) + { + SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor ); + myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) { + int anObjId = anActor->GetNodeObjId( aVtkId ); + + TColStd_IndexedMapOfInteger aMapIndex; + aMapIndex.Add( anObjId ); + myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex ); + + myHighlightSelectionPointActor->SetVisibility( true ); + anIsChanged = true; + break; + } + } } } } else { - if (anActor){ - anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true ); + if( anActorCollection ) + { + anActorCollection->InitTraversal(); + while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) + { + if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) + { + anIsChanged = anActor->PreHighlight( this, aSelectionEvent, true ); + if( anActor->isPreselected() ) + { + aPreHighlightedActor = anActor; + break; + } + } + } } - if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor) + if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != aPreHighlightedActor) anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false ); } - myLastPreHighlitedActor = anActor; + myLastPreHighlitedActor = aPreHighlightedActor; if(anIsChanged) this->Render(); diff --git a/src/SVTK/SVTK_Selector.cxx b/src/SVTK/SVTK_Selector.cxx index 906574ca7..2a509dcdd 100644 --- a/src/SVTK/SVTK_Selector.cxx +++ b/src/SVTK/SVTK_Selector.cxx @@ -44,24 +44,6 @@ #include -/*! - Find first SALOME_Actor from the end of actors collection -*/ -inline -SALOME_Actor* -GetLastSALOMEActor(vtkActorCollection* theCollection) -{ - if (theCollection) { - for (int i = theCollection->GetNumberOfItems() - 1; i >= 0; i--) { - if (SALOME_Actor* anActor = dynamic_cast(theCollection->GetItemAsObject(i))) - if (anActor->hasIO()) - return anActor; - } - } - return NULL; -} - - /*! \return new SVTK_Selector */ @@ -546,7 +528,7 @@ SVTK_SelectorDef return Handle(VTKViewer_Filter)(); } -SALOME_Actor* +vtkActorCollection* SVTK_SelectorDef ::Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const { @@ -555,7 +537,6 @@ SVTK_SelectorDef if ( aResourceMgr ) anAdvancedSelectionAlgorithm = aResourceMgr->booleanValue( "VTKViewer", "use_advanced_selection_algorithm", true ); - SALOME_Actor* anActor = NULL; vtkActorCollection* aListActors = NULL; if ( anAdvancedSelectionAlgorithm ) { myCellPicker->Pick(theEvent->myX, @@ -564,19 +545,17 @@ SVTK_SelectorDef theRenderer); aListActors = myCellPicker->GetActors(); - anActor = GetLastSALOMEActor(aListActors); } - if ( !anActor ) { + if ( !aListActors || !aListActors->GetNumberOfItems() ) { myPicker->Pick(theEvent->myX, theEvent->myY, 0.0, theRenderer); aListActors = myPicker->GetActors(); - anActor = GetLastSALOMEActor(aListActors); } - return anActor; + return aListActors; } void diff --git a/src/SVTK/SVTK_Selector.h b/src/SVTK/SVTK_Selector.h index 3cb1bed65..e959d7286 100644 --- a/src/SVTK/SVTK_Selector.h +++ b/src/SVTK/SVTK_Selector.h @@ -42,6 +42,7 @@ class Handle(VTKViewer_Filter); class SALOME_Actor; struct SVTK_SelectionEvent; +class vtkActorCollection; class vtkRenderer; class Handle(SALOME_InteractiveObject); @@ -211,7 +212,7 @@ public: //---------------------------------------------------------------------------- virtual - SALOME_Actor* + vtkActorCollection* Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const = 0; virtual diff --git a/src/SVTK/SVTK_SelectorDef.h b/src/SVTK/SVTK_SelectorDef.h index 70b957756..9eb5dd1b2 100644 --- a/src/SVTK/SVTK_SelectorDef.h +++ b/src/SVTK/SVTK_SelectorDef.h @@ -171,7 +171,7 @@ public: //---------------------------------------------------------------------------- virtual - SALOME_Actor* + vtkActorCollection* Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const; virtual diff --git a/src/VTKViewer/VTKViewer_Actor.cxx b/src/VTKViewer/VTKViewer_Actor.cxx index 985e05920..0e442a1c3 100755 --- a/src/VTKViewer/VTKViewer_Actor.cxx +++ b/src/VTKViewer/VTKViewer_Actor.cxx @@ -655,6 +655,16 @@ VTKViewer_Actor return myIsHighlighted; } +/*! + \return true if the VTKViewer_Actor is already preselected +*/ +bool +VTKViewer_Actor +::isPreselected() +{ + return myIsPreselected; +} + /*! Set preselection mode */ diff --git a/src/VTKViewer/VTKViewer_Actor.h b/src/VTKViewer/VTKViewer_Actor.h index f2ea80996..6b27e0666 100755 --- a/src/VTKViewer/VTKViewer_Actor.h +++ b/src/VTKViewer/VTKViewer_Actor.h @@ -288,6 +288,11 @@ class VTKVIEWER_EXPORT VTKViewer_Actor : public vtkLODActor bool isHighlighted(); + //! Ask, if the VTKViewer_Actor is already preselected + virtual + bool + isPreselected(); + //! Set preselection mode virtual void -- 2.39.2