Salome HOME
1385ca4330ffd1017f93d88996ce8ec9da646d48
[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 bool VTKViewer_ViewFrame::ComputeTrihedronSize( double& theNewSize, double& theSize )
193 {
194   // calculating diagonal of visible props of the renderer
195   float bnd[ 6 ];
196   m_Triedron->VisibilityOff();
197   if ( ::ComputeVisiblePropBounds( m_Renderer, bnd ) == 0 )
198   {
199     bnd[ 1 ] = bnd[ 3 ] = bnd[ 5 ] = 100;
200     bnd[ 0 ] = bnd[ 2 ] = bnd[ 100 ] = 0;
201   }
202   m_Triedron->VisibilityOn();
203   float aLength = 0;
204   static bool CalcByDiag = false;
205   if ( CalcByDiag )
206   {
207     aLength = sqrt( ( bnd[1]-bnd[0])*(bnd[1]-bnd[0] )+
208                     ( bnd[3]-bnd[2])*(bnd[3]-bnd[2] )+
209                     ( bnd[5]-bnd[4])*(bnd[5]-bnd[4] ) );
210   }
211   else
212   {
213     aLength = bnd[ 1 ]-bnd[ 0 ];
214     aLength = max( ( bnd[ 3 ] - bnd[ 2 ] ),aLength );
215     aLength = max( ( bnd[ 5 ] - bnd[ 4 ] ),aLength );
216   }
217
218   static float aSizeInPercents = 105;
219   QString aSetting = QAD_CONFIG->getSetting( "Viewer:TrihedronSize" );
220   if ( !aSetting.isEmpty() )
221     aSizeInPercents = aSetting.toFloat();
222
223   static float EPS_SIZE = 5.0E-3;
224   theSize = m_Triedron->GetSize();
225   theNewSize = aLength * aSizeInPercents / 100.0;
226
227   // if the new trihedron size have sufficient difference, then apply the value
228   return fabs( theNewSize - theSize) > theSize * EPS_SIZE ||
229          fabs( theNewSize-theSize ) > theNewSize * EPS_SIZE;
230 }
231
232 double VTKViewer_ViewFrame::GetTrihedronSize() const
233 {
234   return m_Triedron->GetSize();
235 }
236
237 void VTKViewer_ViewFrame::AdjustTrihedrons( const bool forcedUpdate )
238 {
239   
240   if ( !isCubeAxesDisplayed() && !isTrihedronDisplayed() && !forcedUpdate )
241     return;
242
243   float bnd[ 6 ];
244   float newbnd[6];
245   newbnd[ 0 ] = newbnd[ 2 ] = newbnd[ 4 ] = VTK_LARGE_FLOAT;
246   newbnd[ 1 ] = newbnd[ 3 ] = newbnd[ 5 ] = -VTK_LARGE_FLOAT;
247
248   m_CubeAxes->GetBounds(bnd);
249   if(MYDEBUG)
250     cout << "Bounds: BEFORE\n"
251          << "\txMin=" << bnd[ 0 ] << " xMax=" << bnd[ 1 ] << "\n"
252          << "\tyMin=" << bnd[ 2 ] << " yMax=" << bnd[ 3 ] << "\n"
253          << "\tzMin=" << bnd[ 4 ] << " zMax=" << bnd[ 5 ] << "\n";
254
255   int aVisibleNum = m_Triedron->GetVisibleActorCount( m_Renderer );
256   if ( aVisibleNum || forcedUpdate )
257   {
258     // if the new trihedron size have sufficient difference, then apply the value
259     double aNewSize = 100, anOldSize;
260     if ( ComputeTrihedronSize( aNewSize, anOldSize ) || forcedUpdate )
261     {
262       m_Triedron->SetSize( aNewSize );
263       // itearte throuh displayed objects and set size if necessary
264
265       vtkActorCollection* anActors = getRenderer()->GetActors();
266       anActors->InitTraversal();
267       while( vtkActor* anActor = anActors->GetNextActor() )
268       {
269         if( SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast( anActor ) )
270         {
271           if ( aSActor->IsResizable() )
272             aSActor->SetSize( 0.5 * aNewSize );
273           if( aSActor->GetVisibility()){
274             float abounds[6];
275             aSActor->GetBounds(abounds);
276             if(MYDEBUG)
277               cout << "Bounds: Actor="<<aSActor<<"\n"
278                    << "\txMin=" << abounds[ 0 ] << " xMax=" << abounds[ 1 ] << "\n"
279                    << "\tyMin=" << abounds[ 2 ] << " yMax=" << abounds[ 3 ] << "\n"
280                    << "\tzMin=" << abounds[ 4 ] << " zMax=" << abounds[ 5 ] << "\n";
281             if (  abounds[0] > -VTK_LARGE_FLOAT && abounds[1] < VTK_LARGE_FLOAT &&
282                   abounds[2] > -VTK_LARGE_FLOAT && abounds[3] < VTK_LARGE_FLOAT &&
283                   abounds[4] > -VTK_LARGE_FLOAT && abounds[5] < VTK_LARGE_FLOAT)
284               for(int i=0;i<5;i=i+2){
285                 if(abounds[i]<newbnd[i]) newbnd[i]=abounds[i];
286                 if(abounds[i+1]>newbnd[i+1]) newbnd[i+1]=abounds[i+1];
287                 
288               }
289           }
290         }
291       }
292     }
293   }
294   if( newbnd[0]<VTK_LARGE_FLOAT && newbnd[2]<VTK_LARGE_FLOAT && newbnd[4]<VTK_LARGE_FLOAT &&
295       newbnd[1]>-VTK_LARGE_FLOAT && newbnd[3]>-VTK_LARGE_FLOAT && newbnd[5]>-VTK_LARGE_FLOAT){
296     for(int i=0;i<6;i++) bnd[i] = newbnd[i];
297     m_CubeAxes->SetBounds(bnd);
298   }
299   if(MYDEBUG)
300     cout << "Bounds AFTER: VisibleActors="<<aVisibleNum<<"\n"
301          << "\txMin=" << bnd[ 0 ] << " xMax=" << bnd[ 1 ] << "\n"
302          << "\tyMin=" << bnd[ 2 ] << " yMax=" << bnd[ 3 ] << "\n"
303          << "\tzMin=" << bnd[ 4 ] << " zMax=" << bnd[ 5 ] << "\n";
304   
305   m_CubeAxes->SetBounds(bnd);
306
307   ::ResetCameraClippingRange(m_Renderer);
308 }
309
310 void VTKViewer_ViewFrame::AdjustAxes( const bool forcedUpdate )
311 {
312   AdjustTrihedrons(forcedUpdate);
313 }
314
315 void VTKViewer_ViewFrame::onAdjustTrihedron()
316 {   
317   AdjustTrihedrons( false );
318 }
319
320 void VTKViewer_ViewFrame::onAdjustAxes()
321 {   
322   AdjustAxes( false );
323 }
324
325 /*!
326   Display/hide Trihedron
327 */
328 void VTKViewer_ViewFrame::onViewTrihedron(){
329   if(!m_Triedron) return;
330   if(isTrihedronDisplayed()){
331     m_Triedron->VisibilityOff();
332     m_CubeAxes->VisibilityOff();
333   }
334   else{
335     m_Triedron->VisibilityOn();
336     m_CubeAxes->VisibilityOn();
337   }
338   Repaint();
339 }
340
341 /*!
342   Provides top projection of the active view
343 */
344 void VTKViewer_ViewFrame::onViewTop(){
345   vtkCamera* camera = m_Renderer->GetActiveCamera();
346   camera->SetPosition(0,0,1);
347   camera->SetViewUp(0,1,0);
348   camera->SetFocalPoint(0,0,0);
349   onViewFitAll();
350 }
351
352 /*!
353   Provides bottom projection of the active view
354 */
355 void VTKViewer_ViewFrame::onViewBottom(){
356   vtkCamera* camera = m_Renderer->GetActiveCamera();
357   camera->SetPosition(0,0,-1);
358   camera->SetViewUp(0,1,0);
359   camera->SetFocalPoint(0,0,0);
360   onViewFitAll();
361 }
362
363 /*!
364   Provides left projection of the active view
365 */
366 void VTKViewer_ViewFrame::onViewLeft(){
367   vtkCamera* camera = m_Renderer->GetActiveCamera(); 
368   camera->SetPosition(0,-1,0);
369   camera->SetViewUp(0,0,1);
370   camera->SetFocalPoint(0,0,0);
371   onViewFitAll();
372 }
373
374 /*!
375   Provides right projection of the active view
376 */
377 void VTKViewer_ViewFrame::onViewRight(){
378   vtkCamera* camera = m_Renderer->GetActiveCamera();
379   camera->SetPosition(0,1,0);
380   camera->SetViewUp(0,0,1);
381   camera->SetFocalPoint(0,0,0);
382   onViewFitAll();
383 }
384
385 /*!
386   Provides back projection of the active view
387 */
388 void VTKViewer_ViewFrame::onViewBack(){
389   vtkCamera* camera = m_Renderer->GetActiveCamera();
390   camera->SetPosition(-1,0,0);
391   camera->SetViewUp(0,0,1);
392   camera->SetFocalPoint(0,0,0);
393   onViewFitAll();
394 }
395
396 /*!
397   Provides front projection of the active view
398 */
399 void VTKViewer_ViewFrame::onViewFront(){
400   vtkCamera* camera = m_Renderer->GetActiveCamera();
401   camera->SetPosition(1,0,0);
402   camera->SetViewUp(0,0,1);
403   camera->SetFocalPoint(0,0,0);
404   onViewFitAll();
405 }
406
407 /*!
408   Fits all objects in the active view
409 */
410 void VTKViewer_ViewFrame::onViewFitAll(){
411
412   int aTriedronWasVisible = false;
413   int aCubeAxesWasVisible = false;
414   if(m_Triedron){
415     aTriedronWasVisible = m_Triedron->GetVisibility() == VTKViewer_Trihedron::eOn;
416     if(aTriedronWasVisible) m_Triedron->VisibilityOff();
417   }
418   if(m_CubeAxes){
419     aCubeAxesWasVisible = m_CubeAxes->GetVisibility();
420     if(aCubeAxesWasVisible) m_CubeAxes->VisibilityOff();
421   }
422
423   if(m_Triedron->GetVisibleActorCount(m_Renderer)){
424     m_Triedron->VisibilityOff();
425     m_CubeAxes->VisibilityOff();
426     ::ResetCamera(m_Renderer);
427   }else{
428     m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
429     m_CubeAxes->SetVisibility(2);
430     ::ResetCamera(m_Renderer,true);
431   }
432   if(aTriedronWasVisible) m_Triedron->VisibilityOn();
433   else m_Triedron->VisibilityOff();
434   if(aCubeAxesWasVisible) m_CubeAxes->VisibilityOn();
435   else m_CubeAxes->VisibilityOff();
436   ::ResetCameraClippingRange(m_Renderer);
437
438   Repaint();
439 }
440
441 /*!
442   Reset the active view
443 */
444 void VTKViewer_ViewFrame::onViewReset(){
445   int aTriedronIsVisible = isTrihedronDisplayed();
446   m_Triedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
447   m_CubeAxes->SetVisibility(2);
448   ::ResetCamera(m_Renderer,true);  
449   vtkCamera* aCamera = m_Renderer->GetActiveCamera();
450   aCamera->SetPosition(1,-1,1);
451   aCamera->SetViewUp(0,0,1);
452   ::ResetCamera(m_Renderer,true);  
453   if(aTriedronIsVisible){
454     m_Triedron->VisibilityOn();
455     m_CubeAxes->VisibilityOn();
456   }
457   else{
458     m_Triedron->VisibilityOff();
459     m_CubeAxes->VisibilityOff();
460   }
461   static float aCoeff = 3.0;
462   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
463   Repaint();
464 }
465
466 /*!
467   Rotates the active view
468 */
469 void VTKViewer_ViewFrame::onViewRotate(){
470   m_RWInteractor->GetInteractorStyleSALOME()->startRotate();
471 }
472
473 /*!
474   Sets a new center of the active view
475 */
476 void VTKViewer_ViewFrame::onViewGlobalPan(){
477   if(m_Triedron->GetVisibleActorCount(m_Renderer))
478     m_RWInteractor->GetInteractorStyleSALOME()->startGlobalPan();
479 }
480
481 /*!
482   Zooms the active view
483 */
484 void VTKViewer_ViewFrame::onViewZoom(){
485   m_RWInteractor->GetInteractorStyleSALOME()->startZoom();
486 }
487
488 /*!
489   Moves the active view
490 */
491 void VTKViewer_ViewFrame::onViewPan(){
492   m_RWInteractor->GetInteractorStyleSALOME()->startPan();
493 }
494
495 /*!
496   Fits all obejcts within a rectangular area of the active view
497 */
498 void VTKViewer_ViewFrame::onViewFitArea(){
499   m_RWInteractor->GetInteractorStyleSALOME()->startFitArea();
500 }
501
502 /*!
503     Set background of the viewport
504 */
505 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
506 {
507   if ( m_Renderer )
508     m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
509 }
510
511 /*!
512     Returns background of the viewport
513 */
514 QColor VTKViewer_ViewFrame::backgroundColor() const
515 {
516   float backint[3];
517   if ( m_Renderer ) {
518     m_Renderer->GetBackground(backint);
519     return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
520   }
521   return QMainWindow::backgroundColor();
522 }
523
524
525 void VTKViewer_ViewFrame::SetSelectionMode( Selection_Mode mode )
526 {
527   m_RWInteractor->SetSelectionMode( mode );
528 }
529
530 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
531 {
532   m_RWInteractor->rename(IObject, newName);
533 }
534
535 void VTKViewer_ViewFrame::unHighlightAll() 
536 {
537   m_RWInteractor->unHighlightAll();
538 }
539
540 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject, 
541                                      bool highlight, 
542                                      bool update ) 
543 {
544   QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
545   SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
546   m_RWInteractor->highlight(IObject, highlight, update);
547
548   if(Sel->HasIndex(IObject) && IObject->hasEntry()){
549     TColStd_IndexedMapOfInteger MapIndex;
550     Sel->GetIndex(IObject,MapIndex);
551     using namespace SALOME::VTK;
552     const char* anEntry = IObject->getEntry();
553     vtkActorCollection* aCollection = getRenderer()->GetActors();
554     if(SALOME_Actor* anActor = Find<SALOME_Actor>(aCollection,TIsSameEntry<SALOME_Actor>(anEntry))){
555       switch (Sel->SelectionMode()) {
556       case NodeSelection:
557         m_RWInteractor->highlightPoint(MapIndex,anActor,highlight,update);
558         break;
559       case EdgeOfCellSelection:
560         m_RWInteractor->highlightEdge(MapIndex,anActor,highlight,update);
561         break;
562       case CellSelection:
563       case EdgeSelection:
564       case FaceSelection:
565       case VolumeSelection:
566         m_RWInteractor->highlightCell(MapIndex,anActor,highlight,update);
567         break;
568       }
569     }
570   }else{
571     m_RWInteractor->unHighlightSubSelection();
572   }
573 }
574
575 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
576 {
577   return m_RWInteractor->isInViewer( IObject );
578 }
579
580 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
581 {
582   return m_RWInteractor->isVisible( IObject );
583 }
584
585 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
586 {
587   m_RW->setPopupServer( App );
588 }
589
590 /* selection */
591 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* theEntry)
592 {
593   using namespace SALOME::VTK;
594   SALOME_Actor* anActor = 
595     Find<SALOME_Actor>(getRenderer()->GetActors(),
596                        TIsSameEntry<SALOME_Actor>(theEntry));
597   if(anActor)
598     return anActor->getIO();
599
600   return Handle(SALOME_InteractiveObject)();
601 }
602
603 /* display */           
604 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
605 {
606   QAD_Study*          aQADStudy = QAD_Application::getDesktop()->getActiveStudy();
607   SALOME_Selection*   aSel      = SALOME_Selection::Selection( aQADStudy->getSelection() );
608   SALOMEDS::Study_var aStudy    = aQADStudy->getStudyDocument();
609
610   m_RWInteractor->Display(theIObject,false);
611   ToolsGUI::SetVisibility( aStudy, theIObject->getEntry(), true, this );
612   aSel->AddIObject(theIObject,false);
613
614   if(update)
615     Repaint();
616 }
617
618
619 struct TDisplayAction{
620   SALOME_Selection* mySel;
621   Handle(SALOME_InteractiveObject) myIO;
622   TDisplayAction(SALOME_Selection* theSel,
623                  Handle(SALOME_InteractiveObject) theIO): 
624     mySel(theSel), myIO(theIO)
625   {}
626   void operator()(SALOME_Actor* theActor){
627     theActor->SetVisibility(true);
628     mySel->AddIObject(myIO,false);
629   }
630 };
631
632 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& theIObject)
633 {
634   QAD_Study* aStudy = QAD_Application::getDesktop()->getActiveStudy();
635   SALOME_Selection* aSel = SALOME_Selection::Selection(aStudy->getSelection());
636
637   aSel->ClearIObjects();
638   //m_RWInteractor->EraseAll();
639   EraseAll();
640
641   using namespace SALOME::VTK;
642   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
643                           TIsSameIObject<SALOME_Actor>(theIObject),
644                           TDisplayAction(aSel,theIObject));
645
646   ToolsGUI::SetVisibility(
647     aStudy->getStudyDocument(), theIObject->getEntry(), true, this );
648
649   Repaint();
650 }
651
652
653 struct TEraseAction: TDisplayAction{
654   VTKViewer_RenderWindowInteractor* myRWInteractor;
655   TEraseAction(SALOME_Selection* theSel,
656                Handle(SALOME_InteractiveObject) theIO,
657                VTKViewer_RenderWindowInteractor* theRWInteractor): 
658     TDisplayAction(theSel,theIO),
659     myRWInteractor(theRWInteractor)
660   {}
661   void operator()(SALOME_Actor* theActor){
662     myRWInteractor->Erase(myIO,false);
663     mySel->RemoveIObject(myIO,false);
664   }
665 };
666
667 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& theIObject, bool update)
668 {
669   QAD_Study* aStudy = QAD_Application::getDesktop()->getActiveStudy();
670   SALOME_Selection* aSel = SALOME_Selection::Selection(aStudy->getSelection());
671
672   using namespace SALOME::VTK;
673   ForEachIf<SALOME_Actor>(getRenderer()->GetActors(),
674                           TIsSameIObject<SALOME_Actor>(theIObject),
675                           TEraseAction(aSel,theIObject,m_RWInteractor));
676
677   ToolsGUI::SetVisibility(
678     aStudy->getStudyDocument(), theIObject->getEntry(), false, this );
679
680   if(update)
681     Repaint();
682 }
683
684
685 void VTKViewer_ViewFrame::DisplayAll()
686 {
687   m_RWInteractor->DisplayAll();
688
689   // update flag of visibility
690   QAD_Study*               aQADStudy  = QAD_Application::getDesktop()->getActiveStudy();
691   SALOMEDS::Study_var      aStudy     = aQADStudy->getStudyDocument();
692   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
693   const QString&           aCompName  = aDesktop->getComponentDataType();
694   SALOMEDS::SObject_var    aComponent =
695     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
696     
697   std::list<SALOMEDS::SObject_var> aList;
698   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
699
700   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
701   for ( ; anIter != aList.end(); ++anIter )
702     ToolsGUI::SetVisibility( aStudy, (*anIter)->GetID(), true, this );
703 }
704
705
706 void VTKViewer_ViewFrame::EraseAll()
707 {
708   m_RWInteractor->EraseAll();
709
710   // update flag of visibility
711   QAD_Study*               aQADStudy  = QAD_Application::getDesktop()->getActiveStudy();
712   SALOMEDS::Study_var      aStudy     = aQADStudy->getStudyDocument();
713   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
714   const QString&           aCompName  = aDesktop->getComponentDataType();
715   SALOMEDS::SObject_var    aComponent =
716     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
717
718   std::list<SALOMEDS::SObject_var> aList;
719   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
720
721   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
722   for ( ; anIter != aList.end(); ++anIter )
723     ToolsGUI::SetVisibility( aStudy, (*anIter)->GetID(), false, this );
724 }
725
726
727 void VTKViewer_ViewFrame::Repaint(bool theUpdateAxes)
728 {
729   if (theUpdateAxes) onAdjustAxes();
730   m_RW->update();
731 }
732
733 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
734   m_Transform->GetScale(theScale);
735 }
736
737 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
738   m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
739   m_RWInteractor->Render();
740   Repaint();
741 }
742
743 void VTKViewer_ViewFrame::InsertActor( SALOME_Actor* theActor, bool theMoveInternalActors ){
744   theActor->AddToRender(m_Renderer);
745   theActor->SetTransform(m_Transform);
746   if(theMoveInternalActors) 
747     m_RWInteractor->MoveInternalActors();
748 }
749
750 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool theUpdate /*=false*/ ){
751   InsertActor(theActor);
752   if(theUpdate) 
753     Repaint();
754 }
755
756 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool theUpdate /*=false*/ ){
757   theActor->RemoveFromRender(m_Renderer);
758   if(theUpdate) 
759     Repaint();
760 }
761
762 void VTKViewer_ViewFrame::MoveActor(SALOME_Actor* theActor)
763 {
764   RemoveActor(theActor);
765   InsertActor(theActor,true);
766 }
767
768 //==========================================================
769 /*!
770  *  VTKViewer_ViewFrame::Display
771  *  Display presentation
772  */
773 //==========================================================
774 void VTKViewer_ViewFrame::Display( const SALOME_VTKPrs* prs )
775 {
776   // try do downcast object
777   const VTKViewer_Prs* aVTKPrs = dynamic_cast<const VTKViewer_Prs*>( prs );
778   if ( !aVTKPrs || aVTKPrs->IsNull() )
779     return;
780
781   vtkActorCollection* actors = aVTKPrs->GetObjects();
782   if ( !actors )
783     return;
784
785   actors->InitTraversal();
786   vtkActor* actor;
787   while( ( actor = actors->GetNextActor() ) )
788   {
789     SALOME_Actor* salomeActor = SALOME_Actor::SafeDownCast( actor );
790     if ( salomeActor )                      
791     {
792       // just display the object
793       m_RWInteractor->Display( salomeActor, false );
794       
795       // Set visibility flag
796       Handle(SALOME_InteractiveObject) anObj = salomeActor->getIO();
797       if ( !anObj.IsNull() && anObj->hasEntry() )
798       {
799         SALOMEDS::Study_var aStudy =
800           QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
801         ToolsGUI::SetVisibility( aStudy, anObj->getEntry(), true, this );
802       }
803
804       if ( salomeActor->IsSetCamera() )
805         salomeActor->SetCamera( getRenderer()->GetActiveCamera() );
806     }
807   }
808 }
809
810 //==========================================================
811 /*!
812  *  VTKViewer_ViewFrame::Erase
813  *  Erase presentation
814  */
815 //==========================================================
816 void VTKViewer_ViewFrame::Erase( const SALOME_VTKPrs* prs, const bool forced )
817 {
818   // try do downcast object
819   const VTKViewer_Prs* aVTKPrs = dynamic_cast<const VTKViewer_Prs*>( prs );
820   if ( !aVTKPrs || aVTKPrs->IsNull() )
821     return;
822
823   vtkActorCollection* actors = aVTKPrs->GetObjects();
824   if ( !actors )
825     return;
826
827   SALOMEDS::Study_var aStudy =
828     QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
829
830   actors->InitTraversal();
831   vtkActor* actor;
832   while( ( actor = actors->GetNextActor() ) ) {
833     SALOME_Actor* salomeActor = SALOME_Actor::SafeDownCast( actor );
834     if ( salomeActor ) {
835       // just erase the object
836       if ( forced )
837         m_RWInteractor->Remove( salomeActor, false );
838       else
839         m_RWInteractor->Erase( salomeActor, forced );
840
841       // Set visibility flag if necessary
842       if ( !forced )
843       {
844         Handle(SALOME_InteractiveObject) anObj = salomeActor->getIO();
845         if ( !anObj.IsNull() && anObj->hasEntry() )
846           ToolsGUI::SetVisibility( aStudy, anObj->getEntry(), true, this );
847       }
848     }
849   }
850 }
851   
852 //==========================================================
853 /*!
854  *  VTKViewer_ViewFrame::CreatePrs
855  *  Create presentation by entry
856  */
857 //==========================================================
858 SALOME_Prs* VTKViewer_ViewFrame::CreatePrs( const char* entry )
859 {
860   VTKViewer_Prs* prs = new VTKViewer_Prs();
861   if ( entry ) {
862     vtkActorCollection* theActors = m_Renderer->GetActors();
863     theActors->InitTraversal();
864     vtkActor* ac;
865     while( ( ac = theActors->GetNextActor() ) ) {
866       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
867       if ( anActor && anActor->hasIO() && !strcmp( anActor->getIO()->getEntry(), entry ) ) {
868         prs->AddObject( ac );
869       }
870     }
871   }
872   return prs;
873 }
874
875 //==========================================================
876 /*!
877  *  VTKViewer_ViewFrame::BeforeDisplay
878  *  Axiluary method called before displaying of objects
879  */
880 //==========================================================
881 void  VTKViewer_ViewFrame::BeforeDisplay( SALOME_Displayer* d )
882 {
883   d->BeforeDisplay( this, SALOME_VTKViewType() );
884 }
885
886 //==========================================================
887 /*!
888  *  VTKViewer_ViewFrame::AfterDisplay
889  *  Axiluary method called after displaying of objects
890  */
891 //==========================================================
892 void  VTKViewer_ViewFrame::AfterDisplay( SALOME_Displayer* d )
893 {
894   d->AfterDisplay( this, SALOME_VTKViewType() );
895 }
896
897 //==========================================================
898 /*!
899  *  VTKViewer_ViewFrame::undo
900  *  Redisplay all objects in viewer
901  */
902 //==========================================================
903 void VTKViewer_ViewFrame::undo( QAD_Study* theQADStudy, const char* /*StudyFrameEntry*/ )
904 {
905   redisplayAll( theQADStudy, true );
906 }
907
908 //==========================================================
909 /*!
910  *  VTKViewer_ViewFrame::redo
911  *  Redisplay all objects in viewer
912  */
913 //==========================================================
914 void VTKViewer_ViewFrame::redo( QAD_Study* theQADStudy, const char* /*StudyFrameEntry*/ )
915 {
916   redisplayAll( theQADStudy, true );
917 }
918
919 //==========================================================
920 /*!
921  *  VTKViewer_ViewFrame::redisplayAll
922  *  Redisplay all objects in viewer
923  */
924 //==========================================================
925 void VTKViewer_ViewFrame::redisplayAll( QAD_Study* theQADStudy, const bool theToUpdate )
926 {
927   SALOMEDS::Study_var      aStudy     = theQADStudy->getStudyDocument();
928   SALOME_Selection*        aSel       = SALOME_Selection::Selection( theQADStudy->getSelection() );
929   QAD_Desktop*             aDesktop   = QAD_Application::getDesktop();
930   SALOMEGUI*               aGUI       = aDesktop->getActiveGUI();
931   const QString&           aCompName  = aDesktop->getComponentDataType();
932   SALOMEDS::SObject_var    aComponent =
933     SALOMEDS::SObject::_narrow( aStudy->FindComponent ( aCompName.latin1() ) );
934
935   if ( aComponent->_is_nil() )
936     return;
937
938 //   bool isTrhDisplayed = isTrihedronDisplayed();
939 //   bool isCubeDisplayed = isCubeAxesDisplayed();
940
941   m_RWInteractor->RemoveAll( false );
942   //m_RWInteractor->EraseAll();
943
944   aSel->ClearIObjects();
945
946   /*  
947    //   ENK commented, already added to renderer in 
948    //   VTKViewer_ViewFrame::VTKViewer_ViewFrame(...)
949   if ( isTrhDisplayed )
950       m_Triedron->AddToRender( m_Renderer );
951   */
952
953   std::list<SALOMEDS::SObject_var> aList;
954   SALOMEDS_Tool::GetAllChildren( aStudy, aComponent, aList );
955
956   std::list<SALOMEDS::SObject_var>::iterator anIter = aList.begin();
957   for ( ; anIter != aList.end(); ++anIter )
958   {
959     SALOMEDS::SObject_var anObj = (*anIter);
960     if ( ToolsGUI::GetVisibility( aStudy, anObj, this ) )
961     {
962       Handle(SALOME_InteractiveObject) anIObj = new SALOME_InteractiveObject();
963       anIObj->setEntry( anObj->GetID() );
964       aGUI->BuildPresentation( anIObj, this );
965     }
966     
967   }
968
969   if ( theToUpdate )
970     Repaint();
971 }
972
973 #define INCREMENT_FOR_OP 10
974
975 //=======================================================================
976 // name    : onPanLeft
977 // Purpose : Performs incremental panning to the left
978 //=======================================================================
979 void VTKViewer_ViewFrame::onPanLeft()
980 {
981   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( -INCREMENT_FOR_OP, 0 );
982 }
983
984 //=======================================================================
985 // name    : onPanRight
986 // Purpose : Performs incremental panning to the right
987 //=======================================================================
988 void VTKViewer_ViewFrame::onPanRight()
989 {
990   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( INCREMENT_FOR_OP, 0 );
991 }
992
993 //=======================================================================
994 // name    : onPanUp
995 // Purpose : Performs incremental panning to the top
996 //=======================================================================
997 void VTKViewer_ViewFrame::onPanUp()
998 {
999   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( 0, INCREMENT_FOR_OP );
1000 }
1001
1002 //=======================================================================
1003 // name    : onPanDown
1004 // Purpose : Performs incremental panning to the bottom
1005 //=======================================================================
1006 void VTKViewer_ViewFrame::onPanDown()
1007 {
1008   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalPan( 0, -INCREMENT_FOR_OP );
1009 }
1010
1011 //=======================================================================
1012 // name    : onZoomIn
1013 // Purpose : Performs incremental zooming in
1014 //=======================================================================
1015 void VTKViewer_ViewFrame::onZoomIn()
1016 {
1017   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalZoom( INCREMENT_FOR_OP );
1018 }
1019
1020 //=======================================================================
1021 // name    : onZoomOut
1022 // Purpose : Performs incremental zooming out
1023 //=======================================================================
1024 void VTKViewer_ViewFrame::onZoomOut()
1025 {
1026   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalZoom( -INCREMENT_FOR_OP );
1027 }
1028
1029 //=======================================================================
1030 // name    : onRotateLeft
1031 // Purpose : Performs incremental rotating to the left
1032 //=======================================================================
1033 void VTKViewer_ViewFrame::onRotateLeft()
1034 {
1035   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( -INCREMENT_FOR_OP, 0 );
1036 }
1037
1038 //=======================================================================
1039 // name    : onRotateRight
1040 // Purpose : Performs incremental rotating to the right
1041 //=======================================================================
1042 void VTKViewer_ViewFrame::onRotateRight()
1043 {
1044   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( INCREMENT_FOR_OP, 0 );
1045 }
1046
1047 //=======================================================================
1048 // name    : onRotateUp
1049 // Purpose : Performs incremental rotating to the top
1050 //=======================================================================
1051 void VTKViewer_ViewFrame::onRotateUp()
1052 {
1053   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( 0, -INCREMENT_FOR_OP );
1054 }
1055
1056 //=======================================================================
1057 // name    : onRotateDown
1058 // Purpose : Performs incremental rotating to the bottom
1059 //=======================================================================
1060 void VTKViewer_ViewFrame::onRotateDown()
1061 {
1062   m_RWInteractor->GetInteractorStyleSALOME()->IncrementalRotate( 0, INCREMENT_FOR_OP );
1063 }