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