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