1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : VTKViewer_ViewFrame.cxx
25 // Author : Nicolas REJNERI
29 #include "VTKViewer_ViewFrame.h"
30 #include "VTKViewer_Utilities.h"
31 #include "VTKViewer_Trihedron.h"
32 #include "VTKViewer_RenderWindow.h"
33 #include "VTKViewer_InteractorStyleSALOME.h"
35 #include "SALOME_Transform.h"
36 #include "SALOME_TransformFilter.h"
37 #include "SALOME_PassThroughFilter.h"
38 #include "SALOME_GeometryFilter.h"
40 #include "QAD_Settings.h"
41 #include "QAD_Config.h"
42 #include "QAD_Application.h"
43 #include "QAD_Desktop.h"
44 #include "SALOME_Selection.h"
45 #include "SALOME_InteractiveObject.hxx"
47 #include "utilities.h"
51 #include <qcolordialog.h>
52 #include <qfiledialog.h>
53 #include <qapplication.h>
57 #include <vtkRenderer.h>
58 #include <vtkTransform.h>
65 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name)
66 : QAD_ViewFrame(parent, name)
68 m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
69 m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
70 m_Triedron = VTKViewer_Trihedron::New();
71 m_Transform = SALOME_Transform::New();
72 //m_Renderer = VTKViewer_Renderer::New() ;
73 m_Renderer = vtkRenderer::New() ;
75 m_Triedron->AddToRender(m_Renderer);
79 void VTKViewer_ViewFrame::InitialSetup() {
80 m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
81 m_RW->getRenderWindow()->AddRenderer(m_Renderer);
83 m_Renderer->GetActiveCamera()->ParallelProjectionOn();
84 m_Renderer->LightFollowCameraOn();
85 m_Renderer->TwoSidedLightingOn();
87 // Set BackgroundColor
88 QString BgrColorRed = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
89 QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
90 QString BgrColorBlue = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
92 if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() )
93 m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
95 m_Renderer->SetBackground( 0, 0, 0 );
97 // Create an interactor.
98 m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
99 m_RWInteractor->setGUIWindow(m_RW);
100 m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
102 VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
103 RWS->setGUIWindow(m_RW);
104 m_RWInteractor->SetInteractorStyle(RWS);
106 m_RWInteractor->Initialize();
107 RWS->setTriedron(m_Triedron);
108 //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle
109 RWS->FindPokedRenderer(0, 0);
111 setCentralWidget( m_RW );
115 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
116 m_Transform->Delete() ;
117 // In order to ensure that the interactor unregisters
118 // this RenderWindow, we assign a NULL RenderWindow to
119 // it before deleting it.
120 m_RWInteractor->SetRenderWindow(NULL) ;
121 m_RWInteractor->Delete() ;
124 m_Renderer->RemoveAllProps();
125 // NRI : BugID 1137: m_Renderer->Delete() ;
126 m_Triedron->Delete();
127 MESSAGE("VTKViewer_ViewFrame::~VTKViewer_ViewFrame()");
131 Returns widget containing 3D-Viewer
133 QWidget* VTKViewer_ViewFrame::getViewWidget(){
137 bool VTKViewer_ViewFrame::isTrihedronDisplayed(){
138 return m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
141 void VTKViewer_ViewFrame::onAdjustTrihedron(){
142 if(!isTrihedronDisplayed())
144 int aVisibleNum = m_Triedron->GetVisibleActorCount(m_Renderer);
146 // calculating diagonal of visible props of the renderer
148 m_Triedron->VisibilityOff();
149 ::ComputeVisiblePropBounds(m_Renderer,bnd);
150 m_Triedron->VisibilityOn();
152 static bool CalcByDiag = false;
154 aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
155 (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
156 (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
158 aLength = bnd[1]-bnd[0];
159 aLength = max((bnd[3]-bnd[2]),aLength);
160 aLength = max((bnd[5]-bnd[4]),aLength);
163 static float aSizeInPercents = 105;
164 QString aSetting = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
165 if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
167 static float EPS_SIZE = 5.0E-3;
168 float aSize = m_Triedron->GetSize();
169 float aNewSize = aLength*aSizeInPercents/100.0;
170 // if the new trihedron size have sufficient difference, then apply the value
171 if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE)
172 m_Triedron->SetSize(aNewSize);
174 m_Triedron->Render(m_Renderer);
175 ::ResetCameraClippingRange(m_Renderer);
179 Display/hide Trihedron
181 void VTKViewer_ViewFrame::onViewTrihedron(){
182 if(!m_Triedron) return;
183 if(isTrihedronDisplayed())
184 m_Triedron->VisibilityOff();
186 m_Triedron->VisibilityOn();
192 Provides top projection of the active view
194 void VTKViewer_ViewFrame::onViewTop(){
195 vtkCamera* camera = m_Renderer->GetActiveCamera();
196 camera->SetPosition(0,0,1);
197 camera->SetViewUp(0,1,0);
198 camera->SetFocalPoint(0,0,0);
203 Provides bottom projection of the active view
205 void VTKViewer_ViewFrame::onViewBottom(){
206 vtkCamera* camera = m_Renderer->GetActiveCamera();
207 camera->SetPosition(0,0,-1);
208 camera->SetViewUp(0,1,0);
209 camera->SetFocalPoint(0,0,0);
214 Provides left projection of the active view
216 void VTKViewer_ViewFrame::onViewLeft(){
217 vtkCamera* camera = m_Renderer->GetActiveCamera();
218 camera->SetPosition(0,1,0);
219 camera->SetViewUp(0,0,1);
220 camera->SetFocalPoint(0,0,0);
225 Provides right projection of the active view
227 void VTKViewer_ViewFrame::onViewRight(){
228 vtkCamera* camera = m_Renderer->GetActiveCamera();
229 camera->SetPosition(0,-1,0);
230 camera->SetViewUp(0,0,1);
231 camera->SetFocalPoint(0,0,0);
236 Provides back projection of the active view
238 void VTKViewer_ViewFrame::onViewBack(){
239 vtkCamera* camera = m_Renderer->GetActiveCamera();
240 camera->SetPosition(-1,0,0);
241 camera->SetViewUp(0,0,1);
242 camera->SetFocalPoint(0,0,0);
247 Provides front projection of the active view
249 void VTKViewer_ViewFrame::onViewFront(){
250 vtkCamera* camera = m_Renderer->GetActiveCamera();
251 camera->SetPosition(1,0,0);
252 camera->SetViewUp(0,0,1);
253 camera->SetFocalPoint(0,0,0);
258 Fits all objects in the active view
260 void VTKViewer_ViewFrame::onViewFitAll(){
261 m_RWInteractor->GetInteractorStyleSALOME()->ViewFitAll();
262 // int aTriedronWasVisible = isTrihedronDisplayed();
263 // if(m_Triedron->GetVisibleActorCount(m_Renderer)){
264 // m_Triedron->VisibilityOff();
265 // ::ResetCamera(m_Renderer);
267 // m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
268 // ::ResetCamera(m_Renderer,true);
270 // if(aTriedronWasVisible) m_Triedron->VisibilityOn();
271 // else m_Triedron->VisibilityOff();
277 Reset the active view
279 void VTKViewer_ViewFrame::onViewReset(){
280 int aTriedronIsVisible = isTrihedronDisplayed();
281 m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
282 ::ResetCamera(m_Renderer,true);
283 vtkCamera* aCamera = m_Renderer->GetActiveCamera();
284 aCamera->SetPosition(1,-1,1);
285 aCamera->SetViewUp(0,0,1);
286 ::ResetCamera(m_Renderer,true);
287 if(aTriedronIsVisible) m_Triedron->VisibilityOn();
288 else m_Triedron->VisibilityOff();
289 static float aCoeff = 3.0;
290 aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
295 Rotates the active view
297 void VTKViewer_ViewFrame::onViewRotate(){
298 m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
302 Sets a new center of the active view
304 void VTKViewer_ViewFrame::onViewGlobalPan(){
305 if(m_Triedron->GetVisibleActorCount(m_Renderer))
306 m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
310 Zooms the active view
312 void VTKViewer_ViewFrame::onViewZoom(){
313 m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
317 Moves the active view
319 void VTKViewer_ViewFrame::onViewPan(){
320 m_RWInteractor->GetInteractorStyleSALOME()->startPan();
324 Fits all obejcts within a rectangular area of the active view
326 void VTKViewer_ViewFrame::onViewFitArea(){
327 m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
331 Set background of the viewport
333 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
336 m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
340 Returns background of the viewport
342 QColor VTKViewer_ViewFrame::backgroundColor() const
346 m_Renderer->GetBackground(backint);
347 return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
349 return QMainWindow::backgroundColor();
353 void VTKViewer_ViewFrame::SetSelectionMode( int mode )
355 m_RWInteractor->SetSelectionMode( mode );
358 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
360 m_RWInteractor->rename(IObject, newName);
363 void VTKViewer_ViewFrame::unHighlightAll()
365 m_RWInteractor->unHighlightAll();
368 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject,
372 QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
373 SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
374 if ( Sel->SelectionMode() == 4 )
375 m_RWInteractor->highlight(IObject, highlight, update);
376 else if ( Sel->SelectionMode() == 3 ) {
377 m_RWInteractor->highlight(IObject, highlight, update);
378 if ( Sel->HasIndex( IObject ) ) {
379 TColStd_MapOfInteger MapIndex;
380 Sel->GetIndex( IObject, MapIndex );
381 m_RWInteractor->highlightCell(IObject, highlight, MapIndex, update);
384 else if ( Sel->SelectionMode() == 2 ) {
385 m_RWInteractor->highlight(IObject, highlight, update);
386 if ( Sel->HasIndex( IObject ) ) {
387 TColStd_MapOfInteger MapIndex;
388 Sel->GetIndex( IObject, MapIndex );
389 m_RWInteractor->highlightEdge(IObject, highlight, MapIndex, update);
392 else if ( Sel->SelectionMode() == 1 ) {
393 m_RWInteractor->highlight(IObject, highlight, update);
394 if ( Sel->HasIndex( IObject ) ) {
395 TColStd_MapOfInteger MapIndex;
396 Sel->GetIndex( IObject, MapIndex );
397 m_RWInteractor->highlightPoint(IObject, highlight, MapIndex, update);
402 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject )
404 return m_RWInteractor->isInViewer( IObject );
407 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject )
409 return m_RWInteractor->isVisible( IObject );
412 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
414 m_RW->setPopupServer( App );
417 void VTKViewer_ViewFrame::undo(SALOMEDS::Study_var aStudy,
418 const char* StudyFrameEntry)
420 vtkActorCollection* theActors = m_Renderer->GetActors();
421 theActors->InitTraversal();
422 vtkActor *ac = theActors->GetNextActor();
424 if ( ac->IsA("SALOME_Actor") ) {
425 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
426 if ( anActor->hasIO() ) {
427 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
428 if ( IO->hasEntry() ) {
429 /*if (!QAD_ViewFrame::isInViewer(aStudy, IO->getEntry(), StudyFrameEntry)) {
430 m_RWInteractor->Erase(IO);
435 ac = theActors->GetNextActor();
439 void VTKViewer_ViewFrame::redo(SALOMEDS::Study_var aStudy,
440 const char* StudyFrameEntry)
442 SALOMEDS::SObject_var RefSO;
443 SALOMEDS::SObject_var SO = aStudy->FindObjectID( StudyFrameEntry );
444 SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
445 for (; it->More();it->Next()){
446 SALOMEDS::SObject_var CSO= it->Value();
447 if (CSO->ReferencedObject(RefSO)) {
448 vtkActorCollection* theActors = m_Renderer->GetActors();
449 theActors->InitTraversal();
450 vtkActor *ac = theActors->GetNextActor();
452 if ( ac->IsA("SALOME_Actor") ) {
453 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
454 if ( anActor->hasIO() ) {
455 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
456 if ( IO->hasEntry() ) {
457 /*if ( strcmp(IO->getEntry(),RefSO->GetID()) == 0 )
458 m_RWInteractor->Display(IO);*/
462 ac = theActors->GetNextActor();
470 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* Entry)
472 Handle(SALOME_InteractiveObject) IO;
473 vtkActorCollection* theActors = m_Renderer->GetActors();
474 theActors->InitTraversal();
475 vtkActor *ac = theActors->GetNextActor();
477 if ( ac->IsA("SALOME_Actor") ) {
478 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
479 if ( anActor->hasIO() ) {
480 IO = anActor->getIO();
481 if ( IO->hasEntry() ) {
482 if ( strcmp( IO->getEntry(), Entry ) == 0 ) {
488 ac = theActors->GetNextActor();
494 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& IObject, bool update)
496 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
497 SALOME_Selection* Sel
498 = SALOME_Selection::Selection( myStudy->getSelection() );
500 vtkActorCollection* theActors = m_Renderer->GetActors();
501 theActors->InitTraversal();
502 vtkActor *ac = theActors->GetNextActor();
505 if ( ac->IsA("SALOME_Actor") )
507 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
508 if ( anActor->hasIO() )
510 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
511 if ( IO->isSame(IObject) )
513 m_RWInteractor->Display(IO, false);
514 Sel->AddIObject(IO, false);
519 ac = theActors->GetNextActor();
526 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& IObject)
528 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
529 SALOME_Selection* Sel
530 = SALOME_Selection::Selection( myStudy->getSelection() );
532 vtkActorCollection* theActors = m_Renderer->GetActors();
533 theActors->InitTraversal();
534 vtkActor *ac = theActors->GetNextActor();
536 if ( ac->IsA("SALOME_Actor") ) {
537 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
538 if ( anActor->hasIO() ) {
539 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
540 if ( !IO->isSame(IObject) ) {
541 m_RWInteractor->Erase(IO, false);
542 Sel->RemoveIObject(IO, false);
544 anActor->SetVisibility(true);
545 Sel->AddIObject(IO, false);
549 ac = theActors->GetNextActor();
554 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& IObject, bool update)
556 QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
557 SALOME_Selection* Sel
558 = SALOME_Selection::Selection( myStudy->getSelection() );
560 vtkActorCollection* theActors = m_Renderer->GetActors();
561 theActors->InitTraversal();
562 vtkActor *ac = theActors->GetNextActor();
565 if ( ac->IsA("SALOME_Actor") )
567 SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
568 if ( anActor->hasIO() )
570 Handle(SALOME_InteractiveObject) IO = anActor->getIO();
571 if ( IO->isSame( IObject ) ) {
572 m_RWInteractor->Erase(IO, false);
573 Sel->RemoveIObject(IO, false);
578 ac = theActors->GetNextActor();
585 void VTKViewer_ViewFrame::DisplayAll()
587 m_RWInteractor->DisplayAll();
591 void VTKViewer_ViewFrame::EraseAll()
593 m_RWInteractor->EraseAll();
597 void VTKViewer_ViewFrame::Repaint(bool theUpdateTrihedron)
599 if (theUpdateTrihedron) onAdjustTrihedron();
603 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
604 m_Transform->GetScale(theScale);
607 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
608 m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
609 m_RWInteractor->Render();
613 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool update /*=false*/ ){
614 theActor->SetVisibility(true);
615 theActor->AddToRender(m_Renderer);
616 theActor->SetTransform(m_Transform);
617 if(update) Repaint();
620 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool update /*=false*/ ){
621 theActor->RemoveFromRender(m_Renderer);
622 if(update) Repaint();