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