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