]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Implementation isuue "21319: EDF 1616 ALL: synchronization of 3D viewers" for the...
authorrnv <rnv@opencascade.com>
Tue, 11 Oct 2011 10:57:12 +0000 (10:57 +0000)
committerrnv <rnv@opencascade.com>
Tue, 11 Oct 2011 10:57:12 +0000 (10:57 +0000)
src/SVTK/SVTK_Event.h
src/SVTK/SVTK_InteractorStyle.cxx
src/SVTK/SVTK_ViewWindow.cxx
src/SVTK/SVTK_ViewWindow.h

index 77e9e487560e83380e1f2da95315cb8c02c93099..4785d794c1ff8918f0d9ade4a3c2684db7fdd5c9 100644 (file)
@@ -73,6 +73,8 @@ namespace SVTK
     SetFocalPointSelected,
     StartFocalPointSelection,
     FocalPointChanged,
+    
+    OperationFinished, // rnv: invoked then SpinXY, RotateXY, DollyXY or PanXY operation is finished.
         
     LastEvent
   };
index 994b855708356ecf3bc09b4f361fd495ef064b68..5346d0981e52b61b36e76eb1f3193524fd08c229 100644 (file)
@@ -271,12 +271,14 @@ void SVTK_InteractorStyle::RotateXY(int dx, int dy)
   GetCurrentRenderer()->ResetCameraClippingRange(); 
 
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::PanXY(int x, int y, int oldX, int oldY)
 {
   TranslateView(x, y, oldX, oldY);   
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::DollyXY(int dx, int dy)
@@ -312,6 +314,7 @@ void SVTK_InteractorStyle::DollyXY(int dx, int dy)
   }
 
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
@@ -334,6 +337,7 @@ void SVTK_InteractorStyle::SpinXY(int x, int y, int oldX, int oldY)
   cam->OrthogonalizeViewUp();
       
   this->Render();
+  this->InvokeEvent(SVTK::OperationFinished,NULL);
 }
 
 
index c682aefaa45806f13075c7ac34031a08d829a107..0a84e834a2feaa9b8b3cb42d98924fe82153abac 100755 (executable)
@@ -46,6 +46,7 @@
 #include <vtkGL2PSExporter.h>
 #include <vtkInteractorStyle.h>
 #include <vtkProperty.h>
+#include <vtkCallbackCommand.h>
 
 #include "QtxAction.h"
 
@@ -123,7 +124,8 @@ SVTK_ViewWindow::SVTK_ViewWindow(SUIT_Desktop* theDesktop):
   SUIT_ViewWindow(theDesktop),
   myView(NULL),
   myDumpImage(QImage()),
-  myKeyFreeInteractorStyle(SVTK_KeyFreeInteractorStyle::New())
+  myKeyFreeInteractorStyle(SVTK_KeyFreeInteractorStyle::New()),
+  myEventCallbackCommand(vtkCallbackCommand::New())
 {
   setWindowFlags( windowFlags() & ~Qt::Window );
   // specific of vtkSmartPointer
@@ -209,6 +211,16 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel)
 
   myView = new SVTK_View(this);
   Initialize(myView,theModel);
+
+
+  myEventCallbackCommand->SetClientData(this);
+  myEventCallbackCommand->SetCallback(SVTK_ViewWindow::ProcessEvents);
+  myEventCallbackCommand->Delete();
+
+  GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished, 
+                                                    myEventCallbackCommand.GetPointer(), 0.0);
+
+
   
   myInteractor->getRenderWindow()->Render();
   onResetView();
@@ -311,6 +323,7 @@ void SVTK_ViewWindow::onFrontView()
 {
   GetRenderer()->OnFrontView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -320,6 +333,7 @@ void SVTK_ViewWindow::onBackView()
 {
   GetRenderer()->OnBackView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -329,6 +343,7 @@ void SVTK_ViewWindow::onTopView()
 {
   GetRenderer()->OnTopView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -338,6 +353,7 @@ void SVTK_ViewWindow::onBottomView()
 {
   GetRenderer()->OnBottomView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -347,6 +363,7 @@ void SVTK_ViewWindow::onLeftView()
 {
   GetRenderer()->OnLeftView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -356,6 +373,7 @@ void SVTK_ViewWindow::onRightView()
 {
   GetRenderer()->OnRightView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -365,6 +383,7 @@ void SVTK_ViewWindow::onClockWiseView()
 {
   GetRenderer()->onClockWiseView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -374,6 +393,7 @@ void SVTK_ViewWindow::onAntiClockWiseView()
 {
   GetRenderer()->onAntiClockWiseView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -383,6 +403,7 @@ void SVTK_ViewWindow::onResetView()
 {
   GetRenderer()->OnResetView();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -392,6 +413,7 @@ void SVTK_ViewWindow::onFitAll()
 {
   GetRenderer()->OnFitAll();
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -592,6 +614,7 @@ void SVTK_ViewWindow::SetScale( double theScale[3] )
 {
   GetRenderer()->SetScale( theScale );
   Repaint();
+  emit transformed( this );
 }
 
 /*!
@@ -845,6 +868,15 @@ void SVTK_ViewWindow::onAdjustCubeAxes()
   GetRenderer()->OnAdjustCubeAxes();
 }
 
+void SVTK_ViewWindow::synchronize(SVTK_ViewWindow* otherViewWindow )
+{
+  if ( otherViewWindow ) {
+    bool blocked = blockSignals( true );
+    doSetVisualParameters( otherViewWindow->getVisualParameters(), true );
+    blockSignals( blocked );
+  }
+}
+
 /*!
   Emits key pressed
 */
@@ -1450,6 +1482,7 @@ void SVTK_ViewWindow::setVisualParameters( const QString& parameters )
 */
 void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool baseParamsOnly )
 {
+  
   double pos[3], focalPnt[3], viewUp[3], parScale, scale[3];
 
   QXmlStreamReader aReader(parameters);
@@ -1517,7 +1550,8 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas
     camera->SetFocalPoint( focalPnt );
     camera->SetViewUp( viewUp );
     camera->SetParallelScale( parScale );
-    SetScale( scale );
+    GetRenderer()->SetScale( scale );
+    //SetScale( scale );
   }
   else {
     QStringList paramsLst = parameters.split( '*' );
@@ -1543,7 +1577,8 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas
       camera->SetFocalPoint( focalPnt );
       camera->SetViewUp( viewUp );
       camera->SetParallelScale( parScale );
-      SetScale( scale );
+      GetRenderer()->SetScale( scale );
+      //SetScale( scale );
       
       // apply graduated axes parameters
       if ( !baseParamsOnly ) {
@@ -1572,6 +1607,7 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas
       }
     }
   }
+  Repaint();
 }
 
 
@@ -1870,8 +1906,9 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr)
                            tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this);
   anAction->setStatusTip(tr("DSC_SYNCHRONIZE_VIEW"));
   anAction->setMenu( new QMenu( this ) );
+  anAction->setCheckable(true);
   connect(anAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews()));
-  connect(anAction, SIGNAL(triggered()), this, SLOT(onSynchronizeView()));
+  connect(anAction, SIGNAL(triggered(bool)), this, SLOT(onSynchronizeView(bool)));
   mgr->registerAction( anAction, SynchronizeId );
 
   // Switch between interaction styles
@@ -2160,33 +2197,94 @@ void SVTK_ViewWindow::hideEvent( QHideEvent * theEvent )
   emit Hide( theEvent );
 }
 
+void SVTK_ViewWindow::synchronizeView( SVTK_ViewWindow* viewWindow, int id )
+{
+  SVTK_ViewWindow* otherViewWindow = 0;
+  QList<SVTK_ViewWindow*> compatibleViews;
+
+  bool isSync = viewWindow->toolMgr()->action( SynchronizeId )->isChecked();
+
+  int vwid = viewWindow->getId();
+  
+  SUIT_Application* app = SUIT_Session::session()->activeApplication();
+  if ( !app ) return;
+
+  QList<SUIT_ViewManager*> wmlist;
+  app->viewManagers( viewWindow->getViewManager()->getType(), wmlist );
+
+  foreach( SUIT_ViewManager* wm, wmlist ) {
+    QVector<SUIT_ViewWindow*> vwlist = wm->getViews();
+
+    foreach( SUIT_ViewWindow* vw, vwlist ) {
+      SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( vw );
+      if ( !vtkVW ) continue;
+      if ( vtkVW->getId() == id ) 
+       otherViewWindow = vtkVW;
+      else if ( vtkVW != viewWindow )
+       compatibleViews.append( vtkVW );
+    }
+  }
+
+  if ( isSync && id ) {
+    // remove all possible disconnections
+    foreach( SVTK_ViewWindow* vw, compatibleViews ) {
+      // disconnect target view
+      vw->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), viewWindow, SLOT( synchronize( SVTK_ViewPort* ) ) );
+      viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), vw, SLOT( synchronize( SVTK_ViewPort* ) ) );
+      if ( otherViewWindow ) {
+       // disconnect source view
+       vw->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewPort* ) ) );
+       otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewPort* ) ), vw, SLOT( synchronize( SVTK_ViewPort* ) ) );
+      }
+      QAction* a = vw->toolMgr()->action( SynchronizeId );
+      if ( a ) {
+       int anid = a->data().toInt();
+       if ( a->isChecked() && ( anid == id || anid == vwid ) ) {
+         bool blocked = a->blockSignals( true );
+         a->setChecked( false );
+         a->blockSignals( blocked );
+       }
+      }
+    }
+    if ( otherViewWindow ) {
+      // reconnect source and target view
+      otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), viewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
+      viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
+      otherViewWindow->connect( viewWindow, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( synchronize( SVTK_ViewWindow* ) ) );
+      viewWindow->connect( otherViewWindow, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( synchronize( SVTK_ViewWindow* ) ) );
+      // synchronize target view with source view
+      viewWindow->doSetVisualParameters( otherViewWindow->getVisualParameters(), true );
+      viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
+      otherViewWindow->toolMgr()->action( SynchronizeId )->setData( viewWindow->getId() );
+      if ( !otherViewWindow->toolMgr()->action( SynchronizeId )->isChecked() ) {
+       bool blocked = otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( true );
+       otherViewWindow->toolMgr()->action( SynchronizeId )->setChecked( true );
+       otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( blocked );
+      }
+    }
+  }
+  else if ( otherViewWindow ) {
+    // reconnect source and target view
+    otherViewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), viewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
+    viewWindow->disconnect( SIGNAL( transformed( SVTK_ViewWindow* ) ), otherViewWindow, SLOT( synchronize( SVTK_ViewWindow* ) ) );
+    viewWindow->doSetVisualParameters( otherViewWindow->getVisualParameters(), true );
+    viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
+    if ( otherViewWindow->toolMgr()->action( SynchronizeId )->data().toInt() == viewWindow->getId() && otherViewWindow->toolMgr()->action( SynchronizeId )->isChecked() ) {
+      bool blocked = otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( true );
+      otherViewWindow->toolMgr()->action( SynchronizeId )->setChecked( false );
+      otherViewWindow->toolMgr()->action( SynchronizeId )->blockSignals( blocked );
+    }
+  }
+}
+
 /*!
   "Synchronize View" action slot.
 */
-void SVTK_ViewWindow::onSynchronizeView()
+void SVTK_ViewWindow::onSynchronizeView(bool checked)
 {
   QAction* a = qobject_cast<QAction*>( sender() );
   if ( a ) {
-    int id = a->data().toInt();
-    if ( id != 0 ) {
-      SUIT_Application* app = SUIT_Session::session()->activeApplication();
-      if ( !app ) return;
-      QList<SUIT_ViewManager*> wmlist;
-      app->viewManagers( getViewManager()->getType(), wmlist );
-      foreach( SUIT_ViewManager* wm, wmlist ) {
-       QVector<SUIT_ViewWindow*> vwlist = wm->getViews();
-       foreach ( SUIT_ViewWindow* vw, vwlist ) {
-         SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( vw );
-         if ( vtkVW && vtkVW->getId() == id && vtkVW != this ) {
-           // perform synchronization
-           doSetVisualParameters( vtkVW->getVisualParameters(), true );
-         }
-       }
-      }
-      
-      if ( a != toolMgr()->action( SynchronizeId ) )
-       toolMgr()->action( SynchronizeId )->setData( id );
-    }
+    synchronizeView( this, a->data().toInt() );
   }
 }
 
@@ -2197,6 +2295,7 @@ void SVTK_ViewWindow::updateSyncViews()
 {
   QAction* anAction = toolMgr()->action( SynchronizeId );
   if ( anAction && anAction->menu() ) {
+    int currentId = anAction->data().toInt();
     anAction->menu()->clear();
     SUIT_Application* app = SUIT_Session::session()->activeApplication();
     if ( app ) { 
@@ -2208,13 +2307,40 @@ void SVTK_ViewWindow::updateSyncViews()
          SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( vw );
          if ( !vtkVW || vtkVW == this ) continue;
          QAction* a = anAction->menu()->addAction( vtkVW->windowTitle() );
+          if ( vtkVW->getId() == currentId ) {
+            QFont f = a->font();
+           f.setBold( true );
+           a->setFont( f );
+         }
          a->setData( vtkVW->getId() );
-         connect( a, SIGNAL( triggered() ), this, SLOT( onSynchronizeView() ) );
+         connect( a, SIGNAL( triggered(bool) ), this, SLOT( onSynchronizeView(bool) ) );
        }
       }
     }
     if ( anAction->menu()->actions().isEmpty() ) {
+      anAction->setData( 0 );
       anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) );
     }
   }
 }
+
+
+/*!
+  Emit transformed signal.
+*/
+void SVTK_ViewWindow::emitTransformed() {
+  transformed(this);
+}
+
+/*!
+  Processes events
+*/
+void SVTK_ViewWindow::ProcessEvents(vtkObject* vtkNotUsed(theObject),
+                                   unsigned long theEvent,
+                                   void* theClientData,
+                                   void* theCallData)
+{
+  SVTK_ViewWindow* self = reinterpret_cast<SVTK_ViewWindow*>(theClientData);
+  if(self)
+    self->emitTransformed();
+}
index 5555b06d3d440e9583bb4faff9215aa953a8746f..0e713d57abffc144484457450634db2ec652ab88 100755 (executable)
@@ -53,6 +53,8 @@ class vtkRenderer;
 class vtkRenderWindow;
 class vtkRenderWindowInteractor;
 class vtkInteractorStyle;
+class vtkCallbackCommand;
+
 class SVTK_RenderWindowInteractor;
 class SVTK_Renderer;
 class SVTK_NonIsometricDlg;
@@ -263,6 +265,8 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow
 
   virtual void RefreshDumpImage();
 
+  void emitTransformed();
+
   //! To invoke a VTK event on #SVTK_RenderWindowInteractor instance
   void InvokeEvent(unsigned long theEvent, void* theCallData);
   
@@ -310,13 +314,11 @@ public slots:
   void onPauseRecording();
   void onStopRecording();
 
-  void onSynchronizeView();
-  void updateSyncViews();
-
 signals:
  void selectionChanged();
  void actorAdded(VTKViewer_Actor*);
  void actorRemoved(VTKViewer_Actor*);
+ void transformed(SVTK_ViewWindow*);
 
 public slots:
   //! Redirect the request to #SVTK_Renderer::OnFrontView
@@ -360,7 +362,9 @@ public slots:
 
   //! Redirect the request to #SVTK_Renderer::OnAdjustCubeAxes
   virtual void onAdjustCubeAxes();
-
+  
+  virtual void synchronize(SVTK_ViewWindow*);
+    
 protected slots:
   void onKeyPressed(QKeyEvent* event);
   void onKeyReleased(QKeyEvent* event);
@@ -373,6 +377,12 @@ protected:
   virtual void Initialize(SVTK_View* theView,
                           SVTK_ViewModelBase* theModel);
 
+  // Main process event method
+  static void ProcessEvents(vtkObject* object,
+                            unsigned long event,
+                            void* clientdata,
+                            void* calldata);
+
   void doSetVisualParameters( const QString&, bool = false );
   void SetEventDispatcher(vtkObject* theDispatcher);
 
@@ -407,6 +417,9 @@ protected:
 
   vtkSmartPointer<vtkObject> myEventDispatcher;
 
+  // Used to process events
+  vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
+
   SVTK_NonIsometricDlg* myNonIsometricDlg;
   SVTK_UpdateRateDlg* myUpdateRateDlg;
   SVTK_CubeAxesDlg* myCubeAxesDlg;
@@ -427,6 +440,13 @@ protected:
 
   vtkPVAxesWidget* myAxesWidget;
 
+private slots:
+  void onSynchronizeView(bool);
+  void updateSyncViews();
+
+private:
+  static void synchronizeView( SVTK_ViewWindow*, int );
+
 private:
   QImage myDumpImage;
 };