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