Salome HOME
Merge from BR_PORTING_VTK6 01/03/2013
[modules/gui.git] / src / SVTK / SALOME_Actor.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, 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.
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 OBJECT : implementation of interactive object visualization for OCC and VTK viewers
24 //  File   : SALOME_Actor.cxx
25 //  Author : Nicolas REJNERI
26
27 /*!
28   \class SALOME_Actor SALOME_Actor.h
29   \brief Abstract class of SALOME Objects in VTK.
30 */
31
32
33 #include "SALOME_Actor.h"
34 #include "SALOME_InteractiveObject.hxx"
35
36 #include "VTKViewer_Algorithm.h"
37 #include "VTKViewer_Transform.h"
38 #include "VTKViewer_TransformFilter.h"
39 #include "VTKViewer_GeometryFilter.h"
40 #include "VTKViewer_FramedTextActor.h"
41 #include "SVTK_RectPicker.h"
42
43 #include "SVTK_Actor.h"
44
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47
48 // VTK Includes
49 #include <vtkCell.h>
50 #include <vtkLine.h>
51 #include <vtkPicker.h>
52 #include <vtkPointPicker.h>
53 #include <vtkCellPicker.h>
54 #include <vtkRenderer.h>
55 #include <vtkPolyData.h>
56 #include <vtkObjectFactory.h>
57 #include <vtkDataSetMapper.h>
58 #include <vtkPolyDataMapper.h>
59 #include <vtkProperty.h>
60 #include <vtkOutlineSource.h>
61
62 #include <vtkInteractorStyle.h>
63 #include <vtkRenderWindowInteractor.h>
64 #include <vtkPassThroughFilter.h>
65
66 #include <TColStd_MapOfInteger.hxx>
67 #include <TColStd_IndexedMapOfInteger.hxx>
68
69 #if defined __GNUC__
70   #if __GNUC__ == 2
71     #define __GNUC_2__
72   #endif
73 #endif
74
75 int SALOME_POINT_SIZE = 5;
76 int SALOME_LINE_WIDTH = 3;
77
78 namespace
79 {
80   int
81   GetEdgeId(SALOME_Actor* theActor,
82             vtkPicker* thePicker, 
83             int theObjId)
84   {
85     int anEdgeId = 0;
86     if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) {
87       double aPickPosition[3];
88       thePicker->GetPickPosition(aPickPosition);
89       double aMinDist = 1000000.0, aDist = 0;
90       for (int i = 0, iEnd = aPickedCell->GetNumberOfEdges(); i < iEnd; i++){
91         if(vtkLine* aLine = vtkLine::SafeDownCast(aPickedCell->GetEdge(i))){
92           int subId;  
93           double pcoords[3], closestPoint[3], weights[3];
94           aLine->EvaluatePosition(aPickPosition,closestPoint,subId,pcoords,aDist,weights);
95           if (aDist < aMinDist) {
96             aMinDist = aDist;
97             anEdgeId = -1 - i;
98           }
99         }
100       }
101     }
102     return anEdgeId;
103   }
104
105   inline
106   bool
107   CheckDimensionId(Selection_Mode theMode, 
108                    SALOME_Actor *theActor, 
109                    vtkIdType theObjId)
110   {
111     switch(theMode) {
112     case CellSelection:
113       return true;
114     case EdgeSelection:
115       return ( theActor->GetObjDimension( theObjId ) == 1 );
116     case FaceSelection:
117       return ( theActor->GetObjDimension( theObjId ) == 2 );
118     case VolumeSelection:
119       return ( theActor->GetObjDimension( theObjId ) == 3 );
120     case Elem0DSelection:        
121       return ((theActor->GetObjDimension( theObjId ) == 0) &&
122                theActor->GetElemCell(theObjId) && 
123               (theActor->GetElemCell(theObjId)->GetCellType() == VTK_VERTEX));
124     case BallSelection:
125       return ((theActor->GetObjDimension( theObjId ) == 0) &&
126                theActor->GetElemCell(theObjId) && 
127               (theActor->GetElemCell(theObjId)->GetCellType() == VTK_POLY_VERTEX));
128
129     };
130     return false;
131   }
132 }
133
134 namespace SVTK
135 {
136   /*!
137     Make picker work with this actor only
138   */
139   TPickLimiter::TPickLimiter(vtkAbstractPicker* picker, SALOME_Actor* actor):myPicker(picker)
140   {
141     myPicker->InitializePickList();
142     myPicker->AddPickList( actor );
143     myPicker->SetPickFromList( true );
144   }
145   /*!
146     Unlimit picking
147   */
148   TPickLimiter::~TPickLimiter()
149   {
150     myPicker->SetPickFromList( false );
151     myPicker->InitializePickList();
152   }
153 }
154
155
156 vtkStandardNewMacro(SALOME_Actor);
157
158 /*!
159   Constructor
160 */
161 SALOME_Actor
162 ::SALOME_Actor():
163   myRenderer(NULL),
164   myInteractor(NULL),
165   mySelectionMode(ActorSelection),
166   myPreHighlightActor(SVTK_Actor::New()),
167   myHighlightActor(SVTK_Actor::New()),
168   myOutline(vtkOutlineSource::New()),
169   myOutlineActor(VTKViewer_Actor::New()),
170   myIsDisplayNameActor(false),
171   myNameActor(VTKViewer_FramedTextActor::New())
172 {
173   myPreHighlightActor->Delete();
174   myPreHighlightActor->Initialize();
175   myPreHighlightActor->PickableOff();
176   myPreHighlightActor->SetVisibility( false );
177   myPreHighlightActor->SetCoincident3DAllowed(true);
178
179   myHighlightActor->Delete();
180   myHighlightActor->Initialize();
181   myHighlightActor->PickableOff();
182   myHighlightActor->SetVisibility( false );
183   myHighlightActor->SetCoincident3DAllowed(true);
184
185   myOutline->Delete();
186
187   vtkPolyDataMapper* anOutlineMapper = vtkPolyDataMapper::New();
188   anOutlineMapper->SetInputConnection(myOutline->GetOutputPort());
189
190   myOutlineActor->Delete();
191   myOutlineActor->SetMapper( anOutlineMapper );
192   anOutlineMapper->Delete();
193
194   myOutlineActor->PickableOff();
195   myOutlineActor->DragableOff();
196   myOutlineActor->GetProperty()->SetColor(1.0,0.0,0.0);
197   myOutlineActor->GetProperty()->SetAmbient(1.0);
198   myOutlineActor->GetProperty()->SetDiffuse(0.0);
199   myOutlineActor->SetVisibility( false );
200
201   // Name actor
202   myNameActor->Delete();
203   myNameActor->SetVisibility(false);
204   myNameActor->SetPickable(false);
205   myNameActor->SetModePosition(VTKViewer_FramedTextActor::TopRight);
206   myNameActor->SetLayoutType(VTKViewer_FramedTextActor::Vertical);
207
208   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
209
210   QColor aForegroundColor = aResourceMgr->colorValue( "VTKViewer", "group_names_text_color", Qt::white );
211   myNameActor->SetForegroundColor(aForegroundColor.redF(),
212                                   aForegroundColor.greenF(),
213                                   aForegroundColor.blueF());
214
215   double aGroupNamesTransparency = 0.5;
216   aGroupNamesTransparency = aResourceMgr->doubleValue( "VTKViewer", "group_names_transparency", aGroupNamesTransparency );
217   myNameActor->SetTransparency(aGroupNamesTransparency);
218 }
219
220 /*!
221   Destructor
222 */
223 SALOME_Actor
224 ::~SALOME_Actor()
225 {}
226
227
228 /*!
229   \return true if the SALOME_Actor has a reference to SALOME_InteractiveObject
230 */
231 Standard_Boolean 
232 SALOME_Actor
233 ::hasIO() 
234
235   return !myIO.IsNull(); 
236 }
237
238 /*!
239   \return correspoinding reference to SALOME_InteractiveObject
240 */
241 const Handle(SALOME_InteractiveObject)& 
242 SALOME_Actor
243 ::getIO()
244
245   return myIO; 
246 }
247
248 /*!
249   Sets reference to SALOME_InteractiveObject
250   \param theIO - new SALOME_InteractiveObject
251 */
252 void
253 SALOME_Actor
254 ::setIO(const Handle(SALOME_InteractiveObject)& theIO) 
255
256   myIO = theIO; 
257 }
258
259 /*!
260   Sets name the SALOME_Actor
261   \param theName - new name
262 */
263 void
264 SALOME_Actor
265 ::setName(const char* theName)
266 {
267   if(hasIO())   
268     myIO->setName(theName);
269   myNameActor->SetText(theName);
270   Superclass::setName(theName);
271 }
272
273
274 /*!
275   Publishes the actor in all its internal devices
276 */
277 void
278 SALOME_Actor
279 ::AddToRender(vtkRenderer* theRenderer)
280 {
281   Superclass::AddToRender(theRenderer);
282
283   myRenderer = theRenderer;
284
285   myHighlightActor->AddToRender(theRenderer);
286   myPreHighlightActor->AddToRender(theRenderer);
287   theRenderer->AddActor( myOutlineActor.GetPointer() );
288   theRenderer->AddActor( myNameActor.GetPointer() );
289 }
290
291 /*!
292   Removes the actor from all its internal devices
293 */
294 void 
295 SALOME_Actor
296 ::RemoveFromRender(vtkRenderer* theRenderer)
297 {
298   Superclass::RemoveFromRender(theRenderer);
299
300   myHighlightActor->RemoveFromRender(theRenderer);
301   myPreHighlightActor->RemoveFromRender(theRenderer);
302
303   theRenderer->RemoveActor( myPreHighlightActor.GetPointer() );
304   theRenderer->RemoveActor( myHighlightActor.GetPointer() );
305   theRenderer->RemoveActor( myOutlineActor.GetPointer() );
306   theRenderer->RemoveActor( myNameActor.GetPointer() );
307 }
308
309 /*!
310   \return reference on renderer where it is published
311 */
312 vtkRenderer*
313 SALOME_Actor
314 ::GetRenderer()
315 {
316   return myRenderer;
317 }
318
319 /*!
320   Sets interactor in order to use vtkInteractorObserver devices
321   \param theInteractor - new interactor
322 */
323 void
324 SALOME_Actor
325 ::SetInteractor(vtkRenderWindowInteractor* theInteractor)
326 {
327   myInteractor = theInteractor;
328 }
329
330 /*!
331   Put a request to redraw the view 
332 */
333 void
334 SALOME_Actor
335 ::Update()
336 {
337   myInteractor->CreateTimer(VTKI_TIMER_UPDATE);    
338 }
339
340 /*!
341   Apply view transformation
342   \param theTransform - transformation
343 */
344 void
345 SALOME_Actor
346 ::SetTransform(VTKViewer_Transform* theTransform)
347 {
348   Superclass::SetTransform(theTransform);
349
350   myPreHighlightActor->SetTransform(theTransform);
351   myHighlightActor->SetTransform(theTransform);
352   myOutlineActor->SetTransform(theTransform);
353 }
354
355 /*!
356   Apply additional position
357 */
358 void
359 SALOME_Actor
360 ::SetPosition(double _arg1, 
361               double _arg2, 
362               double _arg3)
363 {
364   Superclass::SetPosition(_arg1,_arg2,_arg3);
365
366   myPreHighlightActor->SetPosition(_arg1,_arg2,_arg3);
367   myHighlightActor->SetPosition(_arg1,_arg2,_arg3);
368   myOutlineActor->SetPosition(_arg1,_arg2,_arg3);
369 }
370
371 /*!
372   Apply additional position
373 */
374 void
375 SALOME_Actor
376 ::SetPosition(double _arg[3])
377 {
378   SetPosition(_arg[0],_arg[1],_arg[2]);
379 }
380
381 /*!
382   Shows/hides actor
383   \param theVisibility - new visibility state
384 */
385 void
386 SALOME_Actor
387 ::SetVisibility( int theVisibility )
388 {
389   Superclass::SetVisibility( theVisibility );
390
391   myOutlineActor->SetVisibility( theVisibility && isHighlighted() && !hasHighlight() );
392
393   myPreHighlightActor->SetVisibility( theVisibility && myIsPreselected );
394
395   if(mySelector.GetPointer() && hasIO()){
396     if(mySelector->SelectionMode() != ActorSelection){
397       int aHasIndex = mySelector->HasIndex( getIO() );
398       myHighlightActor->SetVisibility( theVisibility && isHighlighted() && aHasIndex);
399     }
400   }
401
402   UpdateNameActors();
403 }
404
405 /*!
406   Gets know whether the actor should be displayed or not
407 */
408 bool 
409 SALOME_Actor
410 ::ShouldBeDisplayed()
411 {
412   return true;
413 }
414
415 /*!
416   Set selector in order to the actor at any time can restore current selection
417   \param theSelector - new selector
418 */
419 void
420 SALOME_Actor
421 ::SetSelector(SVTK_Selector* theSelector)
422 {
423   mySelector = theSelector;
424 }
425
426 /*!
427   To map current selection to VTK representation
428 */
429 void
430 SALOME_Actor
431 ::Highlight(bool theIsHighlight)
432 {
433   mySelectionMode = mySelector->SelectionMode();
434   myHighlightActor->SetVisibility( false );
435   myOutlineActor->SetVisibility( false );
436
437   if(mySelector.GetPointer()){
438     if(mySelectionMode != ActorSelection){
439       TColStd_IndexedMapOfInteger aMapIndex;
440       mySelector->GetIndex( getIO(), aMapIndex );
441       switch( mySelectionMode ){
442       case NodeSelection:
443         myHighlightActor->GetProperty()->SetRepresentationToPoints();
444         myHighlightActor->MapPoints( this, aMapIndex );
445         break;
446       case EdgeOfCellSelection:
447         myHighlightActor->GetProperty()->SetRepresentationToWireframe();
448         myHighlightActor->MapEdge( this, aMapIndex );
449         break;
450       case CellSelection:
451       case EdgeSelection:
452       case FaceSelection:
453       case VolumeSelection:
454       case Elem0DSelection: 
455       case BallSelection: 
456         myHighlightActor->GetProperty()->SetRepresentationToSurface();
457         myHighlightActor->MapCells( this, aMapIndex );
458         break;
459       }
460       myHighlightActor->SetVisibility( GetVisibility() && theIsHighlight );
461     }
462   }
463
464   highlight(theIsHighlight);
465 }
466
467 /*!
468   Updates visibility of the highlight devices  
469 */
470 void
471 SALOME_Actor
472 ::highlight(bool theIsHighlight)
473 {
474   double aBounds[6];
475   vtkDataSet * aDataSet = GetHighlightedDataSet();
476   aDataSet->GetBounds(aBounds);
477   myOutline->SetBounds(aBounds);
478   myOutline->Update();
479   myOutlineActor->SetVisibility( GetVisibility() && theIsHighlight );
480
481   Superclass::highlight(theIsHighlight);
482 }
483
484
485 /*!
486   To process prehighlight (called from SVTK_InteractorStyle)
487 */
488 bool
489 SALOME_Actor
490 ::PreHighlight(vtkInteractorStyle *theInteractorStyle, 
491                SVTK_SelectionEvent* theSelectionEvent,
492                bool theIsHighlight)
493 {
494   if ( !GetPickable() )
495     return false;
496       
497   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
498   //
499   myPreHighlightActor->SetVisibility( false );
500   bool anIsPreselected = myIsPreselected;
501   SetPreSelected( false );
502
503   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
504   bool anIsChanged = (mySelectionMode != aSelectionMode);
505
506   myPreHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
507
508   double x = theSelectionEvent->myX;
509   double y = theSelectionEvent->myY;
510   double z = 0.0;
511
512   if( !theIsHighlight ) {
513     if ( hasIO() ) {
514       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
515       vtkActorCollection* theActors = aCopy.GetActors();
516       theActors->InitTraversal();
517       while( vtkActor *ac = theActors->GetNextActor() )
518         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) )
519           if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
520             anActor->SetPreSelected( false );
521     }
522   }else{
523     switch(aSelectionMode) {
524     case NodeSelection: 
525     {
526       SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
527       myPointPicker->Pick( x, y, z, aRenderer );
528       
529       int aVtkId = myPointPicker->GetPointId();
530       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
531         int anObjId = GetNodeObjId( aVtkId );
532         myIsPreselected = (anObjId >= 0);
533         if(myIsPreselected){
534           const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
535           int anExtent = aMapIndex.Extent();
536           anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
537           if(anIsChanged){
538             TColStd_IndexedMapOfInteger aMapIndex;
539             aMapIndex.Add( anObjId );
540             
541             myPreHighlightActor->GetProperty()->SetRepresentationToPoints();
542             myPreHighlightActor->MapPoints( this, aMapIndex );
543           }
544           myPreHighlightActor->SetVisibility( true );
545         }
546       }
547       break;
548     }
549     case CellSelection: 
550     case EdgeSelection:
551     case FaceSelection:
552     case VolumeSelection: 
553     case Elem0DSelection:        
554     case BallSelection: 
555     {
556       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
557       myCellPicker->Pick( x, y, z, aRenderer );
558       
559       int aVtkId = myCellPicker->GetCellId();
560       if ( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) && hasIO() ) {
561         int anObjId = GetElemObjId (aVtkId );
562         if ( anObjId >= 0 ) {
563           myIsPreselected = CheckDimensionId(aSelectionMode,this,anObjId);
564           if(myIsPreselected){
565             const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
566             int anExtent = aMapIndex.Extent();
567             anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
568             if(anIsChanged){
569               TColStd_IndexedMapOfInteger aMapIndex;
570               aMapIndex.Add( anObjId );
571               
572               myPreHighlightActor->GetProperty()->SetRepresentationToSurface();
573               myPreHighlightActor->MapCells( this, aMapIndex );
574             }
575             myPreHighlightActor->SetVisibility( true );
576           }
577         }
578       }
579       break;
580     }
581     case EdgeOfCellSelection:
582     {
583       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
584       myCellPicker->Pick( x, y, z, aRenderer );
585       
586       int aVtkId = myCellPicker->GetCellId();
587       if ( aVtkId >= 0 && mySelector->IsValid( this, aVtkId )) {
588         int anObjId = GetElemObjId( aVtkId );
589         if ( anObjId >= 0 ) {
590           int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
591           myIsPreselected = anEdgeId < 0;
592           if(myIsPreselected){
593             const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
594             int anExtent = aMapIndex.Extent();
595             anIsChanged |= (anExtent == 0 || anExtent == 1);
596             anIsChanged |= (anExtent == 2 && (anObjId != aMapIndex(1) || anEdgeId != aMapIndex(2)));
597             if(anIsChanged){
598               TColStd_IndexedMapOfInteger aMapIndex;
599               aMapIndex.Add( anObjId );
600               aMapIndex.Add( anEdgeId );
601
602               myPreHighlightActor->GetProperty()->SetRepresentationToWireframe();
603               myPreHighlightActor->MapEdge( this, aMapIndex );
604             }
605             myPreHighlightActor->SetVisibility( true );
606           }
607         }
608       }
609       break;
610     }
611     case ActorSelection : 
612     {
613       if( !mySelector->IsSelected( myIO ) ) {
614         SetPreSelected( true );
615
616         if ( hasIO() ) {
617           VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
618           vtkActorCollection* theActors = aCopy.GetActors();
619           theActors->InitTraversal();
620           while( vtkActor *anAct = theActors->GetNextActor() ) {
621             if( anAct != this )
622               if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( anAct ) )
623                 if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
624                   anActor->SetPreSelected( true );
625           }
626         }
627       }
628     }
629     default:
630       break;
631     }
632   }
633
634   mySelectionMode = aSelectionMode;
635   anIsChanged |= (anIsPreselected != myIsPreselected);
636
637   return anIsChanged;
638 }
639
640 /*!
641   To process highlight (called from SVTK_InteractorStyle)
642 */
643 bool
644 SALOME_Actor
645 ::Highlight(vtkInteractorStyle *theInteractorStyle, 
646             SVTK_SelectionEvent* theSelectionEvent,
647             bool theIsHighlight)
648 {
649   if ( !GetPickable() || !mySelector )
650     return false;
651
652   myOutlineActor->SetVisibility( false );
653   myHighlightActor->SetVisibility( false );
654
655   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
656   //
657   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
658   bool anIsShift = theSelectionEvent->myIsShift;
659   if( !anIsShift || !theIsHighlight ) {
660     mySelector->RemoveIObject( this );
661   }
662
663   if ( !theIsHighlight )
664     return true;
665
666   myHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
667
668   double x = theSelectionEvent->myX;
669   double y = theSelectionEvent->myY;
670   double z = 0.0;
671
672   if( !theSelectionEvent->myIsRectangle ) {
673     switch(aSelectionMode){
674     case NodeSelection: {
675       SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
676       myPointPicker->Pick( x, y, z, aRenderer );
677
678       int aVtkId = myPointPicker->GetPointId();
679       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
680         int anObjId = GetNodeObjId( aVtkId );
681         if( hasIO() && anObjId >= 0 ) {
682           mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
683           mySelector->AddIObject( this );
684         }
685       }
686       break;
687     }
688     case CellSelection: 
689     case EdgeSelection:
690     case FaceSelection:
691     case VolumeSelection: 
692     case Elem0DSelection:        
693     case BallSelection: 
694     {
695       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
696       myCellPicker->Pick( x, y, z, aRenderer );
697     
698       int aVtkId = myCellPicker->GetCellId();
699       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
700         int anObjId = GetElemObjId( aVtkId );
701         if( anObjId >= 0 ) {
702           if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) {
703             mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
704             mySelector->AddIObject( this );
705           }
706         }
707       }
708       break;
709     }
710     case EdgeOfCellSelection: 
711     {
712       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
713       myCellPicker->Pick( x, y, z, aRenderer );
714     
715       int aVtkId = myCellPicker->GetCellId();
716       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
717         int anObjId = GetElemObjId( aVtkId );
718         if( anObjId >= 0 ) {
719           int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
720           if( hasIO() && anEdgeId < 0 ) {
721             mySelector->AddOrRemoveIndex( myIO, anObjId, false );
722             mySelector->AddOrRemoveIndex( myIO, anEdgeId, true );
723             mySelector->AddIObject( this );
724           } 
725         }
726       }
727       break;
728     }
729     case ActorSelection : 
730     {
731       if ( hasIO() ) {
732         if( mySelector->IsSelected( myIO ) && anIsShift )
733           mySelector->RemoveIObject( this );
734         else {
735           mySelector->AddIObject( this );
736         }
737       }
738       break;
739     }
740     default:
741       break;
742     }
743   }else{
744     double xLast = theSelectionEvent->myLastX;
745     double yLast = theSelectionEvent->myLastY;
746     double zLast = 0.0;
747
748     double x1 = x < xLast ? x : xLast;
749     double y1 = y < yLast ? y : yLast;
750     double z1 = z < zLast ? z : zLast;
751     double x2 = x > xLast ? x : xLast;
752     double y2 = y > yLast ? y : yLast;
753     double z2 = z > zLast ? z : zLast;
754
755     switch(aSelectionMode){
756     case NodeSelection: {
757
758       SVTK::TPickLimiter aPickLimiter( myPointRectPicker, this );
759       myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
760
761       const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap();
762       SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
763       TColStd_MapOfInteger anIndexes;
764       if(aMapIter != aVectorIdsMap.end()){
765         const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
766         vtkIdType anEnd = aVectorIds.size();
767         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
768           int aPointId = aVectorIds[anId];
769           if( aPointId >= 0 && mySelector->IsValid( this, aPointId, true ) ) {
770             int anObjId = GetNodeObjId( aPointId );
771             anIndexes.Add( anObjId );
772           }
773         }
774       }
775       
776       if ( hasIO() ) {
777         if( !anIndexes.IsEmpty() ) {
778           mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
779           mySelector->AddIObject( this );
780           anIndexes.Clear();
781         }
782         else if ( !anIsShift )
783           mySelector->RemoveIObject( this );
784       }
785       break;
786     }
787     case ActorSelection :
788     {
789       double aPnt[3];
790       double* aBounds = GetBounds();
791
792       bool anIsPicked = true;
793       for( int i = 0; i <= 1; i++ ) {
794         for( int j = 2; j <= 3; j++ ) {
795           for( int k = 4; k <= 5; k++ ) {
796             aRenderer->SetWorldPoint( aBounds[ i ], aBounds[ j ], aBounds[ k ], 1.0 );
797             aRenderer->WorldToDisplay();
798             aRenderer->GetDisplayPoint( aPnt );
799
800             if( aPnt[0] < x1 || aPnt[0] > x2 || aPnt[1] < y1 || aPnt[1] > y2 ) {
801               anIsPicked = false;
802               break;
803             }
804           }
805         }
806       }
807
808       if( anIsPicked )
809         mySelector->AddIObject(this);
810
811       break;
812     }
813     case CellSelection: 
814     case EdgeSelection:
815     case FaceSelection:
816     case VolumeSelection: 
817     case Elem0DSelection:        
818     case BallSelection: 
819     {
820       SVTK::TPickLimiter aPickLimiter( myCellRectPicker, this );
821       myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
822
823       const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap();
824       SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
825       TColStd_MapOfInteger anIndexes;
826       if(aMapIter != aVectorIdsMap.end()){
827         const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
828         vtkIdType anEnd = aVectorIds.size();
829         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
830           int aCellId = aVectorIds[anId];
831           if ( !mySelector->IsValid( this, aCellId ) )
832             continue;
833
834           int anObjId = GetElemObjId( aCellId );
835           if( anObjId != -1 )
836             if ( CheckDimensionId(aSelectionMode,this,anObjId) ) {
837               anIndexes.Add(anObjId);
838             }
839         }
840       }
841       
842       if ( hasIO() ) {
843         if( !anIndexes.IsEmpty() ) {
844           mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
845           mySelector->AddIObject( this );
846           anIndexes.Clear();
847         }
848         else if ( !anIsShift )
849           mySelector->RemoveIObject( this );
850       }
851     }
852     default:
853       break;
854     }
855   }
856
857   mySelectionMode = aSelectionMode;
858
859   return true;
860 }
861
862 /*!
863   To get flag of displaying of name actor
864   \return flag to display or not to display name actor
865 */
866 bool
867 SALOME_Actor
868 ::IsDisplayNameActor() const
869 {
870   return myIsDisplayNameActor;
871 }
872
873 /*!
874   To set flag of displaying of name actor
875   \param theIsDisplayNameActor flag to display or not to display name actor
876 */
877 void
878 SALOME_Actor
879 ::SetIsDisplayNameActor(bool theIsDisplayNameActor)
880 {
881   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
882   bool isShowGroupNames = aResourceMgr->booleanValue("VTKViewer", "show_group_names", false);
883   myIsDisplayNameActor = theIsDisplayNameActor && isShowGroupNames;
884   UpdateNameActors();
885 }
886
887 /*!
888   To set text of name actor
889   \param theText - text of name actor
890 */
891 void
892 SALOME_Actor
893 ::SetNameActorText(const char* theText)
894 {
895   myNameActor->SetText(theText);
896 }
897
898 /*!
899   To set offset of name actor
900   \param theOffset - offset of name actor
901 */
902 void
903 SALOME_Actor
904 ::SetNameActorOffset(int theOffset[2])
905 {
906   myNameActor->SetOffset(theOffset);
907 }
908
909 /*!
910   To get size of name actor
911   \param theRenderer - renderer
912   \param theSize - size of name actor
913 */
914 void
915 SALOME_Actor
916 ::GetNameActorSize(vtkRenderer* theRenderer, int theSize[2]) const
917 {
918   myNameActor->GetSize(theRenderer, theSize);
919 }
920
921 /*!
922   Update visibility of name actors
923 */
924 void
925 SALOME_Actor
926 ::UpdateNameActors()
927 {
928   if( vtkRenderer* aRenderer = GetRenderer() )
929   {
930     int anOffset[2] = { 0, 0 };
931     VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
932     vtkActorCollection* aCollection = aCopy.GetActors();
933     for( int anIndex = 0, aNbItems = aCollection->GetNumberOfItems(); anIndex < aNbItems; anIndex++ )
934     {
935       if( SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>( aCollection->GetItemAsObject( anIndex ) ) )
936       {
937         if( anActor->IsDisplayNameActor() )
938         {
939           anActor->SetNameActorOffset( anOffset );
940           if( anActor->GetVisibility() )
941           {
942             int aSize[2];
943             anActor->GetNameActorSize( aRenderer, aSize );
944             anOffset[0] = anOffset[0] + aSize[0];
945             anOffset[1] = anOffset[1] + aSize[1];
946           }
947         }
948       }
949     }
950   }
951   myNameActor->SetVisibility( GetVisibility() && IsDisplayNameActor() );
952 }
953
954 /*!
955   To set up a picker for nodal selection (initialized by SVTK_Renderer::AddActor)
956   \param thePointPicker - new picker
957 */
958 void
959 SALOME_Actor
960 ::SetPointPicker(vtkPointPicker* thePointPicker) 
961 {
962   myPointPicker = thePointPicker;
963 }
964
965 /*!
966   To set up a picker for cell selection (initialized by SVTK_Renderer::AddActor)
967   \param theCellPicker - new picker
968 */
969 void
970 SALOME_Actor
971 ::SetCellPicker(vtkCellPicker* theCellPicker) 
972 {
973   myCellPicker = theCellPicker;
974 }
975
976 /*!
977   To set up a picker for point rectangle selection (initialized by SVTK_Renderer::AddActor)
978   \param theRectPicker - new picker
979 */
980 void
981 SALOME_Actor
982 ::SetPointRectPicker(SVTK_RectPicker* theRectPicker) 
983 {
984   myPointRectPicker = theRectPicker;
985 }
986
987 /*!
988   To set up a picker for cell rectangle selection (initialized by SVTK_Renderer::AddActor)
989   \param theRectPicker - new picker
990 */
991 void
992 SALOME_Actor
993 ::SetCellRectPicker(SVTK_RectPicker* theRectPicker) 
994 {
995   myCellRectPicker = theRectPicker;
996 }
997
998 /*!
999   To set up a prehighlight property (initialized by SVTK_Renderer::AddActor)
1000 */
1001 void
1002 SALOME_Actor
1003 ::SetPreHighlightProperty(vtkProperty* theProperty) 
1004 {
1005   myPreHighlightActor->SetProperty(theProperty);
1006 }
1007
1008 /*!
1009   To set up a highlight property (initialized by SVTK_Renderer::AddActor)
1010 */
1011 void
1012 SALOME_Actor
1013 ::SetHighlightProperty(vtkProperty* theProperty) 
1014 {
1015   myHighlightActor->SetProperty(theProperty);
1016 }
1017
1018 /*!
1019   Set standard point marker
1020   \param theMarkerType type of the marker
1021   \param theMarkerScale scale of the marker
1022 */
1023 void
1024 SALOME_Actor
1025 ::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
1026 {
1027   myPreHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
1028   myHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
1029 }
1030
1031 /*!
1032   Set custom point marker
1033   \param theMarkerId id of the marker texture
1034   \param theMarkerTexture marker texture
1035 */
1036 void
1037 SALOME_Actor
1038 ::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
1039 {
1040   myPreHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
1041   myHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
1042 }
1043
1044 /*!
1045   Get type of the point marker
1046   \return type of the point marker
1047 */
1048 VTK::MarkerType
1049 SALOME_Actor
1050 ::GetMarkerType()
1051 {
1052   return myPreHighlightActor->GetMarkerType();
1053 }
1054
1055 /*!
1056   Get scale of the point marker
1057   \return scale of the point marker
1058 */
1059 VTK::MarkerScale
1060 SALOME_Actor
1061 ::GetMarkerScale()
1062 {
1063   return myPreHighlightActor->GetMarkerScale();
1064 }
1065
1066 /*!
1067   Get texture identifier of the point marker
1068   \return texture identifier of the point marker
1069  */
1070 int
1071 SALOME_Actor
1072 ::GetMarkerTexture()
1073 {
1074   return myPreHighlightActor->GetMarkerTexture();
1075 }