1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 #include "SALOME_Actor.h"
21 #include <qapplication.h>
24 #include <vtkTextProperty.h>
25 #include <vtkActorCollection.h>
26 #include <vtkRenderWindow.h>
27 #include <vtkRenderer.h>
28 #include <vtkCamera.h>
29 #include <vtkPointPicker.h>
30 #include <vtkCellPicker.h>
31 #include <vtkAxisActor2D.h>
33 #include "QtxAction.h"
35 #include "SUIT_Session.h"
36 #include "SUIT_ToolButton.h"
37 #include "SUIT_MessageBox.h"
38 #include "SUIT_Accel.h"
40 #include "SUIT_Tools.h"
41 #include "SUIT_ResourceMgr.h"
42 #include "SUIT_Accel.h"
44 #include "VTKViewer_Utilities.h"
46 #include "SVTK_View.h"
47 #include "SVTK_MainWindow.h"
48 #include "SVTK_Selector.h"
50 #include "SVTK_Event.h"
51 #include "SVTK_Renderer.h"
52 #include "SVTK_ViewWindow.h"
53 #include "SVTK_ViewModelBase.h"
54 #include "SVTK_InteractorStyle.h"
55 #include "SVTK_RenderWindowInteractor.h"
56 #include "SVTK_GenericRenderWindowInteractor.h"
57 #include "SVTK_CubeAxesActor2D.h"
59 #include "SALOME_ListIteratorOfListIO.hxx"
61 #include "VTKViewer_Algorithm.h"
62 #include "SVTK_Functor.h"
68 ::SVTK_ViewWindow(SUIT_Desktop* theDesktop):
69 SUIT_ViewWindow(theDesktop),
75 To initialize #SVTK_ViewWindow instance
79 ::Initialize(SVTK_ViewModelBase* theModel)
81 if(SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr()){
82 myMainWindow = new SVTK_MainWindow(this,"SVTK_MainWindow",aResourceMgr,this);
84 SVTK_RenderWindowInteractor* anIteractor =
85 new SVTK_RenderWindowInteractor(myMainWindow,"SVTK_RenderWindowInteractor");
87 SVTK_Selector* aSelector = SVTK_Selector::New();
89 SVTK_GenericRenderWindowInteractor* aDevice =
90 SVTK_GenericRenderWindowInteractor::New();
91 aDevice->SetRenderWidget(anIteractor);
92 aDevice->SetSelector(aSelector);
94 SVTK_Renderer* aRenderer = SVTK_Renderer::New();
95 aRenderer->Initialize(aDevice,aSelector);
97 anIteractor->Initialize(aDevice,aRenderer,aSelector);
103 myMainWindow->Initialize(anIteractor);
105 SVTK_InteractorStyle* aStyle = SVTK_InteractorStyle::New();
106 anIteractor->PushInteractorStyle(aStyle);
109 setCentralWidget(myMainWindow);
111 myView = new SVTK_View(myMainWindow);
112 Initialize(myView,theModel);
117 To initialize #SVTK_ViewWindow instance
121 ::Initialize(SVTK_View* theView,
122 SVTK_ViewModelBase* theModel)
124 connect(theView,SIGNAL(KeyPressed(QKeyEvent*)),
125 this,SLOT(onKeyPressed(QKeyEvent*)) );
126 connect(theView,SIGNAL(KeyReleased(QKeyEvent*)),
127 this,SLOT(onKeyReleased(QKeyEvent*)));
128 connect(theView,SIGNAL(MouseButtonPressed(QMouseEvent*)),
129 this,SLOT(onMousePressed(QMouseEvent*)));
130 connect(theView,SIGNAL(MouseButtonReleased(QMouseEvent*)),
131 this,SLOT(onMouseReleased(QMouseEvent*)));
132 connect(theView,SIGNAL(MouseDoubleClicked(QMouseEvent*)),
133 this,SLOT(onMouseDoubleClicked(QMouseEvent*)));
134 connect(theView,SIGNAL(MouseMove(QMouseEvent*)),
135 this,SLOT(onMouseMoving(QMouseEvent*)));
136 connect(theView,SIGNAL(contextMenuRequested(QContextMenuEvent*)),
137 this,SIGNAL(contextMenuRequested(QContextMenuEvent *)));
138 connect(theView,SIGNAL(selectionChanged()),
139 theModel,SLOT(onSelectionChanged()));
151 \return corresponding view
161 \return corresponding vtk main window
171 \return corresponding vtk render window
177 return getMainWindow()->getRenderWindow();
181 \return corresponding vtk render window interactor
183 vtkRenderWindowInteractor*
187 return getMainWindow()->getInteractor();
191 \return corresponding vtk renderer
197 return myMainWindow->getRenderer();
201 \return corresponding vtk selector
207 return myMainWindow->GetSelector();
211 Processes transformation "front view"
217 myMainWindow->onFrontView();
221 Processes transformation "back view"
227 myMainWindow->onBackView();
231 Processes transformation "top view"
237 myMainWindow->onTopView();
241 Processes transformation "bottom view"
247 myMainWindow->onBottomView();
251 Processes transformation "left view"
257 myMainWindow->onLeftView();
261 Processes transformation "right view"
267 myMainWindow->onRightView();
271 Processes transformation "reset view": sets default orientation of viewport camera
277 myMainWindow->onResetView();
281 Processes transformation "fit all"
287 myMainWindow->onFitAll();
291 SLOT: called if selection is changed
295 ::onSelectionChanged()
297 myView->onSelectionChanged();
301 Change selection mode
302 \param theMode - new selection mode
306 ::SetSelectionMode(Selection_Mode theMode)
308 myMainWindow->SetSelectionMode( theMode );
312 \return selection mode
316 ::SelectionMode() const
318 return myMainWindow->SelectionMode();
322 Unhilights all objects in viewer
328 myView->unHighlightAll();
332 Hilights/unhilights object in viewer
333 \param theIO - object to be updated
334 \param theIsHighlight - if it is true, object will be hilighted, otherwise it will be unhilighted
335 \param theIsUpdate - update current viewer
339 ::highlight(const Handle(SALOME_InteractiveObject)& theIO,
343 myView->highlight( theIO, theIsHighlight, theIsUpdate );
347 \return true if object is in viewer or in collector
348 \param theIO - object to be checked
352 ::isInViewer( const Handle(SALOME_InteractiveObject)& theIO )
354 return myView->isInViewer( theIO );
358 \return true if object is displayed in viewer
359 \param theIO - object to be checked
363 ::isVisible( const Handle(SALOME_InteractiveObject)& theIO )
365 return myView->isVisible( theIO );
370 \param theEntry - entry that corresponds to intractive objects
372 Handle(SALOME_InteractiveObject)
374 ::FindIObject(const char* theEntry)
376 return myView->FindIObject(theEntry);
381 \param theIO - object
382 \param theImmediatly - update viewer
386 ::Display(const Handle(SALOME_InteractiveObject)& theIO,
389 myView->Display(theIO,theImmediatly);
394 \param theIO - object
395 \param theImmediatly - update viewer
399 ::Erase(const Handle(SALOME_InteractiveObject)& theIO,
402 myView->Erase(theIO,theImmediatly);
406 Display only passed object
407 \param theIO - object
411 ::DisplayOnly(const Handle(SALOME_InteractiveObject)& theIO)
413 myView->DisplayOnly(theIO);
417 Display all objects in view
423 myView->DisplayAll();
427 Erase all objects in view
437 Sets background color
438 \param color - new background color
442 ::setBackgroundColor( const QColor& color )
444 myMainWindow->SetBackgroundColor( color );
448 \return background color of viewer
452 ::backgroundColor() const
454 return myMainWindow->BackgroundColor();
458 Updates current viewer
462 ::Repaint(bool theUpdateTrihedron)
464 myMainWindow->Repaint( theUpdateTrihedron );
468 Redirect the request to #SVTK_Renderer::GetScale
472 ::GetScale( double theScale[3] )
474 myMainWindow->GetScale( theScale );
478 Redirect the request to #SVTK_Renderer::SetScale
482 ::SetScale( double theScale[3] )
484 myMainWindow->SetScale( theScale );
488 Redirect the request to #SVTK_Renderer::IsTrihedronDisplayed
492 ::isTrihedronDisplayed()
494 return myMainWindow->IsTrihedronDisplayed();
498 Redirect the request to #SVTK_Renderer::IsCubeAxesDisplayed
502 ::isCubeAxesDisplayed()
504 return myMainWindow->IsCubeAxesDisplayed();
508 Redirect the request to #SVTK_Renderer::OnViewTrihedron
514 myMainWindow->onViewTrihedron();
518 Redirect the request to #SVTK_Renderer::OnViewCubeAxes
524 myMainWindow->onViewCubeAxes();
528 Redirect the request to #SVTK_Renderer::GetTrihedron
534 return myMainWindow->GetTrihedron();
538 Redirect the request to #SVTK_Renderer::GetCubeAxes
540 SVTK_CubeAxesActor2D*
544 return myMainWindow->GetCubeAxes();
548 \return trihedron size
552 ::GetTrihedronSize() const
554 return myMainWindow->GetTrihedronSize();
559 \param theSize - new trihedron size
560 \param theRelative - trihedron relativeness
564 ::SetTrihedronSize(const int theSize, const bool theRelative)
566 myMainWindow->SetTrihedronSize(theSize, theRelative);
569 /*! If parameter theIsForcedUpdate is true, recalculate parameters for
570 * trihedron and cube axes, even if trihedron and cube axes is invisible.
574 ::AdjustTrihedrons(const bool theIsForcedUpdate)
576 myMainWindow->AdjustActors();
580 Redirect the request to #SVTK_Renderer::OnAdjustTrihedron
584 ::onAdjustTrihedron()
586 myMainWindow->onAdjustTrihedron();
590 Redirect the request to #SVTK_Renderer::OnAdjustCubeAxes
596 myMainWindow->onAdjustCubeAxes();
604 ::onKeyPressed(QKeyEvent* event)
606 emit keyPressed( this, event );
614 ::onKeyReleased(QKeyEvent* event)
616 emit keyReleased( this, event );
624 ::onMousePressed(QMouseEvent* event)
626 emit mousePressed(this, event);
634 ::onMouseReleased(QMouseEvent* event)
636 emit mouseReleased( this, event );
644 ::onMouseMoving(QMouseEvent* event)
646 emit mouseMoving( this, event );
650 Emits mouse double clicked
654 ::onMouseDoubleClicked( QMouseEvent* event )
656 emit mouseDoubleClicked( this, event );
660 Redirect the request to #SVTK_Renderer::AddActor
664 ::AddActor( VTKViewer_Actor* theActor,
667 myMainWindow->AddActor( theActor, theUpdate );
671 Redirect the request to #SVTK_Renderer::RemoveActor
675 ::RemoveActor( VTKViewer_Actor* theActor,
678 myMainWindow->RemoveActor( theActor, theUpdate );
682 \return QImage, containing all scene rendering in window
688 return myMainWindow->dumpView();
692 Redirect the request to #SVTK_Renderer::SetSelectionProp
696 ::SetSelectionProp(const double& theRed,
697 const double& theGreen,
698 const double& theBlue,
701 myView->SetSelectionProp(theRed,theGreen,theBlue,theWidth);
705 Redirect the request to #SVTK_Renderer::SetSelectionProp
709 ::SetPreselectionProp(const double& theRed,
710 const double& theGreen,
711 const double& theBlue,
714 myView->SetPreselectionProp(theRed,theGreen,theBlue,theWidth);
718 Redirect the request to #SVTK_Renderer::SetSelectionTolerance
722 ::SetSelectionTolerance(const double& theTolNodes,
723 const double& theTolItems)
725 myView->SetSelectionTolerance(theTolNodes,theTolItems);
728 int convertAction( const int accelAction )
730 switch ( accelAction ) {
731 case SUIT_Accel::PanLeft : return SVTK::PanLeftEvent;
732 case SUIT_Accel::PanRight : return SVTK::PanRightEvent;
733 case SUIT_Accel::PanUp : return SVTK::PanUpEvent;
734 case SUIT_Accel::PanDown : return SVTK::PanDownEvent;
735 case SUIT_Accel::ZoomIn : return SVTK::ZoomInEvent;
736 case SUIT_Accel::ZoomOut : return SVTK::ZoomOutEvent;
737 case SUIT_Accel::RotateLeft : return SVTK::RotateLeftEvent;
738 case SUIT_Accel::RotateRight : return SVTK::RotateRightEvent;
739 case SUIT_Accel::RotateUp : return SVTK::RotateUpEvent;
740 case SUIT_Accel::RotateDown : return SVTK::RotateDownEvent;
747 \param accelAction - action
751 ::action( const int accelAction )
753 if ( !myMainWindow->hasFocus() )
755 if ( accelAction == SUIT_Accel::ZoomFit )
758 int anEvent = convertAction( accelAction );
759 myMainWindow->InvokeEvent( anEvent, 0 );
764 // old visual parameters had 13 values. New format added additional
765 // 76 values for graduated axes, so both numbers are processed.
766 const int nNormalParams = 13; // number of view windows parameters excluding graduated axes params
767 const int nGradAxisParams = 25; // number of parameters of ONE graduated axis (X, Y, or Z)
768 const int nAllParams = nNormalParams + 3*nGradAxisParams + 1; // number of all visual parameters
770 /*! The method returns visual parameters of a graduated axis actor (x,y,z axis of graduated axes)
772 QString getGradAxisVisualParams( vtkAxisActor2D* actor )
779 bool isVisible = actor->GetTitleVisibility();
780 QString title ( actor->GetTitle() );
781 vtkFloatingPointType color[ 3 ];
782 int font = VTK_ARIAL;
787 vtkTextProperty* txtProp = actor->GetTitleTextProperty();
790 txtProp->GetColor( color );
791 font = txtProp->GetFontFamily();
792 bold = txtProp->GetBold();
793 italic = txtProp->GetItalic();
794 shadow = txtProp->GetShadow();
796 params.sprintf( "* Graduated Axis: * Name *%u*%s*%.2f*%.2f*%.2f*%u*%u*%u*%u", isVisible,
797 title.latin1(), color[0], color[1], color[2], font, bold, italic, shadow );
800 isVisible = actor->GetLabelVisibility();
801 int labels = actor->GetNumberOfLabels();
802 int offset = actor->GetTickOffset();
808 txtProp = actor->GetLabelTextProperty();
811 txtProp->GetColor( color );
812 font = txtProp->GetFontFamily();
813 bold = txtProp->GetBold();
814 italic = txtProp->GetItalic();
815 shadow = txtProp->GetShadow();
817 params += QString().sprintf( "* Labels *%u*%u*%u*%.2f*%.2f*%.2f*%u*%u*%u*%u", isVisible, labels, offset,
818 color[0], color[1], color[2], font, bold, italic, shadow );
821 isVisible = actor->GetTickVisibility();
822 int length = actor->GetTickLength();
824 params += QString().sprintf( "* Tick marks *%u*%u", isVisible, length );
829 /*! The method restores visual parameters of a graduated axis actor (x,y,z axis)
831 void setGradAxisVisualParams( vtkAxisActor2D* actor, const QString& params )
836 QStringList paramsLst = QStringList::split( '*', params, true );
838 if ( paramsLst.size() == nGradAxisParams ) { // altogether name, lable, ticks parameters make up 25 values
840 // retrieve and set name parameters
841 bool isVisible = paramsLst[2].toUShort();
842 QString title = paramsLst[3];
843 vtkFloatingPointType color[3];
844 color[0] = paramsLst[4].toDouble();
845 color[1] = paramsLst[5].toDouble();
846 color[2] = paramsLst[6].toDouble();
847 int font = paramsLst[7].toInt();
848 int bold = paramsLst[8].toInt();
849 int italic = paramsLst[9].toInt();
850 int shadow = paramsLst[10].toInt();
852 actor->SetTitleVisibility( isVisible );
853 actor->SetTitle( title.latin1() );
854 vtkTextProperty* txtProp = actor->GetTitleTextProperty();
856 txtProp->SetColor( color );
857 txtProp->SetFontFamily( font );
858 txtProp->SetBold( bold );
859 txtProp->SetItalic( italic );
860 txtProp->SetShadow( shadow );
863 // retrieve and set lable parameters
864 isVisible = paramsLst[12].toUShort();
865 int labels = paramsLst[13].toInt();
866 int offset = paramsLst[14].toInt();
867 color[0] = paramsLst[15].toDouble();
868 color[1] = paramsLst[16].toDouble();
869 color[2] = paramsLst[17].toDouble();
870 font = paramsLst[18].toInt();
871 bold = paramsLst[19].toInt();
872 italic = paramsLst[20].toInt();
873 shadow = paramsLst[21].toInt();
875 actor->SetLabelVisibility( isVisible );
876 actor->SetNumberOfLabels( labels );
877 actor->SetTickOffset( offset );
878 txtProp = actor->GetLabelTextProperty();
880 txtProp->SetColor( color );
881 txtProp->SetFontFamily( font );
882 txtProp->SetBold( bold );
883 txtProp->SetItalic( italic );
884 txtProp->SetShadow( shadow );
887 // retrieve and set tick marks properties
888 isVisible = paramsLst[23].toUShort();
889 int length = paramsLst[24].toInt();
891 actor->SetTickVisibility( isVisible );
892 actor->SetTickLength( length );
896 /*! The method returns the visual parameters of this view as a formated string
900 ::getVisualParameters()
902 double pos[3], focalPnt[3], viewUp[3], parScale, scale[3];
904 // save position, focal point, viewUp, scale
905 vtkCamera* camera = getRenderer()->GetActiveCamera();
906 camera->GetPosition( pos );
907 camera->GetFocalPoint( focalPnt );
908 camera->GetViewUp( viewUp );
909 parScale = camera->GetParallelScale();
912 // Parameters are given in the following format:view position (3 digits), focal point position (3 digits)
913 // view up values (3 digits), parallel scale (1 digit), scale (3 digits,
914 // Graduated axes parameters (X, Y, Z axes parameters)
916 retStr.sprintf( "%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e",
917 pos[0], pos[1], pos[2], focalPnt[0], focalPnt[1], focalPnt[2],
918 viewUp[0], viewUp[1], viewUp[2], parScale, scale[0], scale[1], scale[2] );
920 // save graduated axes parameters
921 if ( SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes() ) {
922 retStr += QString( "*%1" ).arg( getMainWindow()->IsCubeAxesDisplayed() );
923 retStr += ::getGradAxisVisualParams( gradAxesActor->GetXAxisActor2D() );
924 retStr += ::getGradAxisVisualParams( gradAxesActor->GetYAxisActor2D() );
925 retStr += ::getGradAxisVisualParams( gradAxesActor->GetZAxisActor2D() );
932 The method restores visual parameters of this view or postpones it untill the view is shown
936 ::setVisualParameters( const QString& parameters )
938 SVTK_RenderWindowInteractor* anInteractor = getMainWindow()->GetInteractor();
939 if ( anInteractor->isVisible() ) {
940 doSetVisualParameters( parameters );
943 myVisualParams = parameters;
944 anInteractor->installEventFilter(this);
949 The method restores visual parameters of this view from a formated string
953 ::doSetVisualParameters( const QString& parameters )
955 QStringList paramsLst = QStringList::split( '*', parameters, true );
956 if ( paramsLst.size() >= nNormalParams ) {
957 // 'reading' list of parameters
958 double pos[3], focalPnt[3], viewUp[3], parScale, scale[3];
959 pos[0] = paramsLst[0].toDouble();
960 pos[1] = paramsLst[1].toDouble();
961 pos[2] = paramsLst[2].toDouble();
962 focalPnt[0] = paramsLst[3].toDouble();
963 focalPnt[1] = paramsLst[4].toDouble();
964 focalPnt[2] = paramsLst[5].toDouble();
965 viewUp[0] = paramsLst[6].toDouble();
966 viewUp[1] = paramsLst[7].toDouble();
967 viewUp[2] = paramsLst[8].toDouble();
968 parScale = paramsLst[9].toDouble();
969 scale[0] = paramsLst[10].toDouble();
970 scale[1] = paramsLst[11].toDouble();
971 scale[2] = paramsLst[12].toDouble();
973 // applying parameters
974 vtkCamera* camera = getRenderer()->GetActiveCamera();
975 camera->SetPosition( pos );
976 camera->SetFocalPoint( focalPnt );
977 camera->SetViewUp( viewUp );
978 camera->SetParallelScale( parScale );
981 // apply graduated axes parameters
982 SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes();
983 if ( gradAxesActor && paramsLst.size() == nAllParams ) {
985 int i = nNormalParams+1, j = i + nGradAxisParams - 1;
986 ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) );
987 i = j + 1; j += nGradAxisParams;
988 ::setGradAxisVisualParams( gradAxesActor->GetYAxisActor2D(), parameters.section( '*', i, j ) );
989 i = j + 1; j += nGradAxisParams;
990 ::setGradAxisVisualParams( gradAxesActor->GetZAxisActor2D(), parameters.section( '*', i, j ) );
992 if ( paramsLst[13].toUShort() )
993 gradAxesActor->VisibilityOn();
995 gradAxesActor->VisibilityOff();
1002 Delayed setVisualParameters
1004 bool SVTK_ViewWindow::eventFilter( QObject* theWatched, QEvent* theEvent )
1006 if ( theEvent->type() == QEvent::Show && theWatched->inherits( "SVTK_RenderWindowInteractor" ) ) {
1007 SVTK_RenderWindowInteractor* anInteractor = (SVTK_RenderWindowInteractor*)theWatched;
1008 if ( anInteractor->isVisible() ) {
1009 doSetVisualParameters( myVisualParams );
1010 anInteractor->removeEventFilter( this ); // theWatched = RenderWindowInteractor
1013 return SUIT_ViewWindow::eventFilter( theWatched, theEvent );