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