Salome HOME
Debug algorithms and hypotheses assignment
[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->Build();
288     
289     myMergeFilter->SetScalars(aDataSet);
290     aDataSet->Delete();
291   }
292   GetMapper()->SetScalarVisibility(anIsInitialized);
293   theScalarBarActor->SetVisibility(anIsInitialized);
294 }
295
296 void SMESH_DeviceActor::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
297                                           vtkScalarBarActor* theScalarBarActor,
298                                           vtkLookupTable* theLookupTable)
299 {
300   bool anIsInitialized = theFunctor;
301   myExtractUnstructuredGrid->ClearRegisteredCells();
302   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
303   myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
304   myVisualObj->UpdateFunctor(theFunctor);
305
306   using namespace SMESH::Controls;
307   if (anIsInitialized){
308     if (Length2D* aLength2D = dynamic_cast<Length2D*>(theFunctor.get())){
309       SMESH::Controls::Length2D::TValues aValues;
310
311       aLength2D->GetValues(aValues);
312       vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
313       vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
314
315       aDataSet->SetPoints(aGrid->GetPoints());
316       
317       vtkIdType aNbCells = aValues.size();
318       
319       vtkDoubleArray *aScalars = vtkDoubleArray::New();
320       aScalars->SetNumberOfComponents(1);
321       aScalars->SetNumberOfTuples(aNbCells);
322
323       vtkIdType aCellsSize = 3*aNbCells;
324       vtkCellArray* aConnectivity = vtkCellArray::New();
325       aConnectivity->Allocate( aCellsSize, 0 );
326       
327       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
328       aCellTypesArray->SetNumberOfComponents( 1 );
329       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
330       
331       vtkIdList *anIdList = vtkIdList::New();
332       anIdList->SetNumberOfIds(2);
333       
334       Length2D::TValues::const_iterator anIter = aValues.begin();
335       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
336         const Length2D::Value& aValue = *anIter;
337         int aNode[2] = {
338           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
339           myVisualObj->GetNodeVTKId(aValue.myPntId[1])
340         };
341         if(aNode[0] >= 0 && aNode[1] >= 0){
342           anIdList->SetId( 0, aNode[0] );
343           anIdList->SetId( 1, aNode[1] );
344           aConnectivity->InsertNextCell( anIdList );
345           aCellTypesArray->InsertNextValue( VTK_LINE );
346           aScalars->SetValue(aVtkId,aValue.myLength);
347         }
348       }
349       
350       vtkIntArray* aCellLocationsArray = vtkIntArray::New();
351       aCellLocationsArray->SetNumberOfComponents( 1 );
352       aCellLocationsArray->SetNumberOfTuples( aNbCells );
353       
354       aConnectivity->InitTraversal();
355       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
356         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
357       
358       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
359       SetUnstructuredGrid(aDataSet);
360
361       aDataSet->GetCellData()->SetScalars(aScalars);
362       aScalars->Delete();
363       
364       theLookupTable->SetRange(aScalars->GetRange());
365       theLookupTable->Build();
366       
367       myMergeFilter->SetScalars(aDataSet);
368       aDataSet->Delete();
369     }
370     else if (MultiConnection2D* aMultiConnection2D = dynamic_cast<MultiConnection2D*>(theFunctor.get())){
371       SMESH::Controls::MultiConnection2D::MValues aValues;
372
373       aMultiConnection2D->GetValues(aValues);
374       vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
375       vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
376       aDataSet->SetPoints(aGrid->GetPoints());
377       
378       vtkIdType aNbCells = aValues.size();
379       vtkDoubleArray *aScalars = vtkDoubleArray::New();
380       aScalars->SetNumberOfComponents(1);
381       aScalars->SetNumberOfTuples(aNbCells);
382
383       vtkIdType aCellsSize = 3*aNbCells;
384       vtkCellArray* aConnectivity = vtkCellArray::New();
385       aConnectivity->Allocate( aCellsSize, 0 );
386       
387       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
388       aCellTypesArray->SetNumberOfComponents( 1 );
389       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
390       
391       vtkIdList *anIdList = vtkIdList::New();
392       anIdList->SetNumberOfIds(2);
393       
394       MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
395       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
396         const MultiConnection2D::Value& aValue = (*anIter).first;
397         int aNode[2] = {
398           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
399           myVisualObj->GetNodeVTKId(aValue.myPntId[1])
400         };
401         if(aNode[0] >= 0 && aNode[1] >= 0){
402           anIdList->SetId( 0, aNode[0] );
403           anIdList->SetId( 1, aNode[1] );
404           aConnectivity->InsertNextCell( anIdList );
405           aCellTypesArray->InsertNextValue( VTK_LINE );
406           aScalars->SetValue(aVtkId,(*anIter).second);
407         }
408       }
409       
410       vtkIntArray* aCellLocationsArray = vtkIntArray::New();
411       aCellLocationsArray->SetNumberOfComponents( 1 );
412       aCellLocationsArray->SetNumberOfTuples( aNbCells );
413       
414       aConnectivity->InitTraversal();
415       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
416         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
417       
418       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
419       SetUnstructuredGrid(aDataSet);
420
421       aDataSet->GetCellData()->SetScalars(aScalars);
422       aScalars->Delete();
423       
424       theLookupTable->SetRange(aScalars->GetRange());
425       theLookupTable->Build();
426       
427       myMergeFilter->SetScalars(aDataSet);
428       aDataSet->Delete();
429     }
430   }
431   GetMapper()->SetScalarVisibility(anIsInitialized);
432   theScalarBarActor->SetVisibility(anIsInitialized);
433 }
434
435 void SMESH_DeviceActor::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor)
436 {
437   myExtractUnstructuredGrid->ClearRegisteredCells();
438   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
439   myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
440   myVisualObj->UpdateFunctor(theFunctor);
441
442   using namespace SMESH::Controls;
443   if(FreeBorders* aFreeBorders = dynamic_cast<FreeBorders*>(theFunctor.get())){
444     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
445     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
446     vtkIdType aNbCells = aGrid->GetNumberOfCells();
447     for( vtkIdType i = 0; i < aNbCells; i++ ){
448       vtkIdType anObjId = myVisualObj->GetElemObjId(i);
449       if(aFreeBorders->IsSatisfy(anObjId))
450         myExtractUnstructuredGrid->RegisterCell(i);
451     }
452     if(!myExtractUnstructuredGrid->IsCellsRegistered())
453       myExtractUnstructuredGrid->RegisterCell(-1);
454     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
455   }else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get())){
456     SMESH::Controls::FreeEdges::TBorders aBorders;
457     aFreeEdges->GetBoreders(aBorders);
458     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
459     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
460     aDataSet->SetPoints(aGrid->GetPoints());
461
462     vtkIdType aNbCells = aBorders.size();
463     vtkIdType aCellsSize = 3*aNbCells;
464     vtkCellArray* aConnectivity = vtkCellArray::New();
465     aConnectivity->Allocate( aCellsSize, 0 );
466     
467     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
468     aCellTypesArray->SetNumberOfComponents( 1 );
469     aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
470     
471     vtkIdList *anIdList = vtkIdList::New();
472     anIdList->SetNumberOfIds(2);
473     
474     FreeEdges::TBorders::const_iterator anIter = aBorders.begin();
475     for(; anIter != aBorders.end(); anIter++){
476       const FreeEdges::Border& aBorder = *anIter;
477       int aNode[2] = {
478         myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
479         myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
480       };
481       //cout<<"aNode = "<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<endl;
482       if(aNode[0] >= 0 && aNode[1] >= 0){
483         anIdList->SetId( 0, aNode[0] );
484         anIdList->SetId( 1, aNode[1] );
485         aConnectivity->InsertNextCell( anIdList );
486         aCellTypesArray->InsertNextValue( VTK_LINE );
487       }
488     }
489     
490     vtkIntArray* aCellLocationsArray = vtkIntArray::New();
491     aCellLocationsArray->SetNumberOfComponents( 1 );
492     aCellLocationsArray->SetNumberOfTuples( aNbCells );
493     
494     aConnectivity->InitTraversal();
495     for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
496       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
497     
498     aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
499
500     SetUnstructuredGrid(aDataSet);
501     aDataSet->Delete();
502   }
503 }
504
505
506
507
508 unsigned long int SMESH_DeviceActor::GetMTime(){
509   unsigned long mTime = this->Superclass::GetMTime();
510   mTime = max(mTime,myExtractGeometry->GetMTime());
511   mTime = max(mTime,myExtractUnstructuredGrid->GetMTime());
512   mTime = max(mTime,myMergeFilter->GetMTime());
513   mTime = max(mTime,myGeomFilter->GetMTime());
514   mTime = max(mTime,myTransformFilter->GetMTime());
515   return mTime;
516 }
517
518
519 void SMESH_DeviceActor::SetTransform(VTKViewer_Transform* theTransform){
520   myTransformFilter->SetTransform(theTransform);
521 }
522
523
524 void SMESH_DeviceActor::SetShrink() {
525   if ( !myIsShrinkable ) return;
526   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
527   {
528     myShrinkFilter->SetInput( aDataSet );
529     myPassFilter[ 1 ]->SetInput( myShrinkFilter->GetOutput() );
530     myIsShrunk = true;
531   }
532 }
533
534 void SMESH_DeviceActor::UnShrink() {
535   if ( !myIsShrunk ) return;
536   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
537   {    
538     myPassFilter[ 1 ]->SetInput( aDataSet );
539     myPassFilter[ 1 ]->Modified();
540     myIsShrunk = false;
541     Modified();
542   }
543 }
544
545
546 void SMESH_DeviceActor::SetRepresentation(EReperesent theMode){
547   switch(theMode){
548   case ePoint:
549     myGeomFilter->SetInside(true);
550     GetProperty()->SetRepresentation(0);
551     break;
552   case eInsideframe:
553     myGeomFilter->SetInside(true);
554     GetProperty()->SetRepresentation(1);
555     break;
556   default :
557     myGeomFilter->SetInside(false);
558     GetProperty()->SetRepresentation(theMode);
559   }
560   myRepresentation = theMode;
561   GetProperty()->Modified();
562   myMapper->Modified();
563   Modified();
564 }
565
566
567 void SMESH_DeviceActor::SetVisibility(int theMode){
568   if(!myExtractUnstructuredGrid->GetInput() || 
569      GetUnstructuredGrid()->GetNumberOfCells())
570   {
571     vtkLODActor::SetVisibility(theMode);
572   }else{
573     vtkLODActor::SetVisibility(false);
574   }
575 }
576
577
578 int SMESH_DeviceActor::GetVisibility(){
579   if(!GetUnstructuredGrid()->GetNumberOfCells()){
580     vtkLODActor::SetVisibility(false);
581   }
582   return vtkLODActor::GetVisibility();
583 }
584
585
586 int SMESH_DeviceActor::GetNodeObjId(int theVtkID){
587   vtkIdType anID = theVtkID;
588
589   if(IsImplicitFunctionUsed())
590     anID = myExtractGeometry->GetNodeObjId(theVtkID);
591
592   vtkIdType aRetID = myVisualObj->GetNodeObjId(anID);
593   if(MYDEBUG) MESSAGE("GetNodeObjId - theVtkID = "<<theVtkID<<"; anID = "<<anID<<"; aRetID = "<<aRetID);
594   return aRetID;
595 }
596
597 float* SMESH_DeviceActor::GetNodeCoord(int theObjID){
598   vtkDataSet* aDataSet = myMergeFilter->GetOutput();
599   vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID);
600   float* aCoord = aDataSet->GetPoint(anID);
601   if(MYDEBUG) MESSAGE("GetNodeCoord - theObjID = "<<theObjID<<"; anID = "<<anID);
602   return aCoord;
603 }
604
605
606 int SMESH_DeviceActor::GetElemObjId(int theVtkID){
607   vtkIdType anId = myGeomFilter->GetElemObjId(theVtkID);
608   if(anId < 0) 
609     return -1;
610
611   vtkIdType anId2 = anId;
612   if(IsImplicitFunctionUsed())
613     anId2 = myExtractGeometry->GetElemObjId(anId);
614   if(anId2 < 0) 
615     return -1;
616
617   vtkIdType anId3 = myExtractUnstructuredGrid->GetInputId(anId2);
618   if(anId3 < 0) 
619     return -1;
620
621   vtkIdType aRetID = myVisualObj->GetElemObjId(anId3);
622   if(MYDEBUG) 
623      MESSAGE("GetElemObjId - theVtkID = "<<theVtkID<<"; anId2 = "<<anId2<<"; anId3 = "<<anId3<<"; aRetID = "<<aRetID);
624   return aRetID;
625 }
626
627 vtkCell* SMESH_DeviceActor::GetElemCell(int theObjID){
628   vtkDataSet* aDataSet = myVisualObj->GetUnstructuredGrid();
629   vtkIdType aGridID = myVisualObj->GetElemVTKId(theObjID);
630   vtkCell* aCell = aDataSet->GetCell(aGridID);
631   if(MYDEBUG) 
632     MESSAGE("GetElemCell - theObjID = "<<theObjID<<"; aGridID = "<<aGridID);
633   return aCell;
634 }
635
636
637 float SMESH_DeviceActor::GetShrinkFactor(){
638   return myShrinkFilter->GetShrinkFactor();
639 }
640
641 void SMESH_DeviceActor::SetShrinkFactor(float theValue){
642   theValue = theValue > 0.1? theValue: 0.8;
643   myShrinkFilter->SetShrinkFactor(theValue);
644   Modified();
645 }
646
647
648 void SMESH_DeviceActor::SetHighlited(bool theIsHighlited){
649   myIsHighlited = theIsHighlited;
650   Modified();
651 }
652
653 void SMESH_DeviceActor::Render(vtkRenderer *ren, vtkMapper* m){
654   int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
655   float aStoredFactor, aStoredUnit; 
656   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
657
658   vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
659   float aFactor = myPolygonOffsetFactor, aUnits = myPolygonOffsetUnits;
660   if(myIsHighlited){
661     static float EPS = .01;
662     aUnits *= (1.0-EPS);
663   }
664   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnits);
665   vtkLODActor::Render(ren,m);
666
667   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
668   vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
669 }
670
671
672 void SMESH_DeviceActor::SetPolygonOffsetParameters(float factor, float units){
673   myPolygonOffsetFactor = factor;
674   myPolygonOffsetUnits = units;
675 }
676