]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Improvement of the highlighting/selection mechanism for the case of several coinciden...
authorouv <ouv@opencascade.com>
Mon, 30 Jan 2012 12:34:05 +0000 (12:34 +0000)
committerouv <ouv@opencascade.com>
Mon, 30 Jan 2012 12:34:05 +0000 (12:34 +0000)
src/SVTK/SALOME_Actor.cxx
src/SVTK/SALOME_Actor.h
src/SVTK/SVTK_InteractorStyle.cxx
src/SVTK/SVTK_Selector.cxx
src/SVTK/SVTK_Selector.h
src/SVTK/SVTK_SelectorDef.h
src/VTKViewer/VTKViewer_Actor.cxx
src/VTKViewer/VTKViewer_Actor.h

index 624495948c08528d3a3b842ff2dcbdd1c2cfea11..589dee0aa78ed189f61eb5423e113cb86d075a86 100644 (file)
@@ -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();
index 5af43aa5160eabc8ee4e257afa5f85115ecf2648..e51d4eb4383edec3d8e9ac12ab95936c308d00ae 100644 (file)
@@ -44,6 +44,7 @@ class Handle(SALOME_InteractiveObject);
 
 #include <vtkSmartPointer.h>
 
+class vtkAbstractPicker;
 class vtkPointPicker;
 class vtkCellPicker;
 class vtkOutlineSource;
@@ -235,6 +236,17 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor
   vtkSmartPointer<vtkOutlineSource> myOutline;
 };
 
+namespace SVTK
+{
+  class SVTK_EXPORT TPickLimiter
+  {
+    vtkAbstractPicker* myPicker;
+  public:
+    TPickLimiter( vtkAbstractPicker*, SALOME_Actor* );
+    ~TPickLimiter();
+  };
+}
+
 #ifdef WIN32
 //#pragma warning ( default:4251 )
 #endif
index 937c0129f6545d546cb6f6d6dc7e9d04014e044f..5c59da5c88a4eb5bbacae1a97dcb5fe242594824 100644 (file)
@@ -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();
index 906574ca788e04f654cf0562956b895ebc18d305..2a509dcddb2af3711d94ba3f970c2b60fce1dc41 100644 (file)
 #include <vtkCellPicker.h>
 
 
-/*!
-  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<SALOME_Actor*>(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
index 3cb1bed650bd888a0d6a7f803fc9b20c03a03733..e959d72863e541663c5043669a7177ae3d6e937e 100644 (file)
@@ -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
index 70b95775636d3ed84719326f6c99c57347dd8390..9eb5dd1b2161929b24c30bc29393d2b195259f4f 100644 (file)
@@ -171,7 +171,7 @@ public:
 
   //----------------------------------------------------------------------------
   virtual
-  SALOME_Actor*
+  vtkActorCollection*
   Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const;
 
   virtual
index 985e05920a33259b978d58ef370bfa1b7f7c8580..0e442a1c39ddc2660af70a0c5b5f6f811bbf2cab 100755 (executable)
@@ -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
 */
index f2ea80996fe2c04813bb86afc12fea594948b204..6b27e06660331ffa4b3ce708f12e768e87932c72 100755 (executable)
@@ -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