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