Salome HOME
Merge from BR_PORTING_VTK6 01/03/2013
[modules/visu.git] / src / OBJECT / VISU_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 //  VISU OBJECT : interactive object for VISU entities implementation
24 //  File   :
25 //  Author :
26 //  Module : VISU
27 //
28 #include "VISU_Actor.h"
29
30 #include "VISU_ActorFactory.h"
31 #include "VISU_PickingSettings.h"
32 #include "VISU_GaussPtsDeviceActor.h"
33 #include "VISU_SelectVisiblePoints.h"
34
35 #include "VISU_PipeLine.hxx"
36 #include "VISU_UsedPointsFilter.hxx"
37
38 #include "SVTK_Actor.h"
39 #include "SVTK_Event.h"
40
41 #include "VTKViewer_CellCenters.h"
42 #include "VTKViewer_FramedTextActor.h"
43 #include "VTKViewer_ShrinkFilter.h"
44 #include "VTKViewer_GeometryFilter.h"
45
46 #include "SALOME_InteractiveObject.hxx"
47
48 #include "SUIT_Session.h"
49 #include "SUIT_ResourceMgr.h"
50
51 #include <stdexcept>
52 #include <sstream>
53 #include <cmath> // to use std::abs( int )
54
55 // VTK Includes
56 #include <vtkProperty.h>
57 #include <vtkSmartPointer.h>
58 #include <vtkTextMapper.h>
59 #include <vtkTextActor.h>
60 #include <vtkProperty2D.h>
61 #include <vtkRenderer.h>
62 #include <vtkRenderWindow.h>
63 #include <vtkCellPicker.h>
64 #include <vtkCell.h>
65 #include <vtkPointPicker.h>
66 #include <vtkPoints.h>
67 #include <vtkInteractorStyle.h>
68 #include <vtkDataSet.h>
69 #include <vtkPolyData.h>
70 #include <vtkUnstructuredGrid.h>
71 #include <vtkPassThroughFilter.h>
72 #include <vtkFeatureEdges.h>
73 #include <vtkActor2D.h>
74 #include <vtkMaskPoints.h>
75 #include <vtkLabeledDataMapper.h>
76 #include <vtkTextProperty.h>
77 #include <vtkProperty2D.h>
78
79 #include <vtkShrinkFilter.h>
80 #include <vtkShrinkPolyData.h>
81
82 #include <vtkGeometryFilter.h>
83 #include <vtkObjectFactory.h>
84
85 #include <vtkCallbackCommand.h>
86 #include <vtkCamera.h>
87 #include <vtkRenderWindowInteractor.h>
88
89 #include <boost/bind.hpp>
90
91 #include "utilities.h"
92
93 #include "VISU_PipeLineUtils.hxx"
94
95 using namespace std;
96
97 static int MYVTKDEBUG = 0;
98
99 #ifdef _DEBUG_
100 static int MYDEBUG = 0;
101 #else
102 static int MYDEBUG = 0;
103 #endif
104
105 //#define ENABLE_ANNOTATION
106
107 //----------------------------------------------------------------------------
108 //vtkStandardNewMacro(VISU_Actor);
109
110 //----------------------------------------------------------------------------
111 VISU_Actor
112 ::VISU_Actor():
113   myEventCallbackCommand(vtkCallbackCommand::New()),
114   myPriority(0.0),
115   myIsVTKMapping(false),
116   myPrs3d(NULL),
117   myIsShrunk(false),
118   myIsShrinkable(false),
119   myShrinkFilter(VTKViewer_ShrinkFilter::New()),
120   myAnnotationMapper(vtkTextMapper::New()),
121 #if (VTK_XVERSION < 0x050100)
122   myAnnotationActor(vtkTextActor::New()),
123 #else
124   myAnnotationActor(vtkActor2D::New()),
125 #endif
126   myTextActor(VTKViewer_FramedTextActor::New()),
127   myIsFeatureEdgesAllowed(false),
128   myIsFeatureEdgesEnabled(false),
129   myFeatureEdges(vtkFeatureEdges::New()),
130   myLastSelectionMode(ActorSelection),
131   myIsSubElementsHighlighted(false)
132 {
133   if(MYDEBUG) MESSAGE("VISU_Actor::VISU_Actor - this = "<<this);
134
135   myShrinkFilter->Delete();
136
137   myStoreMapping = true;
138
139   myShrinkFilter->SetStoreMapping(true);
140
141   myAnnotationMapper->Delete();
142   myAnnotationActor->vtkActor2D::SetMapper(myAnnotationMapper.GetPointer()); // OUV_PORTING: to check
143
144   myAnnotationActor->Delete();
145   myAnnotationActor->SetVisibility(0);
146
147   myTextActor->Delete();
148   myTextActor->SetVisibility(false);
149   myTextActor->SetPickable(false);
150
151   myFeatureEdges->Delete();
152
153   myEventCallbackCommand->Delete();
154   myEventCallbackCommand->SetClientData(this);
155   myEventCallbackCommand->SetCallback(VISU_Actor::ProcessEvents);
156
157   if( VISU_PickingSettings* aPickingSettings = VISU_PickingSettings::Get() )
158     aPickingSettings->AddObserver(VISU::UpdatePickingSettingsEvent,
159                                   myEventCallbackCommand.GetPointer(),
160                                   myPriority);
161
162   //Definition of values labeling pipeline
163
164   myValLblDataSet = vtkUnstructuredGrid::New();
165
166   myValCellCenters = VTKViewer_CellCenters::New();
167   myValCellCenters->SetInputData(myValLblDataSet);
168
169   myValUsedPoints = VISU_UsedPointsFilter::New();
170   myValUsedPoints->SetInputData(myValLblDataSet);
171
172   myValMaskPoints = vtkMaskPoints::New();
173   myValMaskPoints->SetInputConnection(myValCellCenters->GetOutputPort());
174   myValMaskPoints->SetOnRatio(1);
175
176   myValSelectVisiblePoints = VISU_SelectVisiblePoints::New();
177   myValSelectVisiblePoints->SetInputConnection(myValMaskPoints->GetOutputPort());
178   myValSelectVisiblePoints->SelectInvisibleOff();
179   myValSelectVisiblePoints->SetTolerance(0.1);
180
181   char aFormat[16] = "%g";
182   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
183   if (aResourceMgr) {
184     // san: precision can be negative - this is used by double spin boxes
185     int aFloatingPrec = std::abs( aResourceMgr->integerValue("VISU", "visual_data_precision", 6) );
186     sprintf(aFormat, "%%.%dg", aFloatingPrec);
187     //cout << "$$$ aFormat = " << aFormat << endl;
188   }
189
190   myValLabeledDataMapper = vtkLabeledDataMapper::New();
191   myValLabeledDataMapper->SetInputConnection(myValSelectVisiblePoints->GetOutputPort());
192   //myValLabeledDataMapper->SetLabelFormat("%g");
193   //myValLabeledDataMapper->SetLabelFormat("%.20g");
194   myValLabeledDataMapper->SetLabelFormat(aFormat);
195   myValLabeledDataMapper->SetLabelModeToLabelScalars();
196
197   vtkTextProperty* aClsTextProp = vtkTextProperty::New();
198   aClsTextProp->SetFontFamilyToTimes();
199   static int aCellsFontSize = 12;
200   aClsTextProp->SetFontSize(aCellsFontSize);
201   aClsTextProp->SetBold(1);
202   aClsTextProp->SetItalic(0);
203   aClsTextProp->SetShadow(0);
204   myValLabeledDataMapper->SetLabelTextProperty(aClsTextProp);
205   aClsTextProp->Delete();
206
207   myIsValLabeled = false;
208
209   myValLabels = vtkActor2D::New();
210   myValLabels->SetMapper(myValLabeledDataMapper);
211   myValLabels->GetProperty()->SetColor(0,1,0);
212   myValLabels->SetVisibility( myIsValLabeled );
213
214   // to allow modification of the reference coordinate in redefined SetPosition() methods
215   vtkCoordinate* aValLabelsCoordinate = vtkCoordinate::New();
216   myValLabels->GetPositionCoordinate()->SetReferenceCoordinate( aValLabelsCoordinate );
217   aValLabelsCoordinate->Delete();
218 }
219
220 //----------------------------------------------------------------------------
221 void
222 VISU_Actor
223 ::DeepCopy(VISU_Actor *theActor)
224 {
225   highlight(theActor->isHighlighted());
226   SetRepresentation(theActor->GetRepresentation());
227   SetShrinkable(theActor->IsShrunkable());
228   SetShrinkFactor(theActor->GetShrinkFactor());
229   if(theActor->IsShrunk())
230     SetShrink();
231   else
232     UnShrink();
233
234   SetFeatureEdgesAllowed(theActor->IsFeatureEdgesAllowed());
235   SetFeatureEdgesEnabled(theActor->IsFeatureEdgesEnabled());
236   SetFeatureEdgesAngle(theActor->GetFeatureEdgesAngle());
237   bool aFeatureEdges = false, aBoundaryEdges = false, aManifoldEdges = false, aNonManifoldEdges = false;
238   theActor->GetFeatureEdgesFlags( aFeatureEdges, aBoundaryEdges, aManifoldEdges, aNonManifoldEdges );
239   SetFeatureEdgesFlags( aFeatureEdges, aBoundaryEdges, aManifoldEdges, aNonManifoldEdges );
240   SetFeatureEdgesColoring(theActor->GetFeatureEdgesColoring());
241
242   SetOpacity(theActor->GetOpacity());
243   SetLineWidth(theActor->GetLineWidth());
244   SetPosition(theActor->GetPosition());
245 }
246
247
248 //----------------------------------------------------------------------------
249 void
250 VISU_Actor
251 ::ShallowCopyPL(VISU_PipeLine* thePipeLine)
252 {
253   myPipeLine->ShallowCopy(thePipeLine, true);
254   GetMapper()->Update();
255 }
256
257 //----------------------------------------------------------------------------
258 VISU_Actor
259 ::~VISU_Actor()
260 {
261   // Deleting of values labeling pipeline
262   myValLblDataSet->Delete();
263   myValLabeledDataMapper->RemoveAllInputs();
264   myValLabeledDataMapper->Delete();
265   myValSelectVisiblePoints->Delete();
266   myValMaskPoints->Delete();
267   myValUsedPoints->Delete();
268   myValCellCenters->Delete();
269   myValLabels->Delete();
270
271   if(MYDEBUG) MESSAGE("~VISU_Actor() - this = "<<this);
272   Superclass::SetProperty(NULL);
273   SetDebug(MYVTKDEBUG);
274 }
275
276 //----------------------------------------------------------------------------
277 void
278 VISU_Actor
279 ::setIO(const Handle(SALOME_InteractiveObject)& theIO)
280 {
281   Superclass::setIO(theIO);
282   myName = theIO->getName();
283 }
284
285 //----------------------------------------------------------------------------
286 void
287 VISU_Actor
288 ::SetPrs3d(VISU::Prs3d_i* thePrs3d)
289 {
290   myPrs3d = thePrs3d;
291 }
292
293 VISU::Prs3d_i*
294 VISU_Actor
295 ::GetPrs3d()
296 {
297   return myPrs3d;
298 }
299
300 //----------------------------------------------------------------------------
301 void
302 VISU_Actor
303 ::SetPipeLine(VISU_PipeLine* thePipeLine)
304 {
305   myPipeLine = thePipeLine;
306   if(thePipeLine){
307     if(vtkMapper *aMapper = myPipeLine->GetMapper()){
308       if(vtkDataSet *aDataSet = aMapper->GetInput()){
309         SetShrinkable(thePipeLine->IsShrinkable());
310         SetFeatureEdgesAllowed(thePipeLine->IsFeatureEdgesAllowed());
311         SetMapperInput(aDataSet);
312       }
313     }
314   }
315   this->Modified();
316 }
317
318 VISU_PipeLine*
319 VISU_Actor
320 ::GetPipeLine()
321 {
322   return myPipeLine.GetPointer();
323 }
324
325 VISU_PipeLine*
326 VISU_Actor
327 ::GetCurrentPL()
328 {
329   return GetPipeLine();
330 }
331
332
333 //----------------------------------------------------------------------------
334 void
335 VISU_Actor
336 ::SetRepresentation(int theMode)
337 {
338   Superclass::SetRepresentation(theMode);
339   if(myRepresentation == VTK_POINTS)
340   {
341     UnShrink();
342   }
343   SetFeatureEdgesEnabled( theMode == VTKViewer::Representation::FeatureEdges );
344 }
345
346
347 //----------------------------------------------------------------------------
348 void
349 VISU_Actor
350 ::SetShrink()
351 {
352   if(!myIsShrinkable)
353     return;
354   if(vtkAlgorithmOutput* aDataSet = myPassFilter[0]->GetOutputPort()){
355     myShrinkFilter->SetInputConnection(aDataSet);
356     myPassFilter[1]->SetInputConnection(myShrinkFilter->GetOutputPort());
357     myIsShrunk = true;
358   }
359 }
360
361 void
362 VISU_Actor
363 ::UnShrink()
364 {
365   if(!myIsShrunk)
366     return;
367   if(vtkAlgorithmOutput* aDataSet = myPassFilter[0]->GetOutputPort()){
368     myPassFilter[1]->SetInputConnection(aDataSet);
369     myPassFilter[1]->Modified();
370     myIsShrunk = false;
371     Modified();
372   }
373 }
374
375 bool
376 VISU_Actor
377 ::IsShrunk()
378 {
379   return myIsShrunk;
380 }
381
382 void
383 VISU_Actor
384 ::SetShrinkable(bool theIsShrinkable)
385 {
386   myIsShrinkable = theIsShrinkable;
387 }
388
389 bool
390 VISU_Actor
391 ::IsShrunkable()
392 {
393   return myIsShrinkable;
394 }
395
396 void
397 VISU_Actor
398 ::SetShrinkFactor(double theValue)
399 {
400   myShrinkFilter->SetShrinkFactor(theValue);
401   Modified();
402 }
403
404 double
405 VISU_Actor
406 ::GetShrinkFactor()
407 {
408   return myShrinkFilter->GetShrinkFactor();
409 }
410
411
412 //----------------------------------------------------------------------------
413 bool
414 VISU_Actor
415 ::IsFeatureEdgesAllowed()
416 {
417   return myIsFeatureEdgesAllowed;
418 }
419
420 void
421 VISU_Actor
422 ::SetFeatureEdgesAllowed(bool theIsFeatureEdgesAllowed)
423 {
424   myIsFeatureEdgesAllowed = theIsFeatureEdgesAllowed;
425 }
426
427 bool
428 VISU_Actor
429 ::IsFeatureEdgesEnabled()
430 {
431   return myIsFeatureEdgesEnabled;
432 }
433
434 void
435 VISU_Actor
436 ::SetFeatureEdgesEnabled(bool theIsFeatureEdgesEnabled)
437 {
438   if ( !myIsFeatureEdgesAllowed || myIsFeatureEdgesEnabled == theIsFeatureEdgesEnabled )
439     return;
440
441   //if ( vtkPolyData* aPolyData = myPassFilter[ 2 ]->GetPolyDataOutput() )
442   if ( vtkAlgorithmOutput* aPolyData = myPassFilter[ 2 ]->GetOutputPort() ) // OUV_PORTING: to check
443   {
444     if( theIsFeatureEdgesEnabled )
445     {
446       myFeatureEdges->SetInputConnection( aPolyData );
447       myPassFilter[ 3 ]->SetInputConnection( myFeatureEdges->GetOutputPort() );
448       myIsFeatureEdgesEnabled = true;
449     }
450     else
451     {
452       myPassFilter[3]->SetInputConnection( aPolyData );
453       myPassFilter[3]->Modified();
454       myIsFeatureEdgesEnabled = false;
455       Modified();
456     }
457     myIsFeatureEdgesEnabled = theIsFeatureEdgesEnabled;
458   }
459 }
460
461 double
462 VISU_Actor
463 ::GetFeatureEdgesAngle()
464 {
465   return myFeatureEdges->GetFeatureAngle();
466 }
467
468 void
469 VISU_Actor
470 ::SetFeatureEdgesAngle(double theValue)
471 {
472   myFeatureEdges->SetFeatureAngle(theValue);
473   Modified();
474 }
475
476 void
477 VISU_Actor
478 ::GetFeatureEdgesFlags(bool& theIsFeatureEdges,
479                        bool& theIsBoundaryEdges,
480                        bool& theIsManifoldEdges,
481                        bool& theIsNonManifoldEdges)
482 {
483   theIsFeatureEdges = myFeatureEdges->GetFeatureEdges();
484   theIsBoundaryEdges = myFeatureEdges->GetBoundaryEdges();
485   theIsManifoldEdges = myFeatureEdges->GetManifoldEdges();
486   theIsNonManifoldEdges = myFeatureEdges->GetNonManifoldEdges();
487 }
488
489 void
490 VISU_Actor
491 ::SetFeatureEdgesFlags(bool theIsFeatureEdges,
492                        bool theIsBoundaryEdges,
493                        bool theIsManifoldEdges,
494                        bool theIsNonManifoldEdges)
495 {
496   myFeatureEdges->SetFeatureEdges(theIsFeatureEdges);
497   myFeatureEdges->SetBoundaryEdges(theIsBoundaryEdges);
498   myFeatureEdges->SetManifoldEdges(theIsManifoldEdges);
499   myFeatureEdges->SetNonManifoldEdges(theIsNonManifoldEdges);
500   Modified();
501 }
502
503 bool
504 VISU_Actor
505 ::GetFeatureEdgesColoring()
506 {
507   return myFeatureEdges->GetColoring();
508 }
509
510 void
511 VISU_Actor
512 ::SetFeatureEdgesColoring(bool theIsColoring)
513 {
514   myFeatureEdges->SetColoring(theIsColoring);
515   Modified();
516 }
517
518 //----------------------------------------------------------------------------
519 void
520 VISU_Actor
521 ::SetOpacity(double theValue)
522 {
523   GetProperty()->SetOpacity(theValue);
524 }
525
526 double
527 VISU_Actor
528 ::GetOpacity()
529 {
530   return GetProperty()->GetOpacity();
531 }
532
533 void
534 VISU_Actor
535 ::SetLineWidth(double theLineWidth)
536 {
537   GetProperty()->SetLineWidth(theLineWidth);
538 }
539
540 double
541 VISU_Actor
542 ::GetLineWidth()
543 {
544   return GetProperty()->GetLineWidth();
545 }
546
547 //==================================================================
548 // function: AddToRender
549 // purpose :
550 //==================================================================
551 void
552 VISU_Actor
553 ::AddToRender(vtkRenderer* theRenderer)
554 {
555   Superclass::AddToRender(theRenderer);
556   theRenderer->AddActor(myAnnotationActor.GetPointer());
557   theRenderer->AddActor(myTextActor.GetPointer());
558
559   myValSelectVisiblePoints->SetRenderer( theRenderer );
560   theRenderer->AddActor2D( myValLabels );
561
562 }
563
564 //==================================================================
565 // function: RemoveFromRender
566 // purpose :
567 //==================================================================
568 void
569 VISU_Actor
570 ::RemoveFromRender(vtkRenderer* theRenderer)
571 {
572   theRenderer->RemoveActor(myAnnotationActor.GetPointer());
573   theRenderer->RemoveActor(myTextActor.GetPointer());
574   theRenderer->RemoveActor(myValLabels);
575   Superclass::RemoveFromRender(theRenderer);
576   myDestroySignal(this);
577 }
578
579 //----------------------------------------------------------------------------
580 void
581 VISU_Actor
582 ::SetVisibility(int theMode)
583 {
584   Superclass::SetVisibility( theMode );
585   myValLabels->SetVisibility( myIsValLabeled && theMode );
586
587   // Moved from VISU_GaussPtsAct::SetVisibility() (due to IPAL21159)
588   Highlight(isHighlighted());
589 }
590 //----------------------------------------------------------------------------
591   //! Gets know whether the actor should be displayed or not
592 bool
593 VISU_Actor
594 ::ShouldBeDisplayed()
595 {
596   return GetFactory()->GetActiveState();
597 }
598
599 //----------------------------------------------------------------------------
600 void
601 VISU_Actor
602 ::SetPosition( double thePosition[3] )
603 {
604   Superclass::SetPosition( thePosition );
605   if( vtkCoordinate* aCoord = myValLabels->GetPositionCoordinate()->GetReferenceCoordinate() )
606     aCoord->SetValue( thePosition );
607   myValSelectVisiblePoints->SetOffset( thePosition );
608 }
609
610 //----------------------------------------------------------------------------
611 void
612 VISU_Actor
613 ::SetPosition( double theX, double theY, double theZ )
614 {
615   Superclass::SetPosition( theX, theY, theZ );
616   if( vtkCoordinate* aCoord = myValLabels->GetPositionCoordinate()->GetReferenceCoordinate() )
617     aCoord->SetValue( theX, theY, theZ );
618   myValSelectVisiblePoints->SetOffset( theX, theY, theZ );
619 }
620
621 //----------------------------------------------------------------------------
622 void
623 VISU_Actor
624 ::SetVTKMapping(bool theIsVTKMapping)
625 {
626   myIsVTKMapping = theIsVTKMapping;
627 }
628
629 bool
630 VISU_Actor
631 ::IsVTKMapping() const
632 {
633   return myIsVTKMapping;
634 }
635
636 //----------------------------------------------------------------------------
637 vtkDataSet*
638 VISU_Actor
639 ::GetInput()
640 {
641   if(myIsVTKMapping)
642     return Superclass::GetInput();
643
644   return GetCurrentPL()->GetOutput();
645 }
646
647 //----------------------------------------------------------------------------
648 unsigned long int
649 VISU_Actor
650 ::GetMemorySize()
651 {
652   static double ERR_SIZE_CALC = 1.00;
653   vtkDataSet* aDataSet = GetMapper()->GetInput();
654   unsigned long int aSize = size_t(aDataSet->GetActualMemorySize() * 1024 * ERR_SIZE_CALC);
655
656   aDataSet = myGeomFilter->GetOutput();
657   aSize += aDataSet->GetActualMemorySize() * 1024;
658
659   if(IsShrunk()){
660     aDataSet = myShrinkFilter->GetOutput();
661     aSize += aDataSet->GetActualMemorySize() * 1024;
662   }
663
664   if(IsFeatureEdgesEnabled()){
665     vtkPolyData* aPolyData = myFeatureEdges->GetOutput();
666     aSize += aPolyData->GetActualMemorySize() * 1024;
667   }
668
669   return aSize;
670 }
671
672 //----------------------------------------------------------------------------
673 vtkIdType
674 VISU_Actor
675 ::GetNodeObjId(vtkIdType theID)
676 {
677   if(myIsVTKMapping)
678     return Superclass::GetNodeObjId(theID);
679
680   return VISU::GetNodeObjID(GetMapper()->GetInput(), theID);
681 }
682
683 vtkIdType
684 VISU_Actor
685 ::GetNodeVTKID(vtkIdType theID)
686 {
687   if(myIsVTKMapping)
688     return theID;
689
690   return VISU::GetNodeVTKID(GetMapper()->GetInput(), theID);
691 }
692
693 double*
694 VISU_Actor
695 ::GetNodeCoord(vtkIdType theObjID)
696 {
697   if(myIsVTKMapping)
698     return Superclass::GetNodeCoord(theObjID);
699
700   return VISU::GetNodeCoord(GetInput(), theObjID);
701 }
702
703
704 //----------------------------------------------------------------------------
705 vtkIdType
706 VISU_Actor
707 ::GetElemObjId(vtkIdType theID)
708 {
709   if(myIsVTKMapping)
710     return Superclass::GetElemObjId(theID);
711
712   return VISU::GetElemObjID(GetMapper()->GetInput(), theID);
713 }
714
715 vtkIdType
716 VISU_Actor
717 ::GetElemVTKID(vtkIdType theID)
718 {
719   if(myIsVTKMapping)
720     return theID;
721
722   return VISU::GetElemVTKID(GetMapper()->GetInput(), theID);
723 }
724
725 vtkCell*
726 VISU_Actor
727 ::GetElemCell(vtkIdType theObjID)
728 {
729   if(myIsVTKMapping)
730     return Superclass::GetElemCell(theObjID);
731
732   return VISU::GetElemCell(GetInput(), theObjID);
733 }
734
735
736 //----------------------------------------------------------------------------
737 bool
738 VISU_Actor
739 ::isSubElementsHighlighted()
740 {
741   return myIsSubElementsHighlighted;
742 }
743
744
745 //----------------------------------------------------------------------------
746 inline
747 void
748 ChangeZoom(double theZoomFactor,
749            vtkRenderer* theRenderer,
750            vtkIdType theInitialHasIndex,
751            vtkIdType theCurrentHasIndex)
752 {
753   //printf( "VISU_Actor::ChangeZoom( %d, %d )", theInitialHasIndex, theCurrentHasIndex );
754   if(theInitialHasIndex + theCurrentHasIndex == 1){
755     vtkCamera *aCamera = theRenderer->GetActiveCamera();
756
757     double aScale = aCamera->GetParallelScale();
758     if ( !theInitialHasIndex && theCurrentHasIndex ) {
759       //printf( " : +%f", theZoomFactor );
760       aCamera->SetParallelScale( aScale / theZoomFactor );
761     }
762     else {
763       //printf( " : -%f", theZoomFactor );
764       aCamera->SetParallelScale( aScale * theZoomFactor );
765     }
766   }
767   //printf( "\n" );
768 }
769
770 /*!
771   Updates visibility of the highlight devices
772 */
773 void
774 VISU_Actor
775 ::highlight(bool theIsHighlight)
776 {
777   VISU_PickingSettings* aPickingSettings = VISU_PickingSettings::Get();
778
779   bool aShowTextActor = aPickingSettings->GetInfoWindowEnabled();
780   if( theIsHighlight && mySelectionMode != myLastSelectionMode )
781   {
782     if( mySelectionMode == ActorSelection )
783       ResetTextActor();
784     myLastSelectionMode = mySelectionMode;
785   }
786
787   myTextActor->SetVisibility( GetVisibility() && theIsHighlight && aShowTextActor &&
788                               ( mySelectionMode == ActorSelection || isSubElementsHighlighted() ) );
789
790   bool anInitialHasIndex = isHighlighted();
791   bool aCurrentHasIndex = theIsHighlight;
792
793   if( !theIsHighlight && mySelectionMode == ActorSelection && isSubElementsHighlighted() )
794   {
795     myIsSubElementsHighlighted = false;
796
797     // Zoom
798     if( GetVisibility() && aPickingSettings->GetCameraMovementEnabled() )
799     {
800       double aZoomFactor = aPickingSettings->GetZoomFactor();
801       ChangeZoom(aZoomFactor,
802                  GetRenderer(),
803                  anInitialHasIndex,
804                  aCurrentHasIndex);
805     }
806   }
807
808   Superclass::highlight(theIsHighlight);
809 }
810
811 /*!
812   To process prehighlight (called from SVTK_InteractorStyle)
813 */
814 bool
815 VISU_Actor
816 ::PreHighlight(vtkInteractorStyle* theInteractorStyle,
817                SVTK_SelectionEvent* theSelectionEvent,
818                bool theIsHighlight)
819 {
820   bool aRet = Superclass::PreHighlight(theInteractorStyle,
821                                        theSelectionEvent,
822                                        theIsHighlight);
823 #ifndef ENABLE_ANNOTATION
824   return aRet;
825 #endif
826   //
827   myAnnotationActor->SetVisibility(0);
828   if(theIsHighlight){
829     switch(mySelectionMode){
830     case CellSelection:{
831       vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
832       myCellPicker->Pick(theSelectionEvent->myX,
833                          theSelectionEvent->myY,
834                          0.0,
835                          aRenderer);
836
837       if(myCellPicker->GetActor() != this)
838         return false;
839
840       vtkIdType aVTKId = myCellPicker->GetCellId();
841       if(aVTKId >= 0  && mySelector->IsValid(this,aVTKId,true) && hasIO()){
842         vtkIdType anObjId = GetElemObjId(aVTKId);
843         if(vtkCell* aCell = GetElemCell(anObjId)){
844           vtkPoints* aPts = aCell->GetPoints();
845           if(int aNbPts = aCell->GetNumberOfPoints()){
846             double aCoord[3] = {0.0, 0.0, 0.0};
847             for(int i = 0; i < aNbPts; i++){
848               double *aPntCoord = aPts->GetPoint(i);
849               aCoord[0] += aPntCoord[0];
850               aCoord[1] += aPntCoord[1];
851               aCoord[2] += aPntCoord[2];
852             }
853             // Display coordinates
854             double aWorldCoord[4] = {aCoord[0]/aNbPts, aCoord[1]/aNbPts, aCoord[2]/aNbPts, 1.0};
855             aRenderer->SetWorldPoint(aWorldCoord);
856             aRenderer->WorldToDisplay();
857             double aSelectionPoint[3];
858             aRenderer->GetDisplayPoint(aSelectionPoint);
859             myAnnotationActor->SetPosition(aSelectionPoint);
860             //
861             // To prepare the annotation text
862             std::ostringstream aStr;
863             aStr<<"Cell ID: "<< anObjId;
864             std::string aString = aStr.str();
865             myAnnotationMapper->SetInput(aString.c_str());
866
867             myAnnotationActor->SetVisibility(1);
868             return true;
869           }
870         }
871       }
872       break;
873     }
874     case NodeSelection:{
875       vtkRenderer* aRenderer = theInteractorStyle->GetCurrentRenderer();
876       myPointPicker->Pick(theSelectionEvent->myX,
877                           theSelectionEvent->myY,
878                           0.0,
879                           aRenderer);
880
881       if(myPointPicker->GetActor() != this)
882         return false;
883
884       vtkIdType aVtkId = myPointPicker->GetPointId();
885       if(aVtkId >= 0  && mySelector->IsValid(this,aVtkId,true) && hasIO()){
886         vtkIdType anObjId = GetNodeObjId( aVtkId );
887         if(double* aCoord = GetNodeCoord(anObjId)){
888           // Display coordinates
889           double aWorldCoord[4] = {aCoord[0], aCoord[1], aCoord[2], 1.0};
890           aRenderer->SetWorldPoint(aWorldCoord);
891           aRenderer->WorldToDisplay();
892           double aSelectionPoint[3];
893           aRenderer->GetDisplayPoint(aSelectionPoint);
894           myAnnotationActor->SetPosition(aSelectionPoint);
895           //
896           // To prepare the annotation text
897           std::ostringstream aStr;
898           aStr<<"Node ID: "<< anObjId;
899           std::string aString = aStr.str();
900           myAnnotationMapper->SetInput(aString.c_str());
901
902           myAnnotationActor->SetVisibility(1);
903           return true;
904         }
905       }
906       break;
907     }
908     case EdgeOfCellSelection:
909       break;
910     default:
911       break;
912     }
913   }
914
915   return aRet;
916 }
917
918 void VISU_Actor::RemoveAllClippingPlanes()
919 {
920 }
921
922 vtkIdType VISU_Actor::GetNumberOfClippingPlanes()
923 {
924   return 0;
925 }
926
927 bool VISU_Actor::AddClippingPlane(vtkPlane* thePlane)
928 {
929   return false;
930 }
931
932 vtkPlane* VISU_Actor::GetClippingPlane(vtkIdType theID)
933 {
934   return NULL;
935 }
936
937 vtkImplicitFunctionCollection* VISU_Actor::GetClippingPlanes()
938 {
939   return NULL;
940 }
941
942 //----------------------------------------------------------------------------
943 template<class TData> std::string getScalar(TData* theData, int theId)
944 {
945   std::ostringstream aStr;
946   if (vtkDataArray *aScalar = theData->GetScalars()){
947     double aVal = aScalar->GetTuple1(theId);
948     aStr << "\nScalar: " << aVal;
949   }
950   return aStr.str();
951 }
952
953 template<class TData> std::string getVector(TData* theData, int theId)
954 {
955   std::ostringstream aStr;
956   if (vtkDataArray *aVector = theData->GetVectors()) {
957     double *aVal = aVector->GetTuple3(theId);
958     aStr << "\nVector: " << "{" << aVal[0] << "; " << aVal[1] << "; " << aVal[2] << "}";
959   }
960   return aStr.str();
961 }
962
963 /*!
964   To process highlight (called from SVTK_InteractorStyle)
965 */
966 bool
967 VISU_Actor
968 ::Highlight(vtkInteractorStyle* theInteractorStyle,
969             SVTK_SelectionEvent* theSelectionEvent,
970             bool theIsHighlight)
971 {
972   return Superclass::Highlight(theInteractorStyle,
973                                theSelectionEvent,
974                                theIsHighlight);
975 }
976
977 //-------------------------------------------------------------------------
978 void
979 VISU_Actor
980 ::Highlight(bool theIsHighlight)
981 {
982   Superclass::Highlight(theIsHighlight);
983
984   VISU_PickingSettings* aPickingSettings = VISU_PickingSettings::Get();
985
986   bool anInitialHasIndex = isSubElementsHighlighted() && mySelectionMode != ActorSelection;
987
988   TColStd_IndexedMapOfInteger aMapIndex;
989   mySelector->GetIndex( getIO(), aMapIndex );
990   bool aCurrentHasIndex = aMapIndex.Extent() == 1;
991
992   myIsSubElementsHighlighted = aCurrentHasIndex;
993
994   bool aFlyTo = false;
995   double aFlyToCoord[3] = { 0.0, 0.0, 0.0 };
996   vtkRenderer *aRenderer = GetRenderer();
997
998   if( theIsHighlight )
999   {
1000     vtkDataSet* aDataSet = GetMapper()->GetInput();
1001     switch(mySelectionMode)
1002     {
1003       case ActorSelection:
1004       {
1005         ResetTextActor();
1006         break;
1007       }
1008       case CellSelection:
1009       {
1010         if( !aCurrentHasIndex )
1011         {
1012           myTextActor->SetVisibility(false);
1013           break;
1014         }
1015
1016         int anObjId = aMapIndex(1);
1017         vtkCellData* aCellData = aDataSet->GetCellData();
1018         if(vtkCell* aCell = GetElemCell(anObjId)){
1019           vtkPoints* aPts = aCell->GetPoints();
1020           if(int aNbPts = aCell->GetNumberOfPoints()){
1021             double aCoord[3] = {0.0, 0.0, 0.0};
1022             for(int i = 0; i < aNbPts; i++){
1023               double *aPntCoord = aPts->GetPoint(i);
1024               aCoord[0] += aPntCoord[0];
1025               aCoord[1] += aPntCoord[1];
1026               aCoord[2] += aPntCoord[2];
1027             }
1028
1029             aFlyTo = true;
1030             aFlyToCoord[0] = aCoord[0] / aNbPts;
1031             aFlyToCoord[1] = aCoord[1] / aNbPts;
1032             aFlyToCoord[2] = aCoord[2] / aNbPts;
1033
1034             double aWorldCoord[4] = {aCoord[0]/aNbPts, aCoord[1]/aNbPts, aCoord[2]/aNbPts, 1.0};
1035             aRenderer->SetWorldPoint(aWorldCoord);
1036             aRenderer->WorldToDisplay();
1037             double aSelectionPoint[3];
1038             aRenderer->GetDisplayPoint(aSelectionPoint);
1039             myTextActor->SetPosition(aSelectionPoint);
1040             myTextActor->SetModePosition(aPickingSettings->GetInfoWindowPosition());
1041             myTextActor->SetTransparency(aPickingSettings->GetInfoWindowTransparency());
1042             myTextActor->SetWorldPoint(aWorldCoord);
1043
1044             std::ostringstream aStr;
1045             aStr << "Cell ID: " << anObjId;
1046
1047             vtkCell* aCell = GetElemCell(anObjId);
1048             int aVTKID = GetElemVTKID(anObjId);
1049             if (aCell) {
1050               int aNbOfPoints = aCell->GetNumberOfPoints();
1051               if ( aNbOfPoints > 0 ) {
1052                 aStr << getScalar(aCellData, aVTKID);
1053                 aStr << getVector(aCellData, aVTKID);
1054               }
1055             }
1056
1057             std::string aString = aStr.str();
1058             myTextActor->SetText(aString.c_str());
1059           }
1060         }
1061         break;
1062       }
1063       case NodeSelection:
1064       {
1065         if( !aCurrentHasIndex )
1066         {
1067           myTextActor->SetVisibility(false);
1068           break;
1069         }
1070
1071         int anObjId = aMapIndex(1);
1072         vtkPointData* aPntData = aDataSet->GetPointData();
1073         if(double* aCoord = GetNodeCoord(anObjId)){
1074           aFlyTo = true;
1075           aFlyToCoord[0] = aCoord[0];
1076           aFlyToCoord[1] = aCoord[1];
1077           aFlyToCoord[2] = aCoord[2];
1078
1079           double aWorldCoord[4] = {aCoord[0], aCoord[1], aCoord[2], 1.0};
1080           aRenderer->SetWorldPoint(aWorldCoord);
1081           aRenderer->WorldToDisplay();
1082           double aSelectionPoint[3];
1083           aRenderer->GetDisplayPoint(aSelectionPoint);
1084           myTextActor->SetPosition(aSelectionPoint);
1085           myTextActor->SetModePosition(aPickingSettings->GetInfoWindowPosition());
1086           myTextActor->SetTransparency(aPickingSettings->GetInfoWindowTransparency());
1087           myTextActor->SetWorldPoint(aWorldCoord);
1088
1089           std::ostringstream aStr;
1090           aStr << "Point ID: " << anObjId;
1091
1092           int aVTKID = GetNodeVTKID(anObjId);
1093           if(aVTKID >= 0) {
1094             aStr << getScalar(aPntData, aVTKID);
1095             aStr << getVector(aPntData, aVTKID);
1096           }
1097
1098           const VISU::PIDMapper& aMapper = GetPipeLine()->GetIDMapper();
1099           //VISU::TIdTypeVector aVec = aMapper->GetIndexesOfNode(anObjId);
1100           VISU::TStructuredId aVec = aMapper->GetIndexesOfNode(anObjId);
1101
1102           aStr << "\nCoordinates: " << "[";
1103           aStr << aCoord[0];
1104           //if( aVec.size() > 0 )
1105           if (aVec[0] != -1)
1106             aStr << " (" << aVec[0] << ")";
1107           aStr << "; ";
1108
1109           aStr << aCoord[1];
1110           //if( aVec.size() > 1 )
1111           if (aVec[1] != -1)
1112             aStr << " (" << aVec[1] << ")";
1113           aStr << "; ";
1114
1115           aStr << aCoord[2];
1116           //if( aVec.size() > 2 )
1117           if (aVec[2] != -1)
1118             aStr << " (" << aVec[2] << ")";
1119           aStr << "]";
1120
1121           std::string aString = aStr.str();
1122           myTextActor->SetText(aString.c_str());
1123         }
1124         break;
1125       }
1126       case EdgeOfCellSelection:
1127         break;
1128       default:
1129         break;
1130     }
1131   }
1132
1133   // Zoom
1134   if( GetVisibility() && aPickingSettings->GetCameraMovementEnabled() )
1135   {
1136     double aZoomFactor = aPickingSettings->GetZoomFactor();
1137     ChangeZoom(aZoomFactor,
1138                GetRenderer(),
1139                anInitialHasIndex,
1140                aCurrentHasIndex);
1141   }
1142
1143   // FlyTo
1144   if( GetVisibility() && aPickingSettings->GetCameraMovementEnabled() && aFlyTo )
1145   {
1146     vtkRenderWindowInteractor* anInteractor = myInteractor;
1147     double aDollyWas = anInteractor->GetDolly();
1148     int aNumberOfFlyFramesWas = anInteractor->GetNumberOfFlyFrames();
1149
1150     double aPosition[3];
1151     GetPosition( aPosition );
1152     for( int i = 0; i < 3; i++ )
1153       aFlyToCoord[i] += aPosition[i];
1154
1155     anInteractor->SetDolly(0.0);
1156     anInteractor->SetNumberOfFlyFrames(aPickingSettings->GetStepNumber());
1157     anInteractor->FlyTo(aRenderer, aFlyToCoord);
1158     aRenderer->ResetCameraClippingRange();
1159     anInteractor->SetDolly(aDollyWas);
1160     anInteractor->SetNumberOfFlyFrames(aNumberOfFlyFramesWas);
1161     anInteractor->InvokeEvent(SVTK::ChangeRotationPoint, aFlyToCoord);
1162   }
1163 }
1164
1165 //-------------------------------------------------------------------------
1166 void
1167 VISU_Actor
1168 ::ResetTextActor()
1169 {
1170   VISU_PickingSettings* aPickingSettings = VISU_PickingSettings::Get();
1171
1172   double aCoord[6];
1173   GetBounds(aCoord);
1174
1175   double aWorldCoord[4] = { ( aCoord[0] + aCoord[1] ) / 2,
1176                                           ( aCoord[2] + aCoord[3] ) / 2,
1177                                           ( aCoord[4] + aCoord[5] ) / 2, 1.0};
1178   vtkRenderer* aRenderer = GetRenderer();
1179   aRenderer->SetWorldPoint(aWorldCoord);
1180   aRenderer->WorldToDisplay();
1181   double aSelectionPoint[3];
1182   aRenderer->GetDisplayPoint(aSelectionPoint);
1183   myTextActor->SetPosition(aSelectionPoint);
1184   myTextActor->SetModePosition(aPickingSettings->GetInfoWindowPosition());
1185   myTextActor->SetTransparency(aPickingSettings->GetInfoWindowTransparency());
1186   myTextActor->SetWorldPoint(aWorldCoord);
1187
1188   std::ostringstream aStr;
1189   /*
1190   if( const char* aName = getName() )
1191     aStr << aName << "\n";
1192   */
1193   aStr << "Position: " << "[" << aCoord[0] << "; " << aCoord[2] << "; " << aCoord[4] << "]";
1194   aStr << "\nSize: " << "[" <<
1195     fabs(aCoord[1]-aCoord[0]) << "; " <<
1196     fabs(aCoord[3]-aCoord[2]) << "; " <<
1197     fabs(aCoord[5]-aCoord[4]) << "]";
1198
1199   std::string aString = aStr.str();
1200   myTextActor->SetText(aString.c_str());
1201 }
1202
1203 //-------------------------------------------------------------------------
1204 void
1205 VISU_Actor
1206 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
1207                 unsigned long theEvent,
1208                 void* theClientData,
1209                 void* vtkNotUsed(theCallData))
1210 {
1211   if(vtkObject* anObject = reinterpret_cast<vtkObject*>(theClientData))
1212     if(VISU_Actor* self = dynamic_cast<VISU_Actor*>(anObject)) {
1213       if(theEvent == VISU::UpdatePickingSettingsEvent)
1214         self->UpdatePickingSettings();
1215     }
1216 }
1217
1218 //----------------------------------------------------------------------------
1219 void
1220 VISU_Actor
1221 ::UpdatePickingSettings()
1222 {
1223   //printf( "VISU_Actor::UpdatePickingSettings()\n" );
1224   VISU_PickingSettings* aPickingSettings = VISU_PickingSettings::Get();
1225   if( !aPickingSettings )
1226     return;
1227
1228   myTextActor->SetModePosition(aPickingSettings->GetInfoWindowPosition());
1229   myTextActor->SetTransparency(aPickingSettings->GetInfoWindowTransparency());
1230
1231   Highlight(isHighlighted());
1232
1233   Update();
1234 }
1235
1236 // ---------------------------------------------------------------
1237
1238 void VISU_Actor::SetValuesLabeled( const bool theIsValLabeled )
1239 {
1240   vtkDataSet* aGrid = GetValLabelsInput();
1241   if ( !aGrid )
1242     return;
1243
1244   bool isOnPnt = VISU::IsDataOnPoints( aGrid );
1245   bool isOnCell = VISU::IsDataOnCells( aGrid );
1246   if ( !isOnPnt && !isOnCell )
1247   {
1248     // try to specify location of scalars "manually"
1249     vtkCellData* aCData = aGrid->GetCellData();
1250     if ( aCData )
1251     {
1252       vtkDataArray* anArr = aCData->GetScalars();
1253       if ( anArr && anArr->GetNumberOfTuples() )
1254         isOnCell = true;
1255     }
1256
1257     if ( !isOnCell )
1258     {
1259       vtkPointData* aPData = aGrid->GetPointData();
1260       if ( aPData )
1261       {
1262         vtkDataArray* anArr = aPData->GetScalars();
1263         if ( anArr && anArr->GetNumberOfTuples() )
1264           isOnPnt = true;
1265       }
1266     }
1267
1268     if ( !isOnPnt && !isOnCell )
1269     {
1270       myValLabels->SetVisibility( false );
1271       return;
1272     }
1273   }
1274
1275   myIsValLabeled = theIsValLabeled;
1276
1277   if ( myIsValLabeled )
1278   {
1279     vtkDataSet* aDataSet = aGrid;
1280
1281     if ( isOnCell )
1282     {
1283       myValCellCenters->SetInputData( aDataSet );
1284       myValMaskPoints->SetInputConnection( myValCellCenters->GetOutputPort() );
1285     }
1286     else if ( isOnPnt )
1287     {
1288       myValUsedPoints->SetInputData( aDataSet );
1289       myValMaskPoints->SetInputConnection( myValUsedPoints->GetOutputPort() );
1290     }
1291
1292     myValLabels->SetVisibility( GetVisibility() );
1293   }
1294   else
1295     myValLabels->SetVisibility( false );
1296
1297   Modified();
1298 }
1299
1300 //----------------------------------------------------------------------------
1301
1302 bool VISU_Actor::GetValuesLabeled() const
1303 {
1304   return myIsValLabeled;
1305 }
1306
1307 //----------------------------------------------------------------------------
1308
1309 vtkTextProperty* VISU_Actor::GetsValLabelsProps() const
1310 {
1311   return myValLabeledDataMapper->GetLabelTextProperty();
1312 }
1313
1314 //----------------------------------------------------------------------------
1315
1316 vtkDataSet* VISU_Actor::GetValLabelsInput()
1317 {
1318   vtkDataSet* aDataSet = 0;
1319   VISU_PipeLine* aPL = GetPipeLine();
1320   if ( aPL )
1321     aDataSet = aPL->GetOutput();
1322   if ( !aDataSet )
1323     aDataSet = GetInput();
1324   return aDataSet;
1325 }
1326
1327
1328 VISU_Actor::EQuadratic2DRepresentation
1329 VISU_Actor::GetQuadratic2DRepresentation() const
1330 {
1331   if(Superclass::GetQuadraticArcMode()){
1332     return VISU_Actor::eArcs;
1333   }
1334   else
1335     return VISU_Actor::eLines;
1336 }
1337
1338 void VISU_Actor::SetQuadratic2DRepresentation( EQuadratic2DRepresentation theMode )
1339 {
1340   switch(theMode) {
1341   case VISU_Actor::eArcs:
1342     myPreHighlightActor->SetQuadraticArcMode(true);
1343     myHighlightActor->SetQuadraticArcMode(true);
1344     break;
1345   case VISU_Actor::eLines:
1346     myPreHighlightActor->SetQuadraticArcMode(false);
1347     myHighlightActor->SetQuadraticArcMode(false);
1348     break;
1349   default:
1350     break;
1351   }
1352 }