Salome HOME
0c57a09da43f4fc503ac10e6bfa01bfb4a4d7824
[modules/smesh.git] / src / OBJECT / SMESH_Actor.cxx
1 //  SMESH OBJECT : interactive object for SMESH visualization
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Actor.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SMESH
27 //  $Header$
28
29
30 #include "SMESH_Actor.h"
31 #include "SMESH_ActorUtils.h"
32 #include "SMESH_DeviceActor.h"
33 #include "SMESH_ControlsDef.hxx"
34 #include "SALOME_ExtractUnstructuredGrid.h"
35
36 #include "QAD_Config.h"
37 #include <qstringlist.h>
38
39 #include <vtkTimeStamp.h>
40 #include <vtkObjectFactory.h>
41 #include <vtkShrinkPolyData.h>
42 #include <vtkMergeFilter.h>
43
44 #include <vtkMatrix4x4.h>
45 #include <vtkUnstructuredGrid.h>
46 #include <vtkPointData.h>
47 #include <vtkCellData.h>
48
49 #include <vtkMapper.h>
50 #include <vtkRenderer.h>
51
52 #include <vtkCell.h>
53 #include <vtkIdList.h>
54 #include <vtkIntArray.h>
55
56 #include <vtkActor2D.h>
57 #include <vtkProperty2D.h>
58 #include <vtkPolyData.h>
59 #include <vtkMaskPoints.h>
60 #include <vtkCellCenters.h>
61 #include <vtkTextProperty.h>
62 #include <vtkLabeledDataMapper.h>
63 #include <vtkSelectVisiblePoints.h>
64
65 #include <vtkScalarBarActor.h>
66 #include <vtkLookupTable.h>
67
68 #include <vtkMath.h>
69 #include <vtkPlane.h>
70 #include <vtkImplicitBoolean.h>
71
72 #include "utilities.h"
73
74 #ifdef _DEBUG_
75 static int MYDEBUG = 0;
76 #else
77 static int MYDEBUG = 0;
78 #endif
79
80 static int aLineWidthInc = 2;
81 static int aPointSizeInc = 2;
82
83
84 SMESH_Actor* SMESH_Actor::New(){
85   return new SMESH_Actor();
86 }
87
88
89 SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj, 
90                               const char* theEntry, 
91                               const char* theName,
92                               int theIsClear)
93 {
94   SMESH_Actor* anActor = SMESH_Actor::New();
95   if(!anActor->Init(theVisualObj,theEntry,theName,theIsClear)){
96     anActor->Delete();
97     anActor = NULL;
98   }
99   return anActor;
100 }
101
102
103 SMESH_Actor::SMESH_Actor(){
104   if(MYDEBUG) MESSAGE("SMESH_Actor");
105
106   myTimeStamp = vtkTimeStamp::New();
107
108   myIsPointsVisible = false;
109
110   myIsShrinkable = false;
111   myIsShrunk = false;
112
113   myControlsPrecision = (long)SMESH::GetFloat( "SMESH:ControlsPrecision", -1 );
114
115   float aPointSize = SMESH::GetFloat("SMESH:SettingsNodesSize",3);
116   float aLineWidth = SMESH::GetFloat("SMESH:SettingsWidth",1);
117
118   vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
119   SALOME_ExtractUnstructuredGrid* aFilter = NULL;
120
121   //Definition 2D and 3D divices of the actor
122   //-----------------------------------------
123   float anRGB[3] = {1,1,1};
124   mySurfaceProp = vtkProperty::New();
125   anRGB[0] = SMESH::GetFloat("SMESH:SettingsFillColorRed", 0)/255.;
126   anRGB[1] = SMESH::GetFloat("SMESH:SettingsFillColorGreen", 170)/255.;
127   anRGB[2] = SMESH::GetFloat("SMESH:SettingsFillColorBlue", 255)/255.;
128   mySurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
129
130   myBackSurfaceProp = vtkProperty::New();
131   anRGB[0] = SMESH::GetFloat("SMESH:SettingsBackFaceColorRed", 0)/255.;
132   anRGB[1] = SMESH::GetFloat("SMESH:SettingsBackFaceColorGreen", 0)/255.;
133   anRGB[2] = SMESH::GetFloat("SMESH:SettingsBackFaceColorBlue", 255)/255.;
134   myBackSurfaceProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
135
136   my2DActor = SMESH_DeviceActor::New();
137   my2DActor->SetUserMatrix(aMatrix);
138   my2DActor->SetStoreMapping(true);
139   my2DActor->PickableOff();
140   my2DActor->SetProperty(mySurfaceProp);
141   my2DActor->SetBackfaceProperty(myBackSurfaceProp);
142   my2DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
143   aFilter = my2DActor->GetExtractUnstructuredGrid();
144   aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
145   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
146   aFilter->RegisterCellsWithType(VTK_POLYGON);
147   aFilter->RegisterCellsWithType(VTK_QUAD);
148
149   my3DActor = SMESH_DeviceActor::New();
150   my3DActor->SetUserMatrix(aMatrix);
151   my3DActor->SetStoreMapping(true);
152   my3DActor->PickableOff();
153   my3DActor->SetProperty(mySurfaceProp);
154   my3DActor->SetBackfaceProperty(myBackSurfaceProp);
155   my3DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
156   aFilter = my3DActor->GetExtractUnstructuredGrid();
157   aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
158   aFilter->RegisterCellsWithType(VTK_TETRA);
159   aFilter->RegisterCellsWithType(VTK_VOXEL);
160   aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
161   aFilter->RegisterCellsWithType(VTK_WEDGE);
162   aFilter->RegisterCellsWithType(VTK_PYRAMID);
163
164
165   //Definition 1D divice of the actor
166   //---------------------------------
167   myEdgeProp = vtkProperty::New();
168   myEdgeProp->SetAmbient(1.0);
169   myEdgeProp->SetDiffuse(0.0);
170   myEdgeProp->SetSpecular(0.0);
171   anRGB[0] = SMESH::GetFloat("SMESH:SettingsOutlineColorRed", 0)/255.;
172   anRGB[1] = SMESH::GetFloat("SMESH:SettingsOutlineColorGreen", 170)/255.;
173   anRGB[2] = SMESH::GetFloat("SMESH:SettingsOutlineColorBlue", 255)/255.;
174   myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
175   myEdgeProp->SetLineWidth(aLineWidth);
176
177   my1DActor = SMESH_DeviceActor::New();
178   my1DActor->SetUserMatrix(aMatrix);
179   my1DActor->SetStoreMapping(true);
180   my1DActor->PickableOff();
181   my1DActor->SetHighlited(true);
182   my1DActor->SetProperty(myEdgeProp);
183   my1DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
184   aFilter = my1DActor->GetExtractUnstructuredGrid();
185   aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
186   aFilter->RegisterCellsWithType(VTK_LINE);
187
188   my1DProp = vtkProperty::New();
189   my1DProp->DeepCopy(myEdgeProp);
190   my1DProp->SetLineWidth(aLineWidth + aLineWidthInc);
191   my1DProp->SetPointSize(aPointSize);
192
193   my1DExtProp = vtkProperty::New();
194   my1DExtProp->DeepCopy(myEdgeProp);
195   anRGB[0] = 1 - anRGB[0];
196   anRGB[1] = 1 - anRGB[1];
197   anRGB[2] = 1 - anRGB[2];
198   my1DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
199   my1DExtProp->SetLineWidth(aLineWidth + aLineWidthInc);
200   my1DExtProp->SetPointSize(aPointSize + aPointSizeInc);
201
202   my1DExtActor = SMESH_DeviceActor::New();
203   my1DExtActor->SetUserMatrix(aMatrix);
204   my1DExtActor->SetStoreMapping(true);
205   my1DExtActor->PickableOff();
206   my1DExtActor->SetHighlited(true);
207   my1DExtActor->SetVisibility(false);
208   my1DExtActor->SetProperty(my1DExtProp);
209   my1DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
210   aFilter = my1DExtActor->GetExtractUnstructuredGrid();
211   aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
212   aFilter->RegisterCellsWithType(VTK_LINE);
213
214
215   //Definition 0D divice of the actor
216   //---------------------------------
217   myNodeProp = vtkProperty::New();
218   anRGB[0] = SMESH::GetFloat("SMESH:SettingsNodeColorRed",255)/255.;
219   anRGB[1] = SMESH::GetFloat("SMESH:SettingsNodeColorGreen",0)/255.;
220   anRGB[2] = SMESH::GetFloat("SMESH:SettingsNodeColorBlue",0)/255.;
221   myNodeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
222   myNodeProp->SetPointSize(aPointSize);
223
224   myNodeActor = SMESH_DeviceActor::New();
225   myNodeActor->SetUserMatrix(aMatrix);
226   myNodeActor->SetStoreMapping(true);
227   myNodeActor->PickableOff();
228   myNodeActor->SetVisibility(false);
229   myNodeActor->SetProperty(myNodeProp);
230   myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
231   aFilter = myNodeActor->GetExtractUnstructuredGrid();
232   aFilter->SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints);
233
234
235   //Definition of Pickable and Highlitable engines
236   //----------------------------------------------
237
238   myBaseActor = SMESH_DeviceActor::New();
239   myBaseActor->SetUserMatrix(aMatrix);
240   myBaseActor->SetStoreMapping(true);
241   myBaseActor->GetProperty()->SetOpacity(0.0);
242
243   myPickableActor = myBaseActor;
244
245   myHighlightProp = vtkProperty::New();
246   myHighlightProp->SetAmbient(1.0);
247   myHighlightProp->SetDiffuse(0.0);
248   myHighlightProp->SetSpecular(0.0);
249   anRGB[0] = SMESH::GetFloat("SMESH:SettingsSelectColorRed", 255)/255.;   // 1;
250   anRGB[1] = SMESH::GetFloat("SMESH:SettingsSelectColorGreen", 255)/255.; // 1;
251   anRGB[2] = SMESH::GetFloat("SMESH:SettingsSelectColorBlue", 255)/255.;  // 1;
252   myHighlightProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
253   myHighlightProp->SetPointSize(aPointSize);
254   myHighlightProp->SetRepresentation(1);
255  
256   myPreselectProp = vtkProperty::New();
257   myPreselectProp->SetAmbient(1.0);
258   myPreselectProp->SetDiffuse(0.0);
259   myPreselectProp->SetSpecular(0.0);
260   anRGB[0] = SMESH::GetFloat("SMESH:SettingsPreSelectColorRed", 0)/255.;     // 0;
261   anRGB[1] = SMESH::GetFloat("SMESH:SettingsPreSelectColorGreen", 255)/255.; // 1;
262   anRGB[2] = SMESH::GetFloat("SMESH:SettingsPreSelectColorBlue", 255)/255.;  // 1;
263   myPreselectProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
264   myPreselectProp->SetPointSize(aPointSize);
265   myPreselectProp->SetRepresentation(1);
266
267   myHighlitableActor = SMESH_DeviceActor::New();
268   myHighlitableActor->SetUserMatrix(aMatrix);
269   myHighlitableActor->SetStoreMapping(false);
270   myHighlitableActor->PickableOff();
271   myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
272
273   myNodeHighlitableActor = SMESH_DeviceActor::New();
274   myNodeHighlitableActor->SetUserMatrix(aMatrix);
275   myNodeHighlitableActor->SetStoreMapping(false);
276   myNodeHighlitableActor->PickableOff();
277   myNodeHighlitableActor->SetRepresentation(SMESH_DeviceActor::ePoint);
278   aFilter = myNodeHighlitableActor->GetExtractUnstructuredGrid();
279   aFilter->SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints);
280
281
282   SetShrinkFactor(SMESH::GetFloat("SMESH:SettingsShrinkCoeff", 75)/100.);
283
284   myName = "";
285   myIO = NULL;
286
287   myColorMode = eNone;
288   my1DColorMode = e1DNone;
289   myControlActor = my2DActor;
290
291   //Definition of myScalarBarActor
292   //------------------------------
293   myLookupTable = vtkLookupTable::New();
294   //Fix for Bug PAL5195 - SMESH764: 
295   //Controls - Aspect Ratio: incorrect colors of the best and worst values
296   myLookupTable->SetHueRange(0.667,0.0);
297
298   myScalarBarActor = vtkScalarBarActor::New();
299   myScalarBarActor->SetVisibility(false);
300   myScalarBarActor->SetLookupTable(myLookupTable);
301
302   vtkTextProperty* aScalarBarTitleProp = vtkTextProperty::New();
303
304   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) {
305     QStringList aTColor = QStringList::split(  ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false );
306     aScalarBarTitleProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
307                                    ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ), 
308                                    ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
309   }
310   else
311     aScalarBarTitleProp->SetColor( 1.0, 1.0, 1.0 );
312
313   aScalarBarTitleProp->SetFontFamilyToArial();
314   if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ){
315     if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" )
316       aScalarBarTitleProp->SetFontFamilyToArial();
317     else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" )
318       aScalarBarTitleProp->SetFontFamilyToCourier();
319     else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" )
320       aScalarBarTitleProp->SetFontFamilyToTimes();
321   }
322
323   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" )
324     aScalarBarTitleProp->BoldOn();
325   else
326     aScalarBarTitleProp->BoldOff();
327
328   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" )
329     aScalarBarTitleProp->ItalicOn();
330   else
331     aScalarBarTitleProp->ItalicOff();
332
333   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" )
334     aScalarBarTitleProp->ShadowOn();
335   else
336     aScalarBarTitleProp->ShadowOff();
337
338   myScalarBarActor->SetTitleTextProperty( aScalarBarTitleProp );
339   aScalarBarTitleProp->Delete();
340
341   vtkTextProperty* aScalarBarLabelProp = vtkTextProperty::New();
342
343   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) {
344     QStringList aTColor = QStringList::split(  ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false );
345     aScalarBarLabelProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
346                                    ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ), 
347                                    ( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
348   }
349   else
350     aScalarBarLabelProp->SetColor( 1.0, 1.0, 1.0 );
351
352   aScalarBarLabelProp->SetFontFamilyToArial();
353   if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ){
354     if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" )
355       aScalarBarLabelProp->SetFontFamilyToArial();
356     else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" )
357       aScalarBarLabelProp->SetFontFamilyToCourier();
358     else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" )
359       aScalarBarLabelProp->SetFontFamilyToTimes();
360   }
361
362   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" )
363     aScalarBarLabelProp->BoldOn();
364   else
365     aScalarBarLabelProp->BoldOff();
366
367   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" )
368     aScalarBarLabelProp->ItalicOn();
369   else
370     aScalarBarLabelProp->ItalicOff();
371
372   if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" )
373     aScalarBarLabelProp->ShadowOn();
374   else
375     aScalarBarLabelProp->ShadowOff();
376
377   myScalarBarActor->SetLabelTextProperty( aScalarBarLabelProp );
378   aScalarBarLabelProp->Delete();
379
380   if ( QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" )
381     myScalarBarActor->SetOrientationToHorizontal();
382   else
383     myScalarBarActor->SetOrientationToVertical();
384
385   float aXVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.20 : 0.01;
386   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) )
387     aXVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toFloat();
388   float aYVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.01 : 0.1;
389   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) )
390     aYVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toFloat();
391   myScalarBarActor->SetPosition( aXVal, aYVal );
392
393   float aWVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.60 : 0.10;
394   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) )
395     aWVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toFloat();
396   myScalarBarActor->SetWidth( aWVal );
397
398   float aHVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.12 : 0.80;
399   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) )
400     aHVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toFloat();
401   myScalarBarActor->SetHeight( aHVal );
402
403   int anIntVal = 5;
404   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) )
405     anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfLabels").toInt();
406   myScalarBarActor->SetNumberOfLabels(anIntVal == 0? 5: anIntVal);
407
408   anIntVal = 64;
409   if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) )
410     anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfColors").toInt();
411   myScalarBarActor->SetMaximumNumberOfColors(anIntVal == 0? 64: anIntVal);
412
413
414   //Definition of points numbering pipeline
415   //---------------------------------------
416   myPointsNumDataSet = vtkUnstructuredGrid::New();
417
418   myPtsMaskPoints = vtkMaskPoints::New();
419   myPtsMaskPoints->SetInput(myPointsNumDataSet);
420   myPtsMaskPoints->SetOnRatio(1);
421     
422   myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
423   myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
424   myPtsSelectVisiblePoints->SelectInvisibleOff();
425   myPtsSelectVisiblePoints->SetTolerance(0.1);
426     
427   myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
428   myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
429   myPtsLabeledDataMapper->SetLabelFormat("%g");
430   myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
431     
432   vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
433   aPtsTextProp->SetFontFamilyToTimes();
434   static int aPointsFontSize = 10;
435   aPtsTextProp->SetFontSize(aPointsFontSize);
436   aPtsTextProp->SetBold(1);
437   aPtsTextProp->SetItalic(0);
438   aPtsTextProp->SetShadow(0);
439   myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
440   aPtsTextProp->Delete();
441     
442   myEntityMode = eAllEntity;
443
444   myIsPointsLabeled = false;
445
446   myPointLabels = vtkActor2D::New();
447   myPointLabels->SetMapper(myPtsLabeledDataMapper);
448   myPointLabels->GetProperty()->SetColor(1,1,1);
449   myPointLabels->SetVisibility(myIsPointsLabeled);
450
451
452   //Definition of cells numbering pipeline
453   //---------------------------------------
454   myCellsNumDataSet = vtkUnstructuredGrid::New();
455
456   myCellCenters = vtkCellCenters::New();
457   myCellCenters->SetInput(myCellsNumDataSet);
458
459   myClsMaskPoints = vtkMaskPoints::New();
460   myClsMaskPoints->SetInput(myCellCenters->GetOutput());
461   myClsMaskPoints->SetOnRatio(1);
462     
463   myClsSelectVisiblePoints = vtkSelectVisiblePoints::New();
464   myClsSelectVisiblePoints->SetInput(myClsMaskPoints->GetOutput());
465   myClsSelectVisiblePoints->SelectInvisibleOff();
466   myClsSelectVisiblePoints->SetTolerance(0.1);
467     
468   myClsLabeledDataMapper = vtkLabeledDataMapper::New();
469   myClsLabeledDataMapper->SetInput(myClsSelectVisiblePoints->GetOutput());
470   myClsLabeledDataMapper->SetLabelFormat("%g");
471   myClsLabeledDataMapper->SetLabelModeToLabelScalars();
472     
473   vtkTextProperty* aClsTextProp = vtkTextProperty::New();
474   aClsTextProp->SetFontFamilyToTimes();
475   static int aCellsFontSize = 12;
476   aClsTextProp->SetFontSize(aCellsFontSize);
477   aClsTextProp->SetBold(1);
478   aClsTextProp->SetItalic(0);
479   aClsTextProp->SetShadow(0);
480   myClsLabeledDataMapper->SetLabelTextProperty(aClsTextProp);
481   aClsTextProp->Delete();
482     
483   myIsCellsLabeled = false;
484
485   myCellsLabels = vtkActor2D::New();
486   myCellsLabels->SetMapper(myClsLabeledDataMapper);
487   myCellsLabels->GetProperty()->SetColor(0,1,0);
488   myCellsLabels->SetVisibility(myIsCellsLabeled);
489
490   // Clipping planes
491   myImplicitBoolean = vtkImplicitBoolean::New();
492   myImplicitBoolean->SetOperationTypeToIntersection();
493 }
494
495
496 SMESH_Actor::~SMESH_Actor(){
497   if(MYDEBUG) MESSAGE("~SMESH_Actor");
498
499   myScalarBarActor->Delete();
500   myLookupTable->Delete();
501
502   mySurfaceProp->Delete();
503   myBackSurfaceProp->Delete();
504
505   myEdgeProp->Delete();
506   myHighlightProp->Delete();
507   myPreselectProp->Delete();
508
509   myNodeProp->Delete();
510
511   my1DProp->Delete();
512   my1DActor->Delete();
513
514   my1DExtProp->Delete();
515   my1DExtActor->Delete();
516
517   my2DActor->Delete();
518   my3DActor->Delete();
519
520   myNodeActor->Delete();
521   myBaseActor->Delete();
522
523   myHighlitableActor->Delete();
524   myNodeHighlitableActor->Delete();
525
526
527   //Deleting of pints numbering pipeline
528   //---------------------------------------
529   myPointsNumDataSet->Delete();
530
531   myPtsLabeledDataMapper->RemoveAllInputs();
532   myPtsLabeledDataMapper->Delete();
533
534   myPtsSelectVisiblePoints->UnRegisterAllOutputs();
535   myPtsSelectVisiblePoints->Delete();
536
537   myPtsMaskPoints->UnRegisterAllOutputs();
538   myPtsMaskPoints->Delete();
539
540   myPointLabels->Delete();
541
542
543   //Deleting of cells numbering pipeline
544   //---------------------------------------
545   myCellsNumDataSet->Delete();
546
547   myClsLabeledDataMapper->RemoveAllInputs();
548   myClsLabeledDataMapper->Delete();
549
550   myClsSelectVisiblePoints->UnRegisterAllOutputs();
551   myClsSelectVisiblePoints->Delete();
552
553   myClsMaskPoints->UnRegisterAllOutputs();
554   myClsMaskPoints->Delete();
555
556   myCellCenters->UnRegisterAllOutputs();
557   myCellCenters->Delete();
558
559   myCellsLabels->Delete();
560
561   myImplicitBoolean->Delete();
562
563   myTimeStamp->Delete();
564 }
565
566
567 void SMESH_Actor::SetPointsLabeled( bool theIsPointsLabeled )
568 {
569   vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
570   myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints();
571
572   if ( myIsPointsLabeled )
573   {
574     myPointsNumDataSet->ShallowCopy(aGrid);
575     vtkDataSet *aDataSet = myPointsNumDataSet;
576     
577     int aNbElem = aDataSet->GetNumberOfPoints();
578     
579     vtkIntArray *anArray = vtkIntArray::New();
580     anArray->SetNumberOfValues( aNbElem );
581     
582     for ( int anId = 0; anId < aNbElem; anId++ )
583     {
584       int aSMDSId = myVisualObj->GetNodeObjId( anId );
585       anArray->SetValue( anId, aSMDSId );
586     }
587     
588     aDataSet->GetPointData()->SetScalars( anArray );
589     anArray->Delete();
590     myPtsMaskPoints->SetInput( aDataSet );
591     myPointLabels->SetVisibility( GetVisibility() );
592   }
593   else
594   {
595     myPointLabels->SetVisibility( false );
596   }
597   SetRepresentation(GetRepresentation());
598   myTimeStamp->Modified();
599 }
600
601
602 void SMESH_Actor::SetCellsLabeled(bool theIsCellsLabeled){
603   vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
604   myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints();
605   if(myIsCellsLabeled){
606     myCellsNumDataSet->ShallowCopy(aGrid);
607     vtkDataSet *aDataSet = myCellsNumDataSet;
608     int aNbElem = aDataSet->GetNumberOfCells();
609     vtkIntArray *anArray = vtkIntArray::New();
610     anArray->SetNumberOfValues(aNbElem);
611     for(int anId = 0; anId < aNbElem; anId++){
612       int aSMDSId = myVisualObj->GetElemObjId(anId);
613       anArray->SetValue(anId,aSMDSId);
614     }
615     aDataSet->GetCellData()->SetScalars(anArray);
616     myCellCenters->SetInput(aDataSet);
617     myCellsLabels->SetVisibility(GetVisibility());
618   }else{
619     myCellsLabels->SetVisibility(false);
620   }
621   myTimeStamp->Modified();
622 }
623
624
625 void SMESH_Actor::SetControlMode(eControl theMode){
626   myColorMode = eNone;
627   my1DColorMode = e1DNone;
628
629   my1DActor->GetMapper()->SetScalarVisibility(false);
630   my2DActor->GetMapper()->SetScalarVisibility(false);
631   my3DActor->GetMapper()->SetScalarVisibility(false);
632   myScalarBarActor->SetVisibility(false);
633
634   bool anIsScalarVisible = theMode > eNone;
635
636   if(anIsScalarVisible){
637     SMESH::Controls::FunctorPtr aFunctor;
638     switch(theMode){
639     case eLengthEdges:
640     {
641       SMESH::Controls::Length* aControl = new SMESH::Controls::Length();
642       aControl->SetPrecision( myControlsPrecision );
643       aFunctor.reset( aControl );
644       myControlActor = my1DActor;
645       break;
646     }
647     case eFreeBorders:
648       aFunctor.reset(new SMESH::Controls::FreeBorders());
649       myControlActor = my1DActor;
650       break;
651     case eFreeEdges:
652       aFunctor.reset(new SMESH::Controls::FreeEdges());
653       myControlActor = my2DActor;
654       break;
655     case eMultiConnection:
656       aFunctor.reset(new SMESH::Controls::MultiConnection());
657       myControlActor = my1DActor;
658       break;
659     case eArea:
660     {
661       SMESH::Controls::Area* aControl = new SMESH::Controls::Area();
662       aControl->SetPrecision( myControlsPrecision );
663       aFunctor.reset( aControl );
664       myControlActor = my2DActor;
665       break;
666     }
667     case eTaper:
668     {
669       SMESH::Controls::Taper* aControl = new SMESH::Controls::Taper();
670       aControl->SetPrecision( myControlsPrecision );
671       aFunctor.reset( aControl );
672       myControlActor = my2DActor;
673       break;
674     }
675     case eAspectRatio:
676     {
677       SMESH::Controls::AspectRatio* aControl = new SMESH::Controls::AspectRatio();
678       aControl->SetPrecision( myControlsPrecision );
679       aFunctor.reset( aControl );
680       myControlActor = my2DActor;
681       break;
682     }
683     case eAspectRatio3D:
684     {
685       SMESH::Controls::AspectRatio3D* aControl = new SMESH::Controls::AspectRatio3D();
686       aControl->SetPrecision( myControlsPrecision );
687       aFunctor.reset( aControl );
688       myControlActor = my3DActor;
689       break;
690     }
691     case eMinimumAngle:
692     {
693       SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
694       aControl->SetPrecision( myControlsPrecision );
695       aFunctor.reset( aControl );
696       myControlActor = my2DActor;
697       break;
698     }
699     case eWarping:
700     {
701       SMESH::Controls::Warping* aControl = new SMESH::Controls::Warping();
702       aControl->SetPrecision( myControlsPrecision );
703       aFunctor.reset( aControl );
704       myControlActor = my2DActor;
705       break;
706     }
707     case eSkew:
708     {
709       SMESH::Controls::Skew* aControl = new SMESH::Controls::Skew();
710       aControl->SetPrecision( myControlsPrecision );
711       aFunctor.reset( aControl );
712       myControlActor = my2DActor;
713       break;
714     }
715     default:
716       return;
717     }
718
719     vtkUnstructuredGrid* aGrid = myControlActor->GetUnstructuredGrid();
720     vtkIdType aNbCells = aGrid->GetNumberOfCells();
721     if(aNbCells){
722       myColorMode = theMode;
723       if(theMode == eFreeBorders || theMode == eFreeEdges){
724         my1DColorMode = e1DHighlited;
725         my1DExtActor->SetExtControlMode(aFunctor,myControlActor);
726       }else{
727         if(myControlActor == my1DActor)
728           my1DColorMode = e1DColored;
729         myControlActor->SetControlMode(aFunctor,myScalarBarActor,myLookupTable);
730       }
731     }
732   }
733   SetRepresentation(GetRepresentation());
734
735   myTimeStamp->Modified();
736   Modified();
737 }
738
739
740 void SMESH_Actor::AddToRender(vtkRenderer* theRenderer){
741   SALOME_Actor::AddToRender(theRenderer);
742
743   theRenderer->AddActor(myNodeActor);
744   theRenderer->AddActor(myBaseActor);
745
746   theRenderer->AddActor(my3DActor);
747   theRenderer->AddActor(my2DActor);
748
749   theRenderer->AddActor(my1DActor);
750   theRenderer->AddActor(my1DExtActor);
751
752   theRenderer->AddActor(myHighlitableActor);
753   theRenderer->AddActor(myNodeHighlitableActor);
754
755   theRenderer->AddActor2D(myScalarBarActor);
756
757   myPtsSelectVisiblePoints->SetRenderer(theRenderer);
758   myClsSelectVisiblePoints->SetRenderer(theRenderer);
759
760   theRenderer->AddActor2D(myPointLabels);
761   theRenderer->AddActor2D(myCellsLabels);
762 }
763
764 void SMESH_Actor::RemoveFromRender(vtkRenderer* theRenderer){
765   SALOME_Actor::RemoveFromRender(theRenderer);
766
767   theRenderer->RemoveActor(myNodeActor);
768   theRenderer->RemoveActor(myBaseActor);
769
770   theRenderer->RemoveActor(myHighlitableActor);
771   theRenderer->RemoveActor(myNodeHighlitableActor);
772
773   theRenderer->RemoveActor(my1DActor);
774   theRenderer->RemoveActor(my1DExtActor);
775
776   theRenderer->RemoveActor(my2DActor);
777   theRenderer->RemoveActor(my3DActor);
778
779   theRenderer->RemoveActor(myScalarBarActor);
780   theRenderer->RemoveActor(myPointLabels);
781   theRenderer->RemoveActor(myCellsLabels);
782 }
783
784
785 bool SMESH_Actor::Init(TVisualObjPtr theVisualObj, 
786                        const char* theEntry, 
787                        const char* theName,
788                        int theIsClear)
789 {
790   Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject(theEntry,"SMESH",theName);
791   setIO(anIO);
792   setName(theName);
793
794   myVisualObj = theVisualObj;
795   myNodeActor->myVisualObj = myVisualObj;
796   myBaseActor->myVisualObj = myVisualObj;
797
798   myHighlitableActor->myVisualObj = myVisualObj;
799   myNodeHighlitableActor->myVisualObj = myVisualObj;
800
801   my1DActor->myVisualObj = myVisualObj;
802   my1DExtActor->myVisualObj = myVisualObj;
803
804   my2DActor->myVisualObj = myVisualObj;
805   my3DActor->myVisualObj = myVisualObj;
806
807   myVisualObj->Update(theIsClear);
808
809   myNodeActor->Init(myVisualObj,myImplicitBoolean);
810   myBaseActor->Init(myVisualObj,myImplicitBoolean);
811   
812   myHighlitableActor->Init(myVisualObj,myImplicitBoolean);
813   myNodeHighlitableActor->Init(myVisualObj,myImplicitBoolean);
814   
815   my1DActor->Init(myVisualObj,myImplicitBoolean);
816   my1DExtActor->Init(myVisualObj,myImplicitBoolean);
817   
818   my2DActor->Init(myVisualObj,myImplicitBoolean);
819   my3DActor->Init(myVisualObj,myImplicitBoolean);
820   
821   my1DActor->GetMapper()->SetLookupTable(myLookupTable);
822   my2DActor->GetMapper()->SetLookupTable(myLookupTable);
823   my3DActor->GetMapper()->SetLookupTable(myLookupTable);
824     
825   float aFactor, aUnits;
826   my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
827   my2DActor->SetPolygonOffsetParameters(aFactor,aUnits*0.75);
828
829   //SetIsShrunkable(theGrid->GetNumberOfCells() > 10);
830   SetIsShrunkable(true);
831   
832   QString aMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
833   SetRepresentation(-1);
834   if(aMode.compare("Wireframe") == 0){
835     SetRepresentation(eEdge);
836   }else if(aMode.compare("Shading") == 0){
837     SetRepresentation(eSurface);
838   }else if(aMode.compare("Nodes") == 0){
839     SetRepresentation(ePoint);
840   }
841
842   aMode = QAD_CONFIG->getSetting("SMESH:Shrink");
843   if(aMode == "yes"){
844     SetShrink();
845   }
846
847   myTimeStamp->Modified();
848   Modified();
849   return true;
850 }
851
852
853 float* SMESH_Actor::GetBounds(){
854   return myNodeActor->GetBounds();
855 }
856
857
858 vtkDataSet* SMESH_Actor::GetInput(){
859   return GetUnstructuredGrid();
860 }
861
862
863 void SMESH_Actor::SetTransform(SALOME_Transform* theTransform){
864   myNodeActor->SetTransform(theTransform);
865   myBaseActor->SetTransform(theTransform);
866
867   myHighlitableActor->SetTransform(theTransform);
868   myNodeHighlitableActor->SetTransform(theTransform);
869
870   my1DActor->SetTransform(theTransform);
871   my1DExtActor->SetTransform(theTransform);
872
873   my2DActor->SetTransform(theTransform);
874   my3DActor->SetTransform(theTransform);
875
876   Modified();
877 }
878
879
880 void SMESH_Actor::SetMapper(vtkMapper* theMapper){
881   vtkLODActor::SetMapper(theMapper);
882 }
883
884
885 void SMESH_Actor::ShallowCopy(vtkProp *prop){
886   SALOME_Actor::ShallowCopy(prop);
887 }
888
889
890 vtkMapper* SMESH_Actor::GetMapper(){
891   return myPickableActor->GetMapper();
892 }
893
894
895 vtkUnstructuredGrid* SMESH_Actor::GetUnstructuredGrid(){ 
896   return myVisualObj->GetUnstructuredGrid();
897 }
898
899
900 bool SMESH_Actor::IsInfinitive(){
901   vtkDataSet *aDataSet = myPickableActor->GetUnstructuredGrid();
902   aDataSet->Update();
903   myIsInfinite = aDataSet->GetNumberOfCells() == 0 ||
904     aDataSet->GetNumberOfCells() == 1 && 
905     aDataSet->GetCell(0)->GetCellType() == VTK_VERTEX;
906   return SALOME_Actor::IsInfinitive();
907 }
908
909
910 void SMESH_Actor::SetIsShrunkable(bool theShrunkable){
911   myIsShrinkable = theShrunkable;
912   Modified();
913 }
914
915 float SMESH_Actor::GetShrinkFactor(){
916   return myBaseActor->GetShrinkFactor();
917 }
918
919 void SMESH_Actor::SetShrinkFactor(float theValue){
920   myBaseActor->SetShrinkFactor(theValue);
921
922   my1DActor->SetShrinkFactor(theValue);
923   my1DExtActor->SetShrinkFactor(theValue);
924
925   my2DActor->SetShrinkFactor(theValue);
926   my3DActor->SetShrinkFactor(theValue);
927
928   Modified();
929 }
930
931 void SMESH_Actor::SetShrink(){
932   if(!myIsShrinkable) return;
933
934   myBaseActor->SetShrink();
935
936   my1DActor->SetShrink();
937   my1DExtActor->SetShrink();
938
939   my2DActor->SetShrink();
940   my3DActor->SetShrink();
941
942   myIsShrunk = true;
943   Modified();
944 }
945
946 void SMESH_Actor::UnShrink(){
947   if(!myIsShrunk) return;
948
949   myBaseActor->UnShrink();
950
951   my1DActor->UnShrink();
952   my1DExtActor->UnShrink();
953
954   my2DActor->UnShrink();
955   my3DActor->UnShrink();
956
957   myIsShrunk = false;
958   Modified();
959 }
960
961
962 int SMESH_Actor::GetNodeObjId(int theVtkID){
963   return myPickableActor->GetNodeObjId(theVtkID);
964 }
965
966 float* SMESH_Actor::GetNodeCoord(int theObjID){
967   return myPickableActor->GetNodeCoord(theObjID);
968 }
969
970
971 int SMESH_Actor::GetElemObjId(int theVtkID){
972   return myPickableActor->GetElemObjId(theVtkID);
973 }
974
975 vtkCell* SMESH_Actor::GetElemCell(int theObjID){
976   return myPickableActor->GetElemCell(theObjID);
977 }
978
979
980 void SMESH_Actor::SetVisibility(int theMode){
981   SetVisibility(theMode,true);
982 }
983
984
985 void SMESH_Actor::SetVisibility(int theMode, bool theIsUpdateRepersentation){
986   SALOME_Actor::SetVisibility(theMode);
987   if(GetVisibility()){
988     if(theIsUpdateRepersentation)
989       SetRepresentation(GetRepresentation());
990
991     if(myColorMode != eNone){
992       if(my1DColorMode == e1DHighlited)
993         my1DExtActor->VisibilityOn();
994       else if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells())
995         myScalarBarActor->VisibilityOn();
996     }
997
998     if(myRepresentation != ePoint)
999       myPickableActor->VisibilityOn();
1000
1001     my1DActor->VisibilityOn();
1002
1003     my2DActor->VisibilityOn();
1004     my3DActor->VisibilityOn();
1005
1006     if(myIsPointsLabeled) myPointLabels->VisibilityOn();
1007     if(myIsCellsLabeled) myCellsLabels->VisibilityOn();
1008   }else{
1009     myNodeActor->VisibilityOff();
1010     myBaseActor->VisibilityOff();
1011
1012     my1DActor->VisibilityOff();
1013     my1DExtActor->VisibilityOff();
1014
1015     my2DActor->VisibilityOff();
1016     my3DActor->VisibilityOff();
1017
1018     myScalarBarActor->VisibilityOff();
1019     myPointLabels->VisibilityOff();
1020     myCellsLabels->VisibilityOff();
1021   }
1022   Modified();
1023 }
1024
1025
1026 namespace{
1027
1028   inline bool UpdateEntityMode(unsigned int& theOutputMode, 
1029                                unsigned int theInputMode, 
1030                                unsigned int theMode,
1031                                int theCondition)
1032   {
1033     if(!theCondition)
1034       theOutputMode &= ~theMode;
1035
1036     return theOutputMode & theMode && theCondition;
1037   }
1038
1039 }
1040
1041 void SMESH_Actor::SetEntityMode(unsigned int theMode){
1042   if(!myVisualObj->GetNbEntities(SMESH::EDGE))
1043     theMode &= ~eEdges;
1044
1045   if(!myVisualObj->GetNbEntities(SMESH::FACE))
1046     theMode &= ~eFaces;
1047
1048   if(!myVisualObj->GetNbEntities(SMESH::VOLUME))
1049     theMode &= ~eVolumes;
1050
1051   if(!theMode)
1052     return;
1053
1054   myScalarBarActor->VisibilityOff();
1055
1056   my1DExtActor->VisibilityOff();
1057   my1DActor->VisibilityOff();
1058   
1059   my2DActor->VisibilityOff();
1060   my3DActor->VisibilityOff();
1061   
1062   if(theMode & eEdges)
1063     my1DActor->VisibilityOn();
1064   
1065   if(theMode & eFaces)
1066     my2DActor->VisibilityOn();
1067   
1068   if(theMode & eVolumes)
1069     my3DActor->VisibilityOn();
1070   
1071   myEntityMode = theMode;
1072 }
1073
1074
1075 void SMESH_Actor::SetRepresentation(int theMode){ 
1076   int aNbEdges = myVisualObj->GetNbEntities(SMESH::EDGE);
1077   int aNbFaces = myVisualObj->GetNbEntities(SMESH::FACE);
1078   int aNbVolumes = myVisualObj->GetNbEntities(SMESH::VOLUME);
1079   if(theMode < 0){
1080     myRepresentation = eSurface;
1081     if(!aNbFaces && !aNbVolumes && aNbEdges){
1082       myRepresentation = eEdge;
1083     }else if(!aNbFaces && !aNbVolumes && !aNbEdges){
1084       myRepresentation = ePoint;
1085     }
1086   }else{
1087     switch(theMode){
1088     case eEdge:
1089       if(!aNbFaces && !aNbVolumes && !aNbEdges) return;
1090       break;
1091     case eSurface:
1092       if(!aNbFaces && !aNbVolumes) return;
1093       break;
1094     }    
1095     myRepresentation = theMode;
1096   }
1097
1098   if(!GetUnstructuredGrid()->GetNumberOfCells())
1099     myRepresentation = ePoint;
1100
1101   if(myIsShrunk){
1102     if(myRepresentation == ePoint){
1103       UnShrink();
1104       myIsShrunk = true;
1105     }else{
1106       SetShrink();
1107     }      
1108   }
1109
1110   myPickableActor = myBaseActor;
1111   myNodeActor->SetVisibility(false);
1112   vtkProperty *aProp = NULL, *aBackProp = NULL;
1113   SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1);
1114   switch(myRepresentation){
1115   case ePoint: 
1116     myPickableActor = myNodeActor;
1117     myNodeActor->SetVisibility(true);
1118
1119     aProp = aBackProp = myNodeProp;
1120     aReperesent = SMESH_DeviceActor::ePoint;
1121     break;
1122   case eEdge:
1123     aProp = aBackProp = myEdgeProp;
1124     aReperesent = SMESH_DeviceActor::eInsideframe;
1125     break;
1126   case eSurface:
1127     aProp = mySurfaceProp;
1128     aBackProp = myBackSurfaceProp;
1129     aReperesent = SMESH_DeviceActor::eSurface;
1130     break;
1131   }    
1132
1133   my2DActor->SetProperty(aProp);
1134   my2DActor->SetBackfaceProperty(aBackProp);
1135   my2DActor->SetRepresentation(aReperesent);
1136   
1137   my3DActor->SetProperty(aProp);
1138   my3DActor->SetBackfaceProperty(aBackProp);
1139   my3DActor->SetRepresentation(aReperesent);
1140
1141   my1DExtActor->SetVisibility(false);
1142   switch(my1DColorMode){
1143   case e1DColored: 
1144     aProp = aBackProp = my1DProp;
1145     if(myRepresentation != ePoint)
1146       aReperesent = SMESH_DeviceActor::eInsideframe;
1147     break;
1148   case e1DHighlited: 
1149     my1DExtActor->SetVisibility(true);
1150     break;
1151   }
1152   
1153   my1DActor->SetProperty(aProp);
1154   my1DActor->SetBackfaceProperty(aBackProp);
1155   my1DActor->SetRepresentation(aReperesent);
1156
1157   my1DExtActor->SetRepresentation(aReperesent);
1158   
1159   if(myIsPointsVisible)
1160     myPickableActor = myNodeActor;
1161
1162   if(GetPointRepresentation())
1163     myNodeActor->SetVisibility(true);
1164
1165   SetMapper(myPickableActor->GetMapper());
1166
1167   SetVisibility(GetVisibility(),false);
1168
1169   Modified();
1170 }
1171
1172
1173 void SMESH_Actor::SetPointRepresentation(bool theIsPointsVisible){
1174   myIsPointsVisible = theIsPointsVisible;
1175   SetRepresentation(GetRepresentation());
1176 }
1177
1178 bool SMESH_Actor::GetPointRepresentation(){ 
1179   return myIsPointsVisible || myIsPointsLabeled;
1180 }
1181
1182
1183 void SMESH_Actor::UpdateHighlight(){
1184   myHighlitableActor->SetVisibility(false);
1185   myHighlitableActor->SetHighlited(false);
1186
1187   myNodeHighlitableActor->SetVisibility(false);
1188   myNodeHighlitableActor->SetHighlited(false);
1189
1190   if(myIsHighlighted){
1191     myHighlitableActor->SetProperty(myHighlightProp);
1192   }else if(myIsPreselected){
1193     myHighlitableActor->SetProperty(myPreselectProp);
1194   }
1195
1196   bool isVisible = GetVisibility();
1197
1198   if(myIsHighlighted || myIsPreselected){
1199     if(GetUnstructuredGrid()->GetNumberOfCells()){
1200       myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
1201       myHighlitableActor->SetVisibility(isVisible);
1202       myHighlitableActor->SetHighlited(isVisible);
1203     }
1204     if(myRepresentation == ePoint || GetPointRepresentation()){
1205       myNodeHighlitableActor->SetProperty(myHighlitableActor->GetProperty());
1206       myNodeHighlitableActor->SetVisibility(isVisible);
1207       myNodeHighlitableActor->SetHighlited(isVisible);
1208     }
1209   }
1210 }
1211
1212
1213 void SMESH_Actor::highlight(bool theHighlight){
1214   myIsHighlighted = theHighlight;
1215   UpdateHighlight();
1216 }
1217
1218
1219 void SMESH_Actor::SetPreSelected(bool thePreselect){ 
1220   myIsPreselected = thePreselect; 
1221   UpdateHighlight();
1222 }
1223
1224
1225 // From vtkFollower
1226 int SMESH_Actor::RenderOpaqueGeometry(vtkViewport *vp)
1227 {
1228   if (myPickableActor->GetIsOpaque())
1229     {
1230     vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
1231     this->Render(ren);
1232     return 1;
1233     }
1234   return 0;
1235 }
1236
1237
1238 int SMESH_Actor::RenderTranslucentGeometry(vtkViewport *vp)
1239 {
1240   if (!myPickableActor->GetIsOpaque())
1241     {
1242     vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
1243     this->Render(ren);
1244     return 1;
1245     }
1246   return 0;
1247 }
1248
1249
1250 void SMESH_Actor::Render(vtkRenderer *ren){
1251   unsigned long mTime = myTimeStamp->GetMTime();
1252   unsigned long anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime();
1253   if(anObjTime > mTime)
1254     Update();
1255 }
1256
1257
1258 void SMESH_Actor::Update(){
1259   SetVisibility(GetVisibility());
1260   unsigned long int anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime();
1261   unsigned long int aClippingTime = myImplicitBoolean->GetMTime();
1262   unsigned long int aTime = myTimeStamp->GetMTime();
1263   if(MYDEBUG) MESSAGE("SMESH_Actor::Update");
1264
1265   if(GetControlMode() != eNone) {
1266     if(anObjTime > aTime || aClippingTime > aTime){
1267       SetControlMode(GetControlMode());
1268       SetVisibility(GetVisibility());
1269     }
1270   }
1271   if(myIsPointsLabeled){
1272     if(anObjTime > aTime || aClippingTime > aTime)
1273       SetPointsLabeled(myIsPointsLabeled);
1274   }
1275   if(myIsCellsLabeled){
1276     if(anObjTime > aTime || aClippingTime > aTime)
1277       SetCellsLabeled(myIsCellsLabeled);
1278   }
1279
1280   myTimeStamp->Modified();
1281   Modified();
1282 }
1283
1284
1285 void SMESH_Actor::ReleaseGraphicsResources(vtkWindow *renWin){
1286   SALOME_Actor::ReleaseGraphicsResources(renWin);
1287
1288   myPickableActor->ReleaseGraphicsResources(renWin);
1289 }
1290
1291
1292 static void GetColor(vtkProperty *theProperty, float& r,float& g,float& b){
1293   float* aColor = theProperty->GetColor();
1294   r = aColor[0];
1295   g = aColor[1];
1296   b = aColor[2];
1297 }
1298
1299
1300 void SMESH_Actor::SetOpacity(float theValue){
1301   mySurfaceProp->SetOpacity(theValue);
1302   myBackSurfaceProp->SetOpacity(theValue);
1303   myEdgeProp->SetOpacity(theValue);
1304   myNodeProp->SetOpacity(theValue);
1305
1306   my1DProp->SetOpacity(theValue);
1307 }
1308
1309
1310 float SMESH_Actor::GetOpacity(){
1311   return mySurfaceProp->GetOpacity();
1312 }
1313
1314
1315 void SMESH_Actor::SetSufaceColor(float r,float g,float b){
1316   mySurfaceProp->SetColor(r,g,b);
1317   Modified();
1318 }
1319
1320 void SMESH_Actor::GetSufaceColor(float& r,float& g,float& b){
1321   ::GetColor(mySurfaceProp,r,g,b);
1322 }
1323
1324 void SMESH_Actor::SetBackSufaceColor(float r,float g,float b){
1325   myBackSurfaceProp->SetColor(r,g,b);
1326   Modified();
1327 }
1328
1329 void SMESH_Actor::GetBackSufaceColor(float& r,float& g,float& b){
1330   ::GetColor(myBackSurfaceProp,r,g,b);
1331 }
1332
1333 void SMESH_Actor::SetEdgeColor(float r,float g,float b){
1334   myEdgeProp->SetColor(r,g,b);
1335   my1DProp->SetColor(r,g,b);
1336   my1DExtProp->SetColor(1.0-r,1.0-g,1.0-b);
1337   Modified();
1338 }
1339
1340 void SMESH_Actor::GetEdgeColor(float& r,float& g,float& b){
1341   ::GetColor(myEdgeProp,r,g,b);
1342 }
1343
1344 void SMESH_Actor::SetNodeColor(float r,float g,float b){ 
1345   myNodeProp->SetColor(r,g,b);
1346   Modified();
1347 }
1348
1349 void SMESH_Actor::GetNodeColor(float& r,float& g,float& b){ 
1350   ::GetColor(myNodeProp,r,g,b);
1351 }
1352
1353 void SMESH_Actor::SetHighlightColor(float r,float g,float b){ 
1354   myHighlightProp->SetColor(r,g,b);
1355   Modified();
1356 }
1357
1358 void SMESH_Actor::GetHighlightColor(float& r,float& g,float& b){ 
1359   ::GetColor(myHighlightProp,r,g,b);
1360 }
1361
1362 void SMESH_Actor::SetPreHighlightColor(float r,float g,float b){ 
1363   myPreselectProp->SetColor(r,g,b);
1364   Modified();
1365 }
1366
1367 void SMESH_Actor::GetPreHighlightColor(float& r,float& g,float& b){ 
1368   ::GetColor(myPreselectProp,r,g,b);
1369 }
1370
1371
1372 float SMESH_Actor::GetLineWidth(){
1373   return myEdgeProp->GetLineWidth();
1374 }
1375
1376
1377 void SMESH_Actor::SetLineWidth(float theVal){
1378   myEdgeProp->SetLineWidth(theVal);
1379
1380   my1DProp->SetLineWidth(theVal + aLineWidthInc);
1381   my1DExtProp->SetLineWidth(theVal + aLineWidthInc);
1382
1383   Modified();
1384 }
1385
1386
1387 void SMESH_Actor::SetNodeSize(float theVal){
1388   myNodeProp->SetPointSize(theVal);
1389   myHighlightProp->SetPointSize(theVal);
1390   myPreselectProp->SetPointSize(theVal);
1391
1392   my1DProp->SetPointSize(theVal + aPointSizeInc);
1393   my1DExtProp->SetPointSize(theVal + aPointSizeInc);
1394
1395   Modified();
1396 }
1397
1398 float SMESH_Actor::GetNodeSize(){
1399   return myNodeProp->GetPointSize();
1400 }
1401
1402 int SMESH_Actor::GetObjDimension( const int theObjId )
1403 {
1404   return myVisualObj->GetElemDimension( theObjId );
1405 }
1406
1407
1408 vtkImplicitBoolean* SMESH_Actor::GetPlaneContainer(){
1409   return myImplicitBoolean;
1410 }
1411
1412
1413 static void ComputeBoundsParam(vtkDataSet* theDataSet,
1414                                float theDirection[3], float theMinPnt[3],
1415                                float& theMaxBoundPrj, float& theMinBoundPrj)
1416 {
1417   float aBounds[6];
1418   theDataSet->GetBounds(aBounds);
1419
1420   //Enlarge bounds in order to avoid conflicts of precision
1421   for(int i = 0; i < 6; i += 2){
1422     static double EPS = 1.0E-3;
1423     float aDelta = (aBounds[i+1] - aBounds[i])*EPS;
1424     aBounds[i] -= aDelta;
1425     aBounds[i+1] += aDelta;
1426   }
1427
1428   float aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
1429                                {aBounds[1],aBounds[2],aBounds[4]},
1430                                {aBounds[0],aBounds[3],aBounds[4]},
1431                                {aBounds[1],aBounds[3],aBounds[4]},
1432                                {aBounds[0],aBounds[2],aBounds[5]},
1433                                {aBounds[1],aBounds[2],aBounds[5]}, 
1434                                {aBounds[0],aBounds[3],aBounds[5]}, 
1435                                {aBounds[1],aBounds[3],aBounds[5]}};
1436
1437   int aMaxId = 0, aMinId = aMaxId;
1438   theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
1439   theMinBoundPrj = theMaxBoundPrj;
1440   for(int i = 1; i < 8; i++){
1441     float aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
1442     if(theMaxBoundPrj < aTmp){
1443       theMaxBoundPrj = aTmp;
1444       aMaxId = i;
1445     }
1446     if(theMinBoundPrj > aTmp){
1447       theMinBoundPrj = aTmp;
1448       aMinId = i;
1449     }
1450   }
1451   float *aMinPnt = aBoundPoints[aMaxId];
1452   theMinPnt[0] = aMinPnt[0];
1453   theMinPnt[1] = aMinPnt[1];
1454   theMinPnt[2] = aMinPnt[2];
1455 }
1456
1457
1458 static void DistanceToPosition(vtkDataSet* theDataSet,
1459                                float theDirection[3], float theDist, float thePos[3])
1460 {
1461   float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1462   ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1463   float aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
1464   thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
1465   thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
1466   thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
1467 }
1468
1469
1470 static void PositionToDistance(vtkDataSet* theDataSet, 
1471                                float theDirection[3], float thePos[3], float& theDist)
1472 {
1473   float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
1474   ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
1475   float aPrj = vtkMath::Dot(theDirection,thePos);
1476   theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
1477 }
1478
1479
1480 void SMESH_Actor::SetPlaneParam(float theDir[3], float theDist, vtkPlane* thePlane)
1481 {
1482   thePlane->SetNormal(theDir);
1483   float anOrigin[3];
1484   ::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin);
1485   thePlane->SetOrigin(anOrigin);
1486   Update();
1487 }
1488
1489
1490 void SMESH_Actor::GetPlaneParam(float theDir[3], float& theDist, vtkPlane* thePlane)
1491 {
1492   thePlane->GetNormal(theDir);
1493
1494   float anOrigin[3];
1495   thePlane->GetOrigin(anOrigin);
1496   ::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist);
1497 }