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