]> SALOME platform Git repositories - modules/gui.git/blob - src/VTKViewer/VTKViewer_Actor.cxx
Salome HOME
Merge from V6_main (04/10/2012)
[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 material
625 */
626 vtkProperty* 
627 VTKViewer_Actor
628 ::GetMaterial()
629 {
630   return NULL;
631 }
632
633 /*!
634   \return display mode
635 */
636 int
637 VTKViewer_Actor
638 ::getDisplayMode()
639
640   return myDisplayMode; 
641 }
642
643 /*!
644   Change display mode
645 */
646 void
647 VTKViewer_Actor
648 ::setDisplayMode(int theMode)
649
650   SetRepresentation(theMode + 1); 
651   myDisplayMode = GetRepresentation() - 1;
652 }
653
654
655 /*!
656   \return true if the descendant of the VTKViewer_Actor will implement its own highlight or not
657 */
658 bool
659 VTKViewer_Actor
660 ::hasHighlight() 
661
662   return false; 
663
664
665 /*!
666   \return true if the VTKViewer_Actor is already highlighted
667 */
668 bool
669 VTKViewer_Actor
670 ::isHighlighted() 
671
672   return myIsHighlighted; 
673 }
674
675 /*!
676   \return true if the VTKViewer_Actor is already preselected
677 */
678 bool
679 VTKViewer_Actor
680 ::isPreselected() 
681
682   return myIsPreselected; 
683 }
684
685 /*!
686   Set preselection mode
687 */
688 void
689 VTKViewer_Actor
690 ::SetPreSelected(bool thePreselect) 
691
692   myIsPreselected = thePreselect;
693 }
694
695 /*!
696   Just to update visibility of the highlight devices
697 */
698 void
699 VTKViewer_Actor
700 ::highlight(bool theIsHighlight)
701 {
702   myIsHighlighted = theIsHighlight; 
703 }
704
705 /*!
706  * On/Off representation 2D quadratic element as arked polygon
707  */
708 void VTKViewer_Actor::SetQuadraticArcMode(bool theFlag){
709   myGeomFilter->SetQuadraticArcMode(theFlag);
710 }
711
712 /*!
713  * Return true if 2D quadratic element displayed as arked polygon
714  */
715 bool VTKViewer_Actor::GetQuadraticArcMode() const{
716   return myGeomFilter->GetQuadraticArcMode();
717 }
718 /*!
719  * Set Max angle for representation 2D quadratic element as arked polygon
720  */
721 void VTKViewer_Actor::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle){
722   myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
723 }
724
725 /*!
726  * Return Max angle of the representation 2D quadratic element as arked polygon
727  */
728 vtkFloatingPointType VTKViewer_Actor::GetQuadraticArcAngle() const{
729   return myGeomFilter->GetQuadraticArcAngle();
730 }
731
732 /*!
733  * Return pointer to the dataset, which used to calculation of the bounding box of the actor.
734  * By default it is the input dataset.
735  */
736 vtkDataSet* VTKViewer_Actor::GetHighlightedDataSet() {
737   return GetInput();
738 }
739
740
741
742 vtkCxxSetObjectMacro(VTKViewer_Actor,PreviewProperty,vtkProperty);