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