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