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