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