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