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