Salome HOME
257fcd9f8b08d35b8cced1196d6a4b226088ec3d
[modules/smesh.git] / src / OBJECT / SMESH_DeviceActor.cxx
1 //  SMESH OBJECT : interactive object for SMESH visualization
2 //
3 //  Copyright (C) 2003  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 //
24 //  File   : SMESH_DeviceActor.cxx
25 //  Author : 
26 //  Module : SMESH
27 //  $Header$
28
29
30 #include "SMESH_DeviceActor.h"
31 #include "SMESH_ExtractGeometry.h"
32 #include "SMESH_ControlsDef.hxx"
33 #include "SMESH_ActorUtils.h"
34 #include "SMESH_FaceOrientationFilter.h"
35 #include "VTKViewer_CellLocationsArray.h"
36
37 #include <VTKViewer_Transform.h>
38 #include <VTKViewer_TransformFilter.h>
39 #include <VTKViewer_ExtractUnstructuredGrid.h>
40
41 // VTK Includes
42 #include <vtkObjectFactory.h>
43 #include <vtkShrinkFilter.h>
44 #include <vtkShrinkPolyData.h>
45
46 #include <vtkProperty.h>
47 #include <vtkPolyData.h>
48 #include <vtkMergeFilter.h>
49 #include <vtkPolyDataMapper.h>
50 #include <vtkUnstructuredGrid.h>
51
52 #include <vtkScalarBarActor.h>
53 #include <vtkLookupTable.h>
54 #include <vtkDoubleArray.h>
55 #include <vtkCellData.h>
56
57 #include <vtkCell.h>
58 #include <vtkIdList.h>
59 #include <vtkCellArray.h>
60 #include <vtkUnsignedCharArray.h>
61
62 #include <vtkImplicitBoolean.h>
63 #include <vtkPassThroughFilter.h>
64
65 #include <vtkRenderer.h>
66
67 #include "utilities.h"
68
69 #ifdef _DEBUG_
70 static int MYDEBUG = 0;
71 #else
72 static int MYDEBUG = 0;
73 #endif
74
75 using namespace std;
76
77
78 vtkStandardNewMacro(SMESH_DeviceActor);
79
80
81 SMESH_DeviceActor
82 ::SMESH_DeviceActor()
83 {
84   if(MYDEBUG) MESSAGE("SMESH_DeviceActor - "<<this);
85
86   myIsShrinkable = false;
87   myIsShrunk = false;
88   myIsHighlited = false;
89
90   myRepresentation = eSurface;
91
92   myProperty = vtkProperty::New();
93   myMapper = vtkPolyDataMapper::New();
94
95   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
96                                                                  myPolygonOffsetUnits);
97
98   myMapper->UseLookupTableScalarRangeOn();
99   myMapper->SetColorModeToMapScalars();
100
101   myShrinkFilter = vtkShrinkFilter::New();
102
103   myStoreClippingMapping = false;
104
105   myExtractGeometry = SMESH_ExtractGeometry::New();
106   myExtractGeometry->SetReleaseDataFlag(true);
107   myIsImplicitFunctionUsed = false;
108
109   myExtractUnstructuredGrid = VTKViewer_ExtractUnstructuredGrid::New();
110     
111   myMergeFilter = vtkMergeFilter::New();
112
113   myGeomFilter = VTKViewer_GeometryFilter::New();
114
115   myTransformFilter = VTKViewer_TransformFilter::New();
116
117   for(int i = 0; i < 6; i++)
118     myPassFilter.push_back(vtkPassThroughFilter::New());
119
120   // Orientation of faces
121   myIsFacesOriented = false;
122
123   vtkFloatingPointType anRGB[3] = { 1, 1, 1 };
124   SMESH::GetColor( "SMESH", "orientation_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
125
126   myFaceOrientationFilter = SMESH_FaceOrientationFilter::New();
127
128   myFaceOrientationDataMapper = vtkPolyDataMapper::New();
129   myFaceOrientationDataMapper->SetInput(myFaceOrientationFilter->GetOutput());
130
131   myFaceOrientation = vtkActor::New();
132   myFaceOrientation->SetMapper(myFaceOrientationDataMapper);
133   myFaceOrientation->GetProperty()->SetColor(anRGB[0], anRGB[1], anRGB[2]);
134 }
135
136
137 SMESH_DeviceActor
138 ::~SMESH_DeviceActor()
139 {
140   if(MYDEBUG) MESSAGE("~SMESH_DeviceActor - "<<this);
141
142   myProperty->Delete();
143
144   myMapper->Delete();
145
146   myShrinkFilter->Delete();
147
148   myExtractUnstructuredGrid->Delete();
149
150   myMergeFilter->Delete();
151
152   myGeomFilter->Delete();
153
154   myExtractGeometry->Delete();
155
156   myTransformFilter->Delete();
157
158   for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++){
159     myPassFilter[i]->Delete();
160   }
161
162   // Orientation of faces
163   myFaceOrientationFilter->Delete();
164
165   myFaceOrientationDataMapper->RemoveAllInputs();
166   myFaceOrientationDataMapper->Delete();
167
168   myFaceOrientation->Delete();
169 }
170
171
172 void
173 SMESH_DeviceActor
174 ::SetStoreGemetryMapping(bool theStoreMapping)
175 {
176   myGeomFilter->SetStoreMapping(theStoreMapping);
177   SetStoreClippingMapping(theStoreMapping);
178 }
179
180
181 void
182 SMESH_DeviceActor
183 ::SetStoreClippingMapping(bool theStoreMapping)
184 {
185   myStoreClippingMapping = theStoreMapping;
186   myExtractGeometry->SetStoreMapping(theStoreMapping && myIsImplicitFunctionUsed);
187   SetStoreIDMapping(theStoreMapping);
188 }
189
190
191 void
192 SMESH_DeviceActor
193 ::SetStoreIDMapping(bool theStoreMapping)
194 {
195   myExtractUnstructuredGrid->SetStoreMapping(theStoreMapping);
196 }
197
198
199 void 
200 SMESH_DeviceActor
201 ::Init(TVisualObjPtr theVisualObj, 
202        vtkImplicitBoolean* theImplicitBoolean)
203 {
204   myVisualObj = theVisualObj;
205   myExtractGeometry->SetImplicitFunction(theImplicitBoolean);
206   SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
207 }
208
209
210 void
211 SMESH_DeviceActor
212 ::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
213 {
214   int anId = 0;
215   if(theIsImplicitFunctionUsed)
216     myPassFilter[ anId ]->SetInput( myExtractGeometry->GetOutput() );
217   else
218     myPassFilter[ anId ]->SetInput( myMergeFilter->GetOutput() );
219     
220   myIsImplicitFunctionUsed = theIsImplicitFunctionUsed;
221   SetStoreClippingMapping(myStoreClippingMapping);
222 }
223
224
225 void
226 SMESH_DeviceActor
227 ::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid)
228 {
229   if(theGrid){
230     //myIsShrinkable = theGrid->GetNumberOfCells() > 10;
231     myIsShrinkable = true;
232
233     myExtractUnstructuredGrid->SetInput(theGrid);
234
235     myMergeFilter->SetGeometry(myExtractUnstructuredGrid->GetOutput());
236
237     myExtractGeometry->SetInput(myMergeFilter->GetOutput());
238
239     int anId = 0;
240     SetImplicitFunctionUsed(myIsImplicitFunctionUsed);
241     myPassFilter[ anId + 1]->SetInput( myPassFilter[ anId ]->GetOutput() );
242     
243     anId++; // 1
244     myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
245
246     anId++; // 2
247     myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() ); 
248     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
249
250     anId++; // 3
251     myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
252
253     anId++; // 4
254     myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
255     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
256
257     anId++; // 5
258     myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
259
260     vtkLODActor::SetMapper( myMapper );
261     Modified();
262   }
263 }
264
265
266 VTKViewer_ExtractUnstructuredGrid* 
267 SMESH_DeviceActor
268 ::GetExtractUnstructuredGrid()
269 {
270   return myExtractUnstructuredGrid;
271 }
272
273
274 vtkUnstructuredGrid* 
275 SMESH_DeviceActor
276 ::GetUnstructuredGrid()
277 {
278   myExtractUnstructuredGrid->Update();
279   return myExtractUnstructuredGrid->GetOutput();
280 }
281
282
283 void
284 SMESH_DeviceActor
285 ::SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
286                  vtkScalarBarActor* theScalarBarActor,
287                  vtkLookupTable* theLookupTable)
288 {
289   bool anIsInitialized = theFunctor;
290   if(anIsInitialized){
291     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
292
293     SetStoreIDMapping(true);
294     myExtractUnstructuredGrid->Update();
295     vtkUnstructuredGrid* aGrid = myExtractUnstructuredGrid->GetOutput();
296
297     aDataSet->ShallowCopy(aGrid);
298     
299     vtkDoubleArray *aScalars = vtkDoubleArray::New();
300     vtkIdType aNbCells = aGrid->GetNumberOfCells();
301     aScalars->SetNumberOfComponents(1);
302     aScalars->SetNumberOfTuples(aNbCells);
303     
304     myVisualObj->UpdateFunctor(theFunctor);
305
306     using namespace SMESH::Controls;
307     if(NumericalFunctor* aNumericalFunctor = dynamic_cast<NumericalFunctor*>(theFunctor.get())){
308       for(vtkIdType i = 0; i < aNbCells; i++){
309         vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
310         vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
311         double aValue = aNumericalFunctor->GetValue(anObjId);
312         aScalars->SetValue(i,aValue);
313       }
314     }else if(Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get())){
315       for(vtkIdType i = 0; i < aNbCells; i++){
316         vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
317         vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
318         bool aValue = aPredicate->IsSatisfy(anObjId);
319         aScalars->SetValue(i,aValue);
320       }
321     }
322
323     aDataSet->GetCellData()->SetScalars(aScalars);
324     aScalars->Delete();
325         
326     theLookupTable->SetRange(aScalars->GetRange());
327     theLookupTable->SetNumberOfTableValues(theScalarBarActor->GetMaximumNumberOfColors());
328     theLookupTable->Build();
329     
330     myMergeFilter->SetScalars(aDataSet);
331     aDataSet->Delete();
332   }
333   GetMapper()->SetScalarVisibility(anIsInitialized);
334   theScalarBarActor->SetVisibility(anIsInitialized);
335 }
336
337 void
338 SMESH_DeviceActor
339 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
340                     vtkScalarBarActor* theScalarBarActor,
341                     vtkLookupTable* theLookupTable)
342 {
343   bool anIsInitialized = theFunctor;
344   myExtractUnstructuredGrid->ClearRegisteredCells();
345   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
346   myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
347   myVisualObj->UpdateFunctor(theFunctor);
348
349   using namespace SMESH::Controls;
350   if (anIsInitialized){
351     if (Length2D* aLength2D = dynamic_cast<Length2D*>(theFunctor.get())){
352       SMESH::Controls::Length2D::TValues aValues;
353
354       aLength2D->GetValues(aValues);
355       vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
356       vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
357
358       aDataSet->SetPoints(aGrid->GetPoints());
359       
360       vtkIdType aNbCells = aValues.size();
361       
362       vtkDoubleArray *aScalars = vtkDoubleArray::New();
363       aScalars->SetNumberOfComponents(1);
364       aScalars->SetNumberOfTuples(aNbCells);
365
366       vtkIdType aCellsSize = 3*aNbCells;
367       vtkCellArray* aConnectivity = vtkCellArray::New();
368       aConnectivity->Allocate( aCellsSize, 0 );
369       
370       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
371       aCellTypesArray->SetNumberOfComponents( 1 );
372       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
373       
374       vtkIdList *anIdList = vtkIdList::New();
375       anIdList->SetNumberOfIds(2);
376       
377       Length2D::TValues::const_iterator anIter = aValues.begin();
378       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
379         const Length2D::Value& aValue = *anIter;
380         int aNode[2] = {
381           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
382           myVisualObj->GetNodeVTKId(aValue.myPntId[1])
383         };
384         if(aNode[0] >= 0 && aNode[1] >= 0){
385           anIdList->SetId( 0, aNode[0] );
386           anIdList->SetId( 1, aNode[1] );
387           aConnectivity->InsertNextCell( anIdList );
388           aCellTypesArray->InsertNextValue( VTK_LINE );
389           aScalars->SetValue(aVtkId,aValue.myLength);
390         }
391       }
392       
393       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
394       aCellLocationsArray->SetNumberOfComponents( 1 );
395       aCellLocationsArray->SetNumberOfTuples( aNbCells );
396       
397       aConnectivity->InitTraversal();
398       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
399         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
400       
401       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
402       SetUnstructuredGrid(aDataSet);
403
404       aDataSet->GetCellData()->SetScalars(aScalars);
405       aScalars->Delete();
406       
407       theLookupTable->SetRange(aScalars->GetRange());
408       theLookupTable->Build();
409       
410       myMergeFilter->SetScalars(aDataSet);
411       aDataSet->Delete();
412     }
413     else if (MultiConnection2D* aMultiConnection2D = dynamic_cast<MultiConnection2D*>(theFunctor.get())){
414       SMESH::Controls::MultiConnection2D::MValues aValues;
415
416       aMultiConnection2D->GetValues(aValues);
417       vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
418       vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
419       aDataSet->SetPoints(aGrid->GetPoints());
420       
421       vtkIdType aNbCells = aValues.size();
422       vtkDoubleArray *aScalars = vtkDoubleArray::New();
423       aScalars->SetNumberOfComponents(1);
424       aScalars->SetNumberOfTuples(aNbCells);
425
426       vtkIdType aCellsSize = 3*aNbCells;
427       vtkCellArray* aConnectivity = vtkCellArray::New();
428       aConnectivity->Allocate( aCellsSize, 0 );
429       
430       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
431       aCellTypesArray->SetNumberOfComponents( 1 );
432       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
433       
434       vtkIdList *anIdList = vtkIdList::New();
435       anIdList->SetNumberOfIds(2);
436       
437       MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
438       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
439         const MultiConnection2D::Value& aValue = (*anIter).first;
440         int aNode[2] = {
441           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
442           myVisualObj->GetNodeVTKId(aValue.myPntId[1])
443         };
444         if(aNode[0] >= 0 && aNode[1] >= 0){
445           anIdList->SetId( 0, aNode[0] );
446           anIdList->SetId( 1, aNode[1] );
447           aConnectivity->InsertNextCell( anIdList );
448           aCellTypesArray->InsertNextValue( VTK_LINE );
449           aScalars->SetValue(aVtkId,(*anIter).second);
450         }
451       }
452       
453       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
454       aCellLocationsArray->SetNumberOfComponents( 1 );
455       aCellLocationsArray->SetNumberOfTuples( aNbCells );
456       
457       aConnectivity->InitTraversal();
458       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
459         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
460       
461       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
462       SetUnstructuredGrid(aDataSet);
463
464       aDataSet->GetCellData()->SetScalars(aScalars);
465       aScalars->Delete();
466       
467       theLookupTable->SetRange(aScalars->GetRange());
468       theLookupTable->Build();
469       
470       myMergeFilter->SetScalars(aDataSet);
471       aDataSet->Delete();
472     }
473   }
474   GetMapper()->SetScalarVisibility(anIsInitialized);
475   theScalarBarActor->SetVisibility(anIsInitialized);
476 }
477
478 void
479 SMESH_DeviceActor
480 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor)
481 {
482   myExtractUnstructuredGrid->ClearRegisteredCells();
483   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
484   myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
485   myVisualObj->UpdateFunctor(theFunctor);
486
487   using namespace SMESH::Controls;
488   if(FreeBorders* aFreeBorders = dynamic_cast<FreeBorders*>(theFunctor.get())){
489     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
490     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
491     vtkIdType aNbCells = aGrid->GetNumberOfCells();
492     for( vtkIdType i = 0; i < aNbCells; i++ ){
493       vtkIdType anObjId = myVisualObj->GetElemObjId(i);
494       if(aFreeBorders->IsSatisfy(anObjId))
495         myExtractUnstructuredGrid->RegisterCell(i);
496     }
497     if(!myExtractUnstructuredGrid->IsCellsRegistered())
498       myExtractUnstructuredGrid->RegisterCell(-1);
499     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
500   }else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get())){
501     SMESH::Controls::FreeEdges::TBorders aBorders;
502     aFreeEdges->GetBoreders(aBorders);
503     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
504     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
505     aDataSet->SetPoints(aGrid->GetPoints());
506
507     vtkIdType aNbCells = aBorders.size();
508     vtkIdType aCellsSize = 3*aNbCells;
509     vtkCellArray* aConnectivity = vtkCellArray::New();
510     aConnectivity->Allocate( aCellsSize, 0 );
511     
512     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
513     aCellTypesArray->SetNumberOfComponents( 1 );
514     aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
515     
516     vtkIdList *anIdList = vtkIdList::New();
517     anIdList->SetNumberOfIds(2);
518     
519     FreeEdges::TBorders::const_iterator anIter = aBorders.begin();
520     for(; anIter != aBorders.end(); anIter++){
521       const FreeEdges::Border& aBorder = *anIter;
522       int aNode[2] = {
523         myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
524         myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
525       };
526       //cout<<"aNode = "<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<endl;
527       if(aNode[0] >= 0 && aNode[1] >= 0){
528         anIdList->SetId( 0, aNode[0] );
529         anIdList->SetId( 1, aNode[1] );
530         aConnectivity->InsertNextCell( anIdList );
531         aCellTypesArray->InsertNextValue( VTK_LINE );
532       }
533     }
534     
535     VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
536     aCellLocationsArray->SetNumberOfComponents( 1 );
537     aCellLocationsArray->SetNumberOfTuples( aNbCells );
538     
539     aConnectivity->InitTraversal();
540     for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
541       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
542     
543     aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
544
545     SetUnstructuredGrid(aDataSet);
546     aDataSet->Delete();
547   }
548 }
549
550
551
552
553 unsigned long int 
554 SMESH_DeviceActor
555 ::GetMTime()
556 {
557   unsigned long mTime = this->Superclass::GetMTime();
558   mTime = max(mTime,myExtractGeometry->GetMTime());
559   mTime = max(mTime,myExtractUnstructuredGrid->GetMTime());
560   mTime = max(mTime,myMergeFilter->GetMTime());
561   mTime = max(mTime,myGeomFilter->GetMTime());
562   mTime = max(mTime,myTransformFilter->GetMTime());
563   mTime = max(mTime,myFaceOrientationFilter->GetMTime());
564   return mTime;
565 }
566
567
568 void
569 SMESH_DeviceActor
570 ::SetTransform(VTKViewer_Transform* theTransform)
571 {
572   myTransformFilter->SetTransform(theTransform);
573 }
574
575
576 void
577 SMESH_DeviceActor
578 ::SetShrink() 
579 {
580   if ( !myIsShrinkable ) return;
581   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
582   {
583     myShrinkFilter->SetInput( aDataSet );
584     myPassFilter[ 1 ]->SetInput( myShrinkFilter->GetOutput() );
585     myIsShrunk = true;
586   }
587 }
588
589 void
590 SMESH_DeviceActor
591 ::UnShrink() 
592 {
593   if ( !myIsShrunk ) return;
594   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
595   {    
596     myPassFilter[ 1 ]->SetInput( aDataSet );
597     myPassFilter[ 1 ]->Modified();
598     myIsShrunk = false;
599     Modified();
600   }
601 }
602
603
604 void
605 SMESH_DeviceActor
606 ::SetFacesOriented(bool theIsFacesOriented) 
607 {
608   if ( vtkDataSet* aDataSet = myPassFilter[ 1 ]->GetOutput() )
609   {
610     myIsFacesOriented = theIsFacesOriented;
611     if( theIsFacesOriented )
612       myFaceOrientationFilter->SetInput( aDataSet );
613     UpdateFaceOrientation();
614   }
615 }
616
617 void
618 SMESH_DeviceActor
619 ::UpdateFaceOrientation()
620 {
621   bool aShowFaceOrientation = myIsFacesOriented;
622   aShowFaceOrientation &= GetVisibility();
623   aShowFaceOrientation &= myRepresentation == eSurface;
624   myFaceOrientation->SetVisibility(aShowFaceOrientation);
625 }
626
627
628 void
629 SMESH_DeviceActor
630 ::SetRepresentation(EReperesent theMode)
631 {
632   switch(theMode){
633   case ePoint:
634     myGeomFilter->SetInside(true);
635     myGeomFilter->SetWireframeMode(false);
636     GetProperty()->SetRepresentation(0);
637     break;
638   case eWireframe:
639     myGeomFilter->SetInside(false);
640     myGeomFilter->SetWireframeMode(true);
641     GetProperty()->SetRepresentation(theMode);
642     break;
643   case eInsideframe:
644     myGeomFilter->SetInside(true);
645     myGeomFilter->SetWireframeMode(true);
646     GetProperty()->SetRepresentation(1);
647     break;
648   case eSurface:
649     myGeomFilter->SetInside(false);
650     myGeomFilter->SetWireframeMode(false);
651     GetProperty()->SetRepresentation(theMode);
652   }
653   myRepresentation = theMode;
654   UpdateFaceOrientation();
655   GetProperty()->Modified();
656   myMapper->Modified();
657   Modified();
658 }
659
660
661 void
662 SMESH_DeviceActor
663 ::SetVisibility(int theMode)
664 {
665   if(!myExtractUnstructuredGrid->GetInput() || 
666      GetUnstructuredGrid()->GetNumberOfCells())
667   {
668     vtkLODActor::SetVisibility(theMode);
669   }else{
670     vtkLODActor::SetVisibility(false);
671   }
672   UpdateFaceOrientation();
673 }
674
675
676 int
677 SMESH_DeviceActor
678 ::GetVisibility()
679 {
680   if(!GetUnstructuredGrid()->GetNumberOfCells()){
681     vtkLODActor::SetVisibility(false);
682   }
683   return vtkLODActor::GetVisibility();
684 }
685
686
687 void
688 SMESH_DeviceActor
689 ::AddToRender(vtkRenderer* theRenderer)
690 {
691   theRenderer->AddActor(this);
692   theRenderer->AddActor(myFaceOrientation);
693 }
694
695 void
696 SMESH_DeviceActor
697 ::RemoveFromRender(vtkRenderer* theRenderer)
698 {
699   theRenderer->RemoveActor(this);
700   theRenderer->RemoveActor(myFaceOrientation);
701 }
702
703
704 int
705 SMESH_DeviceActor
706 ::GetNodeObjId(int theVtkID)
707 {
708   vtkIdType anID = theVtkID;
709
710   if(IsImplicitFunctionUsed())
711     anID = myExtractGeometry->GetNodeObjId(theVtkID);
712
713   vtkIdType aRetID = myVisualObj->GetNodeObjId(anID);
714   if(MYDEBUG) MESSAGE("GetNodeObjId - theVtkID = "<<theVtkID<<"; anID = "<<anID<<"; aRetID = "<<aRetID);
715   return aRetID;
716 }
717
718 vtkFloatingPointType* 
719 SMESH_DeviceActor
720 ::GetNodeCoord(int theObjID)
721 {
722   vtkDataSet* aDataSet = myMergeFilter->GetOutput();
723   vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID);
724   vtkFloatingPointType* aCoord = aDataSet->GetPoint(anID);
725   if(MYDEBUG) MESSAGE("GetNodeCoord - theObjID = "<<theObjID<<"; anID = "<<anID);
726   return aCoord;
727 }
728
729
730 int
731 SMESH_DeviceActor
732 ::GetElemObjId(int theVtkID)
733 {
734   vtkIdType anId = myGeomFilter->GetElemObjId(theVtkID);
735   if(anId < 0) 
736     return -1;
737
738   vtkIdType anId2 = anId;
739   if(IsImplicitFunctionUsed())
740     anId2 = myExtractGeometry->GetElemObjId(anId);
741   if(anId2 < 0) 
742     return -1;
743
744   vtkIdType anId3 = myExtractUnstructuredGrid->GetInputId(anId2);
745   if(anId3 < 0) 
746     return -1;
747
748   vtkIdType aRetID = myVisualObj->GetElemObjId(anId3);
749   if(MYDEBUG) 
750      MESSAGE("GetElemObjId - theVtkID = "<<theVtkID<<"; anId2 = "<<anId2<<"; anId3 = "<<anId3<<"; aRetID = "<<aRetID);
751   return aRetID;
752 }
753
754 vtkCell* 
755 SMESH_DeviceActor
756 ::GetElemCell(int theObjID)
757 {
758   vtkDataSet* aDataSet = myVisualObj->GetUnstructuredGrid();
759   vtkIdType aGridID = myVisualObj->GetElemVTKId(theObjID);
760   vtkCell* aCell = aDataSet->GetCell(aGridID);
761   if(MYDEBUG) 
762     MESSAGE("GetElemCell - theObjID = "<<theObjID<<"; aGridID = "<<aGridID);
763   return aCell;
764 }
765
766
767 vtkFloatingPointType 
768 SMESH_DeviceActor
769 ::GetShrinkFactor()
770 {
771   return myShrinkFilter->GetShrinkFactor();
772 }
773
774 void
775 SMESH_DeviceActor
776 ::SetShrinkFactor(vtkFloatingPointType theValue)
777 {
778   theValue = theValue > 0.1? theValue: 0.8;
779   myShrinkFilter->SetShrinkFactor(theValue);
780   Modified();
781 }
782
783
784 void
785 SMESH_DeviceActor
786 ::SetHighlited(bool theIsHighlited)
787 {
788   if ( myIsHighlited == theIsHighlited )
789     return;
790   myIsHighlited = theIsHighlited;
791   Modified();
792 }
793
794 void
795 SMESH_DeviceActor
796 ::Render(vtkRenderer *ren, vtkMapper* m)
797 {
798   int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
799   vtkFloatingPointType aStoredFactor, aStoredUnit; 
800   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
801
802   vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
803   vtkFloatingPointType aFactor = myPolygonOffsetFactor, aUnits = myPolygonOffsetUnits;
804   if(myIsHighlited){
805     static vtkFloatingPointType EPS = .01;
806     aUnits *= (1.0-EPS);
807   }
808   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnits);
809   vtkLODActor::Render(ren,m);
810
811   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
812   vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
813 }
814
815
816 void
817 SMESH_DeviceActor
818 ::SetPolygonOffsetParameters(vtkFloatingPointType factor, 
819                              vtkFloatingPointType units)
820 {
821   myPolygonOffsetFactor = factor;
822   myPolygonOffsetUnits = units;
823 }
824