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