Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / SVTK / SVTK_DeviceActor.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 //  SVTK OBJECT : interactive object for SVTK visualization
23 //  File   : SVTK_DeviceActor.cxx
24 //  Author : 
25 //  Module : 
26 //  $Header$
27 //
28 #include "SVTK_DeviceActor.h"
29
30 #include "VTKViewer_Transform.h"
31 #include "VTKViewer_TransformFilter.h"
32 #include "VTKViewer_GeometryFilter.h"
33
34 // VTK Includes
35 #include <vtkObjectFactory.h>
36 #include <vtkShrinkFilter.h>
37 #include <vtkFeatureEdges.h>
38
39 #include <vtkPolyData.h>
40 #include <vtkUnstructuredGrid.h>
41
42 #include <vtkPolyDataMapper.h>
43 #include <vtkDataSetMapper.h>
44
45 #include <vtkPassThroughFilter.h>
46
47 using namespace std;
48
49 vtkStandardNewMacro(SVTK_DeviceActor);
50
51 /*!
52   Constructor
53 */
54 SVTK_DeviceActor
55 ::SVTK_DeviceActor()
56 {
57   myIsShrunk = false;
58   myIsShrinkable = true;
59
60   myIsFeatureEdgesAllowed = false;
61   myIsFeatureEdgesEnabled = false;
62
63   myIsShaded = true;
64   myProperty = vtkProperty::New();
65   myRepresentation = SVTK::Representation::Surface;
66
67   myIsResolveCoincidentTopology = true;
68   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
69                                                                  myPolygonOffsetUnits);
70
71   myMapper = vtkDataSetMapper::New();
72
73   myShrinkFilter = vtkShrinkFilter::New();
74
75   myFeatureEdges = vtkFeatureEdges::New();
76
77   myGeomFilter = VTKViewer_GeometryFilter::New();
78
79   myTransformFilter = VTKViewer_TransformFilter::New();
80
81   for(int i = 0; i < 6; i++)
82     myPassFilter.push_back(vtkPassThroughFilter::New());
83 }
84
85 /*!
86   Destructor
87 */
88 SVTK_DeviceActor
89 ::~SVTK_DeviceActor()
90 {
91   myMapper->Delete();
92
93   myProperty->Delete();
94
95   myGeomFilter->Delete();
96
97   myTransformFilter->Delete();
98
99   myShrinkFilter->Delete();
100
101   myFeatureEdges->Delete();
102
103   for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
104     myPassFilter[i]->Delete();
105 }
106
107 /*!
108   To insert some additional filters and then sets the given vtkMapper
109 */
110 void
111 SVTK_DeviceActor
112 ::SetMapper(vtkMapper* theMapper)
113 {
114   InitPipeLine(theMapper);
115 }
116
117 /*!
118   To initialize internal pipeline
119 */
120 void
121 SVTK_DeviceActor
122 ::InitPipeLine(vtkMapper* theMapper)
123 {
124   if(theMapper){
125     int anId = 0;
126     myPassFilter[ anId ]->SetInput( theMapper->GetInput() );
127     myPassFilter[ anId + 1]->SetInput( myPassFilter[ anId ]->GetOutput() );
128     
129     anId++; // 1
130     myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
131
132     anId++; // 2
133     myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() ); 
134     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
135
136     anId++; // 3
137     myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
138
139     anId++; // 4
140     myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
141     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
142
143     anId++; // 5
144     if(vtkDataSetMapper* aMapper = dynamic_cast<vtkDataSetMapper*>(theMapper)){
145       aMapper->SetInput(myPassFilter[anId]->GetOutput());
146     }else if(vtkPolyDataMapper* aMapper = dynamic_cast<vtkPolyDataMapper*>(theMapper)){
147       aMapper->SetInput(myPassFilter[anId]->GetPolyDataOutput());
148     }
149   }
150   Superclass::SetMapper(theMapper);
151 }
152
153 /*!
154   Allows to get initial vtkDataSet
155 */
156 vtkDataSet* 
157 SVTK_DeviceActor
158 ::GetInput()
159 {
160   return myPassFilter.front()->GetOutput();
161 }
162
163 /*!
164   Allows to set initial vtkDataSet
165 */
166 void
167 SVTK_DeviceActor
168 ::SetInput(vtkDataSet* theDataSet)
169 {
170   myMapper->SetInput(theDataSet);
171   InitPipeLine(myMapper);
172 }
173
174 /*!
175   To provide VTK to Object and backward mapping
176 */
177 void
178 SVTK_DeviceActor::
179 SetStoreMapping(bool theStoreMapping)
180 {
181   myGeomFilter->SetStoreMapping(theStoreMapping);
182 }
183
184
185 /*!
186   \return time of modification
187 */
188 unsigned long int 
189 SVTK_DeviceActor
190 ::GetMTime()
191 {
192   unsigned long mTime = this->Superclass::GetMTime();
193
194   mTime = max(mTime,myGeomFilter->GetMTime());
195
196   mTime = max(mTime,myTransformFilter->GetMTime());
197
198   if(myIsShrunk)
199     mTime = max(mTime,myShrinkFilter->GetMTime());
200
201   if(myIsFeatureEdgesEnabled)
202     mTime = max(mTime,myFeatureEdges->GetMTime());
203
204   for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++)
205     max(mTime,myPassFilter[i]->GetMTime());
206
207   return mTime;
208 }
209
210 /*!
211   Apply a view transformation
212   \param theTransform - transformation
213 */
214 void 
215 SVTK_DeviceActor
216 ::SetTransform(VTKViewer_Transform* theTransform)
217 {
218   myTransformFilter->SetTransform(theTransform);
219 }
220
221 /*!
222   \return true if actor is shrinkable
223 */
224 bool
225 SVTK_DeviceActor
226 ::IsShrunkable() 
227
228   return myIsShrinkable;
229 }
230
231 /*!
232   Changes shrinkable state of actor
233   theIsShrinkable - new shrinkable state
234 */  
235 void
236 SVTK_DeviceActor
237 ::SetShrinkable(bool theIsShrinkable) 
238
239   myIsShrinkable = theIsShrinkable;
240 }
241   
242 /*!
243   \return true if actor is shrunkable
244 */
245 bool
246 SVTK_DeviceActor
247 ::IsShrunk() 
248
249   return myIsShrunk;
250 }
251
252 /*!
253   Insert shrink filter into pipeline
254 */
255 void
256 SVTK_DeviceActor
257 ::SetShrink() 
258 {
259   if ( !myIsShrinkable ) 
260     return;
261   
262   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
263   {     
264     aDataSet->Update();
265     int numCells=aDataSet->GetNumberOfCells();
266     int numPts = aDataSet->GetNumberOfPoints();
267     //It's impossible to use to apply "shrink" for "empty" dataset
268     if (numCells < 1 || numPts < 1)
269             return;
270     myShrinkFilter->SetInput( aDataSet );
271     myPassFilter[ 1 ]->SetInput( myShrinkFilter->GetOutput() );
272     myIsShrunk = true;
273   }
274 }
275
276 /*!
277   Remove shrink filter from pipeline
278 */
279 void 
280 SVTK_DeviceActor
281 ::UnShrink() 
282 {
283   if ( !myIsShrunk ) return;
284   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
285   {    
286     myPassFilter[ 1 ]->SetInput( aDataSet );
287     myIsShrunk = false;
288   }
289 }
290
291 /*!
292   \return shrink factor
293 */
294 vtkFloatingPointType
295 SVTK_DeviceActor
296 ::GetShrinkFactor()
297 {
298   return myShrinkFilter->GetShrinkFactor();
299 }
300
301 /*!
302   Changes shrink factor
303   \param theValue - new shrink factor
304 */
305 void 
306 SVTK_DeviceActor
307 ::SetShrinkFactor(vtkFloatingPointType theValue)
308 {
309   myShrinkFilter->SetShrinkFactor(theValue);
310 }
311
312 /*!
313   \return true if feature edges are allowed for this actor
314 */
315 bool
316 SVTK_DeviceActor
317 ::IsFeatureEdgesAllowed() 
318
319   return myIsFeatureEdgesAllowed;
320 }
321
322 /*!
323   Allows feature edges for this actor on or off
324   \param theIsFeatureEdgesAllowed - flag which allows feature edges for this actor on or off
325 */
326 void
327 SVTK_DeviceActor
328 ::SetFeatureEdgesAllowed(bool theIsFeatureEdgesAllowed)
329 {
330   myIsFeatureEdgesAllowed = theIsFeatureEdgesAllowed;
331 }
332
333 /*!
334   \return true if feature edges are enabled
335 */
336 bool
337 SVTK_DeviceActor
338 ::IsFeatureEdgesEnabled()
339 {
340   return myIsFeatureEdgesEnabled;
341 }
342
343 /*!
344   Enables feature edges on or off
345   \param theIsFeatureEdgesEnabled - flag which enables feature edges on or off
346 */
347 void
348 SVTK_DeviceActor
349 ::SetFeatureEdgesEnabled(bool theIsFeatureEdgesEnabled)
350 {
351   if ( !myIsFeatureEdgesAllowed || myIsFeatureEdgesEnabled == theIsFeatureEdgesEnabled ) 
352     return;
353
354   if ( vtkPolyData* aPolyData = myPassFilter[ 2 ]->GetPolyDataOutput() )
355   {
356     if( theIsFeatureEdgesEnabled )
357     {
358       aPolyData->Update();
359       myFeatureEdges->SetInput( aPolyData );
360       myPassFilter[ 3 ]->SetInput( myFeatureEdges->GetOutput() );
361       myIsFeatureEdgesEnabled = true;
362     }
363     else
364     {
365       myPassFilter[3]->SetInput( aPolyData );
366       myIsFeatureEdgesEnabled = false;
367     }
368     myIsFeatureEdgesEnabled = theIsFeatureEdgesEnabled;
369   }
370 }
371
372 /*!
373   \return angle of feature edges' filter
374 */
375 vtkFloatingPointType
376 SVTK_DeviceActor
377 ::GetFeatureEdgesAngle()
378 {
379   return myFeatureEdges->GetFeatureAngle();
380 }
381
382 /*!
383   Sets angle of feature edges' filter
384   \param theAngle angle of feature edges' filter
385 */
386 void
387 SVTK_DeviceActor
388 ::SetFeatureEdgesAngle(vtkFloatingPointType theAngle)
389 {
390   myFeatureEdges->SetFeatureAngle(theAngle);
391 }
392
393 /*!
394   Gets information about kinds of edges which are displayed by feature edges' filter
395   \param theIsFeatureEdges flag which shows whether feature edges are displayed
396   \param theIsBoundaryEdges flag which shows whether boundary edges are displayed
397   \param theIsManifoldEdges flag which shows whether manifold edges are displayed
398   \param theIsNonManifoldEdges flag which shows whether non-manifold edges are displayed
399 */
400 void
401 SVTK_DeviceActor
402 ::GetFeatureEdgesFlags(bool& theIsFeatureEdges,
403                        bool& theIsBoundaryEdges,
404                        bool& theIsManifoldEdges,
405                        bool& theIsNonManifoldEdges)
406 {
407   theIsFeatureEdges = myFeatureEdges->GetFeatureEdges();
408   theIsBoundaryEdges = myFeatureEdges->GetBoundaryEdges();
409   theIsManifoldEdges = myFeatureEdges->GetManifoldEdges();
410   theIsNonManifoldEdges = myFeatureEdges->GetNonManifoldEdges();
411 }
412
413 /*!
414   Sets different kinds of edges to be displayed by feature edges' filter
415   \param theIsFeatureEdges flag which displays feature edges
416   \param theIsBoundaryEdges flag which displays boundary edges
417   \param theIsManifoldEdges flag which displays manifold edges
418   \param theIsNonManifoldEdges flag which displays non-manifold edges
419 */
420 void
421 SVTK_DeviceActor
422 ::SetFeatureEdgesFlags(bool theIsFeatureEdges,
423                        bool theIsBoundaryEdges,
424                        bool theIsManifoldEdges,
425                        bool theIsNonManifoldEdges)
426 {
427   myFeatureEdges->SetFeatureEdges(theIsFeatureEdges);
428   myFeatureEdges->SetBoundaryEdges(theIsBoundaryEdges);
429   myFeatureEdges->SetManifoldEdges(theIsManifoldEdges);
430   myFeatureEdges->SetNonManifoldEdges(theIsNonManifoldEdges);
431 }
432
433 /*!
434   \return feature edges' coloring flag
435 */
436 bool
437 SVTK_DeviceActor
438 ::GetFeatureEdgesColoring()
439 {
440   return myFeatureEdges->GetColoring();
441 }
442
443 /*!
444   Sets feature edges' coloring flag
445   \param theIsColoring feature edges' coloring flag
446 */
447 void
448 SVTK_DeviceActor
449 ::SetFeatureEdgesColoring(bool theIsColoring)
450 {
451   myFeatureEdges->SetColoring(theIsColoring);
452 }
453
454 /*!
455   Set representation (VTK_SURFACE, VTK_POINTS, VTK_WIREFRAME and so on)
456   param theMode - new mode
457 */
458 void
459 SVTK_DeviceActor
460 ::SetRepresentation(SVTK::Representation::Type theMode)
461
462   using namespace SVTK::Representation;
463   if(IsShaded()){
464     switch(myRepresentation){
465     case Points : 
466     case Surface : 
467       myProperty->SetAmbient(GetProperty()->GetAmbient());
468       myProperty->SetDiffuse(GetProperty()->GetDiffuse());
469       myProperty->SetSpecular(GetProperty()->GetSpecular());
470     }
471     
472     switch(theMode){
473     case Points : 
474     case Surface : 
475       GetProperty()->SetAmbient(myProperty->GetAmbient());
476       GetProperty()->SetDiffuse(myProperty->GetDiffuse());
477       GetProperty()->SetSpecular(myProperty->GetSpecular());
478       break;
479     default:
480       GetProperty()->SetAmbient(1.0);
481       GetProperty()->SetDiffuse(0.0);
482       GetProperty()->SetSpecular(0.0);
483     }
484   }
485
486   switch(theMode){
487   case Insideframe : 
488     myGeomFilter->SetInside(true);
489     myGeomFilter->SetWireframeMode(true);
490     GetProperty()->SetRepresentation(VTK_WIREFRAME);
491     break;
492   case Points : 
493     GetProperty()->SetPointSize(GetDefaultPointSize());  
494     GetProperty()->SetRepresentation(VTK_POINTS);
495     myGeomFilter->SetWireframeMode(false);
496     myGeomFilter->SetInside(false);
497     break;
498   case Wireframe : 
499     GetProperty()->SetRepresentation(VTK_WIREFRAME);
500     myGeomFilter->SetWireframeMode(true);
501     myGeomFilter->SetInside(false);
502     break;
503   case Surface : 
504     GetProperty()->SetRepresentation(VTK_SURFACE);
505     myGeomFilter->SetWireframeMode(false);
506     myGeomFilter->SetInside(false);
507     break;
508   }
509
510   myRepresentation = theMode;
511 }
512
513 /*!
514   \return current representation mode
515 */
516 SVTK::Representation::Type 
517 SVTK_DeviceActor
518 ::GetRepresentation()
519 {
520   return myRepresentation;
521 }
522
523 /*!
524   \return default point size
525 */
526 vtkFloatingPointType
527 SVTK_DeviceActor
528 ::GetDefaultPointSize()
529 {
530   return 5;
531 }
532
533 /*!
534   \return default line width
535 */
536 vtkFloatingPointType
537 SVTK_DeviceActor
538 ::GetDefaultLineWidth()
539 {
540   return 3;
541 }
542
543 /*!
544   \return true if actor is shaded
545 */
546 bool
547 SVTK_DeviceActor
548 ::IsShaded()
549 {
550   return myIsShaded;
551 }
552
553 /*!
554   Sets shaded state of actor
555   \param theShaded - new shaded state
556 */
557 void
558 SVTK_DeviceActor
559 ::SetShaded(bool theShaded)
560 {
561   myIsShaded = theShaded;
562 }
563
564 /*!
565   Maps VTK index of a node to corresponding object index
566 */
567 int
568 SVTK_DeviceActor
569 ::GetNodeObjId(int theVtkID)
570 {
571   return theVtkID;
572 }
573
574 /*!
575   Get coordinates of a node for given object index
576 */
577 vtkFloatingPointType* 
578 SVTK_DeviceActor
579 ::GetNodeCoord(int theObjID)
580 {
581   return GetInput()->GetPoint(theObjID);
582 }
583
584
585 /*!
586   Get corresponding #vtkCell for given object index
587 */
588 vtkCell* 
589 SVTK_DeviceActor
590 ::GetElemCell(int theObjID)
591 {
592   return GetInput()->GetCell(theObjID);
593 }
594
595 /*!
596   Maps VTK index of a cell to corresponding object index
597 */
598 int
599 SVTK_DeviceActor
600 ::GetElemObjId(int theVtkID) 
601
602   return theVtkID;
603 }
604
605 /*!
606   Renders actor
607 */
608 void
609 SVTK_DeviceActor
610 ::Render(vtkRenderer *ren, vtkMapper* m)
611 {
612   if(myIsResolveCoincidentTopology){
613     int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
614     vtkFloatingPointType aFactor, aUnit; 
615     vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
616     
617     vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
618     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
619                                                                    myPolygonOffsetUnits);
620     Superclass::Render(ren,m);
621     
622     vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnit);
623     vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
624   }else{
625     Superclass::Render(ren,m);
626   }
627 }
628
629 /*!
630   Set polygon offset parameters
631   \param factor, units  - Opengl polygon offset parameters
632 */
633 void
634 SVTK_DeviceActor
635 ::SetPolygonOffsetParameters(vtkFloatingPointType factor, 
636                              vtkFloatingPointType units)
637 {
638   myPolygonOffsetFactor = factor;
639   myPolygonOffsetUnits = units;
640 }
641
642 /*!
643   Get polygon offset parameters
644   \param factor, units  - Opengl polygon offset parameters
645 */
646 void
647 SVTK_DeviceActor
648 ::GetPolygonOffsetParameters(vtkFloatingPointType& factor, 
649                              vtkFloatingPointType& units)
650 {
651   factor = myPolygonOffsetFactor;
652   units = myPolygonOffsetUnits;
653 }
654
655 vtkDataSetMapper* SVTK_DeviceActor::GetDataSetMapper()
656 {
657   return myMapper;
658 }