]> SALOME platform Git repositories - modules/kernel.git/blob - src/VTKViewer/VTKViewer_ViewFrame.cxx
Salome HOME
b68158db7374a2b735edf84261a5794d334119d9
[modules/kernel.git] / src / VTKViewer / VTKViewer_ViewFrame.cxx
1 //  SALOME VTKViewer : build VTK viewer into Salome desktop
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : VTKViewer_ViewFrame.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
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"
34
35 #include "SALOME_Transform.h"
36 #include "SALOME_TransformFilter.h"
37 #include "SALOME_GeometryFilter.h"
38
39 #include "QAD_Settings.h"
40 #include "QAD_Config.h"
41 #include "QAD_Application.h"
42 #include "QAD_Desktop.h"
43 #include "SALOME_Selection.h"
44 #include "SALOME_InteractiveObject.hxx"
45
46 #include "utilities.h"
47
48 //QT Include
49 #include <qlayout.h>
50 #include <qcolordialog.h>
51 #include <qfiledialog.h>
52 #include <qapplication.h>
53
54 // VTK Includes
55 #include <vtkActor.h>
56 #include <vtkRenderer.h>
57 #include <vtkTransform.h>
58
59 using namespace std;
60
61 /*!
62     Constructor
63 */
64 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name) 
65   :  QAD_ViewFrame(parent, name)
66 {
67   m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
68   m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
69   m_Triedron = VTKViewer_Trihedron::New();
70   m_Transform = SALOME_Transform::New();
71   //m_Renderer = VTKViewer_Renderer::New() ;
72   m_Renderer = vtkRenderer::New() ;
73
74   m_Triedron->AddToRender(m_Renderer);
75   InitialSetup();
76 }  
77
78 void VTKViewer_ViewFrame::InitialSetup() {
79   m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
80   m_RW->getRenderWindow()->AddRenderer(m_Renderer);
81
82   m_Renderer->GetActiveCamera()->ParallelProjectionOn();
83   m_Renderer->LightFollowCameraOn();
84   m_Renderer->TwoSidedLightingOn();
85
86   // Set BackgroundColor
87   QString BgrColorRed   = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
88   QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
89   QString BgrColorBlue  = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
90
91   if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() ) 
92     m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
93   else
94     m_Renderer->SetBackground( 0, 0, 0 );
95   
96   // Create an interactor.
97   m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
98   m_RWInteractor->setGUIWindow(m_RW);
99   m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
100
101   VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
102   RWS->setGUIWindow(m_RW);
103   m_RWInteractor->SetInteractorStyle(RWS); 
104
105   m_RWInteractor->Initialize();
106   RWS->setTriedron(m_Triedron);
107   //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle 
108   RWS->FindPokedRenderer(0, 0);
109
110   setCentralWidget( m_RW );
111   onViewReset();
112 }
113
114 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
115   m_Transform->Delete() ;
116   // In order to ensure that the interactor unregisters
117   // this RenderWindow, we assign a NULL RenderWindow to 
118   // it before deleting it.
119   m_RWInteractor->SetRenderWindow(NULL) ;
120   m_RWInteractor->Delete() ;
121   
122   //m_RW->Delete() ;
123   m_Renderer->RemoveAllProps();
124   // NRI : BugID 1137:  m_Renderer->Delete() ;
125   m_Triedron->Delete();
126   MESSAGE("VTKViewer_ViewFrame::~VTKViewer_ViewFrame()");
127 }
128
129 /*!
130   Returns widget containing 3D-Viewer
131 */
132 QWidget* VTKViewer_ViewFrame::getViewWidget(){
133   return m_RW;
134 }
135
136 bool VTKViewer_ViewFrame::isTrihedronDisplayed(){
137   return m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
138 }
139
140 void VTKViewer_ViewFrame::onAdjustTrihedron(){   
141   if(!isTrihedronDisplayed()) 
142     return;
143   int aVisibleNum = m_Triedron->GetVisibleActorCount(m_Renderer);
144   if(aVisibleNum){
145     // calculating diagonal of visible props of the renderer
146     float bnd[6];
147     m_Triedron->VisibilityOff();
148     ::ComputeVisiblePropBounds(m_Renderer,bnd);
149     m_Triedron->VisibilityOn();
150     float aLength = 0;
151     static bool CalcByDiag = false;
152     if(CalcByDiag){
153       aLength = sqrt((bnd[1]-bnd[0])*(bnd[1]-bnd[0])+
154                      (bnd[3]-bnd[2])*(bnd[3]-bnd[2])+
155                      (bnd[5]-bnd[4])*(bnd[5]-bnd[4]));
156     }else{
157       aLength = bnd[1]-bnd[0];
158       aLength = max((bnd[3]-bnd[2]),aLength);
159       aLength = max((bnd[5]-bnd[4]),aLength);
160     }
161    
162     static float aSizeInPercents = 105;
163     QString aSetting = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
164     if(!aSetting.isEmpty()) aSizeInPercents = aSetting.toFloat();
165
166     static float EPS_SIZE = 5.0E-3;
167     float aSize = m_Triedron->GetSize();
168     float aNewSize = aLength*aSizeInPercents/100.0;
169     // if the new trihedron size have sufficient difference, then apply the value
170     if(fabs(aNewSize-aSize) > aSize*EPS_SIZE || fabs(aNewSize-aSize) > aNewSize*EPS_SIZE){
171       m_Triedron->SetSize(aNewSize);
172     }
173   }
174   ::ResetCameraClippingRange(m_Renderer);
175 }
176
177 /*!
178   Display/hide Trihedron
179 */
180 void VTKViewer_ViewFrame::onViewTrihedron(){
181   if(!m_Triedron) return;
182   if(isTrihedronDisplayed())
183     m_Triedron->VisibilityOff();
184   else{
185     m_Triedron->VisibilityOn();
186   }
187   Repaint();
188 }
189
190 /*!
191   Provides top projection of the active view
192 */
193 void VTKViewer_ViewFrame::onViewTop(){
194   vtkCamera* camera = m_Renderer->GetActiveCamera();
195   camera->SetPosition(0,0,1);
196   camera->SetViewUp(0,1,0);
197   camera->SetFocalPoint(0,0,0);
198   onViewFitAll();
199 }
200
201 /*!
202   Provides bottom projection of the active view
203 */
204 void VTKViewer_ViewFrame::onViewBottom(){
205   vtkCamera* camera = m_Renderer->GetActiveCamera();
206   camera->SetPosition(0,0,-1);
207   camera->SetViewUp(0,1,0);
208   camera->SetFocalPoint(0,0,0);
209   onViewFitAll();
210 }
211
212 /*!
213   Provides left projection of the active view
214 */
215 void VTKViewer_ViewFrame::onViewLeft(){
216   vtkCamera* camera = m_Renderer->GetActiveCamera(); 
217   camera->SetPosition(0,1,0);
218   camera->SetViewUp(0,0,1);
219   camera->SetFocalPoint(0,0,0);
220   onViewFitAll();
221 }
222
223 /*!
224   Provides right projection of the active view
225 */
226 void VTKViewer_ViewFrame::onViewRight(){
227   vtkCamera* camera = m_Renderer->GetActiveCamera();
228   camera->SetPosition(0,-1,0);
229   camera->SetViewUp(0,0,1);
230   camera->SetFocalPoint(0,0,0);
231   onViewFitAll();
232 }
233
234 /*!
235   Provides back projection of the active view
236 */
237 void VTKViewer_ViewFrame::onViewBack(){
238   vtkCamera* camera = m_Renderer->GetActiveCamera();
239   camera->SetPosition(-1,0,0);
240   camera->SetViewUp(0,0,1);
241   camera->SetFocalPoint(0,0,0);
242   onViewFitAll();
243 }
244
245 /*!
246   Provides front projection of the active view
247 */
248 void VTKViewer_ViewFrame::onViewFront(){
249   vtkCamera* camera = m_Renderer->GetActiveCamera();
250   camera->SetPosition(1,0,0);
251   camera->SetViewUp(0,0,1);
252   camera->SetFocalPoint(0,0,0);
253   onViewFitAll();
254 }
255
256 /*!
257   Fits all objects in the active view
258 */
259 void VTKViewer_ViewFrame::onViewFitAll(){
260   m_RWInteractor->GetInteractorStyleSALOME()->ViewFitAll();
261 //   int aTriedronWasVisible = isTrihedronDisplayed();
262 //   if(m_Triedron->GetVisibleActorCount(m_Renderer)){
263 //     m_Triedron->VisibilityOff();
264 //     ::ResetCamera(m_Renderer);
265 //   }else{
266 //     m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
267 //     ::ResetCamera(m_Renderer,true);
268 //   }
269 //   if(aTriedronWasVisible) m_Triedron->VisibilityOn();
270 //   else m_Triedron->VisibilityOff();
271
272   Repaint();
273 }
274
275 /*!
276   Reset the active view
277 */
278 void VTKViewer_ViewFrame::onViewReset(){
279   int aTriedronIsVisible = isTrihedronDisplayed();
280   m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
281   ::ResetCamera(m_Renderer,true);  
282   vtkCamera* aCamera = m_Renderer->GetActiveCamera();
283   aCamera->SetPosition(1,-1,1);
284   aCamera->SetViewUp(0,0,1);
285   ::ResetCamera(m_Renderer,true);  
286   if(aTriedronIsVisible) m_Triedron->VisibilityOn();
287   else m_Triedron->VisibilityOff();
288   static float aCoeff = 3.0;
289   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
290   Repaint();
291 }
292
293 /*!
294   Rotates the active view
295 */
296 void VTKViewer_ViewFrame::onViewRotate(){
297   m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
298 }
299
300 /*!
301   Sets a new center of the active view
302 */
303 void VTKViewer_ViewFrame::onViewGlobalPan(){
304   if(m_Triedron->GetVisibleActorCount(m_Renderer))
305     m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
306 }
307
308 /*!
309   Zooms the active view
310 */
311 void VTKViewer_ViewFrame::onViewZoom(){
312   m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
313 }
314
315 /*!
316   Moves the active view
317 */
318 void VTKViewer_ViewFrame::onViewPan(){
319   m_RWInteractor->GetInteractorStyleSALOME()->startPan();
320 }
321
322 /*!
323   Fits all obejcts within a rectangular area of the active view
324 */
325 void VTKViewer_ViewFrame::onViewFitArea(){
326   m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
327 }
328
329 /*!
330     Set background of the viewport
331 */
332 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
333 {
334   if ( m_Renderer )
335     m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
336 }
337
338 /*!
339     Returns background of the viewport
340 */
341 QColor VTKViewer_ViewFrame::backgroundColor() const
342 {
343   float backint[3];
344   if ( m_Renderer ) {
345     m_Renderer->GetBackground(backint);
346     return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
347   }
348   return QMainWindow::backgroundColor();
349 }
350
351
352 void VTKViewer_ViewFrame::SetSelectionMode( Selection_Mode mode )
353 {
354   m_RWInteractor->SetSelectionMode( mode );
355 }
356
357 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
358 {
359   m_RWInteractor->rename(IObject, newName);
360 }
361
362 void VTKViewer_ViewFrame::unHighlightAll() 
363 {
364   m_RWInteractor->unHighlightAll();
365 }
366
367 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject, 
368                                      bool highlight, 
369                                      bool update ) 
370 {
371   QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
372   SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
373   m_RWInteractor->highlight(IObject, highlight, update);
374
375   switch (Sel->SelectionMode()) {
376   case NodeSelection:
377     if ( Sel->HasIndex( IObject ) ) {
378       TColStd_MapOfInteger MapIndex;
379       Sel->GetIndex( IObject, MapIndex );
380       m_RWInteractor->highlightPoint(IObject, highlight, MapIndex, update);
381     }
382     break;
383   case EdgeOfCellSelection:
384     if ( Sel->HasIndex( IObject ) ) {
385       TColStd_MapOfInteger MapIndex;
386       Sel->GetIndex( IObject, MapIndex );
387       m_RWInteractor->highlightEdge(IObject, highlight, MapIndex, update);
388     }
389     break;
390   case CellSelection:
391   case EdgeSelection:
392   case FaceSelection:
393   case VolumeSelection:
394     if ( Sel->HasIndex( IObject ) ) {
395       TColStd_MapOfInteger MapIndex;
396       Sel->GetIndex( IObject, MapIndex );
397       m_RWInteractor->highlightCell(IObject, highlight, MapIndex, update);
398     }
399     break;
400   }
401 }
402
403 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
404 {
405   return m_RWInteractor->isInViewer( IObject );
406 }
407
408 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
409 {
410   return m_RWInteractor->isVisible( IObject );
411 }
412
413 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
414 {
415   m_RW->setPopupServer( App );
416 }
417
418 void VTKViewer_ViewFrame::undo(SALOMEDS::Study_var aStudy,
419                                const char* StudyFrameEntry)
420 {
421   vtkActorCollection* theActors = m_Renderer->GetActors();
422   theActors->InitTraversal();
423   vtkActor *ac = theActors->GetNextActor();
424   while(!(ac==NULL)) {
425     if ( ac->IsA("SALOME_Actor") ) {
426       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
427       if ( anActor->hasIO() ) {
428         Handle(SALOME_InteractiveObject) IO = anActor->getIO();
429         if ( IO->hasEntry() ) { 
430           /*if (!QAD_ViewFrame::isInViewer(aStudy, IO->getEntry(), StudyFrameEntry)) {
431             m_RWInteractor->Erase(IO);
432             }*/
433         }
434       }
435     }
436     ac = theActors->GetNextActor();
437   }
438 }
439
440 void VTKViewer_ViewFrame::redo(SALOMEDS::Study_var aStudy,
441                                const char* StudyFrameEntry)
442 {
443   SALOMEDS::SObject_var RefSO;
444   SALOMEDS::SObject_var SO = aStudy->FindObjectID( StudyFrameEntry );
445   SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
446   for (; it->More();it->Next()){
447     SALOMEDS::SObject_var CSO= it->Value();
448     if (CSO->ReferencedObject(RefSO)) {
449       vtkActorCollection* theActors = m_Renderer->GetActors();
450       theActors->InitTraversal();
451       vtkActor *ac = theActors->GetNextActor();
452       while(!(ac==NULL)) {
453         if ( ac->IsA("SALOME_Actor") ) {
454           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
455           if ( anActor->hasIO() ) {
456             Handle(SALOME_InteractiveObject) IO = anActor->getIO();
457             if ( IO->hasEntry() ) { 
458               /*if ( strcmp(IO->getEntry(),RefSO->GetID()) == 0 )
459                 m_RWInteractor->Display(IO);*/
460             }
461           }
462         }
463         ac = theActors->GetNextActor();
464       }
465     }
466   }
467 }
468
469
470 /* selection */
471 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* Entry)
472 {
473   Handle(SALOME_InteractiveObject) IO;
474   vtkActorCollection* theActors = m_Renderer->GetActors();
475   theActors->InitTraversal();
476   vtkActor *ac = theActors->GetNextActor();
477   while(!(ac==NULL)) {
478     if ( ac->IsA("SALOME_Actor") ) {
479       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
480       if ( anActor->hasIO() ) {
481         IO = anActor->getIO();
482         if ( IO->hasEntry() ) {
483           if ( strcmp( IO->getEntry(), Entry ) == 0 ) {
484             return IO;
485           }
486         }
487       }
488     }
489     ac = theActors->GetNextActor();
490   }
491   return IO;
492 }
493
494 /* display */           
495 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& IObject, bool update)
496 {
497   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
498   SALOME_Selection* Sel
499     = SALOME_Selection::Selection( myStudy->getSelection() );
500
501   vtkActorCollection* theActors = m_Renderer->GetActors();
502   theActors->InitTraversal();
503   vtkActor *ac = theActors->GetNextActor();
504   while(!(ac==NULL))
505     {
506       if ( ac->IsA("SALOME_Actor") )
507         {
508           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
509           if ( anActor->hasIO() ) 
510             {
511               Handle(SALOME_InteractiveObject) IO = anActor->getIO();
512               if ( IO->isSame(IObject) )
513                 {
514                   m_RWInteractor->Display(IO, false);
515                   Sel->AddIObject(IO, false);
516                   break;
517                 }
518             }
519         }
520       ac = theActors->GetNextActor();
521     }
522   if (update)
523     Repaint();
524 }
525
526
527 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& IObject)
528 {
529   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
530   SALOME_Selection* Sel
531     = SALOME_Selection::Selection( myStudy->getSelection() );
532
533   vtkActorCollection* theActors = m_Renderer->GetActors();
534   theActors->InitTraversal();
535   vtkActor *ac = theActors->GetNextActor();
536   while(!(ac==NULL)) {
537     if ( ac->IsA("SALOME_Actor") ) {
538       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
539       if ( anActor->hasIO() ) {
540         Handle(SALOME_InteractiveObject) IO = anActor->getIO();
541         if ( !IO->isSame(IObject) ) {
542           m_RWInteractor->Erase(IO, false);
543           Sel->RemoveIObject(IO, false);
544         } else {
545           anActor->SetVisibility(true);
546           Sel->AddIObject(IO, false);
547         }
548       }
549     }
550     ac = theActors->GetNextActor();
551   }
552   Repaint();
553 }
554
555 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& IObject, bool update)
556 {
557   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
558   SALOME_Selection* Sel
559     = SALOME_Selection::Selection( myStudy->getSelection() );
560
561   vtkActorCollection* theActors = m_Renderer->GetActors();
562   theActors->InitTraversal();
563   vtkActor *ac = theActors->GetNextActor();
564   while(!(ac==NULL)) 
565     {
566       if ( ac->IsA("SALOME_Actor") )
567         {
568           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
569           if ( anActor->hasIO() )
570             {
571               Handle(SALOME_InteractiveObject) IO = anActor->getIO();
572               if ( IO->isSame( IObject ) ) {
573                 m_RWInteractor->Erase(IO, false);
574                 Sel->RemoveIObject(IO, false);
575                 break;
576               }
577             }
578         }
579       ac = theActors->GetNextActor();
580     }
581   if (update)
582     Repaint();
583 }
584
585
586 void VTKViewer_ViewFrame::DisplayAll()
587 {
588   m_RWInteractor->DisplayAll();
589 }
590
591
592 void VTKViewer_ViewFrame::EraseAll()
593 {
594   m_RWInteractor->EraseAll();
595 }
596
597
598 void VTKViewer_ViewFrame::Repaint(bool theUpdateTrihedron)
599 {
600   if (theUpdateTrihedron) onAdjustTrihedron();
601   m_RW->update();
602 }
603
604 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
605   m_Transform->GetScale(theScale);
606 }
607
608 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
609   m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
610   m_RWInteractor->Render();
611   Repaint();
612 }
613
614 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool update /*=false*/ ){
615   theActor->SetVisibility(true);
616   theActor->AddToRender(m_Renderer);
617   theActor->SetTransform(m_Transform);
618   if(update) Repaint();
619 }
620
621 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool update /*=false*/ ){
622   theActor->RemoveFromRender(m_Renderer);
623   if(update) Repaint();
624 }