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