Salome HOME
Updated copyright comment
[modules/gui.git] / src / VTKViewer / VTKViewer_Actor.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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 <vtkPassThrough.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(vtkPassThrough::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(size_t 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 static_cast<vtkDataSet *>( 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 vtkIdType 
437 VTKViewer_Actor
438 ::GetNodeObjId(vtkIdType 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(vtkIdType theObjID)
449 {
450   return GetInput()->GetPoint(theObjID);
451 }
452
453 /*!
454  Maps object index of a node to corresponding VTK index
455 */
456 vtkIdType
457 VTKViewer_Actor
458 ::GetNodeVtkId( vtkIdType theObjID )
459 {
460   return theObjID;
461 }
462
463
464 /*!
465   Get corresponding #vtkCell for given object index
466 */
467 vtkCell* 
468 VTKViewer_Actor
469 ::GetElemCell(vtkIdType theObjID)
470 {
471   return GetInput()->GetCell(theObjID);
472 }
473
474 /*!
475   Maps VTK index of a cell to corresponding object index
476 */
477 vtkIdType
478 VTKViewer_Actor
479 ::GetElemObjId(vtkIdType theVtkID) 
480
481   return theVtkID;
482 }
483
484
485 /*!
486   \return object dimension. Virtual method should be redifined by derived classes
487 */
488 int
489 VTKViewer_Actor
490 ::GetObjDimension( const vtkIdType theObjId )
491 {
492   if ( vtkCell* aCell = GetElemCell(theObjId) )
493     return aCell->GetCellDimension();
494   return 0;
495 }
496
497 /*!
498   Infinitive means actor without size (point for example),
499   which is not taken into account in calculation of boundaries of the scene
500 */
501 void
502 VTKViewer_Actor
503 ::SetInfinitive(bool theIsInfinite)
504
505   myIsInfinite = theIsInfinite;
506 }
507
508 /*!
509   \return infinive flag
510 */
511 bool
512 VTKViewer_Actor
513 ::IsInfinitive()
514
515   if(myIsInfinite)
516     return true;
517
518   static double MAX_DISTANCE = 0.9*VTK_FLOAT_MAX;
519   double aBounds[6];
520   GetBounds(aBounds);
521   for(int i = 0; i < 6; i++)
522     if(fabs(aBounds[i]) > MAX_DISTANCE)
523       return true;
524   
525   static double MIN_DISTANCE = 1.0/VTK_FLOAT_MAX;
526   if(GetLength() < MIN_DISTANCE)
527     return true;
528   
529   return false;
530 }
531
532 /*!
533   \return current bounding box
534 */
535 double* 
536 VTKViewer_Actor
537 ::GetBounds()
538 {
539   return Superclass::GetBounds();
540 }
541
542
543 /*!
544   \return current bounding box
545 */
546 void
547 VTKViewer_Actor
548 ::GetBounds(double theBounds[6])
549 {
550   Superclass::GetBounds(theBounds);
551 }
552
553
554 bool
555 VTKViewer_Actor
556 ::IsSetCamera() const 
557
558   return false; 
559 }
560
561 bool
562 VTKViewer_Actor
563 ::IsResizable() const 
564
565   return false; 
566 }
567
568 void
569 VTKViewer_Actor
570 ::SetSize( const double ) 
571 {}
572
573
574 void 
575 VTKViewer_Actor
576 ::SetCamera( vtkCamera* ) 
577 {}
578
579
580 void
581 VTKViewer_Actor
582 ::SetOpacity(double theOpacity)
583
584   myOpacity = theOpacity;
585   GetProperty()->SetOpacity(theOpacity);
586 }
587
588 double
589 VTKViewer_Actor
590 ::GetOpacity()
591 {
592   return myOpacity;
593 }
594
595
596 /*!
597   Change color
598 */
599 void
600 VTKViewer_Actor
601 ::SetColor(double r,
602            double g,
603            double b)
604 {
605   GetProperty()->SetColor(r,g,b);
606 }
607
608 /*!
609   Change color
610 */
611 void
612 VTKViewer_Actor
613 ::SetColor(const double theRGB[3])
614
615   SetColor(theRGB[0],theRGB[1],theRGB[2]);
616 }
617
618 /*!
619   Get color
620 */
621 void
622 VTKViewer_Actor
623 ::GetColor(double& r,
624            double& g,
625            double& b)
626 {
627   double aColor[3];
628   GetProperty()->GetColor(aColor);
629   r = aColor[0];
630   g = aColor[1];
631   b = aColor[2];
632 }
633
634
635 /*!
636   Change material
637 */
638 void
639 VTKViewer_Actor
640 ::SetMaterial(std::vector<vtkProperty*> /*theProps*/)
641 {
642 }
643
644 /*!
645   Get current front material
646 */
647 vtkProperty* 
648 VTKViewer_Actor
649 ::GetFrontMaterial()
650 {
651   return NULL;
652 }
653
654 /*!
655   Get current back material
656 */
657 vtkProperty* 
658 VTKViewer_Actor
659 ::GetBackMaterial()
660 {
661   return NULL;
662 }
663
664 /*!
665   \return display mode
666 */
667 int
668 VTKViewer_Actor
669 ::getDisplayMode()
670
671   return myDisplayMode; 
672 }
673
674 /*!
675   Change display mode
676 */
677 void
678 VTKViewer_Actor
679 ::setDisplayMode(int theMode)
680
681   SetRepresentation(theMode + 1); 
682   myDisplayMode = GetRepresentation() - 1;
683 }
684
685
686 /*!
687   \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
688 */
689 bool
690 VTKViewer_Actor
691 ::hasHighlight() 
692
693   return false; 
694
695
696 /*!
697   \return true if the VTKViewer_Actor is already highlighted
698 */
699 bool
700 VTKViewer_Actor
701 ::isHighlighted() 
702
703   return myIsHighlighted; 
704 }
705
706 /*!
707   \return true if the VTKViewer_Actor is already preselected
708 */
709 bool
710 VTKViewer_Actor
711 ::isPreselected() 
712
713   return myIsPreselected; 
714 }
715
716 /*!
717   Set preselection mode
718 */
719 void
720 VTKViewer_Actor
721 ::SetPreSelected(bool thePreselect) 
722
723   myIsPreselected = thePreselect;
724 }
725
726 /*!
727   Just to update visibility of the highlight devices
728 */
729 void
730 VTKViewer_Actor
731 ::highlight(bool theIsHighlight)
732 {
733   myIsHighlighted = theIsHighlight; 
734 }
735
736 /*!
737  * On/Off representation 2D quadratic element as arked polygon
738  */
739 void VTKViewer_Actor::SetQuadraticArcMode(bool theFlag){
740   myGeomFilter->SetQuadraticArcMode(theFlag);
741 }
742
743 /*!
744  * Return true if 2D quadratic element displayed as arked polygon
745  */
746 bool VTKViewer_Actor::GetQuadraticArcMode() const{
747   return myGeomFilter->GetQuadraticArcMode();
748 }
749 /*!
750  * Set Max angle for representation 2D quadratic element as arked polygon
751  */
752 void VTKViewer_Actor::SetQuadraticArcAngle(double theMaxAngle){
753   myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
754 }
755
756 /*!
757  * Return Max angle of the representation 2D quadratic element as arked polygon
758  */
759 double VTKViewer_Actor::GetQuadraticArcAngle() const{
760   return myGeomFilter->GetQuadraticArcAngle();
761 }
762
763 /*!
764  * Return pointer to the dataset, which used to calculation of the bounding box of the actor.
765  * By default it is the input dataset.
766  */
767 vtkDataSet* VTKViewer_Actor::GetHighlightedDataSet() {
768   return GetInput();
769 }
770
771
772
773 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty)