Salome HOME
Merge remote-tracking branch 'origin/vsr/fix_single_study_pb' into pre/fix_single_study
[modules/gui.git] / src / VTKViewer / VTKViewer_Actor.cxx
1 // Copyright (C) 2007-2014  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   if(myIsResolveCoincidentTopology){
222     int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
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     vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
233   }else{
234     Superclass::Render(ren,m);
235   }
236 }
237
238 /*!
239   Set ResolveCoincidentTopology flag
240   \param theIsResolve - new flag value
241 */
242 void
243 VTKViewer_Actor
244 ::SetResolveCoincidentTopology(bool theIsResolve) 
245 {
246   myIsResolveCoincidentTopology = theIsResolve;
247 }
248
249 /*!
250   Set polygon offset parameters
251   \param factor, units  - Opengl polygon offset parameters
252 */
253 void
254 VTKViewer_Actor
255 ::SetPolygonOffsetParameters(double factor, 
256                              double units)
257 {
258   myPolygonOffsetFactor = factor;
259   myPolygonOffsetUnits = units;
260 }
261
262 /*!
263   Get polygon offset parameters
264   \param factor, units  - Opengl polygon offset parameters
265 */
266 void
267 VTKViewer_Actor
268 ::GetPolygonOffsetParameters(double& factor, 
269                              double& units)
270 {
271   factor = myPolygonOffsetFactor;
272   units = myPolygonOffsetUnits;
273 }
274
275 /*!
276   \return shrink factor
277 */
278 double
279 VTKViewer_Actor
280 ::GetShrinkFactor() 
281
282   return 1.0;
283 }
284
285 /*!
286   \return true if the actor is shrunkable
287 */
288 bool
289 VTKViewer_Actor
290 ::IsShrunkable() 
291
292   return false;
293 }
294
295 /*!
296   \return true if the actor is shrunk
297 */
298 bool
299 VTKViewer_Actor
300 ::IsShrunk() 
301
302   return false;
303 }
304
305 /*!
306   Insert shrink filter into pipeline
307 */
308 void
309 VTKViewer_Actor
310 ::SetShrink() 
311 {} 
312
313 /*!
314   Remove shrink filter from pipeline
315 */
316 void
317 VTKViewer_Actor
318 ::UnShrink() 
319 {}
320
321 /*!
322   Allows to get initial #vtkDataSet
323 */
324 vtkDataSet* 
325 VTKViewer_Actor
326 ::GetInput()
327 {
328   return myPassFilter.front()->GetOutput();
329 }
330
331 /*!
332   To calculatate last modified time
333 */
334 unsigned long int
335 VTKViewer_Actor
336 ::GetMTime()
337 {
338   unsigned long mTime = this->Superclass::GetMTime();
339   unsigned long time = myTransformFilter->GetMTime();
340   mTime = ( time > mTime ? time : mTime );
341   if(vtkDataSet *aDataSet = dynamic_cast<vtkDataSet*>(myPassFilter[0]->GetInput())){ // bad usage of GetInput
342     time = aDataSet->GetMTime();
343     mTime = ( time > mTime ? time : mTime );
344   }
345   return mTime;
346 }
347
348 /*!
349   Set representation (VTK_SURFACE, VTK_POINTS, VTK_WIREFRAME and so on)
350   param theMode - new mode
351 */
352 void
353 VTKViewer_Actor
354 ::SetRepresentation(int theMode) 
355
356   using namespace VTKViewer::Representation;
357   switch(myRepresentation){
358   case Points : 
359   case Surface : 
360   case SurfaceWithEdges :
361     myProperty->SetAmbient(GetProperty()->GetAmbient());
362     myProperty->SetDiffuse(GetProperty()->GetDiffuse());
363     myProperty->SetSpecular(GetProperty()->GetSpecular());
364     break;
365   }    
366
367   switch(theMode){
368   case Points : 
369   case Surface : 
370   case SurfaceWithEdges :
371     GetProperty()->SetAmbient(myProperty->GetAmbient());
372     GetProperty()->SetDiffuse(myProperty->GetDiffuse());
373     GetProperty()->SetSpecular(myProperty->GetSpecular());
374     break;
375   default:
376     GetProperty()->SetAmbient(1.0);
377     GetProperty()->SetDiffuse(0.0);
378     GetProperty()->SetSpecular(0.0);
379   }
380
381   switch(theMode){
382   case Insideframe : 
383     myGeomFilter->SetInside(true);
384     myGeomFilter->SetWireframeMode(true);
385     GetProperty()->SetRepresentation(VTK_WIREFRAME);
386     break;
387   case Points : 
388     GetProperty()->SetPointSize(VTKViewer_POINT_SIZE);  
389     GetProperty()->SetRepresentation(theMode);
390     myGeomFilter->SetWireframeMode(false);
391     myGeomFilter->SetInside(false);
392     break;
393   case Wireframe : 
394     GetProperty()->SetRepresentation(theMode);
395     myGeomFilter->SetWireframeMode(true);
396     myGeomFilter->SetInside(false);
397     break;
398   case Surface : 
399   case SurfaceWithEdges :
400     GetProperty()->SetRepresentation(theMode);
401     myGeomFilter->SetWireframeMode(false);
402     myGeomFilter->SetInside(false);
403     break;
404   }
405
406   myRepresentation = theMode;
407 }
408
409 /*!
410   \return current representation mode
411 */
412 int
413 VTKViewer_Actor
414 ::GetRepresentation()
415
416   return myRepresentation;
417 }
418
419 /*!
420   Maps VTK index of a node to corresponding object index
421 */
422 int 
423 VTKViewer_Actor
424 ::GetNodeObjId(int theVtkID)
425
426   return theVtkID;
427 }
428
429 /*!
430   Get coordinates of a node for given object index
431 */
432 double* 
433 VTKViewer_Actor
434 ::GetNodeCoord(int theObjID)
435 {
436   return GetInput()->GetPoint(theObjID);
437 }
438
439 /*!
440   Get corresponding #vtkCell for given object index
441 */
442 vtkCell* 
443 VTKViewer_Actor
444 ::GetElemCell(int theObjID)
445 {
446   return GetInput()->GetCell(theObjID);
447 }
448
449 /*!
450   Maps VTK index of a cell to corresponding object index
451 */
452 int
453 VTKViewer_Actor
454 ::GetElemObjId(int theVtkID) 
455
456   return theVtkID;
457 }
458
459
460 /*!
461   \return object dimension. Virtual method should be redifined by derived classes
462 */
463 int
464 VTKViewer_Actor
465 ::GetObjDimension( const int theObjId )
466 {
467   if ( vtkCell* aCell = GetElemCell(theObjId) )
468     return aCell->GetCellDimension();
469   return 0;
470 }
471
472 /*!
473   Infinitive means actor without size (point for example),
474   which is not taken into account in calculation of boundaries of the scene
475 */
476 void
477 VTKViewer_Actor
478 ::SetInfinitive(bool theIsInfinite)
479
480   myIsInfinite = theIsInfinite;
481 }
482
483 /*!
484   \return infinive flag
485 */
486 bool
487 VTKViewer_Actor
488 ::IsInfinitive()
489
490   if(myIsInfinite)
491     return true;
492
493   static double MAX_DISTANCE = 0.9*VTK_LARGE_FLOAT;
494   double aBounds[6];
495   GetBounds(aBounds);
496   for(int i = 0; i < 6; i++)
497     if(fabs(aBounds[i]) > MAX_DISTANCE)
498       return true;
499   
500   static double MIN_DISTANCE = 1.0/VTK_LARGE_FLOAT;
501   if(GetLength() < MIN_DISTANCE)
502     return true;
503   
504   return false;
505 }
506
507 /*!
508   \return current bounding box
509 */
510 double* 
511 VTKViewer_Actor
512 ::GetBounds()
513 {
514   return Superclass::GetBounds();
515 }
516
517
518 /*!
519   \return current bounding box
520 */
521 void
522 VTKViewer_Actor
523 ::GetBounds(double theBounds[6])
524 {
525   Superclass::GetBounds(theBounds);
526 }
527
528
529 bool
530 VTKViewer_Actor
531 ::IsSetCamera() const 
532
533   return false; 
534 }
535
536 bool
537 VTKViewer_Actor
538 ::IsResizable() const 
539
540   return false; 
541 }
542
543 void
544 VTKViewer_Actor
545 ::SetSize( const double ) 
546 {}
547
548
549 void 
550 VTKViewer_Actor
551 ::SetCamera( vtkCamera* ) 
552 {}
553
554
555 void
556 VTKViewer_Actor
557 ::SetOpacity(double theOpacity)
558
559   myOpacity = theOpacity;
560   GetProperty()->SetOpacity(theOpacity);
561 }
562
563 double
564 VTKViewer_Actor
565 ::GetOpacity()
566 {
567   return myOpacity;
568 }
569
570
571 /*!
572   Change color
573 */
574 void
575 VTKViewer_Actor
576 ::SetColor(double r,
577            double g,
578            double b)
579 {
580   GetProperty()->SetColor(r,g,b);
581 }
582
583 /*!
584   Change color
585 */
586 void
587 VTKViewer_Actor
588 ::SetColor(const double theRGB[3])
589
590   SetColor(theRGB[0],theRGB[1],theRGB[2]);
591 }
592
593 /*!
594   Get color
595 */
596 void
597 VTKViewer_Actor
598 ::GetColor(double& r,
599            double& g,
600            double& b)
601 {
602   double aColor[3];
603   GetProperty()->GetColor(aColor);
604   r = aColor[0];
605   g = aColor[1];
606   b = aColor[2];
607 }
608
609
610 /*!
611   Change material
612 */
613 void
614 VTKViewer_Actor
615 ::SetMaterial(std::vector<vtkProperty*> theProps)
616 {
617 }
618
619 /*!
620   Get current front material\r
621 */\r
622 vtkProperty* \r
623 VTKViewer_Actor\r
624 ::GetFrontMaterial()\r
625 {\r
626   return NULL;\r
627 }\r
628 \r
629 /*!\r
630   Get current back material\r
631 */\r
632 vtkProperty* \r
633 VTKViewer_Actor\r
634 ::GetBackMaterial()\r
635 {\r
636   return NULL;\r
637 }
638
639 /*!
640   \return display mode
641 */
642 int
643 VTKViewer_Actor
644 ::getDisplayMode()
645
646   return myDisplayMode; 
647 }
648
649 /*!
650   Change display mode
651 */
652 void
653 VTKViewer_Actor
654 ::setDisplayMode(int theMode)
655
656   SetRepresentation(theMode + 1); 
657   myDisplayMode = GetRepresentation() - 1;
658 }
659
660
661 /*!
662   \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
663 */
664 bool
665 VTKViewer_Actor
666 ::hasHighlight() 
667
668   return false; 
669
670
671 /*!
672   \return true if the VTKViewer_Actor is already highlighted
673 */
674 bool
675 VTKViewer_Actor
676 ::isHighlighted() 
677
678   return myIsHighlighted; 
679 }
680
681 /*!
682   \return true if the VTKViewer_Actor is already preselected
683 */
684 bool
685 VTKViewer_Actor
686 ::isPreselected() 
687
688   return myIsPreselected; 
689 }
690
691 /*!
692   Set preselection mode
693 */
694 void
695 VTKViewer_Actor
696 ::SetPreSelected(bool thePreselect) 
697
698   myIsPreselected = thePreselect;
699 }
700
701 /*!
702   Just to update visibility of the highlight devices
703 */
704 void
705 VTKViewer_Actor
706 ::highlight(bool theIsHighlight)
707 {
708   myIsHighlighted = theIsHighlight; 
709 }
710
711 /*!
712  * On/Off representation 2D quadratic element as arked polygon
713  */
714 void VTKViewer_Actor::SetQuadraticArcMode(bool theFlag){
715   myGeomFilter->SetQuadraticArcMode(theFlag);
716 }
717
718 /*!
719  * Return true if 2D quadratic element displayed as arked polygon
720  */
721 bool VTKViewer_Actor::GetQuadraticArcMode() const{
722   return myGeomFilter->GetQuadraticArcMode();
723 }
724 /*!
725  * Set Max angle for representation 2D quadratic element as arked polygon
726  */
727 void VTKViewer_Actor::SetQuadraticArcAngle(double theMaxAngle){
728   myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
729 }
730
731 /*!
732  * Return Max angle of the representation 2D quadratic element as arked polygon
733  */
734 double VTKViewer_Actor::GetQuadraticArcAngle() const{
735   return myGeomFilter->GetQuadraticArcAngle();
736 }
737
738 /*!
739  * Return pointer to the dataset, which used to calculation of the bounding box of the actor.
740  * By default it is the input dataset.
741  */
742 vtkDataSet* VTKViewer_Actor::GetHighlightedDataSet() {
743   return GetInput();
744 }
745
746
747
748 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty);