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