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