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