Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[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_RenderWindow.h"
31
32 #include "SALOME_Transform.h"
33 #include "SALOME_TransformFilter.h"
34 #include "SALOME_PassThroughFilter.h"
35 #include "SALOME_GeometryFilter.h"
36
37 #include "QAD_Settings.h"
38 #include "QAD_Config.h"
39 #include "QAD_Application.h"
40 #include "QAD_Desktop.h"
41 #include "SALOME_Selection.h"
42 #include "SALOME_InteractiveObject.hxx"
43 #include "VTKViewer_InteractorStyleSALOME.h"
44 #include "VTKViewer_VectorText.h"
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 <vtkPolyDataMapper.h> 
58
59 #include <vtkMath.h>
60 #include <vtkLine.h>
61 #include <vtkConeSource.h>
62 #include <vtkFollower.h>
63
64 using namespace std;
65 /*!
66     Constructor
67 */
68 VTKViewer_ViewFrame::VTKViewer_ViewFrame(QWidget* parent, const char* name) 
69   :  QAD_ViewFrame(parent, name)
70 {
71   m_ViewUp[0] = 0; m_ViewUp[1] = 0; m_ViewUp[2] = -1;
72   m_ViewNormal[0] = 0; m_ViewNormal[1] = 0; m_ViewNormal[2] = 1;
73   m_Transform = SALOME_Transform::New();
74
75   //  m_InitialSetupDone = false ;
76   InitialSetup();
77 }
78
79
80 vtkFollower* CreateTextActor(char *text, float aSize) {
81   VTKViewer_VectorText* aTxt = VTKViewer_VectorText::New();
82   aTxt->SetText(text);
83   vtkPolyDataMapper* textMapper = vtkPolyDataMapper::New();
84   textMapper->SetInput(aTxt->GetOutput());
85   vtkFollower* textActor = vtkFollower::New();
86   textActor->SetMapper(textMapper);
87   float aScale = 17 * aSize/100;
88   textActor->SetScale(aScale, aScale, aScale);
89   return textActor;
90 }
91
92 void VTKViewer_ViewFrame::AddVector(float* o,float* p,vtkRenderer* renderer, float aSize) {
93   vtkPoints* myPoints = vtkPoints::New();
94   vtkLine* myLine = vtkLine::New();
95
96   myPoints->InsertNextPoint(o);
97   myPoints->InsertNextPoint(p);
98
99   (myLine->GetPointIds())->InsertNextId(0);
100   (myLine->GetPointIds())->InsertNextId(1);
101
102   vtkActor* lineActor = vtkActor::New();
103
104   vtkCellArray* cell = vtkCellArray::New();
105
106   cell->InsertNextCell(myLine);
107
108   vtkPolyData* output = vtkPolyData::New();
109   
110   output->SetPoints(myPoints);
111   output->SetLines(cell);
112  
113   vtkPolyDataMapper* mapper = vtkPolyDataMapper::New();
114
115   mapper->SetInput(output);
116
117   lineActor->SetMapper(mapper);
118
119   // Create CONE
120
121   vtkConeSource* acone =  vtkConeSource::New();
122
123   float dim = aSize;
124
125   acone->SetResolution(2);
126   //  acone->SetAngle(70);
127   acone->SetRadius(0.02*dim);
128   acone->SetHeight(0.08*dim);
129
130   vtkActor* coneActor = vtkActor::New();
131  
132   vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
133   coneMapper->SetInput(acone->GetOutput());
134
135   coneActor->SetMapper(coneMapper);
136   float rot[3];
137   rot[0]=0; rot[1]=0; rot[2]=0;
138
139   vtkFollower* aTextActor;
140
141   coneActor->AddPosition(p);
142   if(p[0]!=0) {
143     // x
144     aTextActor = CreateTextActor("X", dim);
145   } else if(p[1]!=0) {
146     // y
147     rot[2]=90;
148     coneActor->AddOrientation(rot);
149     aTextActor = CreateTextActor("Y", dim);
150   } else if(p[2]!=0) {
151     // z
152     rot[1]=-90;
153     coneActor->AddOrientation(rot);
154     aTextActor = CreateTextActor("Z", dim);
155   }
156   aTextActor->AddPosition(p);
157   aTextActor->SetCamera(renderer->GetActiveCamera());
158
159   coneActor->GetProperty()->SetInterpolation(1);
160   coneActor->GetProperty()->SetRepresentationToSurface();
161   coneActor->GetProperty()->SetAmbient(1);
162   coneActor->GetProperty()->SetAmbientColor(1,1,1);
163   coneActor->GetProperty()->SetDiffuseColor(0.7,0.7,0.7);
164   coneActor->GetProperty()->SetSpecularColor(0.7,0.7,0.7);
165
166   lineActor->GetProperty()->SetInterpolation(1);
167   lineActor->GetProperty()->SetRepresentationToSurface();
168   lineActor->GetProperty()->SetAmbient(1);
169   lineActor->GetProperty()->SetAmbientColor(1,1,1);
170   lineActor->GetProperty()->SetDiffuseColor(0.7,0.7,0.7);
171   lineActor->GetProperty()->SetSpecularColor(0.7,0.7,0.7);
172
173   aTextActor->GetProperty()->SetAmbient(1);
174   aTextActor->GetProperty()->SetAmbientColor(1,1,1);
175   aTextActor->GetProperty()->SetDiffuseColor(0.7,0.7,0.7);
176   aTextActor->GetProperty()->SetSpecularColor(0.7,0.7,0.7);
177      
178   coneActor->PickableOff();
179   lineActor->PickableOff();
180   aTextActor->PickableOff();
181   
182   m_Triedron->AddItem(coneActor);
183   m_Triedron->AddItem(lineActor);
184   m_Triedron->AddItem(aTextActor);
185
186   renderer->AddActor(coneActor);
187   renderer->AddActor(lineActor);
188   renderer->AddActor(aTextActor);
189 }  
190
191 bool VTKViewer_ViewFrame::isTrihedronDisplayed() {
192   m_Triedron->InitTraversal();
193   vtkActor *ac = m_Triedron->GetNextActor();
194   while(!(ac==NULL)) {
195     if(ac->GetVisibility()) return true;
196     ac = m_Triedron->GetNextActor();
197   }
198   return false;
199 }
200
201 void VTKViewer_ViewFrame::SetTrihedronSize(int size)
202 {
203   m_Triedron->InitTraversal();
204   vtkActor* anActor = m_Triedron->GetNextActor();
205   while(!(anActor==NULL)) {  
206     m_Renderer->RemoveActor( anActor );
207     anActor = m_Triedron->GetNextActor();
208   }
209
210   m_Triedron->RemoveAllItems();
211   AddAxis(m_Renderer);
212   m_RW->update();
213 }
214
215
216 void VTKViewer_ViewFrame::AddAxis(vtkRenderer* renderer) {  
217   float origine[3];
218   float X[3];
219   float Y[3];
220   float Z[3];
221   float dim;
222
223   QString Size = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
224   if( Size.isEmpty() ){
225     dim = 100;
226   } else {
227     dim = Size.toFloat();
228   }
229
230   origine[0]=0;        origine[1]=0;        origine[2]=0;
231   X[0]=origine[0]+dim; X[1]=origine[0];     X[2]=origine[0];
232   Y[0]=origine[0];     Y[1]=origine[0]+dim; Y[2]=origine[0];
233   Z[0]=origine[0];     Z[1]=origine[0];     Z[2]=origine[0]+dim;
234
235   AddVector(origine,X,renderer, dim);
236   AddVector(origine,Y,renderer, dim);
237   AddVector(origine,Z,renderer, dim);
238  
239 }
240
241 /*!
242   Returns widget containing 3D-Viewer
243 */
244 QWidget* VTKViewer_ViewFrame::getViewWidget() 
245 {
246   return m_RW;
247 }
248
249
250 void VTKViewer_ViewFrame::InitialSetup() {
251   m_Renderer = vtkRenderer::New() ;
252
253   m_RW = new VTKViewer_RenderWindow(this, "RenderWindow");
254   m_RW->getRenderWindow()->AddRenderer(m_Renderer);
255
256   m_Renderer->GetActiveCamera()->ParallelProjectionOn();
257   m_Renderer->LightFollowCameraOn();
258   m_Renderer->TwoSidedLightingOn();
259
260   // Set BackgroundColor
261   QString BgrColorRed   = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorRed");
262   QString BgrColorGreen = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorGreen");
263   QString BgrColorBlue  = QAD_CONFIG->getSetting("VTKViewer:BackgroundColorBlue");
264
265   if( !BgrColorRed.isEmpty() && !BgrColorGreen.isEmpty() && !BgrColorBlue.isEmpty() ) 
266     m_Renderer->SetBackground( BgrColorRed.toInt()/255., BgrColorGreen.toInt()/255., BgrColorBlue.toInt()/255. );
267   else
268     m_Renderer->SetBackground( 0, 0, 0 );
269  
270   // CREATE AXIS
271   m_Triedron = vtkActorCollection::New();
272   AddAxis(m_Renderer);
273  
274   // Create an interactor.
275   m_RWInteractor = VTKViewer_RenderWindowInteractor::New();
276   m_RWInteractor->setGUIWindow(m_RW);
277   m_RWInteractor->SetRenderWindow(m_RW->getRenderWindow());
278
279   VTKViewer_InteractorStyleSALOME* RWS = VTKViewer_InteractorStyleSALOME::New();
280   RWS->setGUIWindow(m_RW);
281   m_RWInteractor->SetInteractorStyle(RWS); 
282
283   m_RWInteractor->Initialize();
284   RWS->setTriedron( m_Triedron );
285   //SRN: additional initialization, to init CurrentRenderer of vtkInteractorStyle 
286   RWS->FindPokedRenderer(0, 0);
287
288   setCentralWidget( m_RW );
289   onViewReset();
290 }
291
292 VTKViewer_ViewFrame::~VTKViewer_ViewFrame() {
293   //
294   // In order to ensure that the interactor unregisters
295   // this RenderWindow, we assign a NULL RenderWindow to 
296   // it before deleting it.
297   //
298   m_Transform->Delete() ;
299     
300   m_RWInteractor->SetRenderWindow(NULL) ;
301   m_RWInteractor->Delete() ;
302   
303   //m_RW->Delete() ;
304
305   // NRI : BugID 1137:  m_Renderer->Delete() ;
306 }
307
308
309 /*!
310   Display/hide Trihedron
311 */
312 void VTKViewer_ViewFrame::onViewTrihedron()
313 {
314   if (isTrihedronDisplayed()) {
315     m_Triedron->InitTraversal();
316     vtkActor *ac = m_Triedron->GetNextActor();
317     while(!(ac==NULL)) {
318       ac->VisibilityOff();
319       ac = m_Triedron->GetNextActor();
320     }
321   }
322   else {
323     m_Triedron->InitTraversal();
324     vtkActor *ac = m_Triedron->GetNextActor();
325     while(!(ac==NULL)) {
326       ac->VisibilityOn();
327       ac = m_Triedron->GetNextActor();
328     }
329     m_TriedronVisible = true;
330   }  
331   m_RW->update();
332 }
333
334 /*!
335   Provides top projection of the active view
336 */
337 void VTKViewer_ViewFrame::onViewTop() {
338   vtkCamera* camera = m_Renderer->GetActiveCamera();
339   camera->SetFocalPoint(0,0,0);
340   camera->SetPosition(0,0,1);
341   camera->SetViewUp(0,1,0);
342   m_Renderer->ResetCamera();  
343   onViewFitAll();
344   m_RW->update();
345 }
346
347 /*!
348   Provides bottom projection of the active view
349 */
350 void VTKViewer_ViewFrame::onViewBottom()
351 {
352   vtkCamera* camera = m_Renderer->GetActiveCamera();
353   camera->SetFocalPoint(0,0,0);
354   camera->SetPosition(0,0,-1);
355   camera->SetViewUp(0,1,0);
356   m_Renderer->ResetCamera();  
357   onViewFitAll();
358   m_RW->update();
359 }
360
361 /*!
362   Provides left projection of the active view
363 */
364 void VTKViewer_ViewFrame::onViewLeft()    
365 {
366   vtkCamera* camera = m_Renderer->GetActiveCamera(); 
367   camera->SetFocalPoint(0,0,0);
368   camera->SetPosition(0,1,0);
369   camera->SetViewUp(0,0,1);
370   m_Renderer->ResetCamera();  
371   onViewFitAll();
372   m_RW->update(); 
373 }
374
375 /*!
376   Provides right projection of the active view
377 */
378 void VTKViewer_ViewFrame::onViewRight()
379 {
380   vtkCamera* camera = m_Renderer->GetActiveCamera();
381   camera->SetFocalPoint(0,0,0);
382   camera->SetPosition(0,-1,0);
383   camera->SetViewUp(0,0,1);
384   m_Renderer->ResetCamera();  
385   onViewFitAll();
386   m_RW->update();
387 }
388
389 /*!
390   Provides back projection of the active view
391 */
392 void VTKViewer_ViewFrame::onViewBack()
393 {
394   vtkCamera* camera = m_Renderer->GetActiveCamera();
395   camera->SetPosition(-1,0,0);
396   camera->SetFocalPoint(0,0,0);
397   camera->SetViewUp(0,0,1);
398   m_Renderer->ResetCamera();  
399   onViewFitAll();
400   m_RW->update();
401 }
402
403 /*!
404   Provides front projection of the active view
405 */
406 void VTKViewer_ViewFrame::onViewFront()
407 {
408   vtkCamera* camera = m_Renderer->GetActiveCamera();
409   camera->SetPosition(1,0,0);
410   camera->SetFocalPoint(0,0,0);
411   camera->SetViewUp(0,0,1);
412   m_Renderer->ResetCamera();  
413   onViewFitAll();
414   m_RW->update();
415 }
416
417 /*!
418   Reset the active view
419 */
420 void VTKViewer_ViewFrame::onViewReset()    
421 {
422   vtkCamera* camera = m_Renderer->GetActiveCamera();
423   camera->SetPosition(1,-1,1);
424   camera->SetFocalPoint(0,0,0);
425   camera->SetViewUp(0,0,1);
426   m_Renderer->ResetCamera();  
427   
428   double aOldScale = camera->GetParallelScale();
429   camera->SetParallelScale(500);
430   double aNewScale = camera->GetParallelScale();
431   
432   //for controlling labels scale after reset
433   float dim;
434   QString Size = QAD_CONFIG->getSetting("Viewer:TrihedronSize");
435   if( Size.isEmpty() ){
436     dim = 100;
437   } else {
438     dim = Size.toFloat();
439   }
440   float aScale = 17 * dim/100;
441
442   m_Triedron->InitTraversal();
443   vtkActor *ac = m_Triedron->GetNextActor();
444   bool IsConeActor = true;
445   while(!(ac==NULL)) {
446     if(ac->IsA("vtkFollower")) {
447       ac->SetScale(aScale, aScale, aScale);
448       IsConeActor = true;
449     }
450     else {
451       if (IsConeActor) {
452         //coneActor is the first in the list (see m_Triedron->AddItem(...) in VTKViewer_ViewFrame::AddVector(...))
453         IsConeActor = false;
454       } 
455     }
456     ac = m_Triedron->GetNextActor();
457   }
458
459   m_Renderer->ResetCameraClippingRange();
460   m_RW->update();
461 }
462
463 /*!
464   Rotates the active view
465 */
466 void VTKViewer_ViewFrame::onViewRotate()
467 {
468   VTKViewer_InteractorStyleSALOME* RWS = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(getRWInteractor()->GetInteractorStyle());
469   if (RWS)
470     RWS->startRotate();
471 }
472
473 /*!
474   Sets a new center of the active view
475 */
476 void VTKViewer_ViewFrame::onViewGlobalPan()
477 {
478   VTKViewer_InteractorStyleSALOME* RWS = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(getRWInteractor()->GetInteractorStyle());
479   if (RWS)
480     RWS->startGlobalPan();
481 }
482
483 /*!
484   Zooms the active view
485 */
486 void VTKViewer_ViewFrame::onViewZoom()
487 {
488   VTKViewer_InteractorStyleSALOME* RWS = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(getRWInteractor()->GetInteractorStyle());
489   if (RWS)
490     RWS->startZoom();
491 }
492
493 /*!
494   Moves the active view
495 */
496 void VTKViewer_ViewFrame::onViewPan()
497 {
498   VTKViewer_InteractorStyleSALOME* RWS = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(getRWInteractor()->GetInteractorStyle());
499   if (RWS)
500     RWS->startPan();
501 }
502
503 /*!
504   Fits all obejcts within a rectangular area of the active view
505 */
506 void VTKViewer_ViewFrame::onViewFitArea()
507 {
508   VTKViewer_InteractorStyleSALOME* RWS = dynamic_cast<VTKViewer_InteractorStyleSALOME*>(getRWInteractor()->GetInteractorStyle());
509   if (RWS)
510     RWS->startFitArea();
511 }
512
513 /*!
514   Fits all objects in the active view
515 */
516 // Reset the camera clipping range to include this entire bounding box
517 static void ResetCameraClippingRange(vtkRenderer* theRenderer, float bounds[6] )
518 {
519   //see vtkRenderer::ResetCameraClippingRange(float bounds[6]) method
520   double  vn[3], position[3], a, b, c, d;
521   double  range[2], dist;
522   int     i, j, k;
523   float center[3];
524   float distance;
525   float width;
526
527   vtkCamera* anActiveCamera = theRenderer->GetActiveCamera();
528   if ( anActiveCamera == NULL )
529     {
530       //vtkErrorMacro(<< "Trying to reset clipping range of non-existant camera");
531     return;
532     }
533   
534   // Find the plane equation for the camera view plane
535   anActiveCamera->GetViewPlaneNormal(vn);
536   anActiveCamera->GetPosition(position);
537 //  a = -vn[0];
538 //  b = -vn[1];
539 //  c = -vn[2];
540 //  d = -(a*position[0] + b*position[1] + c*position[2]);
541
542   // Set the max near clipping plane and the min far clipping plane
543 //  range[0] = a*bounds[0] + b*bounds[2] + c*bounds[4] + d;
544 //  range[1] = 1e-18;
545
546   // Find the closest / farthest bounding box vertex
547 //  for ( k = 0; k < 2; k++ )
548 //    {
549 //    for ( j = 0; j < 2; j++ )
550 //        {
551 //        for ( i = 0; i < 2; i++ )
552 //          {
553 //          dist = a*bounds[i] + b*bounds[2+j] + c*bounds[4+k] + d;
554 //          range[0] = (dist<range[0])?(dist):(range[0]);
555 //          range[1] = (dist>range[1])?(dist):(range[1]);
556 //          }
557 //        }
558 //    }
559   
560   center[0] = (bounds[0] + bounds[1])/2.0;
561   center[1] = (bounds[2] + bounds[3])/2.0;
562   center[2] = (bounds[4] + bounds[5])/2.0;
563   width = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
564                (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
565                (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
566   distance = sqrt((position[0]-center[0])*(position[0]-center[0]) +
567                   (position[1]-center[1])*(position[1]-center[1]) +
568                   (position[2]-center[2])*(position[2]-center[2]));
569   range[0] = distance - width/2.0;
570   range[1] = distance + width/2.0;
571
572   // Give ourselves a little breathing room
573   range[0] = 0.99*range[0] - (range[1] - range[0])*0.5;
574   range[1] = 1.01*range[1] + (range[1] - range[0])*0.5;
575
576   // Make sure near is not bigger than far
577   range[0] = (range[0] >= range[1])?(0.01*range[1]):(range[0]);
578
579   // Make sure near is at least some fraction of far - this prevents near
580   // from being behind the camera or too close in front. How close is too
581   // close depends on the resolution of the depth buffer
582   int ZBufferDepth = 16;
583   vtkRenderWindow* aRenderWindow = theRenderer->GetRenderWindow();
584   if (aRenderWindow)
585     {
586       ZBufferDepth = aRenderWindow->GetDepthBufferSize();
587     }
588   //
589   if ( ZBufferDepth <= 16 )
590     {
591     range[0] = (range[0] < 0.01*range[1])?(0.01*range[1]):(range[0]);
592     }
593   else if ( ZBufferDepth <= 24 )
594     {
595     range[0] = (range[0] < 0.01*range[1])?(0.01*range[1]):(range[0]);
596     }
597   else
598     {
599     range[0] = (range[0] < 0.01*range[1])?(0.01*range[1]):(range[0]);
600     }
601   anActiveCamera->SetClippingRange( range );
602 }
603
604 static void ResetCamera(vtkRenderer* theRenderer, vtkActorCollection* theTriedron, VTKViewer_RenderWindowInteractor* theRWInteractor){  
605   //see vtkRenderer::ResetCamera(float bounds[6]) method
606   float      bounds[6];
607   if(!theRenderer) return;
608   theRenderer->ComputeVisiblePropBounds( bounds );
609
610   float center[3];
611   float distance;
612   float width;
613   double vn[3], *vup;
614   int* winsize;
615   
616   if ( theRenderer->GetActiveCamera() != NULL )
617     {
618     theRenderer->GetActiveCamera()->GetViewPlaneNormal(vn);
619     }
620   else
621     {
622     MESSAGE("Trying to reset non-existant camera");
623     return;
624     }
625
626   center[0] = (bounds[0] + bounds[1])/2.0;
627   center[1] = (bounds[2] + bounds[3])/2.0;
628   center[2] = (bounds[4] + bounds[5])/2.0;
629   width = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
630                (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
631                (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
632   double ang = theRenderer->GetActiveCamera()->GetViewAngle();
633   distance = 2.0*width/tan(ang*vtkMath::Pi()/360.0);
634   
635   // find size of the window
636   winsize = theRenderer->GetSize();
637   
638   // check view-up vector against view plane normal
639   vup = theRenderer->GetActiveCamera()->GetViewUp();
640   if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 )
641     {
642     MESSAGE("Resetting view-up since view plane normal is parallel");
643     theRenderer->GetActiveCamera()->SetViewUp(-vup[2], vup[0], vup[1]);
644     }
645
646   // update the camera
647   theRenderer->GetActiveCamera()->SetFocalPoint(center[0],center[1],center[2]);
648   theRenderer->GetActiveCamera()->SetPosition(center[0]+distance*vn[0],
649                                   center[1]+distance*vn[1],
650                                   center[2]+distance*vn[2]);
651   // setup default parallel scale
652   double aOldScale = theRenderer->GetActiveCamera()->GetParallelScale();
653   
654   if(winsize[0]<winsize[1] )
655     width=width*(float(winsize[1])/float(winsize[0]));
656   
657   theRenderer->GetActiveCamera()->SetParallelScale(width/2.0);
658   double aNewScale = theRenderer->GetActiveCamera()->GetParallelScale();
659   
660   // for controlling label size 
661   VTKViewer_InteractorStyleSALOME* Style = 0;
662   if (theRWInteractor->GetInteractorStyle()->IsA("VTKViewer_InteractorStyleSALOME")) {
663     Style = VTKViewer_InteractorStyleSALOME::SafeDownCast(theRWInteractor->GetInteractorStyle());
664     Style->ControlLblSize(aOldScale,aNewScale);
665   }
666  
667   //workaround on VTK
668   //theRenderer->ResetCameraClippingRange(bounds);
669   ResetCameraClippingRange(theRenderer,bounds);
670 }
671
672 void VTKViewer_ViewFrame::onViewFitAll()
673 {
674   Standard_Boolean TriedronWasVisible = false;
675   if (isTrihedronDisplayed()) {
676     m_Triedron->InitTraversal();
677     vtkActor *ac = m_Triedron->GetNextActor();
678     while(!(ac==NULL)) {
679       ac->VisibilityOff();
680       ac = m_Triedron->GetNextActor();
681     }
682     TriedronWasVisible = true;
683   }
684   bool hasVisibleActors = m_Renderer->VisibleActorCount() > 0;
685   if ( hasVisibleActors ) {   // if there are visible actors, not to take into account Trihedron
686     ResetCamera(m_Renderer,m_Triedron,m_RWInteractor);
687   } 
688   if(TriedronWasVisible) {
689     m_Triedron->InitTraversal();
690     vtkActor *ac = m_Triedron->GetNextActor();
691     while(!(ac==NULL)) {
692       ac->VisibilityOn();
693       ac = m_Triedron->GetNextActor();
694     }
695     if ( !hasVisibleActors ) { // if there are NO visible actors, fit view to see only Trihedron
696       ResetCamera(m_Renderer,m_Triedron,m_RWInteractor);
697     } 
698   }
699   //m_Renderer->ResetCameraClippingRange();
700   m_RW->update();
701 }
702
703 /*!
704     Set background of the viewport
705 */
706 void VTKViewer_ViewFrame::setBackgroundColor( const QColor& color)
707 {
708   if ( m_Renderer )
709     m_Renderer->SetBackground( color.red()/255., color.green()/255., color.blue()/255. );
710 }
711
712 /*!
713     Returns background of the viewport
714 */
715 QColor VTKViewer_ViewFrame::backgroundColor() const
716 {
717   float backint[3];
718   if ( m_Renderer ) {
719     m_Renderer->GetBackground(backint);
720     return QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
721   }
722   return QMainWindow::backgroundColor();
723 }
724
725
726 void VTKViewer_ViewFrame::SetSelectionMode( int mode )
727 {
728   m_RWInteractor->SetSelectionMode( mode );
729 }
730
731 void VTKViewer_ViewFrame::rename( const Handle(SALOME_InteractiveObject)& IObject, QString newName )
732 {
733   m_RWInteractor->rename(IObject, newName);
734 }
735
736 void VTKViewer_ViewFrame::unHighlightAll() 
737 {
738   m_RWInteractor->unHighlightAll();
739 }
740
741 void VTKViewer_ViewFrame::highlight( const Handle(SALOME_InteractiveObject)& IObject, 
742                                      bool highlight, 
743                                      bool update ) 
744 {
745   QAD_Study* ActiveStudy = QAD_Application::getDesktop()->getActiveStudy();
746   SALOME_Selection* Sel = SALOME_Selection::Selection( ActiveStudy->getSelection() );
747   if ( Sel->SelectionMode() == 4 )
748     m_RWInteractor->highlight(IObject, highlight, update);
749   else if ( Sel->SelectionMode() == 3 ) {
750     m_RWInteractor->highlight(IObject, highlight, update);
751     if ( Sel->HasIndex( IObject ) ) {
752       TColStd_MapOfInteger MapIndex;
753       Sel->GetIndex( IObject, MapIndex );
754       m_RWInteractor->highlightCell(IObject, highlight, MapIndex, update);
755     }
756   } 
757   else if ( Sel->SelectionMode() == 2 ) {
758     m_RWInteractor->highlight(IObject, highlight, update);
759     if ( Sel->HasIndex( IObject ) ) {
760       TColStd_MapOfInteger MapIndex;
761       Sel->GetIndex( IObject, MapIndex );
762       m_RWInteractor->highlightEdge(IObject, highlight, MapIndex, update);
763     }
764   }
765   else if ( Sel->SelectionMode() == 1 ) {
766     m_RWInteractor->highlight(IObject, highlight, update);
767     if ( Sel->HasIndex( IObject ) ) {
768       TColStd_MapOfInteger MapIndex;
769       Sel->GetIndex( IObject, MapIndex );
770       m_RWInteractor->highlightPoint(IObject, highlight, MapIndex, update);
771     }
772   }
773 }
774
775 bool VTKViewer_ViewFrame::isInViewer( const Handle(SALOME_InteractiveObject)& IObject ) 
776 {
777   return m_RWInteractor->isInViewer( IObject );
778 }
779
780 bool VTKViewer_ViewFrame::isVisible( const Handle(SALOME_InteractiveObject)& IObject ) 
781 {
782   return m_RWInteractor->isVisible( IObject );
783 }
784
785 void VTKViewer_ViewFrame::setPopupServer( QAD_Application* App )
786 {
787   m_RW->setPopupServer( App );
788 }
789
790 void VTKViewer_ViewFrame::undo(SALOMEDS::Study_var aStudy,
791                                const char* StudyFrameEntry)
792 {
793   vtkActorCollection* theActors = m_Renderer->GetActors();
794   theActors->InitTraversal();
795   vtkActor *ac = theActors->GetNextActor();
796   while(!(ac==NULL)) {
797     if ( ac->IsA("SALOME_Actor") ) {
798       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
799       if ( anActor->hasIO() ) {
800         Handle(SALOME_InteractiveObject) IO = anActor->getIO();
801         if ( IO->hasEntry() ) { 
802           /*if (!QAD_ViewFrame::isInViewer(aStudy, IO->getEntry(), StudyFrameEntry)) {
803             m_RWInteractor->Erase(IO);
804             }*/
805         }
806       }
807     }
808     ac = theActors->GetNextActor();
809   }
810 }
811
812 void VTKViewer_ViewFrame::redo(SALOMEDS::Study_var aStudy,
813                                const char* StudyFrameEntry)
814 {
815   SALOMEDS::SObject_var RefSO;
816   SALOMEDS::SObject_var SO = aStudy->FindObjectID( StudyFrameEntry );
817   SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SO);
818   for (; it->More();it->Next()){
819     SALOMEDS::SObject_var CSO= it->Value();
820     if (CSO->ReferencedObject(RefSO)) {
821       vtkActorCollection* theActors = m_Renderer->GetActors();
822       theActors->InitTraversal();
823       vtkActor *ac = theActors->GetNextActor();
824       while(!(ac==NULL)) {
825         if ( ac->IsA("SALOME_Actor") ) {
826           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
827           if ( anActor->hasIO() ) {
828             Handle(SALOME_InteractiveObject) IO = anActor->getIO();
829             if ( IO->hasEntry() ) { 
830               /*if ( strcmp(IO->getEntry(),RefSO->GetID()) == 0 )
831                 m_RWInteractor->Display(IO);*/
832             }
833           }
834         }
835         ac = theActors->GetNextActor();
836       }
837     }
838   }
839 }
840
841
842 /* selection */
843 Handle(SALOME_InteractiveObject) VTKViewer_ViewFrame::FindIObject(const char* Entry)
844 {
845   Handle(SALOME_InteractiveObject) IO;
846   vtkActorCollection* theActors = m_Renderer->GetActors();
847   theActors->InitTraversal();
848   vtkActor *ac = theActors->GetNextActor();
849   while(!(ac==NULL)) {
850     if ( ac->IsA("SALOME_Actor") ) {
851       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
852       if ( anActor->hasIO() ) {
853         IO = anActor->getIO();
854         if ( IO->hasEntry() ) {
855           if ( strcmp( IO->getEntry(), Entry ) == 0 ) {
856             return IO;
857           }
858         }
859       }
860     }
861     ac = theActors->GetNextActor();
862   }
863   return IO;
864 }
865
866 /* display */           
867 void VTKViewer_ViewFrame::Display(const Handle(SALOME_InteractiveObject)& IObject, bool update)
868 {
869   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
870   SALOME_Selection* Sel
871     = SALOME_Selection::Selection( myStudy->getSelection() );
872
873   vtkActorCollection* theActors = m_Renderer->GetActors();
874   theActors->InitTraversal();
875   vtkActor *ac = theActors->GetNextActor();
876   while(!(ac==NULL))
877     {
878       if ( ac->IsA("SALOME_Actor") )
879         {
880           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
881           if ( anActor->hasIO() ) 
882             {
883               Handle(SALOME_InteractiveObject) IO = anActor->getIO();
884               if ( IO->isSame(IObject) )
885                 {
886                   m_RWInteractor->Display(IO, false);
887                   Sel->AddIObject(IO, false);
888                   break;
889                 }
890             }
891         }
892       ac = theActors->GetNextActor();
893     }
894   if (update)
895     Repaint();
896 }
897
898
899 void VTKViewer_ViewFrame::DisplayOnly(const Handle(SALOME_InteractiveObject)& IObject)
900 {
901   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
902   SALOME_Selection* Sel
903     = SALOME_Selection::Selection( myStudy->getSelection() );
904
905   vtkActorCollection* theActors = m_Renderer->GetActors();
906   theActors->InitTraversal();
907   vtkActor *ac = theActors->GetNextActor();
908   while(!(ac==NULL)) {
909     if ( ac->IsA("SALOME_Actor") ) {
910       SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
911       if ( anActor->hasIO() ) {
912         Handle(SALOME_InteractiveObject) IO = anActor->getIO();
913         if ( !IO->isSame(IObject) ) {
914           m_RWInteractor->Erase(IO, false);
915           Sel->RemoveIObject(IO, false);
916         } else {
917           anActor->SetVisibility(true);
918           Sel->AddIObject(IO, false);
919         }
920       }
921     }
922     ac = theActors->GetNextActor();
923   }
924   Repaint();
925 }
926
927 void VTKViewer_ViewFrame::Erase(const Handle(SALOME_InteractiveObject)& IObject, bool update)
928 {
929   QAD_Study* myStudy = QAD_Application::getDesktop()->getActiveStudy();
930   SALOME_Selection* Sel
931     = SALOME_Selection::Selection( myStudy->getSelection() );
932
933   vtkActorCollection* theActors = m_Renderer->GetActors();
934   theActors->InitTraversal();
935   vtkActor *ac = theActors->GetNextActor();
936   while(!(ac==NULL)) 
937     {
938       if ( ac->IsA("SALOME_Actor") )
939         {
940           SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac );
941           if ( anActor->hasIO() )
942             {
943               Handle(SALOME_InteractiveObject) IO = anActor->getIO();
944               if ( IO->isSame( IObject ) ) {
945                 m_RWInteractor->Erase(IO, false);
946                 Sel->RemoveIObject(IO, false);
947                 break;
948               }
949             }
950         }
951       ac = theActors->GetNextActor();
952     }
953   if (update)
954     Repaint();
955 }
956
957
958 void VTKViewer_ViewFrame::DisplayAll()
959 {
960   m_RWInteractor->DisplayAll();
961 }
962
963
964 void VTKViewer_ViewFrame::EraseAll()
965 {
966   m_RWInteractor->EraseAll();
967 }
968
969
970 void VTKViewer_ViewFrame::Repaint()
971 {
972   // m_RWInteractor->Render();
973   m_RW->update();
974 }
975
976 void VTKViewer_ViewFrame::GetScale(double theScale[3]){
977   m_Transform->GetScale(theScale);
978 }
979
980 void VTKViewer_ViewFrame::SetScale(double theScale[3]){
981   m_Transform->SetScale(theScale[0], theScale[1], theScale[2]);
982   m_Transform->Modified();
983   vtkActorCollection* theActors = m_Renderer->GetActors();
984   theActors->InitTraversal();
985   vtkActor *anActor;
986   while(anActor = theActors->GetNextActor())
987     anActor->GetMapper()->Update();
988   Repaint();
989 }
990
991 void VTKViewer_ViewFrame::AddActor( SALOME_Actor* theActor, bool update /*=false*/ ){
992   theActor->SetVisibility(true);
993   theActor->AddToRender(m_Renderer);
994   theActor->SetTransform(m_Transform);
995   if(update){
996     m_Renderer->ResetCameraClippingRange();
997     m_RWInteractor->Render();
998   }
999 }
1000
1001 void VTKViewer_ViewFrame::RemoveActor( SALOME_Actor* theActor, bool update /*=false*/ ){
1002   theActor->RemoveFromRender(m_Renderer);
1003   if(update){
1004     m_Renderer->ResetCameraClippingRange();
1005     m_RWInteractor->Render();
1006   }
1007 }
1008
1009