Salome HOME
3fa967e2a0d4b67153d98700989e82f08bede3fb
[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 "SALOME_CubeAxesActor2D.h"
33 #include "VTKViewer_RenderWindow.h"
34 #include "VTKViewer_RenderWindowInteractor.h"
35 #include "VTKViewer_InteractorStyleSALOME.h"
36 #include "VTKViewer_Algorithm.h"
37 #include "VTKViewer_Functor.h"
38 #include "VTKViewer_Prs.h"
39
40 #include "SALOME_Actor.h"
41 #include "SALOME_Transform.h"
42 #include "SALOME_TransformFilter.h"
43 #include "SALOME_GeometryFilter.h"
44 #include "SALOMEGUI.h"
45
46 #include "QAD_Settings.h"
47 #include "QAD_Config.h"
48 #include "QAD_Application.h"
49 #include "QAD_Desktop.h"
50 #include "SALOME_Selection.h"
51 #include "SALOME_InteractiveObject.hxx"
52 #include "ToolsGUI.h"
53 #include "SALOMEDS_Tool.hxx"
54
55 #include "utilities.h"
56
57 //QT Include
58 #include <qlayout.h>
59 #include <qcolordialog.h>
60 #include <qfiledialog.h>
61 #include <qapplication.h>
62
63 // VTK Includes
64 #include <vtkActor.h>
65 #include <vtkCamera.h>
66 #include <vtkRenderer.h>
67 #include <vtkTransform.h>
68 #include <vtkActorCollection.h>
69 #include <vtkTextProperty.h>
70
71 #include <TColStd_IndexedMapOfInteger.hxx>
72
73 #ifdef _DEBUG_
74 static int MYDEBUG = 0;
75 #else
76 static int MYDEBUG = 0;
77 #endif
78
79 using namespace std;
80
81 /*!
82     Constructor
83 */
84 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name) 
85   :  QAD_ViewFrame(parent, name)
86 {
87   m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
88   m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
89   m_Triedron = VTKViewer_Trihedron::New();
90   m_CubeAxes = SALOME_CubeAxesActor2D::New();
91   m_Transform = SALOME_Transform::New();
92   //m_Renderer = VTKViewer_Renderer::New() ;
93   m_Renderer = vtkRenderer::New() ;
94
95   m_Triedron->AddToRender(m_Renderer);
96   m_Renderer->AddProp(m_CubeAxes);
97   InitialSetup();
98 }  
99
100 void VTKViewer_ViewFrame::InitialSetup() {
101   m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
102   m_RW->getRenderWindow()->AddRenderer(m_Renderer);
103
104   m_Renderer->GetActiveCamera()->ParallelProjectionOn();
105   m_Renderer->LightFollowCameraOn();
106   m_Renderer->TwoSidedLightingOn();
107
108   // Set BackgroundColor
109   QString BgrColorRed   = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
110   QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
111   QString BgrColorBlue  = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
112
113   if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() ) 
114     m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
115   else
116     m_Renderer->SetBackground( 0, 0, 0 );
117   
118   // Create an interactor.
119   m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
120   m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
121
122   VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
123   m_RWInteractor->SetInteractorStyle(RWS); 
124   RWS->Delete();
125
126   m_RWInteractor->setGUIWindow(m_RW);
127   RWS->setGUIWindow(m_RW);
128
129   m_RWInteractor->Initialize();
130   m_RWInteractor->setViewFrame(this);
131
132   RWS->setViewFrame(this);
133   //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle 
134   RWS->FindPokedRenderer(0, 0);
135
136   vtkTextProperty* tprop = vtkTextProperty::New();
137   tprop->SetColor(1, 1, 1);
138   tprop->ShadowOn();
139   
140   float bnd[6];
141   bnd[0] = bnd[2] = bnd[4] = 0;
142   bnd[1] = bnd[3] = bnd[5] = m_Triedron->GetSize();
143   m_CubeAxes->SetLabelFormat("%6.4g");
144   m_CubeAxes->SetBounds(bnd);
145   m_CubeAxes->SetCamera(m_Renderer->GetActiveCamera());
146   m_CubeAxes->SetLabelFormat("%6.4g");
147   m_CubeAxes->SetFlyModeToOuterEdges(); // ENK remarks: it must bee
148   m_CubeAxes->SetFontFactor(0.8);
149   m_CubeAxes->SetAxisTitleTextProperty(tprop);
150   m_CubeAxes->SetAxisLabelTextProperty(tprop);
151   m_CubeAxes->SetCornerOffset(0.0);
152   m_CubeAxes->SetScaling(0);
153   m_CubeAxes->SetNumberOfLabels(5);
154   tprop->Delete();
155   
156   setCentralWidget( m_RW );
157   onViewReset();
158 }
159
160 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
161   // In order to ensure that the interactor unregisters
162   // this RenderWindow, we assign a NULL RenderWindow to 
163   // it before deleting it.
164   m_RWInteractor->SetRenderWindow(NULL) ;
165   m_RWInteractor->Delete() ;
166   
167   m_Transform->Delete() ;
168   //m_RW->Delete() ;
169   m_Renderer->RemoveAllProps();
170   // NRI : BugID 1137:  m_Renderer->Delete() ;
171   m_Triedron->Delete();
172
173   m_CubeAxes->Delete();
174   INFOS("VTKViewer_ViewFrame::~VTKViewer_ViewFrame()");
175 }
176
177 /*!
178   Returns widget containing 3D-Viewer
179 */
180 QWidget* VTKViewer_ViewFrame::getViewWidget(){
181   return m_RW;
182 }
183
184 bool VTKViewer_ViewFrame::isTrihedronDisplayed(){
185   return m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
186 }
187
188 bool VTKViewer_ViewFrame::isCubeAxesDisplayed(){
189   return m_CubeAxes->GetVisibility() == 1;
190 }
191
192 double VTKViewer_ViewFrame::GetTrihedronSize() const
193 {
194   return m_Triedron->GetSize();
195 }
196
197 void VTKViewer_ViewFrame::AdjustTrihedrons(const bool forced)
198 {
199   
200   if ( (!isCubeAxesDisplayed() || !isTrihedronDisplayed()) && forced)
201     return;
202
203   float bnd[ 6 ];
204   float newbnd[6];
205   newbnd[ 0 ] = newbnd[ 2 ] = newbnd[ 4 ] = VTK_LARGE_FLOAT;
206   newbnd[ 1 ] = newbnd[ 3 ] = newbnd[ 5 ] = -VTK_LARGE_FLOAT;
207
208   m_CubeAxes->GetBounds(bnd);
209   if(MYDEBUG)
210     cout << "Bounds: BEFORE\n"
211          << "\txMin=" << bnd[ 0 ] << " xMax=" << bnd[ 1 ] << "\n"
212          << "\tyMin=" << bnd[ 2 ] << " yMax=" << bnd[ 3 ] << "\n"
213          << "\tzMin=" << bnd[ 4 ] << " zMax=" << bnd[ 5 ] << "\n";
214
215   int aVisibleNum = m_Triedron->GetVisibleActorCount( m_Renderer );
216   if ( aVisibleNum )
217   {
218     // if the new trihedron size have sufficient difference, then apply the value
219     double aNewSize = 100, anOldSize=m_Triedron->GetSize();
220     
221     m_Triedron->VisibilityOff();
222     m_CubeAxes->VisibilityOff();
223     static float aSizeInPercents = 105;
224     QString aSetting = QAD_CONFIG->getSetting( "Viewer:TrihedronSize" );
225     if ( !aSetting.isEmpty() )
226       aSizeInPercents = aSetting.toFloat();
227     bool isComputeTrihedronSize = ::ComputeTrihedronSize(m_Renderer, aNewSize, anOldSize, aSizeInPercents);
228     m_Triedron->VisibilityOn();
229     m_CubeAxes->VisibilityOn();
230     
231     if ( isComputeTrihedronSize )
232     {
233       m_Triedron->SetSize( aNewSize );
234       // itearte throuh displayed objects and set size if necessary
235
236       vtkActorCollection* anActors = getRenderer()->GetActors();
237       anActors->InitTraversal();
238       while( vtkActor* anActor = anActors->GetNextActor() )
239       {
240         if( SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast( anActor ) )
241         {
242           if ( aSActor->IsResizable() )
243             aSActor->SetSize( 0.5 * aNewSize );
244           if( aSActor->GetVisibility()){
245             float abounds[6];
246             aSActor->GetBounds(abounds);
247             if(MYDEBUG)
248               cout << "Bounds: Actor="<<aSActor<<"\n"
249                    << "\txMin=" << abounds[ 0 ] << " xMax=" << abounds[ 1 ] << "\n"
250                    << "\tyMin=" << abounds[ 2 ] << " yMax=" << abounds[ 3 ] << "\n"
251                    << "\tzMin=" << abounds[ 4 ] << " zMax=" << abounds[ 5 ] << "\n";
252             if (  abounds[0] > -VTK_LARGE_FLOAT && abounds[1] < VTK_LARGE_FLOAT &&
253                   abounds[2] > -VTK_LARGE_FLOAT && abounds[3] < VTK_LARGE_FLOAT &&
254                   abounds[4] > -VTK_LARGE_FLOAT && abounds[5] < VTK_LARGE_FLOAT)
255               for(int i=0;i<5;i=i+2){
256                 if(abounds[i]<newbnd[i]) newbnd[i]=abounds[i];
257                 if(abounds[i+1]>newbnd[i+1]) newbnd[i+1]=abounds[i+1];
258                 
259               }
260           }
261         }
262       }
263     }
264   }
265   if( newbnd[0]<VTK_LARGE_FLOAT && newbnd[2]<VTK_LARGE_FLOAT && newbnd[4]<VTK_LARGE_FLOAT &&
266       newbnd[1]>-VTK_LARGE_FLOAT && newbnd[3]>-VTK_LARGE_FLOAT && newbnd[5]>-VTK_LARGE_FLOAT){
267     for(int i=0;i<6;i++) bnd[i] = newbnd[i];
268     m_CubeAxes->SetBounds(bnd);
269   }
270   if(MYDEBUG)
271     cout << "Bounds AFTER: VisibleActors="<<aVisibleNum<<"\n"
272          << "\txMin=" << bnd[ 0 ] << " xMax=" << bnd[ 1 ] << "\n"
273          << "\tyMin=" << bnd[ 2 ] << " yMax=" << bnd[ 3 ] << "\n"
274          << "\tzMin=" << bnd[ 4 ] << " zMax=" << bnd[ 5 ] << "\n";
275   
276   m_CubeAxes->SetBounds(bnd);
277
278   ::ResetCameraClippingRange(m_Renderer);
279 }
280
281 void VTKViewer_ViewFrame::onAdjustTrihedron()
282 {
283   AdjustTrihedrons(false);
284 }
285
286 void VTKViewer_ViewFrame::onAdjustCubeAxes()
287 {   
288   AdjustTrihedrons(false);
289 }
290
291 /*!
292   Display/hide Trihedron
293 */
294 void VTKViewer_ViewFrame::onViewTrihedron(){
295   onViewCubeAxes();
296   if(!m_Triedron) return;
297   if(isTrihedronDisplayed()) m_Triedron->VisibilityOff();
298   else m_Triedron->VisibilityOn();
299   Repaint();
300 }
301
302 void VTKViewer_ViewFrame::onViewCubeAxes(){
303   if(!m_CubeAxes) return;
304   if(isCubeAxesDisplayed()) m_CubeAxes->VisibilityOff();
305   else m_CubeAxes->VisibilityOn();
306   Repaint();
307 }
308
309
310 /*!
311   Provides top projection of the active view
312 */
313 void VTKViewer_ViewFrame::onViewTop(){
314   vtkCamera* camera = m_Renderer->GetActiveCamera();
315   camera->SetPosition(0,0,1);
316   camera->SetViewUp(0,1,0);
317   camera->SetFocalPoint(0,0,0);
318   onViewFitAll();
319 }
320
321 /*!
322   Provides bottom projection of the active view
323 */
324 void VTKViewer_ViewFrame::onViewBottom(){
325   vtkCamera* camera = m_Renderer->GetActiveCamera();
326   camera->SetPosition(0,0,-1);
327   camera->SetViewUp(0,1,0);
328   camera->SetFocalPoint(0,0,0);
329   onViewFitAll();
330 }
331
332 /*!
333   Provides left projection of the active view
334 */
335 void VTKViewer_ViewFrame::onViewLeft(){
336   vtkCamera* camera = m_Renderer->GetActiveCamera(); 
337   camera->SetPosition(0,-1,0);
338   camera->SetViewUp(0,0,1);
339   camera->SetFocalPoint(0,0,0);
340   onViewFitAll();
341 }
342
343 /*!
344   Provides right projection of the active view
345 */
346 void VTKViewer_ViewFrame::onViewRight(){
347   vtkCamera* camera = m_Renderer->GetActiveCamera();
348   camera->SetPosition(0,1,0);
349   camera->SetViewUp(0,0,1);
350   camera->SetFocalPoint(0,0,0);
351   onViewFitAll();
352 }
353
354 /*!
355   Provides back projection of the active view
356 */
357 void VTKViewer_ViewFrame::onViewBack(){
358   vtkCamera* camera = m_Renderer->GetActiveCamera();
359   camera->SetPosition(-1,0,0);
360   camera->SetViewUp(0,0,1);
361   camera->SetFocalPoint(0,0,0);
362   onViewFitAll();
363 }
364
365 /*!
366   Provides front projection of the active view
367 */
368 void VTKViewer_ViewFrame::onViewFront(){
369   vtkCamera* camera = m_Renderer->GetActiveCamera();
370   camera->SetPosition(1,0,0);
371   camera->SetViewUp(0,0,1);
372   camera->SetFocalPoint(0,0,0);
373   onViewFitAll();
374 }
375
376 /*!
377   Fits all objects in the active view
378 */
379 void VTKViewer_ViewFrame::onViewFitAll(){
380
381   int aTriedronWasVisible = false;
382   int aCubeAxesWasVisible = false;
383   if(m_Triedron){
384     aTriedronWasVisible = isTrihedronDisplayed();
385     if(aTriedronWasVisible) m_Triedron->VisibilityOff();
386   }
387   if(m_CubeAxes){
388     aCubeAxesWasVisible = isCubeAxesDisplayed();
389     if(aCubeAxesWasVisible) m_CubeAxes->VisibilityOff();
390   }
391
392   if(m_Triedron->GetVisibleActorCount(m_Renderer)){
393     m_Triedron->VisibilityOff();
394     m_CubeAxes->VisibilityOff();
395     ::ResetCamera(m_Renderer);
396   }else{
397     m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
398     m_CubeAxes->SetVisibility(2);
399     ::ResetCamera(m_Renderer,true);
400   }
401   if(aTriedronWasVisible) m_Triedron->VisibilityOn();
402   else m_Triedron->VisibilityOff();
403   if(aCubeAxesWasVisible) m_CubeAxes->VisibilityOn();
404   else m_CubeAxes->VisibilityOff();
405   ::ResetCameraClippingRange(m_Renderer);
406
407   Repaint();
408 }
409
410 /*!
411   Reset the active view
412 */
413 void VTKViewer_ViewFrame::onViewReset(){
414   int aTriedronIsVisible = isTrihedronDisplayed();
415   int aCubeAxesIsVisible = isCubeAxesDisplayed();
416   
417   m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
418   m_CubeAxes->SetVisibility(0);
419   
420   ::ResetCamera(m_Renderer,true);  
421   vtkCamera* aCamera = m_Renderer->GetActiveCamera();
422   aCamera->SetPosition(1,-1,1);
423   aCamera->SetViewUp(0,0,1);
424   ::ResetCamera(m_Renderer,true);  
425   
426   if(aTriedronIsVisible) m_Triedron->VisibilityOn();
427   else m_Triedron->VisibilityOff();
428   
429   if(aCubeAxesIsVisible) m_CubeAxes->VisibilityOn();
430   else m_CubeAxes->VisibilityOff();
431
432   static float aCoeff = 3.0;
433   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
434   Repaint();
435 }
436
437 /*!
438   Rotates the active view
439 */
440 void VTKViewer_ViewFrame::onViewRotate(){
441   m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
442 }
443
444 /*!
445   Sets a new center of the active view
446 */
447 void VTKViewer_ViewFrame::onViewGlobalPan(){
448   if(m_Triedron->GetVisibleActorCount(m_Renderer))
449     m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
450 }
451
452 /*!
453   Zooms the active view
454 */
455 void VTKViewer_ViewFrame::onViewZoom(){
456   m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
457 }
458
459 /*!
460   Moves the active view
461 */
462 void VTKViewer_ViewFrame::onViewPan(){
463   m_RWInteractor->GetInteractorStyleSALOME()->startPan();
464 }
465
466 /*!
467   Fits all obejcts within a rectangular area of the active view
468 */
469 void VTKViewer_ViewFrame::onViewFitArea(){
470   m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
471 }
472
473 /*!
474     Set background of the viewport
475 */
476 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
477 {
478   if ( m_Renderer )
479     m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
480 }
481
482 /*!
483     Returns background of the viewport
484 */
485 QColor VTKViewer_ViewFrame::backgroundColor() const
486 {
487   float backint[3];
488   if ( m_Renderer ) {
489     m_Renderer->GetBackground(backint);
490     return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
491   }
492   return QMainWindow::backgroundColor();
493 }
494
495
496 void VTKViewer_ViewFrame::SetSelectionMode( Selection_Mode mode )
497 {
498   m_RWInteractor->SetSelectionMode( mode );
499 }
500
501 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
502 {
503   m_RWInteractor->rename(IObject, newName);
504 }
505
506 void VTKViewer_ViewFrame::unHighlightAll() 
507 {
508   m_RWInteractor->unHighlightAll();
509 }
510
511 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject, 
512                                      bool highlight, 
513                                      bool update ) 
514 {
515   QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
516   SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
517   m_RWInteractor->highlight(IObject, highlight, update);
518
519   if(Sel->HasIndex(IObject) && IObject->hasEntry()){
520     TColStd_IndexedMapOfInteger MapIndex;
521     Sel->GetIndex(IObject,MapIndex);
522     using namespace SALOME::VTK;
523     const char* anEntry = IObject->getEntry();
524     vtkActorCollection* aCollection = getRenderer()->GetActors();
525     if(SALOME_Actor* anActor = Find<SALOME_Actor>(aCollection,TIsSameEntry<SALOME_Actor>(anEntry))){
526       switch (Sel->SelectionMode()) {
527       case NodeSelection:
528         m_RWInteractor->highlightPoint(MapIndex,anActor,highlight,update);
529         break;
530       case EdgeOfCellSelection:
531         m_RWInteractor->highlightEdge(MapIndex,anActor,highlight,update);
532         break;
533       case CellSelection:
534       case EdgeSelection:
535       case FaceSelection:
536       case VolumeSelection:
537         m_RWInteractor->highlightCell(MapIndex,anActor,highlight,update);
538         break;
539       }
540     }
541   }else{
542     m_RWInteractor->unHighlightSubSelection();
543   }
544 }
545
546 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
547 {
548   return m_RWInteractor->isInViewer( IObject );
549 }
550
551 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
552 {
553   return m_RWInteractor->isVisible( IObject );
554 }
555
556 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
557 {
558   m_RW->setPopupServer( App );
559 }
560
561 /* selection */
562 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* theEntry)
563 {
564   using namespace SALOME::VTK;
565   SALOME_Actor* anActor = 
566     Find<SALOME_Actor>(getRenderer()->GetActors(),
567                        TIsSameEntry<SALOME_Actor>(theEntry));
568   if(anActor)
569     return anActor->getIO();
570
571   return Handle(SALOME_InteractiveObject)();
572 }
573
574 /* display */           
575 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
576 {
577   QAD_Study*          aQADStudy = QAD_Application::getDesktop()->getActiveStudy();
578   SALOME_Selection*   aSel      = SALOME_Selection::Selection( aQADStudy->getSelection() );
579   SALOMEDS::Study_var aStudy    = aQADStudy->getStudyDocument();
580
581   m_RWInteractor->Display(theIObject,false);
582   ToolsGUI::SetVisibility( aStudy, theIObject->getEntry(), true, this );
583   aSel->AddIObject(theIObject,false);
584
585   if(update)
586     Repaint();
587 }
588
589
590 struct TDisplayAction{
591   SALOME_Selection* mySel;
592   Handle(SALOME_InteractiveObject) myIO;
593   TDisplayAction(SALOME_Selection* theSel,
594                  Handle(SALOME_InteractiveObject) theIO): 
595     mySel(theSel), myIO(theIO)
596   {}
597   void operator()(SALOME_Actor* theActor){
598     theActor->SetVisibility(true);
599     mySel->AddIObject(myIO,false);
600   }
601 };
602
603 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& theIObject)
604 {
605   QAD_Study* aStudy = QAD_Application::getDesktop()->getActiveStudy();
606   SALOME_Selection* aSel = SALOME_Selection::Selection(aStudy->getSelection());
607
608   aSel->ClearIObjects();
609   //m_RWInteractor->EraseAll();
610   EraseAll();
611
612   using namespace SALOME::VTK;
613   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
614                           TIsSameIObject<SALOME_Actor>(theIObject),
615                           TDisplayAction(aSel,theIObject));
616
617   ToolsGUI::SetVisibility(
618     aStudy->getStudyDocument(), theIObject->getEntry(), true, this );
619
620   Repaint();
621 }
622
623
624 struct TEraseAction: TDisplayAction{
625   VTKViewer_RenderWindowInteractor* myRWInteractor;
626   TEraseAction(SALOME_Selection* theSel,
627                Handle(SALOME_InteractiveObject) theIO,
628                VTKViewer_RenderWindowInteractor* theRWInteractor): 
629     TDisplayAction(theSel,theIO),
630     myRWInteractor(theRWInteractor)
631   {}
632   void operator()(SALOME_Actor* theActor){
633     myRWInteractor->Erase(myIO,false);
634     mySel->RemoveIObject(myIO,false);
635   }
636 };
637
638 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
639 {
640   QAD_Study* aStudy = QAD_Application::getDesktop()->getActiveStudy();
641   SALOME_Selection* aSel = SALOME_Selection::Selection(aStudy->getSelection());
642
643   using namespace SALOME::VTK;
644   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
645                           TIsSameIObject<SALOME_Actor>(theIObject),
646                           TEraseAction(aSel,theIObject,m_RWInteractor));
647
648   ToolsGUI::SetVisibility(
649     aStudy->getStudyDocument(), theIObject->getEntry(), false, this );
650
651   if(update)
652     Repaint();
653 }
654
655
656 void VTKViewer_ViewFrame::DisplayAll()
657 {
658   m_RWInteractor->DisplayAll();
659
660   // update flag of visibility
661   QAD_Study*               aQADStudy  = QAD_Application::getDesktop()->getActiveStudy();
662   SALOMEDS::Study_var      aStudy     = aQADStudy->getStudyDocument();
663   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
664   const QString&           aCompName  = aDesktop->getComponentDataType();
665   SALOMEDS::SObject_var    aComponent =
666     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
667     
668   std::list<SALOMEDS::SObject_var> aList;
669   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
670
671   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
672   for ( ; anIter != aList.end(); ++anIter )
673     ToolsGUI::SetVisibility( aStudy, (*anIter)->GetID(), true, this );
674 }
675
676
677 void VTKViewer_ViewFrame::EraseAll()
678 {
679   m_RWInteractor->EraseAll();
680
681   // update flag of visibility
682   QAD_Study*               aQADStudy  = QAD_Application::getDesktop()->getActiveStudy();
683   SALOMEDS::Study_var      aStudy     = aQADStudy->getStudyDocument();
684   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
685   const QString&           aCompName  = aDesktop->getComponentDataType();
686   SALOMEDS::SObject_var    aComponent =
687     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
688
689   std::list<SALOMEDS::SObject_var> aList;
690   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
691
692   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
693   for ( ; anIter != aList.end(); ++anIter )
694     ToolsGUI::SetVisibility( aStudy, (*anIter)->GetID(), false, this );
695 }
696
697
698 void VTKViewer_ViewFrame::Repaint(bool theUpdateTrihedron)
699 {
700   if (theUpdateTrihedron) onAdjustTrihedron();
701   //if (theUpdateCubeAxes) onAdjustCubeAxes();
702   m_RW->update();
703 }
704
705 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
706   m_Transform->GetScale(theScale);
707 }
708
709 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
710   m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
711   m_RWInteractor->Render();
712   Repaint();
713 }
714
715 void VTKViewer_ViewFrame::InsertActor( SALOME_Actor* theActor, bool theMoveInternalActors ){
716   theActor->AddToRender(m_Renderer);
717   theActor->SetTransform(m_Transform);
718   if(theMoveInternalActors) 
719     m_RWInteractor->MoveInternalActors();
720 }
721
722 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool theUpdate /*=false*/ ){
723   InsertActor(theActor);
724   if(theUpdate) 
725     Repaint();
726 }
727
728 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool theUpdate /*=false*/ ){
729   theActor->RemoveFromRender(m_Renderer);
730   if(theUpdate) 
731     Repaint();
732 }
733
734 void VTKViewer_ViewFrame::MoveActor(SALOME_Actor* theActor)
735 {
736   RemoveActor(theActor);
737   InsertActor(theActor,true);
738 }
739
740 //==========================================================
741 /*!
742  *  VTKViewer_ViewFrame::Display
743  *  Display presentation
744  */
745 //==========================================================
746 void VTKViewer_ViewFrame::Display( const SALOME_VTKPrs* prs )
747 {
748   // try do downcast object
749   const VTKViewer_Prs* aVTKPrs = dynamic_cast<const VTKViewer_Prs*>( prs );
750   if ( !aVTKPrs || aVTKPrs->IsNull() )
751     return;
752
753   vtkActorCollection* actors = aVTKPrs->GetObjects();
754   if ( !actors )
755     return;
756
757   actors->InitTraversal();
758   vtkActor* actor;
759   while( ( actor = actors->GetNextActor() ) )
760   {
761     SALOME_Actor* salomeActor = SALOME_Actor::SafeDownCast( actor );
762     if ( salomeActor )                      
763     {
764       // just display the object
765       m_RWInteractor->Display( salomeActor, false );
766       
767       // Set visibility flag
768       Handle(SALOME_InteractiveObject) anObj = salomeActor->getIO();
769       if ( !anObj.IsNull() && anObj->hasEntry() )
770       {
771         SALOMEDS::Study_var aStudy =
772           QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
773         ToolsGUI::SetVisibility( aStudy, anObj->getEntry(), true, this );
774       }
775
776       if ( salomeActor->IsSetCamera() )
777         salomeActor->SetCamera( getRenderer()->GetActiveCamera() );
778     }
779   }
780 }
781
782 //==========================================================
783 /*!
784  *  VTKViewer_ViewFrame::Erase
785  *  Erase presentation
786  */
787 //==========================================================
788 void VTKViewer_ViewFrame::Erase( const SALOME_VTKPrs* prs, const bool forced )
789 {
790   // try do downcast object
791   const VTKViewer_Prs* aVTKPrs = dynamic_cast<const VTKViewer_Prs*>( prs );
792   if ( !aVTKPrs || aVTKPrs->IsNull() )
793     return;
794
795   vtkActorCollection* actors = aVTKPrs->GetObjects();
796   if ( !actors )
797     return;
798
799   SALOMEDS::Study_var aStudy =
800     QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
801
802   actors->InitTraversal();
803   vtkActor* actor;
804   while( ( actor = actors->GetNextActor() ) ) {
805     SALOME_Actor* salomeActor = SALOME_Actor::SafeDownCast( actor );
806     if ( salomeActor ) {
807       // just erase the object
808       if ( forced )
809         m_RWInteractor->Remove( salomeActor, false );
810       else
811         m_RWInteractor->Erase( salomeActor, forced );
812
813       // Set visibility flag if necessary
814       if ( !forced )
815       {
816         Handle(SALOME_InteractiveObject) anObj = salomeActor->getIO();
817         if ( !anObj.IsNull() && anObj->hasEntry() )
818           ToolsGUI::SetVisibility( aStudy, anObj->getEntry(), true, this );
819       }
820     }
821   }
822 }
823   
824 //==========================================================
825 /*!
826  *  VTKViewer_ViewFrame::CreatePrs
827  *  Create presentation by entry
828  */
829 //==========================================================
830 SALOME_Prs* VTKViewer_ViewFrame::CreatePrs( const char* entry )
831 {
832   VTKViewer_Prs* prs = new VTKViewer_Prs();
833   if ( entry ) {
834     vtkActorCollection* theActors = m_Renderer->GetActors();
835     theActors->InitTraversal();
836     vtkActor* ac;
837     while( ( ac = theActors->GetNextActor() ) ) {
838       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
839       if ( anActor && anActor->hasIO() && !strcmp( anActor->getIO()->getEntry(), entry ) ) {
840         prs->AddObject( ac );
841       }
842     }
843   }
844   return prs;
845 }
846
847 //==========================================================
848 /*!
849  *  VTKViewer_ViewFrame::BeforeDisplay
850  *  Axiluary method called before displaying of objects
851  */
852 //==========================================================
853 void  VTKViewer_ViewFrame::BeforeDisplay( SALOME_Displayer* d )
854 {
855   d->BeforeDisplay( this, SALOME_VTKViewType() );
856 }
857
858 //==========================================================
859 /*!
860  *  VTKViewer_ViewFrame::AfterDisplay
861  *  Axiluary method called after displaying of objects
862  */
863 //==========================================================
864 void  VTKViewer_ViewFrame::AfterDisplay( SALOME_Displayer* d )
865 {
866   d->AfterDisplay( this, SALOME_VTKViewType() );
867 }
868
869 //==========================================================
870 /*!
871  *  VTKViewer_ViewFrame::undo
872  *  Redisplay all objects in viewer
873  */
874 //==========================================================
875 void VTKViewer_ViewFrame::undo( QAD_Study* theQADStudy, const char* /*StudyFrameEntry*/ )
876 {
877   redisplayAll( theQADStudy, true );
878 }
879
880 //==========================================================
881 /*!
882  *  VTKViewer_ViewFrame::redo
883  *  Redisplay all objects in viewer
884  */
885 //==========================================================
886 void VTKViewer_ViewFrame::redo( QAD_Study* theQADStudy, const char* /*StudyFrameEntry*/ )
887 {
888   redisplayAll( theQADStudy, true );
889 }
890
891 //==========================================================
892 /*!
893  *  VTKViewer_ViewFrame::redisplayAll
894  *  Redisplay all objects in viewer
895  */
896 //==========================================================
897 void VTKViewer_ViewFrame::redisplayAll( QAD_Study* theQADStudy, const bool theToUpdate )
898 {
899   SALOMEDS::Study_var      aStudy     = theQADStudy->getStudyDocument();
900   SALOME_Selection*        aSel       = SALOME_Selection::Selection( theQADStudy->getSelection() );
901   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
902   SALOMEGUI*               aGUI       = aDesktop->getActiveGUI();
903   const QString&           aCompName  = aDesktop->getComponentDataType();
904   SALOMEDS::SObject_var    aComponent =
905     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
906
907   if ( aComponent->_is_nil() )
908     return;
909
910   m_RWInteractor->RemoveAll( false );
911   //m_RWInteractor->EraseAll();
912
913   aSel->ClearIObjects();
914
915   /*  
916    //   ENK commented, already added to renderer in 
917    //   VTKViewer_ViewFrame::VTKViewer_ViewFrame(...)
918   if ( isTrhDisplayed )
919       m_Triedron->AddToRender( m_Renderer );
920   */
921
922   std::list<SALOMEDS::SObject_var> aList;
923   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
924
925   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
926   for ( ; anIter != aList.end(); ++anIter )
927   {
928     SALOMEDS::SObject_var anObj = (*anIter);
929     if ( ToolsGUI::GetVisibility( aStudy, anObj, this ) )
930     {
931       Handle(SALOME_InteractiveObject) anIObj = new SALOME_InteractiveObject();
932       anIObj->setEntry( anObj->GetID() );
933       aGUI->BuildPresentation( anIObj, this );
934     }
935     
936   }
937
938   if ( theToUpdate )
939     Repaint();
940 }
941
942 #define INCREMENT_FOR_OP 10
943
944 //=======================================================================
945 // name    : onPanLeft
946 // Purpose : Performs incremental panning to the left
947 //=======================================================================
948 void VTKViewer_ViewFrame::onPanLeft()
949 {
950   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( -INCREMENT_FOR_OP, 0 );
951 }
952
953 //=======================================================================
954 // name    : onPanRight
955 // Purpose : Performs incremental panning to the right
956 //=======================================================================
957 void VTKViewer_ViewFrame::onPanRight()
958 {
959   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( INCREMENT_FOR_OP, 0 );
960 }
961
962 //=======================================================================
963 // name    : onPanUp
964 // Purpose : Performs incremental panning to the top
965 //=======================================================================
966 void VTKViewer_ViewFrame::onPanUp()
967 {
968   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( 0, INCREMENT_FOR_OP );
969 }
970
971 //=======================================================================
972 // name    : onPanDown
973 // Purpose : Performs incremental panning to the bottom
974 //=======================================================================
975 void VTKViewer_ViewFrame::onPanDown()
976 {
977   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( 0, -INCREMENT_FOR_OP );
978 }
979
980 //=======================================================================
981 // name    : onZoomIn
982 // Purpose : Performs incremental zooming in
983 //=======================================================================
984 void VTKViewer_ViewFrame::onZoomIn()
985 {
986   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalZoom( INCREMENT_FOR_OP );
987 }
988
989 //=======================================================================
990 // name    : onZoomOut
991 // Purpose : Performs incremental zooming out
992 //=======================================================================
993 void VTKViewer_ViewFrame::onZoomOut()
994 {
995   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalZoom( -INCREMENT_FOR_OP );
996 }
997
998 //=======================================================================
999 // name    : onRotateLeft
1000 // Purpose : Performs incremental rotating to the left
1001 //=======================================================================
1002 void VTKViewer_ViewFrame::onRotateLeft()
1003 {
1004   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( -INCREMENT_FOR_OP, 0 );
1005 }
1006
1007 //=======================================================================
1008 // name    : onRotateRight
1009 // Purpose : Performs incremental rotating to the right
1010 //=======================================================================
1011 void VTKViewer_ViewFrame::onRotateRight()
1012 {
1013   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( INCREMENT_FOR_OP, 0 );
1014 }
1015
1016 //=======================================================================
1017 // name    : onRotateUp
1018 // Purpose : Performs incremental rotating to the top
1019 //=======================================================================
1020 void VTKViewer_ViewFrame::onRotateUp()
1021 {
1022   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( 0, -INCREMENT_FOR_OP );
1023 }
1024
1025 //=======================================================================
1026 // name    : onRotateDown
1027 // Purpose : Performs incremental rotating to the bottom
1028 //=======================================================================
1029 void VTKViewer_ViewFrame::onRotateDown()
1030 {
1031   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( 0, INCREMENT_FOR_OP );
1032 }