Salome HOME
52633: Activation of the ParaVis module leads to the breaking on the pre-selection...
[modules/gui.git] / src / VTKViewer / VTKViewer_Actor.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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 //  SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers
24 //  File   : SALOME_Actor.cxx
25 //  Author : Nicolas REJNERI
26
27 /*!
28   \class SALOME_Actor SALOME_Actor.h
29   \brief Abstract class of SALOME Objects in VTK.
30 */
31
32 #include "VTKViewer_Actor.h"
33
34 #include "VTKViewer_Transform.h"
35 #include "VTKViewer_TransformFilter.h"
36 #include "VTKViewer_GeometryFilter.h"
37
38 // VTK Includes
39 #include <vtkCell.h>
40 #include <vtkPolyData.h>
41 #include <vtkObjectFactory.h>
42 #include <vtkDataSetMapper.h>
43 #include <vtkPolyDataMapper.h>
44 #include <vtkRenderer.h>
45 #include <vtkPassThroughFilter.h>
46
47 #if defined __GNUC__
48   #if __GNUC__ == 2
49     #define __GNUC_2__
50   #endif
51 #endif
52
53 int VTKViewer_POINT_SIZE = 5;
54 int VTKViewer_LINE_WIDTH = 3;
55
56
57 vtkStandardNewMacro(VTKViewer_Actor);
58
59 /*!
60   Constructor
61 */
62 VTKViewer_Actor
63 ::VTKViewer_Actor():
64   myOpacity(1.0),
65   myIsHighlighted(false),
66   myIsPreselected(false),
67   myRepresentation(VTKViewer::Representation::Surface),
68   myDisplayMode(1),
69   myProperty(vtkProperty::New()),
70   PreviewProperty(NULL),
71   myIsInfinite(false),
72   myIsResolveCoincidentTopology(true),
73   myStoreMapping(false),
74   myGeomFilter(VTKViewer_GeometryFilter::New()),
75   myTransformFilter(VTKViewer_TransformFilter::New())
76 {
77   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
78                                                                  myPolygonOffsetUnits);
79
80   for(int i = 0; i < 6; i++)
81     myPassFilter.push_back(vtkPassThroughFilter::New());
82 }
83
84 /*!
85   Destructor
86 */
87 VTKViewer_Actor
88 ::~VTKViewer_Actor()
89 {
90   SetPreviewProperty(NULL);
91
92   myGeomFilter->Delete();
93
94   myTransformFilter->Delete();
95
96   for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
97     if(myPassFilter[i])
98       myPassFilter[i]->Delete();
99   
100   myProperty->Delete();
101 }
102
103 /*!
104   \return name
105 */
106 const char* 
107 VTKViewer_Actor
108 ::getName() 
109
110   return myName.c_str(); 
111 }
112
113 /*!
114   Sets name
115   \param theName - new name
116 */
117 void
118 VTKViewer_Actor
119 ::setName(const char* theName)
120 {
121   myName = theName;
122 }
123
124 /*!
125   To publish the actor an all its internal devices
126 */
127 void
128 VTKViewer_Actor
129 ::AddToRender(vtkRenderer* theRenderer)
130 {
131   theRenderer->AddActor(this);
132 }
133
134 /*!
135   To remove the actor an all its internal devices
136 */
137 void 
138 VTKViewer_Actor
139 ::RemoveFromRender(vtkRenderer* theRenderer)
140 {
141   theRenderer->RemoveActor(this);
142 }
143
144 /*!
145   Used to obtain all dependent actors
146 */
147 void
148 VTKViewer_Actor
149 ::GetChildActors(vtkActorCollection*) 
150 {}
151
152 /*!
153   Apply view transformation
154   \param theTransform - view transformation
155 */
156 void
157 VTKViewer_Actor
158 ::SetTransform(VTKViewer_Transform* theTransform)
159 {
160   myTransformFilter->SetTransform(theTransform);
161 }
162
163
164 /*!
165   To insert some additional filters and then sets the given #vtkMapper
166 */
167 void
168 VTKViewer_Actor
169 ::SetMapper(vtkMapper* theMapper)
170 {
171   InitPipeLine(theMapper);
172 }
173
174 /*!
175   Initialization
176 */
177 void
178 VTKViewer_Actor
179 ::InitPipeLine(vtkMapper* theMapper)
180 {
181   if(theMapper){
182     int anId = 0;
183     myPassFilter[ anId ]->SetInputData( theMapper->GetInput() );
184     myPassFilter[ anId + 1]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
185     
186     anId++; // 1
187     myGeomFilter->SetStoreMapping( myStoreMapping );
188     myGeomFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
189
190     anId++; // 2
191     myPassFilter[ anId ]->SetInputConnection( myGeomFilter->GetOutputPort() ); 
192     myPassFilter[ anId + 1 ]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
193
194     anId++; // 3
195     myTransformFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
196
197     anId++; // 4
198     myPassFilter[ anId ]->SetInputConnection( myTransformFilter->GetOutputPort() );
199     myPassFilter[ anId + 1 ]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() );
200
201     anId++; // 5
202     theMapper->SetInputConnection(myPassFilter[anId]->GetOutputPort());
203   }
204   Superclass::SetMapper(theMapper);
205 }
206
207 /*!
208   Renders actor
209 */
210 void
211 VTKViewer_Actor
212 ::Render(vtkRenderer *ren, vtkMapper* m)
213 {
214   if(vtkDataSet* aDataSet = GetInput()){
215     static double PERCENTS_OF_DETAILS = 0.50;
216     vtkIdType aNbOfPoints = vtkIdType(aDataSet->GetNumberOfPoints()*PERCENTS_OF_DETAILS);
217     if(aNbOfPoints > 0)
218       SetNumberOfCloudPoints(aNbOfPoints);
219   }
220
221   int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
222   if(myIsResolveCoincidentTopology){
223     double aFactor, aUnit; 
224     vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
225     
226     vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
227     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
228                                                                    myPolygonOffsetUnits);
229     Superclass::Render(ren,m);
230     
231     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
232   }else{
233     vtkMapper::SetResolveCoincidentTopologyToOff();
234     Superclass::Render(ren,m);
235   }
236   vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
237 }
238
239 /*!
240   Set ResolveCoincidentTopology flag
241   \param theIsResolve - new flag value
242 */
243 void
244 VTKViewer_Actor
245 ::SetResolveCoincidentTopology(bool theIsResolve) 
246 {
247   myIsResolveCoincidentTopology = theIsResolve;
248 }
249
250 /*!
251   Set polygon offset parameters
252   \param factor, units  - Opengl polygon offset parameters
253 */
254 void
255 VTKViewer_Actor
256 ::SetPolygonOffsetParameters(double factor, 
257                              double units)
258 {
259   myPolygonOffsetFactor = factor;
260   myPolygonOffsetUnits = units;
261 }
262
263 /*!
264   Get polygon offset parameters
265   \param factor, units  - Opengl polygon offset parameters
266 */
267 void
268 VTKViewer_Actor
269 ::GetPolygonOffsetParameters(double& factor, 
270                              double& units)
271 {
272   factor = myPolygonOffsetFactor;
273   units = myPolygonOffsetUnits;
274 }
275
276 /*!
277   \return shrink factor
278 */
279 double
280 VTKViewer_Actor
281 ::GetShrinkFactor() 
282
283   return 1.0;
284 }
285
286 /*!
287   \return true if the actor is shrunkable
288 */
289 bool
290 VTKViewer_Actor
291 ::IsShrunkable() 
292
293   return false;
294 }
295
296 /*!
297   \return true if the actor is shrunk
298 */
299 bool
300 VTKViewer_Actor
301 ::IsShrunk() 
302
303   return false;
304 }
305
306 /*!
307   Insert shrink filter into pipeline
308 */
309 void
310 VTKViewer_Actor
311 ::SetShrink() 
312 {} 
313
314 /*!
315   Remove shrink filter from pipeline
316 */
317 void
318 VTKViewer_Actor
319 ::UnShrink() 
320 {}
321
322 /*!
323   Allows to get initial #vtkDataSet
324 */
325 vtkDataSet* 
326 VTKViewer_Actor
327 ::GetInput()
328 {
329   return myPassFilter.front()->GetOutput();
330 }
331
332 /*!
333   To calculatate last modified time
334 */
335 unsigned long int
336 VTKViewer_Actor
337 ::GetMTime()
338 {
339   unsigned long mTime = this->Superclass::GetMTime();
340   unsigned long time = myTransformFilter->GetMTime();
341   mTime = ( time > mTime ? time : mTime );
342   if(vtkDataSet *aDataSet = dynamic_cast<vtkDataSet*>(myPassFilter[0]->GetInput())){ // bad usage of GetInput
343     time = aDataSet->GetMTime();
344     mTime = ( time > mTime ? time : mTime );
345   }
346   return mTime;
347 }
348
349 /*!
350   Set representation (VTK_SURFACE, VTK_POINTS, VTK_WIREFRAME and so on)
351   param theMode - new mode
352 */
353 void
354 VTKViewer_Actor
355 ::SetRepresentation(int theMode) 
356
357   using namespace VTKViewer::Representation;
358   switch(myRepresentation){
359   case Points : 
360   case Surface : 
361   case SurfaceWithEdges :
362     myProperty->SetAmbient(GetProperty()->GetAmbient());
363     myProperty->SetDiffuse(GetProperty()->GetDiffuse());
364     myProperty->SetSpecular(GetProperty()->GetSpecular());
365     break;
366   }    
367
368   switch(theMode){
369   case Points : 
370   case Surface : 
371   case SurfaceWithEdges :
372     GetProperty()->SetAmbient(myProperty->GetAmbient());
373     GetProperty()->SetDiffuse(myProperty->GetDiffuse());
374     GetProperty()->SetSpecular(myProperty->GetSpecular());
375     break;
376   default:
377     GetProperty()->SetAmbient(1.0);
378     GetProperty()->SetDiffuse(0.0);
379     GetProperty()->SetSpecular(0.0);
380   }
381
382   switch(theMode){
383   case Insideframe : 
384     myGeomFilter->SetInside(true);
385     myGeomFilter->SetWireframeMode(true);
386     GetProperty()->SetRepresentation(VTK_WIREFRAME);
387     break;
388   case Points : 
389     GetProperty()->SetPointSize(VTKViewer_POINT_SIZE);  
390     GetProperty()->SetRepresentation(theMode);
391     myGeomFilter->SetWireframeMode(false);
392     myGeomFilter->SetInside(false);
393     break;
394   case Wireframe : 
395     GetProperty()->SetRepresentation(theMode);
396     myGeomFilter->SetWireframeMode(true);
397     myGeomFilter->SetInside(false);
398     break;
399   case Surface : 
400   case SurfaceWithEdges :
401     GetProperty()->SetRepresentation(theMode);
402     myGeomFilter->SetWireframeMode(false);
403     myGeomFilter->SetInside(false);
404     break;
405   }
406
407   myRepresentation = theMode;
408 }
409
410 /*!
411   \return current representation mode
412 */
413 int
414 VTKViewer_Actor
415 ::GetRepresentation()
416
417   return myRepresentation;
418 }
419
420 /*!
421   Maps VTK index of a node to corresponding object index
422 */
423 int 
424 VTKViewer_Actor
425 ::GetNodeObjId(int theVtkID)
426
427   return theVtkID;
428 }
429
430 /*!
431   Get coordinates of a node for given object index
432 */
433 double* 
434 VTKViewer_Actor
435 ::GetNodeCoord(int theObjID)
436 {
437   return GetInput()->GetPoint(theObjID);
438 }
439
440 /*!
441   Get corresponding #vtkCell for given object index
442 */
443 vtkCell* 
444 VTKViewer_Actor
445 ::GetElemCell(int theObjID)
446 {
447   return GetInput()->GetCell(theObjID);
448 }
449
450 /*!
451   Maps VTK index of a cell to corresponding object index
452 */
453 int
454 VTKViewer_Actor
455 ::GetElemObjId(int theVtkID) 
456
457   return theVtkID;
458 }
459
460
461 /*!
462   \return object dimension. Virtual method should be redifined by derived classes
463 */
464 int
465 VTKViewer_Actor
466 ::GetObjDimension( const int theObjId )
467 {
468   if ( vtkCell* aCell = GetElemCell(theObjId) )
469     return aCell->GetCellDimension();
470   return 0;
471 }
472
473 /*!
474   Infinitive means actor without size (point for example),
475   which is not taken into account in calculation of boundaries of the scene
476 */
477 void
478 VTKViewer_Actor
479 ::SetInfinitive(bool theIsInfinite)
480
481   myIsInfinite = theIsInfinite;
482 }
483
484 /*!
485   \return infinive flag
486 */
487 bool
488 VTKViewer_Actor
489 ::IsInfinitive()
490
491   if(myIsInfinite)
492     return true;
493
494   static double MAX_DISTANCE = 0.9*VTK_LARGE_FLOAT;
495   double aBounds[6];
496   GetBounds(aBounds);
497   for(int i = 0; i < 6; i++)
498     if(fabs(aBounds[i]) > MAX_DISTANCE)
499       return true;
500   
501   static double MIN_DISTANCE = 1.0/VTK_LARGE_FLOAT;
502   if(GetLength() < MIN_DISTANCE)
503     return true;
504   
505   return false;
506 }
507
508 /*!
509   \return current bounding box
510 */
511 double* 
512 VTKViewer_Actor
513 ::GetBounds()
514 {
515   return Superclass::GetBounds();
516 }
517
518
519 /*!
520   \return current bounding box
521 */
522 void
523 VTKViewer_Actor
524 ::GetBounds(double theBounds[6])
525 {
526   Superclass::GetBounds(theBounds);
527 }
528
529
530 bool
531 VTKViewer_Actor
532 ::IsSetCamera() const 
533
534   return false; 
535 }
536
537 bool
538 VTKViewer_Actor
539 ::IsResizable() const 
540
541   return false; 
542 }
543
544 void
545 VTKViewer_Actor
546 ::SetSize( const double ) 
547 {}
548
549
550 void 
551 VTKViewer_Actor
552 ::SetCamera( vtkCamera* ) 
553 {}
554
555
556 void
557 VTKViewer_Actor
558 ::SetOpacity(double theOpacity)
559
560   myOpacity = theOpacity;
561   GetProperty()->SetOpacity(theOpacity);
562 }
563
564 double
565 VTKViewer_Actor
566 ::GetOpacity()
567 {
568   return myOpacity;
569 }
570
571
572 /*!
573   Change color
574 */
575 void
576 VTKViewer_Actor
577 ::SetColor(double r,
578            double g,
579            double b)
580 {
581   GetProperty()->SetColor(r,g,b);
582 }
583
584 /*!
585   Change color
586 */
587 void
588 VTKViewer_Actor
589 ::SetColor(const double theRGB[3])
590
591   SetColor(theRGB[0],theRGB[1],theRGB[2]);
592 }
593
594 /*!
595   Get color
596 */
597 void
598 VTKViewer_Actor
599 ::GetColor(double& r,
600            double& g,
601            double& b)
602 {
603   double aColor[3];
604   GetProperty()->GetColor(aColor);
605   r = aColor[0];
606   g = aColor[1];
607   b = aColor[2];
608 }
609
610
611 /*!
612   Change material
613 */
614 void
615 VTKViewer_Actor
616 ::SetMaterial(std::vector<vtkProperty*> theProps)
617 {
618 }
619
620 /*!
621   Get current front material\r
622 */\r
623 vtkProperty* \r
624 VTKViewer_Actor\r
625 ::GetFrontMaterial()\r
626 {\r
627   return NULL;\r
628 }\r
629 \r
630 /*!\r
631   Get current back material\r
632 */\r
633 vtkProperty* \r
634 VTKViewer_Actor\r
635 ::GetBackMaterial()\r
636 {\r
637   return NULL;\r
638 }
639
640 /*!
641   \return display mode
642 */
643 int
644 VTKViewer_Actor
645 ::getDisplayMode()
646
647   return myDisplayMode; 
648 }
649
650 /*!
651   Change display mode
652 */
653 void
654 VTKViewer_Actor
655 ::setDisplayMode(int theMode)
656
657   SetRepresentation(theMode + 1); 
658   myDisplayMode = GetRepresentation() - 1;
659 }
660
661
662 /*!
663   \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
664 */
665 bool
666 VTKViewer_Actor
667 ::hasHighlight() 
668
669   return false; 
670
671
672 /*!
673   \return true if the VTKViewer_Actor is already highlighted
674 */
675 bool
676 VTKViewer_Actor
677 ::isHighlighted() 
678
679   return myIsHighlighted; 
680 }
681
682 /*!
683   \return true if the VTKViewer_Actor is already preselected
684 */
685 bool
686 VTKViewer_Actor
687 ::isPreselected() 
688
689   return myIsPreselected; 
690 }
691
692 /*!
693   Set preselection mode
694 */
695 void
696 VTKViewer_Actor
697 ::SetPreSelected(bool thePreselect) 
698
699   myIsPreselected = thePreselect;
700 }
701
702 /*!
703   Just to update visibility of the highlight devices
704 */
705 void
706 VTKViewer_Actor
707 ::highlight(bool theIsHighlight)
708 {
709   myIsHighlighted = theIsHighlight; 
710 }
711
712 /*!
713  * On/Off representation 2D quadratic element as arked polygon
714  */
715 void VTKViewer_Actor::SetQuadraticArcMode(bool theFlag){
716   myGeomFilter->SetQuadraticArcMode(theFlag);
717 }
718
719 /*!
720  * Return true if 2D quadratic element displayed as arked polygon
721  */
722 bool VTKViewer_Actor::GetQuadraticArcMode() const{
723   return myGeomFilter->GetQuadraticArcMode();
724 }
725 /*!
726  * Set Max angle for representation 2D quadratic element as arked polygon
727  */
728 void VTKViewer_Actor::SetQuadraticArcAngle(double theMaxAngle){
729   myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
730 }
731
732 /*!
733  * Return Max angle of the representation 2D quadratic element as arked polygon
734  */
735 double VTKViewer_Actor::GetQuadraticArcAngle() const{
736   return myGeomFilter->GetQuadraticArcAngle();
737 }
738
739 /*!
740  * Return pointer to the dataset, which used to calculation of the bounding box of the actor.
741  * By default it is the input dataset.
742  */
743 vtkDataSet* VTKViewer_Actor::GetHighlightedDataSet() {
744   return GetInput();
745 }
746
747
748
749 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty);