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