Salome HOME
Merge Python 3 porting.
[modules/gui.git] / src / SVTK / SALOME_Actor.cxx
1 // Copyright (C) 2007-2016  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     myHighlightActor->SetMarkerEnabled( mySelectionMode == NodeSelection );
472   }
473
474   highlight(theIsHighlight);
475 }
476
477 /*!
478   Updates visibility of the highlight devices  
479 */
480 void
481 SALOME_Actor
482 ::highlight(bool theIsHighlight)
483 {
484   double aBounds[6];
485   vtkDataSet * aDataSet = GetHighlightedDataSet();
486   aDataSet->GetBounds(aBounds);
487   myOutline->SetBounds(aBounds);
488   myOutline->Update();
489   myOutlineActor->SetVisibility( GetVisibility() && theIsHighlight );
490
491   Superclass::highlight(theIsHighlight);
492 }
493
494
495 /*!
496   To process prehighlight (called from SVTK_InteractorStyle)
497 */
498 bool
499 SALOME_Actor
500 ::PreHighlight(vtkInteractorStyle *theInteractorStyle, 
501                SVTK_SelectionEvent* theSelectionEvent,
502                bool theIsHighlight)
503 {
504   if ( !GetPickable() || !mySelector || !mySelector->IsPreSelectionEnabled() )
505     return false;
506       
507   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
508   //
509   myPreHighlightActor->SetVisibility( false );
510   bool anIsPreselected = myIsPreselected;
511   SetPreSelected( false );
512
513   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
514   bool anIsChanged = (mySelectionMode != aSelectionMode);
515
516   myPreHighlightActor->SetMarkerEnabled( aSelectionMode == NodeSelection );
517
518   double x = theSelectionEvent->myX;
519   double y = theSelectionEvent->myY;
520   double z = 0.0;
521
522   if( !theIsHighlight ) {
523     if ( hasIO() ) {
524       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
525       vtkActorCollection* theActors = aCopy.GetActors();
526       theActors->InitTraversal();
527       while( vtkActor *ac = theActors->GetNextActor() )
528         if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( ac ) )
529           if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
530             anActor->SetPreSelected( false );
531     }
532   }else{
533     switch(aSelectionMode) {
534     case NodeSelection: 
535     {
536       SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
537       myPointPicker->Pick( x, y, z, aRenderer );
538       
539       int aVtkId = myPointPicker->GetPointId();
540       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
541         int anObjId = GetNodeObjId( aVtkId );
542         myIsPreselected = (anObjId >= 0);
543         if(myIsPreselected){
544           const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
545           int anExtent = aMapIndex.Extent();
546           anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
547           if(anIsChanged){
548             TColStd_IndexedMapOfInteger aMapIndex;
549             aMapIndex.Add( anObjId );
550             
551             myPreHighlightActor->GetProperty()->SetRepresentationToPoints();
552             myPreHighlightActor->MapPoints( this, aMapIndex );
553           }
554           myPreHighlightActor->SetVisibility( true );
555         }
556       }
557       break;
558     }
559     case CellSelection: 
560     case EdgeSelection:
561     case FaceSelection:
562     case VolumeSelection: 
563     case Elem0DSelection:        
564     case BallSelection: 
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 ) && hasIO() ) {
571         int anObjId = GetElemObjId (aVtkId );
572         if ( anObjId >= 0 ) {
573           myIsPreselected = CheckDimensionId(aSelectionMode,this,anObjId);
574           if(myIsPreselected){
575             const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
576             int anExtent = aMapIndex.Extent();
577             anIsChanged |= (anExtent == 0 || (anExtent > 0 && anObjId != aMapIndex(1)));
578             if(anIsChanged){
579               TColStd_IndexedMapOfInteger aMapIndex;
580               aMapIndex.Add( anObjId );
581               
582               myPreHighlightActor->GetProperty()->SetRepresentationToSurface();
583               myPreHighlightActor->MapCells( this, aMapIndex );
584             }
585             myPreHighlightActor->SetVisibility( true );
586           }
587         }
588       }
589       break;
590     }
591     case EdgeOfCellSelection:
592     {
593       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
594       myCellPicker->Pick( x, y, z, aRenderer );
595       
596       int aVtkId = myCellPicker->GetCellId();
597       if ( aVtkId >= 0 && mySelector->IsValid( this, aVtkId )) {
598         int anObjId = GetElemObjId( aVtkId );
599         if ( anObjId >= 0 ) {
600           int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
601           myIsPreselected = anEdgeId < 0;
602           if(myIsPreselected){
603             const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex();
604             int anExtent = aMapIndex.Extent();
605             anIsChanged |= (anExtent == 0 || anExtent == 1);
606             anIsChanged |= (anExtent == 2 && (anObjId != aMapIndex(1) || anEdgeId != aMapIndex(2)));
607             if(anIsChanged){
608               TColStd_IndexedMapOfInteger aMapIndex;
609               aMapIndex.Add( anObjId );
610               aMapIndex.Add( anEdgeId );
611
612               myPreHighlightActor->GetProperty()->SetRepresentationToWireframe();
613               myPreHighlightActor->MapEdge( this, aMapIndex );
614             }
615             myPreHighlightActor->SetVisibility( true );
616           }
617         }
618       }
619       break;
620     }
621     case ActorSelection : 
622     {
623       if( !mySelector->IsSelected( myIO ) ) {
624         SetPreSelected( true );
625
626         if ( hasIO() ) {
627           VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
628           vtkActorCollection* theActors = aCopy.GetActors();
629           theActors->InitTraversal();
630           while( vtkActor *anAct = theActors->GetNextActor() ) {
631             if( anAct != this )
632               if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( anAct ) )
633                 if( anActor->hasIO() && myIO->isSame( anActor->getIO() ) )
634                   anActor->SetPreSelected( true );
635           }
636         }
637       }
638     }
639     default:
640       break;
641     }
642   }
643
644   mySelectionMode = aSelectionMode;
645   anIsChanged |= (anIsPreselected != myIsPreselected);
646
647   return anIsChanged;
648 }
649
650 /*!
651   To process highlight (called from SVTK_InteractorStyle)
652 */
653 bool
654 SALOME_Actor
655 ::Highlight(vtkInteractorStyle *theInteractorStyle, 
656             SVTK_SelectionEvent* theSelectionEvent,
657             bool theIsHighlight)
658 {
659   if ( !GetPickable() || !mySelector || !mySelector->IsSelectionEnabled() )
660     return false;
661
662   myOutlineActor->SetVisibility( false );
663   myHighlightActor->SetVisibility( false );
664
665   vtkRenderer *aRenderer = theInteractorStyle->GetCurrentRenderer();
666   //
667   Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
668   bool anIsShift = theSelectionEvent->myIsShift;
669   if( !anIsShift || !theIsHighlight ) {
670     mySelector->RemoveIObject( this );
671   }
672
673   if ( !theIsHighlight )
674     return true;
675
676   double x = theSelectionEvent->myX;
677   double y = theSelectionEvent->myY;
678
679   if( theSelectionEvent->myIsRectangle || theSelectionEvent->myIsPolygon ) {
680     double xLast = theSelectionEvent->myLastX;
681     double yLast = theSelectionEvent->myLastY;
682
683     double x1 = x < xLast ? x : xLast;
684     double y1 = y < yLast ? y : yLast;
685     double x2 = x > xLast ? x : xLast;
686     double y2 = y > yLast ? y : yLast;
687
688     switch(aSelectionMode){
689     case NodeSelection: {
690
691       SVTK::TPickLimiter aPickLimiter( myPointAreaPicker, this );
692       if ( theSelectionEvent->myIsRectangle )
693         myPointAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode );
694       else if( theSelectionEvent->myIsPolygon )
695         myPointAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode );
696
697       const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myPointAreaPicker->GetPointIdsMap();
698       SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
699       TColStd_MapOfInteger anIndexes;
700       if(aMapIter != aVectorIdsMap.end()){
701         const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
702         vtkIdType anEnd = aVectorIds.size();
703         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
704           int aPointId = aVectorIds[anId];
705           if( aPointId >= 0 && mySelector->IsValid( this, aPointId, true ) ) {
706             int anObjId = GetNodeObjId( aPointId );
707             anIndexes.Add( anObjId );
708           }
709         }
710       }
711       
712       if ( hasIO() ) {
713         if( !anIndexes.IsEmpty() ) {
714           mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
715           mySelector->AddIObject( this );
716           anIndexes.Clear();
717         }
718         else if ( !anIsShift )
719           mySelector->RemoveIObject( this );
720       }
721       break;
722     }
723     case ActorSelection :
724     {
725       double aPnt[3];
726       double* aBounds = GetBounds();
727
728       bool anIsPicked = true;
729       for( int i = 0; i <= 1; i++ ) {
730         for( int j = 2; j <= 3; j++ ) {
731           for( int k = 4; k <= 5; k++ ) {
732             aRenderer->SetWorldPoint( aBounds[ i ], aBounds[ j ], aBounds[ k ], 1.0 );
733             aRenderer->WorldToDisplay();
734             aRenderer->GetDisplayPoint( aPnt );
735             bool anIsPointInSelection;
736             if( theSelectionEvent->myIsRectangle )
737               anIsPointInSelection =  aPnt[0] > x1 && aPnt[0] < x2 && aPnt[1] > y1 && aPnt[1] < y2;
738             else if( theSelectionEvent->myIsPolygon )
739               anIsPointInSelection = myPointAreaPicker->isPointInPolygon( QPoint( aPnt[0], aPnt[1] ),
740                                                                           theSelectionEvent->myPolygonPoints );
741
742             if( !anIsPointInSelection ) {
743                 anIsPicked = false;
744                 break;
745             }
746           }
747         }
748       }
749
750       if ( hasIO() ) {
751         if( anIsPicked && mySelector->IsSelected( myIO ) && anIsShift )
752           mySelector->RemoveIObject( this );
753         else if ( anIsPicked ){
754           mySelector->AddIObject( this );
755         }
756       }
757
758       break;
759     }
760     case CellSelection: 
761     case EdgeSelection:
762     case FaceSelection:
763     case VolumeSelection: 
764     case Elem0DSelection:        
765     case BallSelection: 
766     {
767       SVTK::TPickLimiter aPickLimiter( myCellAreaPicker, this );
768       if( theSelectionEvent->myIsRectangle )
769         myCellAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode );
770       else if( theSelectionEvent->myIsPolygon )
771         myCellAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode );
772
773       const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myCellAreaPicker->GetCellIdsMap();
774       SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
775       TColStd_MapOfInteger anIndexes;
776       if(aMapIter != aVectorIdsMap.end()){
777         const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second;
778         vtkIdType anEnd = aVectorIds.size();
779         for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
780           int aCellId = aVectorIds[anId];
781           if ( !mySelector->IsValid( this, aCellId ) )
782             continue;
783
784           int anObjId = GetElemObjId( aCellId );
785           if( anObjId != -1 )
786             if ( CheckDimensionId(aSelectionMode,this,anObjId) ) {
787               anIndexes.Add(anObjId);
788             }
789         }
790       }
791       
792       if ( hasIO() ) {
793         if( !anIndexes.IsEmpty() ) {
794           mySelector->AddOrRemoveIndex( myIO, anIndexes, anIsShift );
795           mySelector->AddIObject( this );
796           anIndexes.Clear();
797         }
798         else if ( !anIsShift )
799           mySelector->RemoveIObject( this );
800       }
801     }
802     default:
803       break;
804     }
805   }
806   else {
807     switch(aSelectionMode){
808     case NodeSelection: {
809       SVTK::TPickLimiter aPickLimiter( myPointPicker, this );
810       myPointPicker->Pick( x, y, 0.0, aRenderer );
811
812       int aVtkId = myPointPicker->GetPointId();
813       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
814         int anObjId = GetNodeObjId( aVtkId );
815         if( hasIO() && anObjId >= 0 ) {
816           mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
817           mySelector->AddIObject( this );
818         }
819       }
820       break;
821     }
822     case CellSelection:
823     case EdgeSelection:
824     case FaceSelection:
825     case VolumeSelection:
826     case Elem0DSelection:
827     case BallSelection:
828     {
829       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
830       myCellPicker->Pick( x, y, 0.0, aRenderer );
831
832       int aVtkId = myCellPicker->GetCellId();
833       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
834         int anObjId = GetElemObjId( aVtkId );
835         if( anObjId >= 0 ) {
836           if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) {
837             mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift );
838             mySelector->AddIObject( this );
839           }
840         }
841       }
842       break;
843     }
844     case EdgeOfCellSelection:
845     {
846       SVTK::TPickLimiter aPickLimiter( myCellPicker, this );
847       myCellPicker->Pick( x, y, 0.0, aRenderer );
848
849       int aVtkId = myCellPicker->GetCellId();
850       if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) {
851         int anObjId = GetElemObjId( aVtkId );
852         if( anObjId >= 0 ) {
853           int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId);
854           if( hasIO() && anEdgeId < 0 ) {
855             mySelector->AddOrRemoveIndex( myIO, anObjId, false );
856             mySelector->AddOrRemoveIndex( myIO, anEdgeId, true );
857             mySelector->AddIObject( this );
858           }
859         }
860       }
861       break;
862     }
863     case ActorSelection :
864     {
865       if ( hasIO() ) {
866         if( mySelector->IsSelected( myIO ) && anIsShift )
867           mySelector->RemoveIObject( this );
868         else {
869           mySelector->AddIObject( this );
870         }
871       }
872       break;
873     }
874     default:
875       break;
876     }
877   }
878
879   mySelectionMode = aSelectionMode;
880
881   return true;
882 }
883
884 /*!
885   To get flag of displaying of name actor
886   \return flag to display or not to display name actor
887 */
888 bool
889 SALOME_Actor
890 ::IsDisplayNameActor() const
891 {
892   return myIsDisplayNameActor;
893 }
894
895 /*!
896   To set flag of displaying of name actor
897   \param theIsDisplayNameActor flag to display or not to display name actor
898 */
899 void
900 SALOME_Actor
901 ::SetIsDisplayNameActor(bool theIsDisplayNameActor)
902 {
903   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
904   bool isShowGroupNames = aResourceMgr->booleanValue("VTKViewer", "show_group_names", false);
905   myIsDisplayNameActor = theIsDisplayNameActor && isShowGroupNames;
906   UpdateNameActors();
907 }
908
909 /*!
910   To set text of name actor
911   \param theText - text of name actor
912 */
913 void
914 SALOME_Actor
915 ::SetNameActorText(const char* theText)
916 {
917   myNameActor->SetText(theText);
918 }
919
920 /*!
921   To set offset of name actor
922   \param theOffset - offset of name actor
923 */
924 void
925 SALOME_Actor
926 ::SetNameActorOffset(double theOffset[2])
927 {
928   myNameActor->SetOffset(theOffset);
929 }
930
931 /*!
932   To get size of name actor
933   \param theRenderer - renderer
934   \param theSize - size of name actor
935 */
936 void
937 SALOME_Actor
938 ::GetNameActorSize(vtkRenderer* theRenderer, double theSize[2]) const
939 {
940   myNameActor->GetSize(theRenderer, theSize);
941 }
942
943 /*!
944   Update visibility of name actors
945 */
946 void
947 SALOME_Actor
948 ::UpdateNameActors()
949 {
950   if( vtkRenderer* aRenderer = GetRenderer() )
951   {
952     double anOffset[2] = { 0, 0 };
953     VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
954     vtkActorCollection* aCollection = aCopy.GetActors();
955     for( int anIndex = 0, aNbItems = aCollection->GetNumberOfItems(); anIndex < aNbItems; anIndex++ )
956     {
957       if( SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>( aCollection->GetItemAsObject( anIndex ) ) )
958       {
959         if( anActor->IsDisplayNameActor() )
960         {
961           anActor->SetNameActorOffset( anOffset );
962           if( anActor->GetVisibility() )
963           {
964             double aSize[2];
965             anActor->GetNameActorSize( aRenderer, aSize );
966             anOffset[0] = anOffset[0] + aSize[0];
967             anOffset[1] = anOffset[1] + aSize[1];
968           }
969         }
970       }
971     }
972   }
973   myNameActor->SetVisibility( GetVisibility() && IsDisplayNameActor() );
974 }
975
976 /*!
977   To set up a picker for nodal selection (initialized by SVTK_Renderer::AddActor)
978   \param thePointPicker - new picker
979 */
980 void
981 SALOME_Actor
982 ::SetPointPicker(vtkPointPicker* thePointPicker) 
983 {
984   myPointPicker = thePointPicker;
985 }
986
987 /*!
988   To set up a picker for cell selection (initialized by SVTK_Renderer::AddActor)
989   \param theCellPicker - new picker
990 */
991 void
992 SALOME_Actor
993 ::SetCellPicker(vtkCellPicker* theCellPicker) 
994 {
995   myCellPicker = theCellPicker;
996 }
997
998 /*!
999   To set up a picker for point rectangle or polygonal selection (initialized by SVTK_Renderer::AddActor)
1000   \param theAreaPicker - new picker
1001 */
1002 void
1003 SALOME_Actor
1004 ::SetPointAreaPicker(SVTK_AreaPicker* theAreaPicker)
1005 {
1006   myPointAreaPicker = theAreaPicker;
1007 }
1008
1009 /*!
1010   To set up a picker for cell rectangle of polygonal selection (initialized by SVTK_Renderer::AddActor)
1011   \param theAreaPicker - new picker
1012 */
1013 void
1014 SALOME_Actor
1015 ::SetCellAreaPicker(SVTK_AreaPicker* theAreaPicker)
1016 {
1017   myCellAreaPicker = theAreaPicker;
1018 }
1019
1020 /*!
1021   To find a gravity center of object
1022   \param theObjId - identification of object
1023 */
1024 double*
1025 SALOME_Actor
1026 ::GetGravityCenter( int theObjId )
1027 {
1028   double* result = new double[3];
1029   for( int i = 0; i < 3; i++ )
1030     result[i]= 0.0;
1031
1032   vtkPoints* points = GetElemCell( theObjId )->GetPoints();
1033   int nbPoints = points->GetNumberOfPoints();
1034
1035   if( nbPoints <= 0 )
1036     return NULL;
1037
1038   for( int i = 0; i < nbPoints; i++ )
1039   {
1040     double* aPoint = points->GetPoint(i);
1041     result[0] += aPoint[0];
1042     result[1] += aPoint[1];
1043     result[2] += aPoint[2];
1044   }
1045   result[0] = result[0] / nbPoints;
1046   result[1] = result[1] / nbPoints;
1047   result[2] = result[2] / nbPoints;
1048
1049   return result;
1050 }
1051
1052 /*!
1053   To set up a prehighlight property (initialized by SVTK_Renderer::AddActor)
1054 */
1055 void
1056 SALOME_Actor
1057 ::SetPreHighlightProperty(vtkProperty* theProperty) 
1058 {
1059   myPreHighlightActor->SetProperty(theProperty);
1060 }
1061
1062 /*!
1063   To set up a highlight property (initialized by SVTK_Renderer::AddActor)
1064 */
1065 void
1066 SALOME_Actor
1067 ::SetHighlightProperty(vtkProperty* theProperty) 
1068 {
1069   myHighlightActor->SetProperty(theProperty);
1070 }
1071
1072 /*!
1073   Set standard point marker
1074   \param theMarkerType type of the marker
1075   \param theMarkerScale scale of the marker
1076 */
1077 void
1078 SALOME_Actor
1079 ::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
1080 {
1081   myPreHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
1082   myHighlightActor->SetMarkerStd( theMarkerType, theMarkerScale );
1083 }
1084
1085 /*!
1086   Set custom point marker
1087   \param theMarkerId id of the marker texture
1088   \param theMarkerTexture marker texture
1089 */
1090 void
1091 SALOME_Actor
1092 ::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
1093 {
1094   myPreHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
1095   myHighlightActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
1096 }
1097
1098 /*!
1099   Get type of the point marker
1100   \return type of the point marker
1101 */
1102 VTK::MarkerType
1103 SALOME_Actor
1104 ::GetMarkerType()
1105 {
1106   return myPreHighlightActor->GetMarkerType();
1107 }
1108
1109 /*!
1110   Get scale of the point marker
1111   \return scale of the point marker
1112 */
1113 VTK::MarkerScale
1114 SALOME_Actor
1115 ::GetMarkerScale()
1116 {
1117   return myPreHighlightActor->GetMarkerScale();
1118 }
1119
1120 /*!
1121   Get texture identifier of the point marker
1122   \return texture identifier of the point marker
1123  */
1124 int
1125 SALOME_Actor
1126 ::GetMarkerTexture()
1127 {
1128   return myPreHighlightActor->GetMarkerTexture();
1129 }