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