]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
0021808: [CEA 662] Synchronize OCC et VTK views (merge from BR_PAL21808 02/11/2012)
authorvsr <vsr@opencascade.com>
Fri, 2 Nov 2012 11:18:54 +0000 (11:18 +0000)
committervsr <vsr@opencascade.com>
Fri, 2 Nov 2012 11:18:54 +0000 (11:18 +0000)
26 files changed:
src/OCCViewer/Makefile.am
src/OCCViewer/OCCViewer_ViewFrame.cxx
src/OCCViewer/OCCViewer_ViewFrame.h
src/OCCViewer/OCCViewer_ViewWindow.cxx
src/OCCViewer/OCCViewer_ViewWindow.h
src/OCCViewer/resources/OCCViewer_images.ts
src/OCCViewer/resources/OCCViewer_msg_en.ts
src/OCCViewer/resources/OCCViewer_msg_fr.ts
src/OCCViewer/resources/occ_view_sync.png [deleted file]
src/SUIT/CMakeLists.txt
src/SUIT/Makefile.am
src/SUIT/SUIT_CameraProperties.cxx [new file with mode: 0644]
src/SUIT/SUIT_CameraProperties.h [new file with mode: 0644]
src/SUIT/SUIT_ViewWindow.cxx
src/SUIT/SUIT_ViewWindow.h
src/SUIT/resources/SUIT_images.ts
src/SUIT/resources/SUIT_msg_en.ts
src/SUIT/resources/SUIT_msg_fr.ts
src/SUIT/resources/view_sync.png [new file with mode: 0644]
src/SVTK/Makefile.am
src/SVTK/SVTK_ViewWindow.cxx
src/SVTK/SVTK_ViewWindow.h
src/SVTK/resources/SVTK_images.ts
src/SVTK/resources/SVTK_msg_en.ts
src/SVTK/resources/SVTK_msg_fr.ts
src/SVTK/resources/vtk_view_sync.png [deleted file]

index 14c993ba4aaabdd883c0ac52a8e51a81b6694db9..5adeea751d438f4867f7ccb97a2b5920404f5d21 100755 (executable)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-#  File   : Makefile.in
-#  Author : Vladimir Klyachin (OCN)
-#  Module : OCCViewer
-#  $Header$
-#
-
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 lib_LTLIBRARIES = libOCCViewer.la
@@ -118,8 +112,7 @@ dist_salomeres_DATA =                               \
        resources/occ_view_style_switch.png     \
        resources/occ_view_zooming_style_switch.png \
        resources/occ_view_maximized.png        \
-       resources/occ_view_minimized.png        \
-       resources/occ_view_sync.png
+       resources/occ_view_minimized.png
 
 nodist_salomeres_DATA =                \
        OCCViewer_images.qm     \
index 2d3b66ae7957558ca19bfaa569c9894c7b34fe64..ada4a63a83d6566f5eeee31b6ab27d1d6fddb202 100644 (file)
@@ -37,6 +37,7 @@ OCCViewer_ViewFrame::OCCViewer_ViewFrame(SUIT_Desktop* theDesktop, OCCViewer_Vie
   setCentralWidget( centralFrame );
 
   OCCViewer_ViewWindow* view0 = theModel->createSubWindow();
+  updateWindowTitle( view0 );
   view0->setParent( centralFrame );
   myViews.append( view0 ); // MAIN_VIEW
 
@@ -52,6 +53,17 @@ OCCViewer_ViewFrame::~OCCViewer_ViewFrame()
 {
 }
 
+bool OCCViewer_ViewFrame::event( QEvent* e )
+{
+  if ( e->type() == QEvent::WindowTitleChange ) {
+    updateWindowTitle( getView( MAIN_VIEW ) );
+    updateWindowTitle( getView( BOTTOM_LEFT ) );
+    updateWindowTitle( getView( TOP_LEFT ) );
+    updateWindowTitle( getView( TOP_RIGHT ) );
+  }
+  return OCCViewer_ViewWindow::event( e );
+}
+
 //**************************************************************************************
 OCCViewer_ViewWindow* OCCViewer_ViewFrame::getView( const int i ) const
 {
@@ -101,6 +113,7 @@ void OCCViewer_ViewFrame::onMaximizedView( OCCViewer_ViewWindow* theView, bool i
         view->set2dMode( (Mode2dType) i );
         view->setParent( centralWidget() );
         view->setViewManager(myManager); 
+       updateWindowTitle( view );
         myViews.append( view ); 
         aModel->initView(view);
         view->setMaximized(false, false);
@@ -337,3 +350,30 @@ void OCCViewer_ViewFrame::setVisualParameters( const QString& parameters )
     getView(MAIN_VIEW)->setVisualParameters( parameters );
   }
 }
+
+SUIT_CameraProperties OCCViewer_ViewFrame::cameraProperties()
+{
+  // view frame does not have camera properties
+  return SUIT_CameraProperties();
+}
+
+void OCCViewer_ViewFrame::updateWindowTitle(OCCViewer_ViewWindow* theView)
+{
+  if ( !theView )
+    return;
+  QString title;
+  switch ( theView->get2dMode() ) {
+  case No2dMode:
+    title = "3D"; break;
+  case XYPlane:
+    title = "YX"; break;
+  case XZPlane:
+    title = "XZ"; break;
+  case YZPlane:
+    title = "YZ"; break;
+  default:
+    break;
+  }
+  if ( !title.isEmpty() )
+    theView->setWindowTitle( windowTitle() + " - " + title );
+}
index b00bc6a8ba538f0e1782abb8417c08821b1704bd..b9ce195e238ca19d2410fdaced23e83f0b306966 100644 (file)
@@ -41,6 +41,8 @@ public:
   OCCViewer_ViewFrame(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel);
   virtual ~OCCViewer_ViewFrame();
 
+  bool event( QEvent* e );
+
   OCCViewer_ViewWindow*   getView( const int ) const;
 
   virtual OCCViewer_ViewPort3d* getViewPort() { return getView(MAIN_VIEW)->getViewPort(); }
@@ -82,6 +84,8 @@ public:
 
   virtual void   setDropDownButtons( bool );
 
+  virtual SUIT_CameraProperties cameraProperties();
+
 public slots:
   virtual void onFrontView() { getView(MAIN_VIEW)->onFrontView(); }
   virtual void onViewFitAll();
@@ -123,8 +127,8 @@ private slots:
   void onContextMenuRequested(QContextMenuEvent*);
 
 private:
-  void connectViewSignals(OCCViewer_ViewWindow* theView);
-
+  void connectViewSignals( OCCViewer_ViewWindow* theView );
+  void updateWindowTitle( OCCViewer_ViewWindow* theView );
 
   QList<OCCViewer_ViewWindow*> myViews;
   QGridLayout* myLayout;
index 26e9ba79db5f86e6772d1b1dbdce2634d67a52a6..0a4905ef930632f59202a8937fe92175ae9b1190 100755 (executable)
@@ -287,6 +287,8 @@ void OCCViewer_ViewWindow::initLayout()
   QtxAction* anAction = dynamic_cast<QtxAction*>( toolMgr()->action( GraduatedAxesId ) );
   myCubeAxesDlg = new OCCViewer_CubeAxesDlg( anAction, this, "OCCViewer_CubeAxesDlg" );
   myCubeAxesDlg->initialize();
+  
+  connect( myViewPort, SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), this, SLOT( emitViewModified() ) );
 }
 
 OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const
@@ -1240,15 +1242,8 @@ void OCCViewer_ViewWindow::createActions()
   connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView()));
   toolMgr()->registerAction( aAction, MaximizedId );
 
-  // Synchronize view
-  aAction = new QtxAction(tr("MNU_SYNCHRONIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SYNC" ) ),
-                          tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this );
-  aAction->setStatusTip(tr("DSC_SYNCHRONIZE_VIEW"));
-  aAction->setMenu( new QMenu( this ) );
-  aAction->setCheckable(true);
-  connect(aAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateSyncViews()));
-  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSynchronizeView(bool)));
-  toolMgr()->registerAction( aAction, SynchronizeId );
+  // Synchronize View 
+  toolMgr()->registerAction( synchronizeAction(), SynchronizeId );
 }
 
 /*!
@@ -1547,7 +1542,10 @@ void OCCViewer_ViewWindow::onAxialScale()
     myScalingDlg = new OCCViewer_AxialScaleDlg( this );
   
   if ( !myScalingDlg->isVisible() )
+  {
+    myScalingDlg->Update();
     myScalingDlg->show();
+  }
 }
 
 /*!
@@ -2493,144 +2491,174 @@ void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList )
   myViewAspects = aViewList;
 }
 
-void OCCViewer_ViewWindow::synchronizeView( OCCViewer_ViewWindow* viewWindow, int id )
+/*!
+  Get camera properties for the OCC view window.
+  \return shared pointer on camera properties.
+*/
+SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
 {
-  OCCViewer_ViewWindow* otherViewWindow = 0;
-  QList<OCCViewer_ViewWindow*> compatibleViews;
+  SUIT_CameraProperties aProps;
 
-  bool isSync = viewWindow->toolMgr()->action( SynchronizeId )->isChecked();
+  Handle(V3d_View) aSourceView = getViewPort()->getView();
+  if ( aSourceView.IsNull() )
+    return aProps;
 
-  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 ) {
-      OCCViewer_ViewWindow* occVW = dynamic_cast<OCCViewer_ViewWindow*>( vw );
-      if ( !occVW ) continue;
-
-      // check only compatible types
-      occVW = occVW->getView( viewWindow->get2dMode() );
-      if ( occVW ) {
-       if ( occVW->getId() == id ) 
-         otherViewWindow = occVW;
-       else if ( occVW != viewWindow )
-         compatibleViews.append( occVW );
-      }
-    }
+  if ( get2dMode() == No2dMode ) {
+    aProps.setDimension( SUIT_CameraProperties::Dim3D );
   }
-
-  if ( isSync && id ) {
-    // remove all possible disconnections
-    foreach( OCCViewer_ViewWindow* vw, compatibleViews ) {
-      // disconnect target view
-      vw->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), vw->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      if ( otherViewWindow ) {
-       // disconnect source view
-       vw->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-       otherViewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), vw->getViewPort(), SLOT( synchronize( OCCViewer_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->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      otherViewWindow->getViewPort()->connect( viewWindow->getViewPort(), SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      viewWindow->getViewPort()->connect( otherViewWindow->getViewPort(), SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-      // synchronize target view with source view
-      viewWindow->getViewPort()->synchronize( otherViewWindow->getViewPort() );
-      viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
-      QAction* anOtherAcion = otherViewWindow->toolMgr()->action( SynchronizeId );
-      if (anOtherAcion) {
-        anOtherAcion->setData( viewWindow->getId() );
-        if ( !anOtherAcion->isChecked() ) {
-               bool blocked = anOtherAcion->blockSignals( true );
-               anOtherAcion->setChecked( true );
-               anOtherAcion->blockSignals( blocked );
-        }
-      }
-    }
-  }
-  else if ( otherViewWindow ) {
-    // reconnect source and target view
-    otherViewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), viewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-    viewWindow->getViewPort()->disconnect( SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), otherViewWindow->getViewPort(), SLOT( synchronize( OCCViewer_ViewPort* ) ) );
-    viewWindow->getViewPort()->synchronize( otherViewWindow->getViewPort() );
-    viewWindow->toolMgr()->action( SynchronizeId )->setData( otherViewWindow->getId() );
-    QAction* anOtherAcion = otherViewWindow->toolMgr()->action( SynchronizeId );
-    if (anOtherAcion) {
-      if ( anOtherAcion->data().toInt() == viewWindow->getId() && anOtherAcion->isChecked() ) {
-        bool blocked = anOtherAcion->blockSignals( true );
-        anOtherAcion->setChecked( false );
-        anOtherAcion->blockSignals( blocked );
-      }
-    }
+  else {
+    aProps.setDimension( SUIT_CameraProperties::Dim2D );
+    aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() );
   }
+  
+  // read common properites of the view
+  Standard_Real anUpDir[3];
+  Standard_Real aPrjDir[3];
+  Standard_Real aMapScale[2];
+  Standard_Real aTranslation[3];
+  Standard_Real anAxialScale[3];
+  
+  aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]);
+  aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]);
+  aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
+  aSourceView->Size(aMapScale[0], aMapScale[1]);
+
+  getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+
+  // we use similar depth to the one used in perspective projection 
+  // to proivde a convinience synchronization with other camera views that
+  // can switch between orthogonal & perspective projection. otherwise,
+  // the camera will get to close when switching from orthogonal to perspective.
+  Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5;
+
+  // store common props
+  aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
+  aProps.setMappingScale(aMapScale[1] / 2.0);
+  aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  
+  // generate view orientation matrix for transforming OCC projection reference point
+  // into a camera (eye) position.
+  gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
+    gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2]));
+
+  gp_Trsf aTrsf;
+  aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0],
+                   aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1],
+                   aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2],
+                   Precision::Confusion(),
+                   Precision::Confusion() );
+
+  // get projection reference point in view coordinates
+  Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint();
+  
+  // transform to world-space coordinate system
+  gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf);
+  
+  // compute focal point
+  double aFocalPoint[3];
+
+  aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth;
+  aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth;
+  aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth;
+
+  aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+  aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z());
+
+  return aProps;
 }
 
 /*!
-  "Synchronize View" action slot.
+  Synchronize views.
+  This implementation synchronizes OCC view's camera propreties.
 */
-void OCCViewer_ViewWindow::onSynchronizeView(bool checked)
+void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
 {
-  QAction* a = qobject_cast<QAction*>( sender() );
-  if ( a ) {
-    synchronizeView( this, a->data().toInt() );
-  }
-}
+  bool blocked = blockSignals( true );
 
-/*!
-  Update list of available view for the "Synchronize View" action
-*/
-void OCCViewer_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 ) { 
-      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 ) {
-         OCCViewer_ViewWindow* occVW = dynamic_cast<OCCViewer_ViewWindow*>( vw );
-         if ( !occVW || occVW == this ) continue;
-         // list only compatible types
-         OCCViewer_ViewWindow* subWindow = occVW->getView( get2dMode() );
-         if ( subWindow && subWindow != this ) {
-           QAction* a = anAction->menu()->addAction( occVW->windowTitle() );
-           if ( subWindow->getId() == currentId ) {
-             QFont f = a->font();
-             f.setBold( true );
-             a->setFont( f );
-           }
-           a->setData( subWindow->getId() );
-           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" ) );
-    }
+  SUIT_CameraProperties aProps = theView->cameraProperties();
+  if ( !cameraProperties().isCompatible( aProps ) ) {
+    // other view, this one is being currently synchronized to, seems has become incompatible
+    // we have to break synchronization
+    updateSyncViews();
+    return;
   }
+
+  Handle(V3d_View) aDestView = getViewPort()->getView();
+
+  aDestView->SetImmediateUpdate( Standard_False );
+
+  double anUpDir[3];
+  double aPosition[3];
+  double aFocalPoint[3];
+  double aMapScaling;
+  double anAxialScale[3];
+
+  // get common properties
+  aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+  aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
+  aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
+  aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  aMapScaling = aProps.getMappingScale() * 2.0;
+
+  gp_Dir aProjDir(aPosition[0] - aFocalPoint[0],
+                  aPosition[1] - aFocalPoint[1],
+                  aPosition[2] - aFocalPoint[2]);
+  
+  // get custom view translation
+  Standard_Real aTranslation[3];
+  aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
+
+  gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
+    gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z()));
+
+  // convert camera position into a view reference point
+  gp_Trsf aTrsf;
+  aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0],
+                   aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1],
+                   aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], 
+                   Precision::Confusion(),
+                   Precision::Confusion() );
+  aTrsf.Invert();
+
+  // transform to view-space coordinate system
+  gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
+  aProjRef.Transform(aTrsf);
+
+  // set view camera properties using low-level approach. this is done
+  // in order to avoid interference with static variables in v3d view used
+  // when rotation is in process in another view.
+  Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping();
+  Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation();
+
+  Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z());
+  Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]);
+
+  aMappingProj.Normalize();
+  aMappingUp.Normalize();
+
+  anOrientation.SetViewReferencePlane(aMappingProj);
+  anOrientation.SetViewReferenceUp(aMappingUp);
+
+  aDestView->SetViewMapping(aMapping);
+  aDestView->SetViewOrientation(anOrientation);
+
+  // set panning
+  aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
+
+  // set mapping scale
+  Standard_Real aWidth, aHeight;
+  aDestView->Size(aWidth, aHeight);
+  
+  if ( aWidth > aHeight )
+    aDestView->SetSize (aMapScaling * (aWidth / aHeight));
+  else
+    aDestView->SetSize (aMapScaling);
+
+  getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+
+  aDestView->ZFitAll();
+  aDestView->SetImmediateUpdate( Standard_True );
+  aDestView->Redraw();
+
+  blockSignals( blocked );
 }
index 28d3d8d649bf53aea819a0b044f813fa02386e1d..625e4c58cf826d0d327b3fd532a8181d644e2a3e 100755 (executable)
@@ -195,6 +195,8 @@ public:
   virtual void                    updateViewAspects( const viewAspectList& );
   virtual void                    clearViewAspects();
 
+  virtual SUIT_CameraProperties   cameraProperties();
+
 public slots:
   virtual void onFrontView();
   virtual void onViewFitAll();
@@ -244,6 +246,9 @@ signals:
   void Hide( QHideEvent * );
   void maximized( OCCViewer_ViewWindow*, bool );
 
+protected slots:
+  void synchronize( SUIT_ViewWindow* );
+
 public:
   virtual QImage dumpView();
   virtual bool   dumpViewToFormat( const QImage&, const QString& fileName, const QString& format );
@@ -315,13 +320,6 @@ protected:
 
   double myCurScale;
 
-private slots:
-  void                  onSynchronizeView(bool);
-  void                  updateSyncViews();
-
-private:
-  static void           synchronizeView( OCCViewer_ViewWindow*, int );
-
 private:
   OCCViewer_ClippingDlg* myClippingDlg;
   QtxAction* myClippingAction;
index 21c1ae70581fb893b2a1d34b5e5bdfdcf7428467..40bb075112c5cb4bdc789dc2005573086f1c920c 100644 (file)
         <source>ICON_OCCVIEWER_MINIMIZE</source>
         <translation>occ_view_minimized.png</translation>
     </message>
-    <message>
-        <source>ICON_OCCVIEWER_SYNC</source>
-        <translation>occ_view_sync.png</translation>
-    </message>
 </context>
 </TS>
index 301870645feacc1a2c5cd258b7605e98a8291628..029eda7dc759c5686877b7047400c9d0ff4be19b 100644 (file)
         <source>DSC_MINIMIZE_VIEW</source>
         <translation>Minimize view</translation>
     </message>
-    <message>
-        <source>DSC_SYNCHRONIZE_VIEW</source>
-        <translation>Synchronize view</translation>
-    </message>
     <message>
         <source>MNU_MAXIMIZE_VIEW</source>
         <translation>Maximize</translation>
         <source>MNU_MINIMIZE_VIEW</source>
         <translation>Minimize</translation>
     </message>
-    <message>
-        <source>MNU_SYNCHRONIZE_VIEW</source>
-        <translation>Synchronize</translation>
-    </message>
-    <message>
-        <source>MNU_SYNC_NO_VIEW</source>
-        <translation>[ No appropriate view ]</translation>
-    </message>
 </context>
 <context>
     <name>OCCViewer_CreateRestoreViewDlg</name>
index 843d08b779e706f0f12fb74b22f1ca69624fd899..c54f679891909763a1d8aaa89d5d378800365de2 100755 (executable)
         <source>DSC_MINIMIZE_VIEW</source>
         <translation>Minimiser la vue</translation>
     </message>
-    <message>
-        <source>DSC_SYNCHRONIZE_VIEW</source>
-        <translation>Synchroniser la vue</translation>
-    </message>
     <message>
         <source>MNU_MAXIMIZE_VIEW</source>
         <translation>Maximiser</translation>
         <source>MNU_MINIMIZE_VIEW</source>
         <translation>Minimiser</translation>
     </message>
-    <message>
-        <source>MNU_SYNCHRONIZE_VIEW</source>
-        <translation>Synchroniser</translation>
-    </message>
-    <message>
-        <source>MNU_SYNC_NO_VIEW</source>
-        <translation>[ Pas de vue appropriée ]</translation>
-    </message>
 </context>
 <context>
     <name>OCCViewer_CreateRestoreViewDlg</name>
diff --git a/src/OCCViewer/resources/occ_view_sync.png b/src/OCCViewer/resources/occ_view_sync.png
deleted file mode 100755 (executable)
index 32b9522..0000000
Binary files a/src/OCCViewer/resources/occ_view_sync.png and /dev/null differ
index fcd2d6c293232bd32dffff4001e04e333c891e27..e2f2c98e2c922003b306d475b11b63572fc7524b 100644 (file)
@@ -59,6 +59,7 @@ SET(GUI_HEADERS
   SUIT_ViewModel.h 
   SUIT_ViewWindow.h 
   SUIT_ShortcutMgr.h
+  SUIT_CameraProperties.h
 )
 QT4_WRAP_CPP(GUI_HEADERS_MOC ${GUI_HEADERS})
 
@@ -93,6 +94,7 @@ SET(suit_SOURCES
   SUIT_ViewModel.cxx
   SUIT_ViewWindow.cxx
   SUIT_ShortcutMgr.cxx
+  SUIT_CameraProperties.cxx
 )
 SET(GUITS_SOURCES
   resources/SUIT_msg_en.ts
index 68f6184c0e8859e1d9a71ff61875bbe845674f23..e9ec7b620a63dd3da47bbad792b8bc1b6c2d7300 100755 (executable)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-#  File   : Makefile.in
-#  Author : Vladimir Klyachin (OCN)
-#  Module : suit
-#  $Header$
-#
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 lib_LTLIBRARIES = libsuit.la
@@ -62,7 +57,8 @@ salomeinclude_HEADERS =                       \
        SUIT_ViewManager.h              \
        SUIT_ViewModel.h                \
        SUIT_ViewWindow.h               \
-       SUIT_ShortcutMgr.h
+       SUIT_ShortcutMgr.h              \
+       SUIT_CameraProperties.h
 
 dist_libsuit_la_SOURCES =              \
        SUIT_Accel.cxx                  \
@@ -94,7 +90,8 @@ dist_libsuit_la_SOURCES =             \
        SUIT_ViewManager.cxx            \
        SUIT_ViewModel.cxx              \
        SUIT_ViewWindow.cxx             \
-       SUIT_ShortcutMgr.cxx
+       SUIT_ShortcutMgr.cxx            \
+       SUIT_CameraProperties.cxx
 
 MOC_FILES =                            \
        SUIT_Accel_moc.cxx              \
@@ -124,11 +121,11 @@ nodist_salomeres_DATA =                   \
        SUIT_msg_en.qm                  \
        SUIT_msg_fr.qm                  \
        SUIT_images.qm
-               
+
 dist_salomeres_DATA =                     \
        resources/icon_visibility_on.png  \
-       resources/icon_visibility_off.png
-                               
+       resources/icon_visibility_off.png \
+       resources/view_sync.png
 
 libsuit_la_CPPFLAGS = $(QT_INCLUDES) -I$(srcdir)/../Qtx -I$(srcdir)/../ObjBrowser
 
diff --git a/src/SUIT/SUIT_CameraProperties.cxx b/src/SUIT/SUIT_CameraProperties.cxx
new file mode 100644 (file)
index 0000000..2848887
--- /dev/null
@@ -0,0 +1,357 @@
+// Copyright (C) 2007-2012  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.
+//
+// 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
+//
+
+#include "SUIT_CameraProperties.h"
+
+/*!
+  \class SUIT_CameraProperties
+  \brief Base class for Camera Properties
+  
+  This class provides common properties that
+  can be used for any arbitrary camera. This
+  properties are employed by camera synchronization
+  algorithms.
+*/
+
+/*!
+  \brief Default constructor. 
+
+  Creates invalid camera properties data, i.e. IsValid() returns \c false.
+*/
+SUIT_CameraProperties::SUIT_CameraProperties()
+{
+  // init with some default values
+  myUpDir[0] = 0.0;
+  myUpDir[1] = 1.0;
+  myUpDir[2] = 0.0;
+  
+  myPosition[0] = 0.0;
+  myPosition[1] = 0.0;
+  myPosition[2] = 500.0;
+  
+  myFocalPoint[0] = 0.0;
+  myFocalPoint[1] = 0.0;
+  myFocalPoint[2] = 0.0;
+    
+  myAxialScale[0] = 1.0;
+  myAxialScale[1] = 1.0;
+  myAxialScale[2] = 1.0;
+  
+  myMappingScale = 1000;
+
+  myDimension   = DimNone;        // none dimension by default
+  myProjection  = PrjOrthogonal;  // orthogonal projection by default
+  myViewSide    = ViewNone;       // no side view by default
+  
+  myViewAngle = 45.0;
+}
+
+/*!
+  \brief Destructor
+*/
+SUIT_CameraProperties::~SUIT_CameraProperties()
+{
+}
+
+/*!
+  \brief Check if camera properties are valid.
+  \return \c true if camera properties data is valid.
+  \sa setDimension()
+*/
+bool SUIT_CameraProperties::isValid() const
+{
+  return myDimension != DimNone;
+}
+
+/*!
+  \brief Check if this camera properties data is compatible with other camera properties.
+  \param other other properties data
+  \return \c true if both camera properties sets are compatible
+*/
+bool SUIT_CameraProperties::isCompatible( const SUIT_CameraProperties& other )
+{
+  bool result = false;
+  // check only valid data and data with same dimensions
+  if ( isValid() && other.isValid() && getDimension() == other.getDimension() ) {
+    switch( getDimension() ) {
+    case SUIT_CameraProperties::Dim2D:
+      // two 2d views are compatible if their view side is the same
+      result = getViewSide() == other.getViewSide();
+      break;
+    case SUIT_CameraProperties::Dim3D:
+      // two 3d views are compatible if their projection mode is the same
+      result = getProjection() == other.getProjection();
+      break;
+    default:
+      break;
+    }
+  }
+  return result;
+}
+
+/*!
+  \brief get dimension supported by camera.
+  \return dimension mode.
+  \sa setDimension()
+*/
+SUIT_CameraProperties::Dimension SUIT_CameraProperties::getDimension() const
+{
+  return myDimension;
+}
+
+/*!
+  \brief set dimension supported by camera.
+  \param theDimension [in] dimension mode.
+  \sa getDimension()
+*/
+void SUIT_CameraProperties::setDimension( const SUIT_CameraProperties::Dimension theDimension )
+{
+  myDimension = theDimension;
+}
+
+/*!
+  \brief get side view supported by camera (for 2d viewer).
+
+  For 2d viewer, side view can be of following values:
+  - SUIT_CameraProperties::ViewNone - no side view (for instance, for true 2d viewer)
+  - SUIT_CameraProperties::ViewXY   - XY side view of 3d scene
+  - SUIT_CameraProperties::ViewXZ   - XZ side view of 3d scene
+  - SUIT_CameraProperties::ViewYZ   - YZ side view of 3d scene
+
+  \return side view.
+  \sa setViewSide()
+*/
+SUIT_CameraProperties::ViewSide SUIT_CameraProperties::getViewSide() const
+{
+  return myViewSide;
+}
+
+/*!
+  \brief set side view supported by camera (for 2d viewer).
+
+  For 2d viewer, side view can be of following values:
+  - SUIT_CameraProperties::ViewNone - no side view (for instance, for true 2d viewer)
+  - SUIT_CameraProperties::ViewXY   - XY side view of 3d scene
+  - SUIT_CameraProperties::ViewXZ   - XZ side view of 3d scene
+  - SUIT_CameraProperties::ViewYZ   - YZ side view of 3d scene
+
+  \param theViewSide [in] view side.
+  \sa getViewSide()
+*/
+void SUIT_CameraProperties::setViewSide( const SUIT_CameraProperties::ViewSide theViewSide )
+{
+  myViewSide = theViewSide;
+}
+
+/*!
+  \brief get projection mode supported by camera (for 3d viewer).
+
+  For 3d viewer, projection mode can be of following values:
+  - SUIT_CameraProperties::PrjOrthogonal - orthogonal projection
+  - SUIT_CameraProperties::PrjPerspective - perspective projection
+
+  \return projection mode.
+  \sa setProjection()
+*/
+SUIT_CameraProperties::Projection SUIT_CameraProperties::getProjection() const
+{
+  return myProjection;
+}
+
+/*!
+  \brief set projection mode supported by camera (for 3d viewer).
+
+  For 3d viewer, projection mode can be of following values:
+  - SUIT_CameraProperties::PrjOrthogonal - orthogonal projection
+  - SUIT_CameraProperties::PrjPerspective - perspective projection
+
+  \param theProjection [in] projection mode.
+  \sa getProjection()
+*/
+void SUIT_CameraProperties::setProjection( const SUIT_CameraProperties::Projection theProjection )
+{
+  myProjection = theProjection;
+}
+
+/*!
+  \brief get camera up direction vector.
+  \param theX [out] vector's x coordinate in world-coordinates space.
+  \param theY [out] vector's y coordinate in world-coordinates space.
+  \param theZ [out] vector's z coordinate in world-coordinates space.
+  \sa setViewUp()
+*/
+void SUIT_CameraProperties::getViewUp(double& theX, double& theY, double& theZ) const
+{
+  theX = myUpDir[0];
+  theY = myUpDir[1];
+  theZ = myUpDir[2];
+}
+
+/*!
+  \brief set camera up direction vector.
+
+  It is recommended to set normalized vector coordinates for
+  synchronization compatibility.
+  
+  \param theX [in] vector's x coordinate in world-coordinates space.
+  \param theY [in] vector's y coordinate in world-coordinates space.
+  \param theZ [in] vector's z coordinate in world-coordinates space.
+  \sa getViewUp()
+*/
+void SUIT_CameraProperties::setViewUp(const double theX, const double theY, const double theZ)
+{
+  myUpDir[0] = theX;
+  myUpDir[1] = theY;
+  myUpDir[2] = theZ;
+}
+
+/*!
+  \brief get camera's position (eye).
+  \param theX [out] x coordinate in world-coordinates space.
+  \param theY [out] y coordinate in world-coordinates space.
+  \param theZ [out] z coordinate in world-coordinates space.
+  \sa setPosition()
+*/
+void SUIT_CameraProperties::getPosition(double& theX, double& theY, double& theZ) const
+{
+  theX = myPosition[0];
+  theY = myPosition[1];
+  theZ = myPosition[2];
+}
+
+/*!
+  \brief get camera's position (eye).
+  \param theX [in] x coordinate in world-coordinates space.
+  \param theY [in] y coordinate in world-coordinates space.
+  \param theZ [in] z coordinate in world-coordinates space.
+  \sa getPosition()
+*/
+void SUIT_CameraProperties::setPosition(const double theX, const double theY, const double theZ)
+{
+  myPosition[0] = theX;
+  myPosition[1] = theY;
+  myPosition[2] = theZ;
+}
+
+/*!
+  \brief get camera's focal point (look point).
+  \param theX [out] x coordinate in world-coordinates space.
+  \param theY [out] y coordinate in world-coordinates space.
+  \param theZ [out] z coordinate in world-coordinates space.
+  \sa setFocalPoint()
+*/
+void SUIT_CameraProperties::getFocalPoint(double& theX, double& theY, double& theZ) const
+{
+  theX = myFocalPoint[0];
+  theY = myFocalPoint[1];
+  theZ = myFocalPoint[2];
+}
+
+/*!
+  \brief set camera's focal point (look point).
+  \param theX [in] x coordinate in world-coordinates space.
+  \param theY [in] y coordinate in world-coordinates space.
+  \param theZ [in] z coordinate in world-coordinates space.
+  \sa getFocalPoint()
+*/
+void SUIT_CameraProperties::setFocalPoint(const double theX, const double theY, const double theZ)
+{
+  myFocalPoint[0] = theX;
+  myFocalPoint[1] = theY;
+  myFocalPoint[2] = theZ;
+}
+
+/*!
+  \brief get window mapping scale (parallel scale).
+
+  Mapping scale defines a mapping scaling factor for the height
+  of the viewport in world-coordinate distances.
+
+  \return scaling value.
+  \sa setMappingScale()
+*/
+double SUIT_CameraProperties::getMappingScale() const
+{
+  return myMappingScale;
+}
+
+/*!
+  \brief set window mapping scale (parallel scale).
+
+  Mapping scale defines a mapping scaling factor for the height
+  of the viewport in world-coordinate distances.
+
+  \param theScale [in] the scaling.
+  \sa getMappingScale()
+*/
+void SUIT_CameraProperties::setMappingScale(const double theScale)
+{
+  myMappingScale = theScale;
+}
+
+/*! 
+  \brief get scaling factors for world-coordinate space axes.
+  \param theScaleX [out] scale by x coordinate.
+  \param theScaleY [out] scale by y coordinate.
+  \param theScaleZ [out] scale by z coordinate.
+  \sa setAxialScale()
+*/
+void SUIT_CameraProperties::getAxialScale(double& theScaleX, double& theScaleY, double& theScaleZ)
+{
+  theScaleX = myAxialScale[0];
+  theScaleY = myAxialScale[1];
+  theScaleZ = myAxialScale[2];
+}
+
+/*!
+  \brief set scaling factors for world-coordinate space axes.
+  \param theScaleX [in] scale by x coordinate.
+  \param theScaleY [in] scale by y coordinate.
+  \param theScaleZ [in] scale by z coordinate.
+  \sa getAxialScale()
+*/
+void SUIT_CameraProperties::setAxialScale(const double theScaleX, const double theScaleY, const double theScaleZ)
+{ 
+  myAxialScale[0] = theScaleX;
+  myAxialScale[1] = theScaleY;
+  myAxialScale[2] = theScaleZ;
+}
+
+/*!
+  \brief get angle (typically in degrees) of view for perpective projection mode.
+  \return the angle of view.
+  \sa setViewAngle()
+*/
+double SUIT_CameraProperties::getViewAngle() const
+{
+  return myViewAngle;
+}
+
+/*!
+  \brief set angle (typically in degrees) of view for perpective projection mode.
+  \param theViewAngle [in] the angle of view.
+  \sa getViewAngle()
+*/
+void SUIT_CameraProperties::setViewAngle(const double theViewAngle)
+{
+  myViewAngle = theViewAngle;
+}
diff --git a/src/SUIT/SUIT_CameraProperties.h b/src/SUIT/SUIT_CameraProperties.h
new file mode 100644 (file)
index 0000000..366de65
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2007-2012  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.
+//
+// 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
+//
+
+#ifndef SUIT_CAMERAPROPERITES_H
+#define SUIT_CAMERAPROPERITES_H
+
+#include "SUIT.h"
+
+class SUIT_EXPORT SUIT_CameraProperties
+{
+public:
+  enum Dimension  { DimNone, Dim2D, Dim3D };
+  enum ViewSide   { ViewNone, ViewXY, ViewXZ, ViewYZ };
+  enum Projection { PrjOrthogonal, PrjPerspective };
+
+  SUIT_CameraProperties();
+  virtual ~SUIT_CameraProperties();
+
+  bool       isValid() const;
+  bool       isCompatible( const SUIT_CameraProperties& other );
+
+  Dimension  getDimension() const;
+  void       setDimension( const Dimension theDimension );
+
+  ViewSide   getViewSide() const;
+  void       setViewSide( const ViewSide theViewSide );
+
+  Projection getProjection() const;
+  void       setProjection( const Projection theProjection );
+
+  void       getViewUp(double& theX, double& theY, double& theZ) const;
+  void       setViewUp(const double theX, const double theY, const double theZ);
+
+  void       getPosition(double& theX, double& theY, double& theZ) const;
+  void       setPosition(const double theX, const double theY, const double theZ);
+
+  void       getFocalPoint(double& theX, double& theY, double& theZ) const;
+  void       setFocalPoint(const double theX, const double theY, const double theZ);
+
+  double     getMappingScale() const;
+  void       setMappingScale(const double theScale);
+
+  void       getAxialScale(double& theScaleX, double& theScaleY, double& theScaleZ);
+  void       setAxialScale(const double theScaleX, const double theScaleY, const double theScaleZ);
+
+  double     getViewAngle() const;
+  void       setViewAngle(const double theViewAngle);
+  
+// common properties for all viewers
+private:
+  Dimension  myDimension;        //!< dimension
+  ViewSide   myViewSide;         //!< side view (for 2d viewer)
+  Projection myProjection;       //!< projection mode (for 3d viewer): orthogonal / perspective
+  double     myUpDir[3];         //!< camera up vector
+  double     myPosition[3];      //!< camera position (eye).
+  double     myFocalPoint[3];    //!< focal point position in world-space coordinates
+  double     myMappingScale;     //!< window mapping scale (parallel projection scale)
+  double     myAxialScale[3];    //!< scaling factors for world axes
+  double     myViewAngle;        //!< perspective view angle in degrees
+};
+
+#endif // SUIT_CAMERAPROPERITES_H
index 6bf0ebe3c3a8fb0bcbe60f56659d07fc08d70787..b063cbb8be07b65b3ea0dac166bd314fa2878c2a 100755 (executable)
 #include "SUIT_ViewWindow.h"
 
 #include "SUIT_Tools.h"
+#include "SUIT_Session.h"
 #include "SUIT_Study.h"
 #include "SUIT_Desktop.h"
 #include "SUIT_MessageBox.h"
 #include "SUIT_Application.h"
 #include "SUIT_ViewManager.h"
+#include "SUIT_ResourceMgr.h"
 #include "QtxActionToolMgr.h"
 #include "QtxMultiAction.h"
 
 #include <QEvent>
 #include <QIcon>
+#include <QMenu>
 #include <QApplication>
 #include <QContextMenuEvent>
 
@@ -47,7 +50,7 @@ const int DUMP_EVENT = QEvent::User + 123;
 
 /*! Constructor.*/
 SUIT_ViewWindow::SUIT_ViewWindow( SUIT_Desktop* theDesktop )
-  : QMainWindow( theDesktop ), myManager( 0 ), myIsDropDown( true )
+  : QMainWindow( theDesktop ), myManager( 0 ), myIsDropDown( true ), mySyncAction( 0 )
 {
   myDesktop = theDesktop;
 
@@ -259,7 +262,7 @@ QtxActionToolMgr* SUIT_ViewWindow::toolMgr() const
 }
 
 /*!
-  \brief Set buttons mode to drop-down (\a on = \c true) or ligned (\a on = \c false) 
+  \brief Set buttons mode to drop-down (\a on = \c true) or ligned (\a on = \c false)
   \param on new buttons mode
   \sa dropDownButtons()
 */
@@ -320,9 +323,222 @@ bool SUIT_ViewWindow::dropDownButtons() const
 }
 
 /*!
-  \return window unique identifier  
+  \return window unique identifier
 */
 int SUIT_ViewWindow::getId() const
 {
   return int(long(this));
 }
+
+/*!
+  Get camera properties for the view window.
+  \return shared pointer on camera properties. Base implementation
+          returns null properties.
+*/
+SUIT_CameraProperties SUIT_ViewWindow::cameraProperties()
+{
+  return SUIT_CameraProperties();
+}
+
+/*!
+  Synchronize this view window's camera properties with specified
+  view window.
+
+  This method is a part of general views synchronization mechanism.
+  It should be redefined in successors. Base imlementation does nothing.
+
+  \param otherWindow other view window
+*/
+void SUIT_ViewWindow::synchronize( SUIT_ViewWindow* /*otherWindow*/ )
+{
+  // base implementation does nothing
+}
+
+/*!
+  Get action for views syncronization.
+
+  This method is a part of general views synchronization mechanism.
+  It creates an action that can be inserted, for instance, to the toolbar.
+
+  \return action for views synchronization
+*/
+QAction* SUIT_ViewWindow::synchronizeAction()
+{
+  if ( !mySyncAction ) {
+    SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+    mySyncAction = new QtxAction( tr( "MNU_SYNCHRONIZE_VIEW" ),
+                                 resMgr->loadPixmap( "SUIT", tr( "ICON_VIEW_SYNC" ) ),
+                                 tr( "MNU_SYNCHRONIZE_VIEW" ), 0, this );
+    mySyncAction->setStatusTip( tr( "DSC_SYNCHRONIZE_VIEW" ) );
+    mySyncAction->setMenu( new QMenu( this ) );
+    mySyncAction->setCheckable( true );
+    connect( mySyncAction->menu(), SIGNAL( aboutToShow() ),     this, SLOT( updateSyncViews() ) );
+    connect( mySyncAction,         SIGNAL( triggered( bool ) ), this, SLOT( onSynchronizeView( bool ) ) );
+  }
+  return mySyncAction;
+}
+
+/*!
+  Emit notification signal that the view is transformed.
+  Other views can use the signal for synchronization.
+*/
+void SUIT_ViewWindow::emitViewModified()
+{
+  emit viewModified( this );
+}
+
+/*!
+  Update list of available view for the "Synchronize View" action
+*/
+void SUIT_ViewWindow::updateSyncViews()
+{
+  SUIT_CameraProperties props = cameraProperties();
+  if ( !props.isValid() )
+    return;
+
+  QAction* anAction = synchronizeAction();
+  if ( anAction && anAction->menu() ) {
+    int currentId = anAction->data().toInt();
+    anAction->menu()->clear();
+    SUIT_Application* app = SUIT_Session::session()->activeApplication();
+    if ( app ) {
+      SUIT_Desktop* d = app->desktop();
+      QList<SUIT_ViewWindow*> allViews = qFindChildren<SUIT_ViewWindow*>( d );
+      foreach( SUIT_ViewWindow* vw, allViews ) {
+       if ( !vw || vw == this ) continue; // skip invalid views and this one
+       SUIT_CameraProperties otherProps = vw->cameraProperties();
+       if ( otherProps.isCompatible( props ) ) {
+         QAction* a = anAction->menu()->addAction( vw->windowTitle() );
+         if ( vw->getId() == currentId ) {
+           QFont f = a->font();
+           f.setBold( true );
+           a->setFont( f );
+         }
+         a->setData( vw->getId() );
+         connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onSynchronizeView( bool ) ) );
+       }
+       else if ( vw->getId() == currentId ) {
+         // other view, this one is being currently synchronized to, seems has become incompatible
+         // we have to break synchronization
+         vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), this, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+         this->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+         // 
+         bool blocked = anAction->blockSignals( true );
+         anAction->setChecked( false );
+         anAction->blockSignals( blocked );
+         anAction->setData( 0 );
+         //
+         QAction* a = vw->synchronizeAction();
+         if ( a ) {
+           blocked = a->blockSignals( true );
+           a->setChecked( false );
+           a->blockSignals( blocked );
+         }
+       }
+      }
+    }
+    if ( anAction->menu()->actions().isEmpty() ) {
+      anAction->setData( 0 );
+      anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) );
+    }
+  }
+}
+
+/*!
+  "Synchronize View" action slot.
+*/
+void SUIT_ViewWindow::onSynchronizeView( bool checked )
+{
+  QAction* a = qobject_cast<QAction*>( sender() );
+  if ( a ) {
+    synchronizeView( this, a->data().toInt() );
+  }
+}
+
+/*!
+  Synchronize camera properties of view \a viewWindow with
+  camera properties of view specified via \a id
+*/
+void SUIT_ViewWindow::synchronizeView( SUIT_ViewWindow* viewWindow, int id )
+{
+  SUIT_ViewWindow* sourceView = 0;
+  QList<SUIT_ViewWindow*> otherViews;
+
+  bool isSync = viewWindow->synchronizeAction() && viewWindow->synchronizeAction()->isChecked();
+
+  int vwid = viewWindow->getId();
+
+  SUIT_Application* app = SUIT_Session::session()->activeApplication();
+  if ( !app ) return;
+  SUIT_Desktop* d = app->desktop();
+  if ( !d ) return;
+
+  QList<SUIT_ViewWindow*> allViews = qFindChildren<SUIT_ViewWindow*>( d );
+  foreach( SUIT_ViewWindow* vw, allViews ) {
+    if ( !vw->cameraProperties().isValid() )
+      continue;                    // omit views not supporting camera properties
+    if ( vw->getId() == id )
+      sourceView = vw;             // remember source view
+    else if ( vw != viewWindow )
+      otherViews.append( vw );     // collect all remaining views
+  }
+
+  if ( isSync && id ) {
+    // remove all possible disconnections
+    foreach( SUIT_ViewWindow* vw, otherViews ) {
+      // disconnect target view
+      vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      if ( sourceView ) {
+       // disconnect source view
+       vw->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+       sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), vw, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      }
+      QAction* a = vw->synchronizeAction();
+      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 ( sourceView ) {
+      // reconnect source and target views
+      sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      sourceView->connect( viewWindow, SIGNAL( viewModified( SUIT_ViewWindow* ) ), SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      viewWindow->connect( sourceView, SIGNAL( viewModified( SUIT_ViewWindow* ) ), SLOT( synchronize( SUIT_ViewWindow* ) ) );
+      // synchronize target view with source view
+      viewWindow->synchronize( sourceView );
+      if ( viewWindow->synchronizeAction() )
+       viewWindow->synchronizeAction()->setData( sourceView->getId() );
+      QAction* sourceAction = sourceView->synchronizeAction();
+      if ( sourceAction ) {
+        sourceAction->setData( viewWindow->getId() );
+        if ( !sourceAction->isChecked() ) {
+         bool blocked = sourceAction->blockSignals( true );
+         sourceAction->setChecked( true );
+         sourceAction->blockSignals( blocked );
+        }
+      }
+    }
+  }
+  else if ( sourceView ) {
+    // reconnect source and target view
+    sourceView->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), viewWindow, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+    viewWindow->disconnect( SIGNAL( viewModified( SUIT_ViewWindow* ) ), sourceView, SLOT( synchronize( SUIT_ViewWindow* ) ) );
+    viewWindow->synchronize( sourceView );
+    if ( viewWindow->synchronizeAction() )
+      viewWindow->synchronizeAction() ->setData( sourceView->getId() );
+    QAction* sourceAction = sourceView->synchronizeAction();
+    if ( sourceAction ) {
+      if ( sourceAction->data().toInt() == viewWindow->getId() && sourceAction->isChecked() ) {
+        bool blocked = sourceAction->blockSignals( true );
+        sourceAction->setChecked( false );
+        sourceAction->blockSignals( blocked );
+      }
+    }
+  }
+}
index e7dc87a1a8492625fc37c8face92e17287a06b5f..bf39ba042beaba793b02a51674f540d8454279b8 100755 (executable)
@@ -26,6 +26,7 @@
 #define SUIT_VIEWWINDOW_H
 
 #include "SUIT.h"
+#include "SUIT_CameraProperties.h"
 
 #include <QMainWindow>
 #include <QList>
@@ -71,6 +72,8 @@ public:
   virtual void      setDropDownButtons( bool );
   bool              dropDownButtons() const;
 
+  virtual SUIT_CameraProperties cameraProperties();
+
 public slots:
   virtual void      onDumpView();
 
@@ -85,7 +88,8 @@ signals:
   void              keyPressed( SUIT_ViewWindow*, QKeyEvent* );
   void              keyReleased( SUIT_ViewWindow*, QKeyEvent* );
   void              contextMenuRequested( QContextMenuEvent *e );
-
+  void              viewModified( SUIT_ViewWindow* );
+  
 protected:
   void              closeEvent( QCloseEvent* );
   virtual void      contextMenuEvent( QContextMenuEvent* );
@@ -93,15 +97,25 @@ protected:
   virtual bool      action( const int );
   virtual bool      dumpViewToFormat( const QImage&, const QString& fileName, const QString& format );
 
+  virtual QAction*  synchronizeAction();
+  static void       synchronizeView( SUIT_ViewWindow* viewWindow, int id );
+  
   SUIT_Desktop*     myDesktop;
   SUIT_ViewManager* myManager;
 
+protected slots:
+  void              updateSyncViews();
+  void              onSynchronizeView(bool);
+  virtual void      synchronize( SUIT_ViewWindow* );
+  void              emitViewModified();
+  
 private:
   typedef QMap< int, QList<QtxMultiAction*> > ActionsMap;
 
   QtxActionToolMgr* myToolMgr;
   bool              myIsDropDown;
   ActionsMap        myMultiActions;
+  QAction*          mySyncAction;
 };
 
 #endif // SUIT_VIEWWINDOW_H
index ff3f7d4fcaece79d4540a7567790f90fb06d4122..63c6010503e7d186a44db1bd65c3368e51a0b8af 100644 (file)
@@ -11,5 +11,9 @@
         <source>ICON_DATAOBJ_INVISIBLE</source>
         <translation>icon_visibility_off.png</translation>
     </message>
+    <message>
+        <source>ICON_VIEW_SYNC</source>
+        <translation>view_sync.png</translation>
+    </message>
 </context>
 </TS>
index c1435da5bad404f50a62202a39d585a34dc45712..31bbc382a8d46ff7f789c34ebf8e6cf918ff57f0 100644 (file)
@@ -113,6 +113,18 @@ Do you want to overwrite it?</translation>
         <source>NAME_COLUMN</source>
         <translation>Name</translation>
     </message>
+    <message>
+        <source>MNU_SYNCHRONIZE_VIEW</source>
+        <translation>Synchronize</translation>
+    </message>
+    <message>
+        <source>DSC_SYNCHRONIZE_VIEW</source>
+        <translation>Synchronize view</translation>
+    </message>
+    <message>
+        <source>MNU_SYNC_NO_VIEW</source>
+        <translation>[ No appropriate view ]</translation>
+    </message>
 </context>
 <context>
     <name>SUIT_Study</name>
index 345b25512aaf2c3cd962ebbb3272b23ae6e75a03..d3785c28da1ece546f7d5a85e0f6c922cc31c496 100755 (executable)
@@ -113,6 +113,18 @@ Voulez-vous l&apos;écraser ?</translation>
         <source>NAME_COLUMN</source>
         <translation>Nom</translation>
     </message>
+    <message>
+        <source>MNU_SYNCHRONIZE_VIEW</source>
+        <translation>Synchroniser</translation>
+    </message>
+    <message>
+        <source>DSC_SYNCHRONIZE_VIEW</source>
+        <translation>Synchroniser la vue</translation>
+    </message>
+    <message>
+        <source>MNU_SYNC_NO_VIEW</source>
+        <translation>[ Pas de vue appropriée ]</translation>
+    </message>
 </context>
 <context>
     <name>SUIT_Study</name>
diff --git a/src/SUIT/resources/view_sync.png b/src/SUIT/resources/view_sync.png
new file mode 100644 (file)
index 0000000..32b9522
Binary files /dev/null and b/src/SUIT/resources/view_sync.png differ
index c048c3f49a9e073abe496551c4c51dada3907942..ad697f4fae752ab2b2447610f49eafd69dc57286 100755 (executable)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-#  File   : Makefile.in
-#  Author : Alexander Solovyov(OCN)
-#  Module : SVTK
-# $Header$
-#
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 lib_LTLIBRARIES = libSVTK.la
@@ -135,7 +130,6 @@ dist_salomeres_DATA=\
        resources/vtk_view_recording_play.png \
        resources/vtk_view_recording_pause.png \
        resources/vtk_view_recording_stop.png \
-       resources/vtk_view_sync.png \
        resources/vtk_view_highlight.png
 
 nodist_salomeres_DATA =        \
index 3a81fc72a29871a7ed2a78224cedd9ff22767375..271aa4c938e9e4809392a4ad2dbd9aeffce4b9f8 100755 (executable)
@@ -76,7 +76,6 @@
 #include "VTKViewer_Trihedron.h"
 
 #include "SVTK_View.h"
-//#include "SVTK_MainWindow.h"
 #include "SVTK_Selector.h"
 
 #include "SVTK_Event.h"
@@ -229,6 +228,8 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel)
 
   GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished, 
                                                     myEventCallbackCommand.GetPointer(), 0.0);
+  myKeyFreeInteractorStyle->AddObserver(SVTK::OperationFinished, 
+                                       myEventCallbackCommand.GetPointer(), 0.0);
 
 
   
@@ -259,6 +260,8 @@ void SVTK_ViewWindow::Initialize(SVTK_View* theView,
           this,SIGNAL(contextMenuRequested(QContextMenuEvent *)));
   connect(theView,SIGNAL(selectionChanged()),
           theModel,SLOT(onSelectionChanged()));
+
+  connect( this, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( emitViewModified() ) );
 }
 
 /*!
@@ -1843,6 +1846,8 @@ void SVTK_ViewWindow::onPerspectiveMode()
   vtkCamera* aCamera = getRenderer()->GetActiveCamera();
   aCamera->SetParallelProjection(anIsParallelMode);
   GetInteractor()->GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
+
+  emit transformed( this );
 }
 
 void SVTK_ViewWindow::SetEventDispatcher(vtkObject* theDispatcher)
@@ -2065,15 +2070,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr)
   mgr->registerAction( anAction, ViewParametersId );
 
   // Synchronize View 
-  anAction = new QtxAction(tr("MNU_SYNCHRONIZE_VIEW"), 
-                           theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_SVTK_SYNCHRONIZE" ) ),
-                           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(bool)), this, SLOT(onSynchronizeView(bool)));
-  mgr->registerAction( anAction, SynchronizeId );
+  mgr->registerAction( synchronizeAction(), SynchronizeId );
 
   // Switch between interaction styles
   anAction = new QtxAction(tr("MNU_SVTK_STYLE_SWITCH"), 
@@ -2361,134 +2358,6 @@ 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(bool checked)
-{
-  QAction* a = qobject_cast<QAction*>( sender() );
-  if ( a ) {
-    synchronizeView( this, a->data().toInt() );
-  }
-}
-
-/*!
-  Update list of available view for the "Synchronize View" action
-*/
-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 ) { 
-      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 == 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(bool) ), this, SLOT( onSynchronizeView(bool) ) );
-       }
-      }
-    }
-    if ( anAction->menu()->actions().isEmpty() ) {
-      anAction->setData( 0 );
-      anAction->menu()->addAction( tr( "MNU_SYNC_NO_VIEW" ) );
-    }
-  }
-}
-
-
 /*!
   Emit transformed signal.
 */
@@ -2508,3 +2377,99 @@ void SVTK_ViewWindow::ProcessEvents(vtkObject* vtkNotUsed(theObject),
   if(self)
     self->emitTransformed();
 }
+
+/*!
+  Get camera properties for the SVTK view window.
+  \return shared pointer on camera properties.
+*/
+SUIT_CameraProperties SVTK_ViewWindow::cameraProperties()
+{
+  SUIT_CameraProperties aProps;
+
+  // get vtk camera
+  vtkCamera* aCamera = getRenderer()->GetActiveCamera();
+  if ( !aCamera )
+    return aProps;
+  
+  aProps.setDimension( SUIT_CameraProperties::Dim3D );
+  if ( toolMgr()->action( ParallelModeId ) ) {
+    if ( toolMgr()->action( ParallelModeId )->isChecked() )
+      aProps.setProjection( SUIT_CameraProperties::PrjOrthogonal );
+    else
+      aProps.setProjection( SUIT_CameraProperties::PrjPerspective );
+  }
+
+  double aFocalPoint[3];
+  double aPosition[3];
+  double aViewUp[3];
+  double anAxialScale[3];
+
+  aCamera->OrthogonalizeViewUp();
+  aCamera->GetFocalPoint(aFocalPoint);
+  aCamera->GetPosition(aPosition);
+  aCamera->GetViewUp(aViewUp);
+  
+  aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+  aProps.setPosition(aPosition[0], aPosition[1], aPosition[2]);
+  aProps.setViewUp(aViewUp[0], aViewUp[1], aViewUp[2]);
+  aProps.setMappingScale(aCamera->GetParallelScale());
+
+  if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective)
+  {
+    aProps.setViewAngle(aCamera->GetViewAngle());
+  }
+
+  GetRenderer()->GetScale(anAxialScale);
+  aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  
+  return aProps;
+}
+
+/*!
+  Synchronize views.
+  This implementation synchronizes camera propreties.
+*/
+void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView )
+{
+  bool blocked = blockSignals( true );
+
+  SUIT_CameraProperties aProps = theView->cameraProperties();
+  if ( !cameraProperties().isCompatible( aProps ) ) {
+    // other view, this one is being currently synchronized to, seems has become incompatible
+    // we have to break synchronization
+    updateSyncViews();
+    return;
+  }
+
+  // get camera
+  vtkCamera* aCamera = getRenderer()->GetActiveCamera();
+  
+  double aFocalPoint[3];
+  double aPosition[3];
+  double aViewUp[3];
+  double anAxialScale[3];
+
+  // get common properties
+  aProps.getViewUp(aViewUp[0], aViewUp[1], aViewUp[2]);
+  aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
+  aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
+  aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  
+  // restore properties to the camera
+  aCamera->SetViewUp(aViewUp);
+  aCamera->SetPosition(aPosition);
+  aCamera->SetFocalPoint(aFocalPoint);
+  aCamera->SetParallelScale(aProps.getMappingScale());
+
+  if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective)
+  {
+    aCamera->SetViewAngle(aProps.getViewAngle());
+  }
+
+  GetRenderer()->SetScale(anAxialScale);
+
+  getRenderer()->ResetCameraClippingRange();
+  Repaint(false);
+
+  blockSignals( blocked );
+}
index 15c977e3eb0044b13232d805fb57a047ff0b4381..abb6c0968d7dc2ce5a170405c97a2f9ec3fd9dc8 100755 (executable)
@@ -276,6 +276,8 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow
   //! To invoke a VTK event on #SVTK_RenderWindowInteractor instance
   void InvokeEvent(unsigned long theEvent, void* theCallData);
   
+  virtual SUIT_CameraProperties cameraProperties();
+  
  signals:
   void Show( QShowEvent * );
   void Hide( QHideEvent * );
@@ -372,6 +374,7 @@ public slots:
   virtual void synchronize(SVTK_ViewWindow*);
     
 protected slots:
+  void synchronize( SUIT_ViewWindow* );
   void onKeyPressed(QKeyEvent* event);
   void onKeyReleased(QKeyEvent* event);
   void onMousePressed(QMouseEvent* event);
@@ -446,13 +449,6 @@ protected:
   vtkPVAxesWidget* myAxesWidget;
   Qtx::BackgroundData myBackground;
 
-private slots:
-  void onSynchronizeView(bool);
-  void updateSyncViews();
-
-private:
-  static void synchronizeView( SVTK_ViewWindow*, int );
-
 private:
   QImage myDumpImage;
 };
index 362ffef6e05bce95d7672a7ea037e7b622a830a7..3794dfb5484936bf515ef3d47c51d554786dbb7a 100644 (file)
         <source>ICON_SVTK_RECORDING_STOP</source>
         <translation>vtk_view_recording_stop.png</translation>
     </message>
-    <message>
-        <source>ICON_SVTK_SYNCHRONIZE</source>
-        <translation>vtk_view_sync.png</translation>
-    </message>
     <message>
         <source>ICON_SVTK_DYNAMIC_PRESLECTION_SWITCH</source>
         <translation>vtk_view_highlight.png</translation>
index f4da48aa4999901649befbfa91e321d0f62c42e5..623656fef725fe54d64257f63301db8156edb705 100644 (file)
         <source>DSC_VIEWPARAMETERS_VIEW</source>
         <translation>Change the parameters of the view</translation>
     </message>
-    <message>
-        <source>MNU_SYNCHRONIZE_VIEW</source>
-        <translation>Synchronize</translation>
-    </message>
-    <message>
-        <source>DSC_SYNCHRONIZE_VIEW</source>
-        <translation>Synchronize view</translation>
-    </message>
-    <message>
-        <source>MNU_SYNC_NO_VIEW</source>
-        <translation>[ No appropriate view ]</translation>
-    </message>
     <message>
         <source>MNU_SVTK_PARALLEL_MODE</source>
         <translation>Orthogonal Mode</translation>
index 57c6e2f0519f31975f40a2ac36cdee64cfe0502a..5c188b2f52c9fa2033d54dc66d8bd28a9403bb20 100755 (executable)
         <source>DSC_VIEWPARAMETERS_VIEW</source>
         <translation>Changer les paramètres de la vue</translation>
     </message>
-    <message>
-        <source>MNU_SYNCHRONIZE_VIEW</source>
-        <translation>Synchroniser</translation>
-    </message>
-    <message>
-        <source>DSC_SYNCHRONIZE_VIEW</source>
-        <translation>Synchroniser la vue</translation>
-    </message>
-    <message>
-        <source>MNU_SYNC_NO_VIEW</source>
-        <translation>[ Pas de vue appropriée ]</translation>
-    </message>
     <message>
         <source>MNU_SVTK_PARALLEL_MODE</source>
         <translation>Mode orthogonal</translation>
diff --git a/src/SVTK/resources/vtk_view_sync.png b/src/SVTK/resources/vtk_view_sync.png
deleted file mode 100755 (executable)
index 32b9522..0000000
Binary files a/src/SVTK/resources/vtk_view_sync.png and /dev/null differ