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