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