# 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
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 \
setCentralWidget( centralFrame );
OCCViewer_ViewWindow* view0 = theModel->createSubWindow();
+ updateWindowTitle( view0 );
view0->setParent( centralFrame );
myViews.append( view0 ); // MAIN_VIEW
{
}
+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
{
view->set2dMode( (Mode2dType) i );
view->setParent( centralWidget() );
view->setViewManager(myManager);
+ updateWindowTitle( view );
myViews.append( view );
aModel->initView(view);
view->setMaximized(false, false);
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 );
+}
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(); }
virtual void setDropDownButtons( bool );
+ virtual SUIT_CameraProperties cameraProperties();
+
public slots:
virtual void onFrontView() { getView(MAIN_VIEW)->onFrontView(); }
virtual void onViewFitAll();
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;
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
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 );
}
/*!
myScalingDlg = new OCCViewer_AxialScaleDlg( this );
if ( !myScalingDlg->isVisible() )
+ {
+ myScalingDlg->Update();
myScalingDlg->show();
+ }
}
/*!
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 );
}
virtual void updateViewAspects( const viewAspectList& );
virtual void clearViewAspects();
+ virtual SUIT_CameraProperties cameraProperties();
+
public slots:
virtual void onFrontView();
virtual void onViewFitAll();
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 );
double myCurScale;
-private slots:
- void onSynchronizeView(bool);
- void updateSyncViews();
-
-private:
- static void synchronizeView( OCCViewer_ViewWindow*, int );
-
private:
OCCViewer_ClippingDlg* myClippingDlg;
QtxAction* myClippingAction;
<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>
<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>
<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>
SUIT_ViewModel.h
SUIT_ViewWindow.h
SUIT_ShortcutMgr.h
+ SUIT_CameraProperties.h
)
QT4_WRAP_CPP(GUI_HEADERS_MOC ${GUI_HEADERS})
SUIT_ViewModel.cxx
SUIT_ViewWindow.cxx
SUIT_ShortcutMgr.cxx
+ SUIT_CameraProperties.cxx
)
SET(GUITS_SOURCES
resources/SUIT_msg_en.ts
# 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
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 \
SUIT_ViewManager.cxx \
SUIT_ViewModel.cxx \
SUIT_ViewWindow.cxx \
- SUIT_ShortcutMgr.cxx
+ SUIT_ShortcutMgr.cxx \
+ SUIT_CameraProperties.cxx
MOC_FILES = \
SUIT_Accel_moc.cxx \
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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
#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>
/*! Constructor.*/
SUIT_ViewWindow::SUIT_ViewWindow( SUIT_Desktop* theDesktop )
- : QMainWindow( theDesktop ), myManager( 0 ), myIsDropDown( true )
+ : QMainWindow( theDesktop ), myManager( 0 ), myIsDropDown( true ), mySyncAction( 0 )
{
myDesktop = theDesktop;
}
/*!
- \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()
*/
}
/*!
- \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 );
+ }
+ }
+ }
+}
#define SUIT_VIEWWINDOW_H
#include "SUIT.h"
+#include "SUIT_CameraProperties.h"
#include <QMainWindow>
#include <QList>
virtual void setDropDownButtons( bool );
bool dropDownButtons() const;
+ virtual SUIT_CameraProperties cameraProperties();
+
public slots:
virtual void onDumpView();
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* );
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
<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>
<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>
<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>
# 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
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 = \
#include "VTKViewer_Trihedron.h"
#include "SVTK_View.h"
-//#include "SVTK_MainWindow.h"
#include "SVTK_Selector.h"
#include "SVTK_Event.h"
GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished,
myEventCallbackCommand.GetPointer(), 0.0);
+ myKeyFreeInteractorStyle->AddObserver(SVTK::OperationFinished,
+ myEventCallbackCommand.GetPointer(), 0.0);
this,SIGNAL(contextMenuRequested(QContextMenuEvent *)));
connect(theView,SIGNAL(selectionChanged()),
theModel,SLOT(onSelectionChanged()));
+
+ connect( this, SIGNAL( transformed( SVTK_ViewWindow* ) ), SLOT( emitViewModified() ) );
}
/*!
vtkCamera* aCamera = getRenderer()->GetActiveCamera();
aCamera->SetParallelProjection(anIsParallelMode);
GetInteractor()->GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
+
+ emit transformed( this );
}
void SVTK_ViewWindow::SetEventDispatcher(vtkObject* theDispatcher)
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"),
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.
*/
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 );
+}
//! 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 * );
virtual void synchronize(SVTK_ViewWindow*);
protected slots:
+ void synchronize( SUIT_ViewWindow* );
void onKeyPressed(QKeyEvent* event);
void onKeyReleased(QKeyEvent* event);
void onMousePressed(QMouseEvent* event);
vtkPVAxesWidget* myAxesWidget;
Qtx::BackgroundData myBackground;
-private slots:
- void onSynchronizeView(bool);
- void updateSyncViews();
-
-private:
- static void synchronizeView( SVTK_ViewWindow*, int );
-
private:
QImage myDumpImage;
};
<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>
<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>
<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>