Salome HOME
d086127716801013a4ddee98ff470161f2bd670b
[modules/gui.git] / src / VTKViewer / VTKViewer_Actor.cxx
1 //  Copyright (C) 2007-2008  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 //  SALOME OBJECT : implementation of interactive object visualization for OCC and VTK viewers
23 //  File   : SALOME_Actor.cxx
24 //  Author : Nicolas REJNERI
25 //  Module : SALOME
26 //  $Header$
27 //
28 /*!
29   \class SALOME_Actor SALOME_Actor.h
30   \brief Abstract class of SALOME Objects in VTK.
31 */
32
33
34 #include "VTKViewer_Actor.h"
35
36 #include "VTKViewer_Transform.h"
37 #include "VTKViewer_TransformFilter.h"
38 #include "VTKViewer_GeometryFilter.h"
39
40 // VTK Includes
41 #include <vtkCell.h>
42 #include <vtkPolyData.h>
43 #include <vtkObjectFactory.h>
44 #include <vtkDataSetMapper.h>
45 #include <vtkPolyDataMapper.h>
46 #include <vtkProperty.h>
47 #include <vtkRenderer.h>
48 #include <vtkPassThroughFilter.h>
49
50 using namespace std;
51
52 #if defined __GNUC__
53   #if __GNUC__ == 2
54     #define __GNUC_2__
55   #endif
56 #endif
57
58 int VTKViewer_POINT_SIZE = 5;
59 int VTKViewer_LINE_WIDTH = 3;
60
61
62 vtkStandardNewMacro(VTKViewer_Actor);
63
64 /*!
65   Constructor
66 */
67 VTKViewer_Actor
68 ::VTKViewer_Actor():
69   myIsHighlighted(false),
70   myIsPreselected(false),
71   myRepresentation(VTK_SURFACE),
72   myDisplayMode(1),
73   myProperty(vtkProperty::New()),
74   PreviewProperty(NULL),
75   myIsInfinite(false),
76   myIsResolveCoincidentTopology(true),
77   myStoreMapping(false),
78   myGeomFilter(VTKViewer_GeometryFilter::New()),
79   myTransformFilter(VTKViewer_TransformFilter::New())
80 {
81   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
82                                                                  myPolygonOffsetUnits);
83
84   for(int i = 0; i < 6; i++)
85     myPassFilter.push_back(vtkPassThroughFilter::New());
86 }
87
88 /*!
89   Destructor
90 */
91 VTKViewer_Actor
92 ::~VTKViewer_Actor()
93 {
94   SetPreviewProperty(NULL);
95
96   myGeomFilter->Delete();
97
98   myTransformFilter->Delete();
99
100   for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
101     if(myPassFilter[i])
102       myPassFilter[i]->Delete();
103   
104   myProperty->Delete();
105 }
106
107 /*!
108   \return name
109 */
110 const char* 
111 VTKViewer_Actor
112 ::getName() 
113
114   return myName.c_str(); 
115 }
116
117 /*!
118   Sets name
119   \param theName - new name
120 */
121 void
122 VTKViewer_Actor
123 ::setName(const char* theName)
124 {
125   myName = theName;
126 }
127
128 /*!
129   To publish the actor an all its internal devices
130 */
131 void
132 VTKViewer_Actor
133 ::AddToRender(vtkRenderer* theRenderer)
134 {
135   theRenderer->AddActor(this);
136 }
137
138 /*!
139   To remove the actor an all its internal devices
140 */
141 void 
142 VTKViewer_Actor
143 ::RemoveFromRender(vtkRenderer* theRenderer)
144 {
145   theRenderer->RemoveActor(this);
146 }
147
148 /*!
149   Used to obtain all dependent actors
150 */
151 void
152 VTKViewer_Actor
153 ::GetChildActors(vtkActorCollection*) 
154 {}
155
156 /*!
157   Apply view transformation
158   \param theTransform - view transformation
159 */
160 void
161 VTKViewer_Actor
162 ::SetTransform(VTKViewer_Transform* theTransform)
163 {
164   myTransformFilter->SetTransform(theTransform);
165 }
166
167
168 /*!
169   To insert some additional filters and then sets the given #vtkMapper
170 */
171 void
172 VTKViewer_Actor
173 ::SetMapper(vtkMapper* theMapper)
174 {
175   InitPipeLine(theMapper);
176 }
177
178 /*!
179   Initialization
180 */
181 void
182 VTKViewer_Actor
183 ::InitPipeLine(vtkMapper* theMapper)
184 {
185   if(theMapper){
186     int anId = 0;
187     myPassFilter[ anId ]->SetInput( theMapper->GetInput() );
188     myPassFilter[ anId + 1]->SetInput( myPassFilter[ anId ]->GetOutput() );
189     
190     anId++; // 1
191     myGeomFilter->SetStoreMapping( myStoreMapping );
192     myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
193
194     anId++; // 2
195     myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() ); 
196     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
197
198     anId++; // 3
199     myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
200
201     anId++; // 4
202     myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
203     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
204
205     anId++; // 5
206     if(vtkDataSetMapper* aMapper = dynamic_cast<vtkDataSetMapper*>(theMapper)){
207       aMapper->SetInput(myPassFilter[anId]->GetOutput());
208     }else if(vtkPolyDataMapper* aMapper = dynamic_cast<vtkPolyDataMapper*>(theMapper)){
209       aMapper->SetInput(myPassFilter[anId]->GetPolyDataOutput());
210     }
211   }
212   Superclass::SetMapper(theMapper);
213 }
214
215 /*!
216   Renders actor
217 */
218 void
219 VTKViewer_Actor
220 ::Render(vtkRenderer *ren, vtkMapper* m)
221 {
222   if(vtkDataSet* aDataSet = GetInput()){
223     static vtkFloatingPointType PERCENTS_OF_DETAILS = 0.50;
224     vtkIdType aNbOfPoints = vtkIdType(aDataSet->GetNumberOfPoints()*PERCENTS_OF_DETAILS);
225     if(aNbOfPoints > 0)
226       SetNumberOfCloudPoints(aNbOfPoints);
227   }
228
229   if(myIsResolveCoincidentTopology){
230     int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
231     vtkFloatingPointType aFactor, aUnit; 
232     vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
233     
234     vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
235     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
236                                                                    myPolygonOffsetUnits);
237     Superclass::Render(ren,m);
238     
239     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
240     vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
241   }else{
242     Superclass::Render(ren,m);
243   }
244 }
245
246 /*!
247   Set ResolveCoincidentTopology flag
248   \param theIsResolve - new flag value
249 */
250 void
251 VTKViewer_Actor
252 ::SetResolveCoincidentTopology(bool theIsResolve) 
253 {
254   myIsResolveCoincidentTopology = theIsResolve;
255 }
256
257 /*!
258   Set polygon offset parameters
259   \param factor, units  - Opengl polygon offset parameters
260 */
261 void
262 VTKViewer_Actor
263 ::SetPolygonOffsetParameters(vtkFloatingPointType factor, 
264                              vtkFloatingPointType units)
265 {
266   myPolygonOffsetFactor = factor;
267   myPolygonOffsetUnits = units;
268 }
269
270 /*!
271   Get polygon offset parameters
272   \param factor, units  - Opengl polygon offset parameters
273 */
274 void
275 VTKViewer_Actor
276 ::GetPolygonOffsetParameters(vtkFloatingPointType& factor, 
277                              vtkFloatingPointType& units)
278 {
279   factor = myPolygonOffsetFactor;
280   units = myPolygonOffsetUnits;
281 }
282
283 /*!
284   \return shrink factor
285 */
286 vtkFloatingPointType
287 VTKViewer_Actor
288 ::GetShrinkFactor() 
289
290   return 1.0;
291 }
292
293 /*!
294   \return true if the actor is shrunkable
295 */
296 bool
297 VTKViewer_Actor
298 ::IsShrunkable() 
299
300   return false;
301 }
302
303 /*!
304   \return true if the actor is shrunk
305 */
306 bool
307 VTKViewer_Actor
308 ::IsShrunk() 
309
310   return false;
311 }
312
313 /*!
314   Insert shrink filter into pipeline
315 */
316 void
317 VTKViewer_Actor
318 ::SetShrink() 
319 {} 
320
321 /*!
322   Remove shrink filter from pipeline
323 */
324 void
325 VTKViewer_Actor
326 ::UnShrink() 
327 {}
328
329 /*!
330   Allows to get initial #vtkDataSet
331 */
332 vtkDataSet* 
333 VTKViewer_Actor
334 ::GetInput()
335 {
336   return myPassFilter.front()->GetOutput();
337 }
338
339 /*!
340   To calculatate last modified time
341 */
342 unsigned long int
343 VTKViewer_Actor
344 ::GetMTime()
345 {
346   unsigned long mTime = this->Superclass::GetMTime();
347   unsigned long time = myTransformFilter->GetMTime();
348   mTime = ( time > mTime ? time : mTime );
349   if(vtkDataSet *aDataSet = dynamic_cast<vtkDataSet*>(myPassFilter[0]->GetInput())){ // bad usage of GetInput
350     time = aDataSet->GetMTime();
351     mTime = ( time > mTime ? time : mTime );
352   }
353   return mTime;
354 }
355
356 /*!
357   Set representation (VTK_SURFACE, VTK_POINTS, VTK_WIREFRAME and so on)
358   param theMode - new mode
359 */
360 void
361 VTKViewer_Actor
362 ::SetRepresentation(int theMode) 
363
364   switch(myRepresentation){
365   case VTK_POINTS : 
366   case VTK_SURFACE : 
367     myProperty->SetAmbient(GetProperty()->GetAmbient());
368     myProperty->SetDiffuse(GetProperty()->GetDiffuse());
369     myProperty->SetSpecular(GetProperty()->GetSpecular());
370     break;
371   }    
372
373   switch(theMode){
374   case VTK_POINTS : 
375   case VTK_SURFACE : 
376     GetProperty()->SetAmbient(myProperty->GetAmbient());
377     GetProperty()->SetDiffuse(myProperty->GetDiffuse());
378     GetProperty()->SetSpecular(myProperty->GetSpecular());
379     break;
380   default:
381     GetProperty()->SetAmbient(1.0);
382     GetProperty()->SetDiffuse(0.0);
383     GetProperty()->SetSpecular(0.0);
384   }
385
386   switch(theMode){
387   case 3 : 
388     myGeomFilter->SetInside(true);
389     myGeomFilter->SetWireframeMode(true);
390     GetProperty()->SetRepresentation(VTK_WIREFRAME);
391     break;
392   case VTK_POINTS : 
393     GetProperty()->SetPointSize(VTKViewer_POINT_SIZE);  
394     GetProperty()->SetRepresentation(theMode);
395     myGeomFilter->SetWireframeMode(false);
396     myGeomFilter->SetInside(false);
397     break;
398   case VTK_WIREFRAME : 
399     GetProperty()->SetRepresentation(theMode);
400     myGeomFilter->SetWireframeMode(true);
401     myGeomFilter->SetInside(false);
402     break;
403   case VTK_SURFACE : 
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   \return display mode
616 */
617 int
618 VTKViewer_Actor
619 ::getDisplayMode()
620
621   return myDisplayMode; 
622 }
623
624 /*!
625   Change display mode
626 */
627 void
628 VTKViewer_Actor
629 ::setDisplayMode(int theMode)
630
631   SetRepresentation(theMode + 1); 
632   myDisplayMode = GetRepresentation() - 1;
633 }
634
635
636 /*!
637   \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
638 */
639 bool
640 VTKViewer_Actor
641 ::hasHighlight() 
642
643   return false; 
644
645
646 /*!
647   \return true if the VTKViewer_Actor is already highlighted
648 */
649 bool
650 VTKViewer_Actor
651 ::isHighlighted() 
652
653   return myIsHighlighted; 
654 }
655
656 /*!
657   Set preselection mode
658 */
659 void
660 VTKViewer_Actor
661 ::SetPreSelected(bool thePreselect) 
662
663   myIsPreselected = thePreselect;
664 }
665
666 /*!
667   Just to update visibility of the highlight devices
668 */
669 void
670 VTKViewer_Actor
671 ::highlight(bool theIsHighlight)
672 {
673   myIsHighlighted = theIsHighlight; 
674 }
675
676 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty);