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