Salome HOME
updated copyright message
[modules/gui.git] / src / SVTK / SVTK_Renderer.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME VTKViewer : build VTK viewer into Salome desktop
24 //  File   :
25 //  Author :
26
27 #include "SVTK_Renderer.h"
28
29 #include "SVTK_Trihedron.h"
30 #include "SVTK_CubeAxesActor2D.h"
31 #include "SVTK_AreaPicker.h"
32
33 #include "SALOME_Actor.h"
34 #include "VTKViewer_Actor.h"
35 #include "VTKViewer_Algorithm.h"
36 #include "VTKViewer_Transform.h"
37 #include "VTKViewer_Utilities.h"
38 #include "VTKViewer_OpenGLRenderer.h"
39
40 #include <vtkCamera.h>
41 #include <vtkTextProperty.h>
42 #include <vtkObjectFactory.h>
43 #include <vtkCallbackCommand.h>
44
45 #include <vtkPicker.h>
46 #include <vtkPointPicker.h>
47 #include <vtkCellPicker.h>
48
49 #include <vtkProperty.h>
50 #include <vtkProp3DCollection.h>
51
52 // undefining min and max because CASCADE's defines them and
53 // it clashes with std::min(), std::max() included in utilities.h
54 #undef min
55 #undef max
56
57
58 vtkStandardNewMacro(SVTK_Renderer)
59
60 /*!
61   Constructor
62 */
63 SVTK_Renderer
64 ::SVTK_Renderer():
65   myPriority(0.0),
66   myEventCallbackCommand(vtkCallbackCommand::New()),
67   myDevice(VTKViewer_OpenGLRenderer::New()),
68   myInteractor(NULL),
69   myTransform(VTKViewer_Transform::New()),
70   myPointPicker(vtkPointPicker::New()),
71   myCellPicker(vtkCellPicker::New()),
72   myPointAreaPicker(SVTK_AreaPicker::New()),
73   myCellAreaPicker(SVTK_AreaPicker::New()),
74   myPreHighlightProperty(vtkProperty::New()),
75   myHighlightProperty(vtkProperty::New()),
76   myCubeAxes(SVTK_CubeAxesActor2D::New()),
77   myTrihedron(SVTK_Trihedron::New()),
78   myTrihedronSize(105),
79   myIsTrihedronRelative(true)
80 {
81   myDevice->Delete();
82   myTransform->Delete();
83
84   myPointPicker->Delete();
85   myCellPicker->Delete();
86
87   myPointAreaPicker->Delete();
88   myPointAreaPicker->PickFromListOn();
89
90   myCellAreaPicker->Delete();
91   myCellAreaPicker->PickFromListOn();
92   myCellAreaPicker->PickPointsOff();
93
94   //SetPreselectionProp();
95   myPreHighlightProperty->Delete();
96   myPreHighlightProperty->SetColor(0,1,1);
97   myPreHighlightProperty->SetPointSize(SALOME_POINT_SIZE+2);
98   myPreHighlightProperty->SetLineWidth(SALOME_LINE_WIDTH+2);
99   myPreHighlightProperty->SetRepresentationToPoints();
100
101   //SetSelectionProp();
102   myHighlightProperty->Delete();
103   myHighlightProperty->SetColor(1,1,0);
104   myHighlightProperty->SetPointSize(SALOME_POINT_SIZE+2);
105   myHighlightProperty->SetLineWidth(SALOME_LINE_WIDTH+2);
106   myHighlightProperty->SetRepresentationToPoints();
107
108   // Bug 0020123, note 0005217 - Problem with zoom
109   GetDevice()->SetNearClippingPlaneTolerance( 0.00001 );
110
111   myTrihedron->Delete();
112   myCubeAxes->Delete();
113   myEventCallbackCommand->Delete();
114
115   myTrihedron->AddToRender(GetDevice());
116   GetDevice()->AddViewProp(GetCubeAxes());
117
118   myBndBox[0] = myBndBox[2] = myBndBox[4] = 0;
119   myBndBox[1] = myBndBox[3] = myBndBox[5] = myTrihedron->GetSize();
120
121   myCubeAxes->SetBounds(myBndBox);
122   myCubeAxes->SetCamera(GetDevice()->GetActiveCamera());
123
124   myCubeAxes->SetLabelFormat("%6.4g");
125   myCubeAxes->SetFlyModeToOuterEdges(); // ENK remarks: it must bee
126   myCubeAxes->SetFontFactor(0.8);
127   myCubeAxes->SetCornerOffset(0);
128   myCubeAxes->SetScaling(0);
129   myCubeAxes->SetNumberOfLabels(5);
130   myCubeAxes->VisibilityOff();
131   myCubeAxes->SetTransform(GetTransform());
132
133   vtkTextProperty* aTextProp = vtkTextProperty::New();
134   aTextProp->SetColor(1, 1, 1);
135   aTextProp->ShadowOn();
136   myCubeAxes->SetAxisTitleTextProperty(aTextProp);
137   myCubeAxes->SetAxisLabelTextProperty(aTextProp);
138   aTextProp->Delete();
139
140   GetDevice()->GetActiveCamera()->ParallelProjectionOn();
141   GetDevice()->LightFollowCameraOn();
142   GetDevice()->TwoSidedLightingOn();
143
144   myEventCallbackCommand->SetClientData(this);
145   myEventCallbackCommand->SetCallback(SVTK_Renderer::ProcessEvents);
146   GetDevice()->AddObserver(vtkCommand::ConfigureEvent,
147                            myEventCallbackCommand.GetPointer(), 
148                            myPriority);
149   GetDevice()->AddObserver(vtkCommand::ResetCameraEvent,
150                            myEventCallbackCommand.GetPointer(), 
151                            myPriority);
152   GetDevice()->AddObserver(vtkCommand::ResetCameraClippingRangeEvent,
153                            myEventCallbackCommand.GetPointer(), 
154                            myPriority);
155 }
156
157 /*!
158   Destructor
159 */
160 SVTK_Renderer
161 ::~SVTK_Renderer()
162 {
163   VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
164   vtkActorCollection* anActors = aCopy.GetActors();
165   vtkActorCollection* anActors2 = vtkActorCollection::New();
166
167   anActors->InitTraversal();
168   while(vtkActor* anAct = anActors->GetNextActor()){
169     if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
170       anActors2->AddItem(anActor);
171     }
172   }
173
174   anActors2->InitTraversal();
175   while(vtkActor* anAct = anActors2->GetNextActor()){
176     if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
177       RemoveActor(anActor);
178     }
179   }
180
181   anActors2->Delete();
182 }
183
184
185 /*!
186   Main process event method
187 */
188 void 
189 SVTK_Renderer
190 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
191                 unsigned long theEvent,
192                 void* theClientData, 
193                 void* vtkNotUsed(theCallData))
194 {
195   SVTK_Renderer* self = reinterpret_cast<SVTK_Renderer*>(theClientData);
196
197   switch(theEvent){
198   case vtkCommand::ConfigureEvent:
199     self->OnResetView();
200     break;
201   case vtkCommand::ResetCameraEvent:
202     self->OnFitAll();
203     break;
204   case vtkCommand::ResetCameraClippingRangeEvent:
205     self->OnResetClippingRange();
206     break;
207   }
208 }
209
210 /*!
211   \return renderer's device
212 */
213 vtkRenderer* 
214 SVTK_Renderer
215 ::GetDevice()
216 {
217   return myDevice.GetPointer();
218 }
219
220 /*!
221   Initialize renderer
222 */
223 void 
224 SVTK_Renderer
225 ::Initialize(vtkRenderWindowInteractor* theInteractor,
226              SVTK_Selector* theSelector)
227 {
228   myInteractor = theInteractor;
229   mySelector = theSelector;
230   SetSelectionTolerance();
231 }
232
233 /*!
234   Publishes pointed actor into the renderer
235 */
236 void
237 SVTK_Renderer
238 ::AddActor(VTKViewer_Actor* theActor, bool theIsAdjustActors)
239 {
240   if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
241     anActor->SetInteractor(myInteractor);
242     anActor->SetTransform(GetTransform());
243     anActor->SetSelector(mySelector.GetPointer());
244
245     anActor->SetPointPicker(myPointPicker.GetPointer());
246     anActor->SetCellPicker(myCellPicker.GetPointer());
247
248     anActor->SetPointAreaPicker(myPointAreaPicker.GetPointer());
249     anActor->SetCellAreaPicker(myCellAreaPicker.GetPointer());
250
251     anActor->SetPreHighlightProperty(myPreHighlightProperty.GetPointer());
252     anActor->SetHighlightProperty(myHighlightProperty.GetPointer());
253
254     anActor->AddToRender(GetDevice());
255     anActor->UpdateNameActors();
256
257     if(theIsAdjustActors)
258       AdjustActors();
259   }
260 }
261
262 /*!
263   Removes pointed actor from the renderer
264 */
265 void
266 SVTK_Renderer
267 ::RemoveActor(VTKViewer_Actor* theActor, bool theIsAdjustActors)
268 {
269   if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
270     // Order of the calls are important because VTKViewer_Actor::RemoveFromRender
271     //   can leads do destruction of the actor
272     anActor->SetInteractor(NULL);
273     anActor->SetTransform(NULL);
274     anActor->SetSelector(NULL);
275
276     anActor->SetPointPicker(NULL);
277     anActor->SetCellPicker(NULL);
278
279     anActor->SetPointAreaPicker(NULL);
280     anActor->SetCellAreaPicker(NULL);
281
282     anActor->SetPreHighlightProperty(NULL);
283     anActor->SetHighlightProperty(NULL);
284
285     anActor->RemoveFromRender(GetDevice());
286
287     while ( int i = myPointPicker->GetProp3Ds()->IsItemPresent( theActor ))
288       myPointPicker->GetProp3Ds()->RemoveItem( i-1 );
289     while ( int i = myCellPicker->GetProp3Ds()->IsItemPresent( theActor ))
290       myCellPicker->GetProp3Ds()->RemoveItem( i-1 );
291
292     while ( int i = myPointPicker->GetActors()->IsItemPresent( theActor ))
293       myPointPicker->GetActors()->RemoveItem( i-1 );
294     while ( int i = myCellPicker->GetActors()->IsItemPresent( theActor ))
295       myCellPicker->GetActors()->RemoveItem( i-1 );
296
297     if(theIsAdjustActors)
298       AdjustActors();
299   }
300 }
301
302 /*!
303   Get special container that keeps scaling of the scene
304 */
305 VTKViewer_Transform* 
306 SVTK_Renderer
307 ::GetTransform()
308 {
309   return myTransform.GetPointer();
310 }
311
312 /*!
313   Allows to get a scale that is applied on the whole scene
314 */
315 void
316 SVTK_Renderer
317 ::GetScale( double theScale[3] ) 
318 {
319   myTransform->GetMatrixScale( theScale );
320 }
321
322 /*!
323   Allows to apply a scale on the whole scene
324 */
325 void
326 SVTK_Renderer
327 ::SetScale( double theScale[3] ) 
328 {
329   myTransform->SetMatrixScale( theScale[0], theScale[1], theScale[2] );
330   AdjustActors();
331
332   VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
333   vtkActorCollection* anActors = aCopy.GetActors();
334   anActors->InitTraversal();
335   while(vtkActor* anAct = anActors->GetNextActor())
336     if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct))
337       if(anActor->isHighlighted() && !anActor->IsInfinitive())
338         anActor->highlight(true);
339 }
340
341 /*!
342   Applies color and size (PointSize and LineWidth) of primitives in selection mode
343 */
344 void
345 SVTK_Renderer
346 ::SetSelectionProp(const double& theRed, 
347                    const double& theGreen, 
348                    const double& theBlue, 
349                    const int& theWidth) 
350 {
351   myHighlightProperty->SetColor( theRed, theGreen, theBlue );
352   myHighlightProperty->SetLineWidth( theWidth );
353   myHighlightProperty->SetPointSize( theWidth );
354 }
355
356 /*!
357   Applies color and size (PointSize and LineWidth) of primitives in preselection mode
358 */
359 void
360 SVTK_Renderer
361 ::SetPreselectionProp(const double& theRed, 
362                       const double& theGreen, 
363                       const double& theBlue, 
364                       const int& theWidth) 
365 {
366   myPreHighlightProperty->SetColor( theRed, theGreen, theBlue );
367   myPreHighlightProperty->SetLineWidth( theWidth );
368   myPreHighlightProperty->SetPointSize( theWidth );
369 }
370
371 /*!
372   Setup requested tolerance for the picking
373 */
374 void
375 SVTK_Renderer
376 ::SetSelectionTolerance(const double& theTolNodes, 
377                         const double& theTolCell,
378                         const double& theTolObjects)
379 {
380   myPointPicker->SetTolerance( theTolNodes );
381   myCellPicker->SetTolerance( theTolCell );
382
383   myPointAreaPicker->SetTolerance( theTolNodes );
384   myCellAreaPicker->SetTolerance( theTolCell );
385
386   mySelector->SetTolerance( theTolObjects );
387 }
388
389
390 /*! If parameter theIsForcedUpdate is true, recalculate parameters for
391  *  trihedron and cube axes, even if trihedron and cube axes is invisible.
392  */
393
394 inline
395 bool
396 CheckBndBox(const double theBounds[6])
397 {
398   if(theBounds[0] > -VTK_FLOAT_MAX && theBounds[1] < VTK_FLOAT_MAX &&
399      theBounds[2] > -VTK_FLOAT_MAX && theBounds[3] < VTK_FLOAT_MAX &&
400      theBounds[4] > -VTK_FLOAT_MAX && theBounds[5] < VTK_FLOAT_MAX)
401     return true;
402   return false;
403 }
404
405 /*!
406   Adjusts size of actors
407 */
408 bool
409 SVTK_Renderer
410 ::OnAdjustActors()
411 {
412   bool aTDisplayed = IsTrihedronDisplayed();
413   bool aCDisplayed = IsCubeAxesDisplayed();
414
415   double aNewBndBox[6];
416   aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_FLOAT_MAX;
417   aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_FLOAT_MAX;
418
419   int aVisibleNum = myTrihedron->GetVisibleActorCount(GetDevice());
420   if(aVisibleNum){
421     if(aTDisplayed)
422       myTrihedron->VisibilityOff();
423
424     if(aCDisplayed) 
425       myCubeAxes->VisibilityOff();
426
427     // if the new trihedron size have sufficient difference, then apply the value
428     double aSize = myTrihedron->GetSize();
429     if ( IsTrihedronRelative() )
430       {
431         ComputeTrihedronSize(GetDevice(),aSize,aSize,myTrihedronSize);
432         myTrihedron->SetSize(aSize);
433       }
434     else
435       myTrihedron->SetSize( myTrihedronSize );
436
437     // iterate through displayed objects and set size if necessary
438     VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
439     vtkActorCollection* anActors = aCopy.GetActors();
440     anActors->InitTraversal();
441     while(vtkActor* anAct = anActors->GetNextActor()){
442       if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
443         if(anActor->IsResizable())
444           anActor->SetSize(0.5*aSize);
445         if(anActor->GetVisibility() && !anActor->IsInfinitive()){
446           double *aBounds = anActor->GetBounds();
447           if(CheckBndBox(aBounds))
448             for(int i = 0; i < 5; i = i + 2){
449               if(aBounds[i] < aNewBndBox[i]) 
450                 aNewBndBox[i] = aBounds[i];
451               if(aBounds[i+1] > aNewBndBox[i+1]) 
452                 aNewBndBox[i+1] = aBounds[i+1];
453             }
454         }
455       }
456     }
457
458     if(aTDisplayed) 
459       myTrihedron->VisibilityOn();
460
461     if(aCDisplayed) 
462       myCubeAxes->VisibilityOn();
463     
464   }else{
465     double aSize = myTrihedron->GetSize();
466     aNewBndBox[0] = aNewBndBox[2] = aNewBndBox[4] = 0;
467     aNewBndBox[1] = aNewBndBox[3] = aNewBndBox[5] = aSize;
468   }
469   
470   if(CheckBndBox(aNewBndBox)){
471     for(int i = 0; i < 6; i++)
472       myBndBox[i] = aNewBndBox[i];
473     myCubeAxes->SetBounds(myBndBox);
474     return true;
475   }
476
477   return false;
478 }
479
480 /*!
481   Adjusts size of actors
482 */
483 void
484 SVTK_Renderer
485 ::AdjustActors()
486 {
487   if(OnAdjustActors())
488     ::ResetCameraClippingRange(GetDevice());
489 }
490
491 /*!
492   Set size of the trihedron
493   \param theSize - new size
494   \param theRelative - if it is true, then size is mesured in percents from bounding box of the scene,
495   otherwise - in viewer units
496 */
497 void
498 SVTK_Renderer
499 ::SetTrihedronSize(double theSize, const bool theRelative)
500 {
501   if(myTrihedronSize != theSize || myIsTrihedronRelative != theRelative){
502     myTrihedronSize = theSize;
503     myIsTrihedronRelative = theRelative;
504     AdjustActors();
505   }
506 }
507
508 /*!
509   \return size of the trihedron in percents from bounding box of the scene
510 */
511 double
512 SVTK_Renderer
513 ::GetTrihedronSize() const
514 {
515   return myTrihedronSize;
516 }
517
518 /*!
519   \return true if the size of the trihedron is relative
520 */
521 bool 
522 SVTK_Renderer
523 ::IsTrihedronRelative() const
524 {
525   return myIsTrihedronRelative;
526 }
527
528 /*!
529   \return trihedron control
530 */
531 VTKViewer_Trihedron* 
532 SVTK_Renderer
533 ::GetTrihedron()
534 {
535   return myTrihedron.GetPointer();
536 }
537
538 /*!
539   \return true if trihedron is displayed
540 */
541 bool
542 SVTK_Renderer
543 ::IsTrihedronDisplayed()
544 {
545   return myTrihedron->GetVisibility() == VTKViewer_Trihedron::eOn;
546 }
547
548 /*!
549   Toggle trihedron visibility
550 */
551 void 
552 SVTK_Renderer
553 ::OnViewTrihedron()
554 {
555   if(IsTrihedronDisplayed())
556     myTrihedron->VisibilityOff();
557   else
558     myTrihedron->VisibilityOn();
559 }
560
561 /*!
562   Set trihedron visibility
563 */
564 void 
565 SVTK_Renderer
566 ::SetTrihedronVisibility( const bool show ) {
567   if(show)
568     myTrihedron->VisibilityOn();
569   else
570     myTrihedron->VisibilityOff();  
571 }
572
573 /*!
574   Adjust size of the trihedron to the bounding box of the scene
575 */
576 void
577 SVTK_Renderer
578 ::OnAdjustTrihedron()
579 {   
580   AdjustActors();
581 }
582
583 /*!
584   \return graduated rules control
585 */
586 SVTK_CubeAxesActor2D* 
587 SVTK_Renderer
588 ::GetCubeAxes()
589 {
590   return myCubeAxes.GetPointer();
591 }
592
593 /*!
594   \return true if graduated rules displayed
595 */
596 bool
597 SVTK_Renderer
598 ::IsCubeAxesDisplayed()
599 {
600   return myCubeAxes->GetVisibility() == 1;
601 }
602
603 /*!
604   Toggle graduated rules visibility
605 */
606 void
607 SVTK_Renderer
608 ::OnViewCubeAxes()
609 {
610   if(IsCubeAxesDisplayed())
611     myCubeAxes->VisibilityOff();
612   else
613     myCubeAxes->VisibilityOn();
614 }
615
616 /*!
617   Adjust size of the graduated rules to the bounding box of the scene
618 */
619 void
620 SVTK_Renderer
621 ::OnAdjustCubeAxes()
622 {   
623   AdjustActors();
624 }
625
626 /*!
627   Sets camera into predefined state
628 */
629 void
630 SVTK_Renderer
631 ::OnResetView()
632 {
633   int aTrihedronIsVisible = IsTrihedronDisplayed();
634   int aCubeAxesIsVisible = IsCubeAxesDisplayed();
635
636   myTrihedron->SetVisibility( VTKViewer_Trihedron::eOnlyLineOn );
637   myCubeAxes->SetVisibility(0);
638
639   ::ResetCamera(GetDevice(),true);  
640   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
641   aCamera->SetPosition(1,-1,1);
642   aCamera->SetViewUp(0,0,1);
643   ::ResetCamera(GetDevice(),true);  
644
645   if(aTrihedronIsVisible) 
646     myTrihedron->VisibilityOn();
647   else
648     myTrihedron->VisibilityOff();
649
650   if(aCubeAxesIsVisible) 
651     myCubeAxes->VisibilityOn();
652   else
653     myCubeAxes->VisibilityOff();
654
655   static double aCoeff = 3.0;
656   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
657 }
658
659 /*!
660   Fit all presentation in the scene into the window
661 */
662 void
663 SVTK_Renderer
664 ::OnFitAll()
665 {
666   int aTrihedronWasVisible = false;
667   int aCubeAxesWasVisible = false;
668
669   aTrihedronWasVisible = IsTrihedronDisplayed();
670   if(aTrihedronWasVisible)
671     myTrihedron->VisibilityOff();
672
673   aCubeAxesWasVisible = IsCubeAxesDisplayed();
674   if(aCubeAxesWasVisible)
675     myCubeAxes->VisibilityOff();
676
677   if(myTrihedron->GetVisibleActorCount(GetDevice())){
678     myTrihedron->VisibilityOff();
679     myCubeAxes->VisibilityOff();
680     ::ResetCamera(GetDevice());
681   }else{
682     myTrihedron->SetVisibility(VTKViewer_Trihedron::eOnlyLineOn);
683     myCubeAxes->SetVisibility(2);
684     ::ResetCamera(GetDevice(),true);
685   }
686
687   if(aTrihedronWasVisible)
688     myTrihedron->VisibilityOn();
689   else
690     myTrihedron->VisibilityOff();
691   
692   if(aCubeAxesWasVisible)
693     myCubeAxes->VisibilityOn();
694   else
695     myCubeAxes->VisibilityOff();
696
697   ::ResetCameraClippingRange(GetDevice());
698 }
699
700 /*!
701   Fit all selected presentation in the scene
702 */
703 void SVTK_Renderer::onFitSelection()
704 {
705   vtkActorCollection* aSelectedCollection = vtkActorCollection::New();
706
707   VTK::ActorCollectionCopy aCopy( GetDevice()->GetActors() );
708   vtkActorCollection* aCollection = aCopy.GetActors();
709   aCollection->InitTraversal();
710   while ( vtkActor* aProp = aCollection->GetNextActor() )
711     if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aProp ) ) {
712       const Handle(SALOME_InteractiveObject)& io = anActor->getIO();
713       if ( !io.IsNull() && mySelector->IsSelected( io ) )
714         aSelectedCollection->AddItem( aProp );
715     }
716   
717   if( aSelectedCollection->GetNumberOfItems() == 0 )
718     return; // if collection is empty
719   
720   double bounds[6];
721   ::ComputeBounds( aSelectedCollection, bounds );
722
723   if ( aSelectedCollection->GetNumberOfItems() && ::isBoundValid( bounds ) ) {
724     GetDevice()->ResetCamera( bounds );
725     GetDevice()->ResetCameraClippingRange( bounds );
726   }
727 }
728
729 void SVTK_Renderer::OnFitIObjects(const SALOME_ListIO& objects)
730 {
731   vtkActorCollection* aSelectedCollection = vtkActorCollection::New();
732
733   VTK::ActorCollectionCopy aCopy( GetDevice()->GetActors() );
734   vtkActorCollection* aCollection = aCopy.GetActors();
735   aCollection->InitTraversal();
736   while ( vtkActor* aProp = aCollection->GetNextActor() )
737   {
738     if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aProp ) ) {
739       const Handle(SALOME_InteractiveObject)& io = anActor->getIO();
740       if ( anActor->GetVisibility() && !io.IsNull() ) {
741         SALOME_ListIteratorOfListIO iter( objects );
742         for ( ; iter.More(); iter.Next() ) {
743           if ( iter.Value().IsNull() )
744             continue;
745           if ( io->isSame( iter.Value() ) ) {
746             aSelectedCollection->AddItem( aProp );
747             break;
748           }
749         }
750       }
751     }
752   }
753
754   if( aSelectedCollection->GetNumberOfItems() == 0 )
755     return; // if collection is empty
756   
757   double bounds[6];
758   ::ComputeBounds( aSelectedCollection, bounds );
759
760   if ( aSelectedCollection->GetNumberOfItems() && ::isBoundValid( bounds ) ) {
761     GetDevice()->ResetCamera( bounds );
762     GetDevice()->ResetCameraClippingRange( bounds );
763   }
764 }
765
766 /*!
767   Reset camera clipping range to adjust the range to the bounding box of the scene
768 */
769 void
770 SVTK_Renderer
771 ::OnResetClippingRange()
772 {
773   return;
774   ::ResetCameraClippingRange(GetDevice());
775 }
776
777 /*!
778   To reset direction of the camera to front view
779 */
780 void
781 SVTK_Renderer
782 ::OnFrontView()
783 {
784   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
785   aCamera->SetPosition(1,0,0);
786   aCamera->SetViewUp(0,0,1);
787   aCamera->SetFocalPoint(0,0,0);
788   this->OnFitAll();
789 }
790
791 /*!
792   To reset direction of the camera to back view
793 */
794 void
795 SVTK_Renderer
796 ::OnBackView()
797 {
798   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
799   aCamera->SetPosition(-1,0,0);
800   aCamera->SetViewUp(0,0,1);
801   aCamera->SetFocalPoint(0,0,0);
802   this->OnFitAll();
803 }
804
805 /*!
806   To reset direction of the camera to top view
807 */
808 void
809 SVTK_Renderer
810 ::OnTopView()
811 {
812   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
813   aCamera->SetPosition(0,0,1);
814   aCamera->SetViewUp(0,1,0);
815   aCamera->SetFocalPoint(0,0,0);
816   this->OnFitAll();
817 }
818
819 /*!
820   To reset direction of the camera to bottom view
821 */
822 void
823 SVTK_Renderer
824 ::OnBottomView()
825 {
826   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
827   aCamera->SetPosition(0,0,-1);
828   aCamera->SetViewUp(0,1,0);
829   aCamera->SetFocalPoint(0,0,0);
830   this->OnFitAll();
831 }
832
833 /*!
834   To reset direction of the camera to left view
835 */
836 void
837 SVTK_Renderer
838 ::OnLeftView()
839 {
840   vtkCamera* aCamera = GetDevice()->GetActiveCamera(); 
841   aCamera->SetPosition(0,-1,0);
842   aCamera->SetViewUp(0,0,1);
843   aCamera->SetFocalPoint(0,0,0);
844   this->OnFitAll();
845 }
846
847
848 /*!
849   To rotate view 90 degrees clockwise
850 */
851 void
852 SVTK_Renderer
853 ::onClockWiseView()
854 {
855   vtkCamera* aCamera = GetDevice()->GetActiveCamera(); 
856   aCamera->Roll(-90);
857   aCamera->OrthogonalizeViewUp();
858 }
859
860 /*!
861   To rotate view 90 degrees counterclockwise
862 */
863 void
864 SVTK_Renderer
865 ::onAntiClockWiseView()
866 {
867   vtkCamera* aCamera = GetDevice()->GetActiveCamera(); 
868   aCamera->Roll(90);
869   aCamera->OrthogonalizeViewUp();
870 }
871
872 /*!
873   To reset direction of the camera to right view
874 */
875 void
876 SVTK_Renderer
877 ::OnRightView()
878 {
879   vtkCamera* aCamera = GetDevice()->GetActiveCamera();
880   aCamera->SetPosition(0,1,0);
881   aCamera->SetViewUp(0,0,1);
882   aCamera->SetFocalPoint(0,0,0);
883   this->OnFitAll();
884 }