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