Salome HOME
2b7beccf86dd1d952535cacc38cab49091e24a96
[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 //
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 ( dynamic_cast<FreeBorders*>(theFunctor.get()) ||
487        dynamic_cast<FreeFaces*>(theFunctor.get()) ) {
488     Predicate* aFreePredicate = dynamic_cast<Predicate*>(theFunctor.get());
489     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
490     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
491     vtkIdType aNbCells = aGrid->GetNumberOfCells();
492     for( vtkIdType i = 0; i < aNbCells; i++ ){
493       vtkIdType anObjId = myVisualObj->GetElemObjId(i);
494       if(aFreePredicate->IsSatisfy(anObjId))
495         myExtractUnstructuredGrid->RegisterCell(i);
496     }
497     if(!myExtractUnstructuredGrid->IsCellsRegistered())
498       myExtractUnstructuredGrid->RegisterCell(-1);
499     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
500   }else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get())){
501     SMESH::Controls::FreeEdges::TBorders aBorders;
502     aFreeEdges->GetBoreders(aBorders);
503     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
504     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
505     aDataSet->SetPoints(aGrid->GetPoints());
506
507     vtkIdType aNbCells = aBorders.size();
508     vtkIdType aCellsSize = 3*aNbCells;
509     vtkCellArray* aConnectivity = vtkCellArray::New();
510     aConnectivity->Allocate( aCellsSize, 0 );
511     
512     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
513     aCellTypesArray->SetNumberOfComponents( 1 );
514     aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
515     
516     vtkIdList *anIdList = vtkIdList::New();
517     anIdList->SetNumberOfIds(2);
518     
519     FreeEdges::TBorders::const_iterator anIter = aBorders.begin();
520     for(; anIter != aBorders.end(); anIter++){
521       const FreeEdges::Border& aBorder = *anIter;
522       int aNode[2] = {
523         myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
524         myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
525       };
526       //cout<<"aNode = "<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<endl;
527       if(aNode[0] >= 0 && aNode[1] >= 0){
528         anIdList->SetId( 0, aNode[0] );
529         anIdList->SetId( 1, aNode[1] );
530         aConnectivity->InsertNextCell( anIdList );
531         aCellTypesArray->InsertNextValue( VTK_LINE );
532       }
533     }
534     
535     VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
536     aCellLocationsArray->SetNumberOfComponents( 1 );
537     aCellLocationsArray->SetNumberOfTuples( aNbCells );
538     
539     aConnectivity->InitTraversal();
540     for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
541       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
542     
543     aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
544
545     SetUnstructuredGrid(aDataSet);
546     aDataSet->Delete();
547   }else if(FreeNodes* aFreeNodes = dynamic_cast<FreeNodes*>(theFunctor.get())){
548     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
549     vtkIdType aNbNodes = myVisualObj->GetNbEntities(SMDSAbs_Node);
550     for( vtkIdType i = 0; i < aNbNodes; i++ ){
551       vtkIdType anObjId = myVisualObj->GetNodeObjId(i);
552       if(aFreeNodes->IsSatisfy(anObjId))
553         myExtractUnstructuredGrid->RegisterCell(i);
554     }
555     if(!myExtractUnstructuredGrid->IsCellsRegistered())
556       myExtractUnstructuredGrid->RegisterCell(-1);
557     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
558   }
559 }
560
561
562
563
564 unsigned long int 
565 SMESH_DeviceActor
566 ::GetMTime()
567 {
568   unsigned long mTime = this->Superclass::GetMTime();
569   mTime = max(mTime,myExtractGeometry->GetMTime());
570   mTime = max(mTime,myExtractUnstructuredGrid->GetMTime());
571   mTime = max(mTime,myMergeFilter->GetMTime());
572   mTime = max(mTime,myGeomFilter->GetMTime());
573   mTime = max(mTime,myTransformFilter->GetMTime());
574   mTime = max(mTime,myFaceOrientationFilter->GetMTime());
575   return mTime;
576 }
577
578
579 void
580 SMESH_DeviceActor
581 ::SetTransform(VTKViewer_Transform* theTransform)
582 {
583   myTransformFilter->SetTransform(theTransform);
584 }
585
586
587 void
588 SMESH_DeviceActor
589 ::SetShrink() 
590 {
591   if ( !myIsShrinkable ) return;
592   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
593   {
594     myShrinkFilter->SetInput( aDataSet );
595     myPassFilter[ 1 ]->SetInput( myShrinkFilter->GetOutput() );
596     myIsShrunk = true;
597   }
598 }
599
600 void
601 SMESH_DeviceActor
602 ::UnShrink() 
603 {
604   if ( !myIsShrunk ) return;
605   if ( vtkDataSet* aDataSet = myPassFilter[ 0 ]->GetOutput() )
606   {    
607     myPassFilter[ 1 ]->SetInput( aDataSet );
608     myPassFilter[ 1 ]->Modified();
609     myIsShrunk = false;
610     Modified();
611   }
612 }
613
614
615 void
616 SMESH_DeviceActor
617 ::SetFacesOriented(bool theIsFacesOriented) 
618 {
619   if ( vtkDataSet* aDataSet = myPassFilter[ 1 ]->GetOutput() )
620   {
621     myIsFacesOriented = theIsFacesOriented;
622     if( theIsFacesOriented )
623       myFaceOrientationFilter->SetInput( aDataSet );
624     UpdateFaceOrientation();
625   }
626 }
627
628 void
629 SMESH_DeviceActor
630 ::UpdateFaceOrientation()
631 {
632   bool aShowFaceOrientation = myIsFacesOriented;
633   aShowFaceOrientation &= GetVisibility();
634   aShowFaceOrientation &= myRepresentation == eSurface;
635   myFaceOrientation->SetVisibility(aShowFaceOrientation);
636 }
637
638
639 void
640 SMESH_DeviceActor
641 ::SetRepresentation(EReperesent theMode)
642 {
643   switch(theMode){
644   case ePoint:
645     myGeomFilter->SetInside(true);
646     myGeomFilter->SetWireframeMode(false);
647     GetProperty()->SetRepresentation(0);
648     break;
649   case eWireframe:
650     myGeomFilter->SetInside(false);
651     myGeomFilter->SetWireframeMode(true);
652     GetProperty()->SetRepresentation(theMode);
653     break;
654   case eInsideframe:
655     myGeomFilter->SetInside(true);
656     myGeomFilter->SetWireframeMode(true);
657     GetProperty()->SetRepresentation(1);
658     break;
659   case eSurface:
660     myGeomFilter->SetInside(false);
661     myGeomFilter->SetWireframeMode(false);
662     GetProperty()->SetRepresentation(theMode);
663   }
664   myRepresentation = theMode;
665   UpdateFaceOrientation();
666   GetProperty()->Modified();
667   myMapper->Modified();
668   Modified();
669 }
670
671
672 void
673 SMESH_DeviceActor
674 ::SetVisibility(int theMode)
675 {
676   if(!myExtractUnstructuredGrid->GetInput() || 
677      GetUnstructuredGrid()->GetNumberOfCells())
678   {
679     vtkLODActor::SetVisibility(theMode);
680   }else{
681     vtkLODActor::SetVisibility(false);
682   }
683   UpdateFaceOrientation();
684 }
685
686
687 int
688 SMESH_DeviceActor
689 ::GetVisibility()
690 {
691   if(!GetUnstructuredGrid()->GetNumberOfCells()){
692     vtkLODActor::SetVisibility(false);
693   }
694   return vtkLODActor::GetVisibility();
695 }
696
697
698 void
699 SMESH_DeviceActor
700 ::AddToRender(vtkRenderer* theRenderer)
701 {
702   theRenderer->AddActor(this);
703   theRenderer->AddActor(myFaceOrientation);
704 }
705
706 void
707 SMESH_DeviceActor
708 ::RemoveFromRender(vtkRenderer* theRenderer)
709 {
710   theRenderer->RemoveActor(this);
711   theRenderer->RemoveActor(myFaceOrientation);
712 }
713
714
715 int
716 SMESH_DeviceActor
717 ::GetNodeObjId(int theVtkID)
718 {
719   vtkIdType anID = theVtkID;
720
721   if(IsImplicitFunctionUsed())
722     anID = myExtractGeometry->GetNodeObjId(theVtkID);
723
724   vtkIdType aRetID = myVisualObj->GetNodeObjId(anID);
725   if(MYDEBUG) MESSAGE("GetNodeObjId - theVtkID = "<<theVtkID<<"; anID = "<<anID<<"; aRetID = "<<aRetID);
726   return aRetID;
727 }
728
729 vtkFloatingPointType* 
730 SMESH_DeviceActor
731 ::GetNodeCoord(int theObjID)
732 {
733   vtkDataSet* aDataSet = myMergeFilter->GetOutput();
734   vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID);
735   vtkFloatingPointType* aCoord = (anID >=0) ? aDataSet->GetPoint(anID) : NULL;
736   if(MYDEBUG) MESSAGE("GetNodeCoord - theObjID = "<<theObjID<<"; anID = "<<anID);
737   return aCoord;
738 }
739
740
741 int
742 SMESH_DeviceActor
743 ::GetElemObjId(int theVtkID)
744 {
745   vtkIdType anId = myGeomFilter->GetElemObjId(theVtkID);
746   if(anId < 0) 
747     return -1;
748
749   vtkIdType anId2 = anId;
750   if(IsImplicitFunctionUsed())
751     anId2 = myExtractGeometry->GetElemObjId(anId);
752   if(anId2 < 0) 
753     return -1;
754
755   vtkIdType anId3 = myExtractUnstructuredGrid->GetInputId(anId2);
756   if(anId3 < 0) 
757     return -1;
758
759   vtkIdType aRetID = myVisualObj->GetElemObjId(anId3);
760   if(MYDEBUG) 
761      MESSAGE("GetElemObjId - theVtkID = "<<theVtkID<<"; anId2 = "<<anId2<<"; anId3 = "<<anId3<<"; aRetID = "<<aRetID);
762   return aRetID;
763 }
764
765 vtkCell* 
766 SMESH_DeviceActor
767 ::GetElemCell(int theObjID)
768 {
769   vtkDataSet* aDataSet = myVisualObj->GetUnstructuredGrid();
770   vtkIdType aGridID = myVisualObj->GetElemVTKId(theObjID);
771   vtkCell* aCell = (aGridID >= 0 ) ? aDataSet->GetCell(aGridID) : NULL;
772   if(MYDEBUG) 
773     MESSAGE("GetElemCell - theObjID = "<<theObjID<<"; aGridID = "<<aGridID);
774   return aCell;
775 }
776
777
778 vtkFloatingPointType 
779 SMESH_DeviceActor
780 ::GetShrinkFactor()
781 {
782   return myShrinkFilter->GetShrinkFactor();
783 }
784
785 void
786 SMESH_DeviceActor
787 ::SetShrinkFactor(vtkFloatingPointType theValue)
788 {
789   theValue = theValue > 0.1? theValue: 0.8;
790   myShrinkFilter->SetShrinkFactor(theValue);
791   Modified();
792 }
793
794
795 void
796 SMESH_DeviceActor
797 ::SetHighlited(bool theIsHighlited)
798 {
799   if ( myIsHighlited == theIsHighlited )
800     return;
801   myIsHighlited = theIsHighlited;
802   Modified();
803 }
804
805 void
806 SMESH_DeviceActor
807 ::Render(vtkRenderer *ren, vtkMapper* m)
808 {
809   int aResolveCoincidentTopology = vtkMapper::GetResolveCoincidentTopology();
810   vtkFloatingPointType aStoredFactor, aStoredUnit; 
811   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
812
813   vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
814   vtkFloatingPointType aFactor = myPolygonOffsetFactor, aUnits = myPolygonOffsetUnits;
815   if(myIsHighlited){
816     static vtkFloatingPointType EPS = .01;
817     aUnits *= (1.0-EPS);
818   }
819   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aFactor,aUnits);
820   vtkLODActor::Render(ren,m);
821
822   vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(aStoredFactor,aStoredUnit);
823   vtkMapper::SetResolveCoincidentTopology(aResolveCoincidentTopology);
824 }
825
826
827 void
828 SMESH_DeviceActor
829 ::SetPolygonOffsetParameters(vtkFloatingPointType factor, 
830                              vtkFloatingPointType units)
831 {
832   myPolygonOffsetFactor = factor;
833   myPolygonOffsetUnits = units;
834 }
835
836 /*!
837  * On/Off representation 2D quadratic element as arked polygon
838  */
839 void SMESH_DeviceActor::SetQuadraticArcMode(bool theFlag){
840   myGeomFilter->SetQuadraticArcMode(theFlag);
841 }
842
843 /*!
844  * Return true if 2D quadratic element displayed as arked polygon
845  */
846 bool SMESH_DeviceActor::GetQuadraticArcMode(){
847   return myGeomFilter->GetQuadraticArcMode();
848 }
849 /*!
850  * Set Max angle for representation 2D quadratic element as arked polygon
851  */
852 void SMESH_DeviceActor::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle){
853   myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
854 }
855
856 /*!
857  * Return Max angle of the representation 2D quadratic element as arked polygon
858  */
859 vtkFloatingPointType SMESH_DeviceActor::GetQuadraticArcAngle(){
860   return myGeomFilter->GetQuadraticArcAngle();
861 }