Salome HOME
Fix for the "0051899: curves are not shown in opened study" issue.
[modules/visu.git] / src / PIPELINE / VISU_ScalarBarActor.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  VISU OBJECT : interactive object for VISU entities implementation
24 // File:    VISU_PipeLine.hxx
25 // Author:  Alexey PETROV
26 // Module : VISU
27 //
28 #include "VISU_ScalarBarActor.hxx"
29
30 #include <vtkPolyDataMapper2D.h>
31 #include <vtkCellArray.h>
32 #include <vtkCellData.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkPolyData.h>
35 #include <vtkPolyDataMapper2D.h>
36 #include <vtkScalarsToColors.h>
37 #include <vtkTextMapper.h>
38 #include <vtkTextProperty.h>
39 #include <vtkViewport.h>
40 #include <vtkWindow.h>
41 #include <vtkLogLookupTable.h>
42 #include <vtkProperty2D.h> // RKV
43 #include <vtkAxisActor2D.h> // RKV
44
45 using namespace std;
46
47 vtkCxxSetObjectMacro(VISU_ScalarBarActor,LookupTable,VISU_LookupTable);
48 vtkCxxSetObjectMacro(VISU_ScalarBarActor,LabelTextProperty,vtkTextProperty);
49 vtkCxxSetObjectMacro(VISU_ScalarBarActor,TitleTextProperty,vtkTextProperty);
50
51 //------------------------------------------------------------------------------
52 VISU_ScalarBarActor* VISU_ScalarBarActor::New(){
53   vtkObject* ret = vtkObjectFactory::CreateInstance("VISU_ScalarBarActor");
54   if(ret)
55     return (VISU_ScalarBarActor*)ret;
56   return new VISU_ScalarBarActor;
57 }
58
59 VISU_ScalarBarActor::VISU_ScalarBarActor()
60 {
61   this->LookupTable = NULL;
62   this->Position2Coordinate->SetValue(0.17, 0.8);
63   
64   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
65   this->PositionCoordinate->SetValue(0.82,0.1);
66   
67   this->MaximumNumberOfColors = 64;
68   this->NumberOfLabels = 5;
69   this->NumberOfLabelsBuilt = 0;
70   this->Orientation = VTK_ORIENT_VERTICAL;
71   this->Title = NULL;
72
73   this->LabelTextProperty = vtkTextProperty::New();
74   this->LabelTextProperty->SetFontSize(12);
75   this->LabelTextProperty->SetBold(1);
76   this->LabelTextProperty->SetItalic(1);
77   this->LabelTextProperty->SetShadow(1);
78   this->LabelTextProperty->SetFontFamilyToArial();
79
80   this->TitleTextProperty = vtkTextProperty::New();
81   this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
82
83   this->LabelFormat = new char[8]; 
84   sprintf(this->LabelFormat,"%s","%-#6.3g");
85
86   this->TitleMapper = vtkTextMapper::New();
87   this->TitleActor = vtkActor2D::New();
88   this->TitleActor->SetMapper(this->TitleMapper);
89   this->TitleActor->GetPositionCoordinate()->
90     SetReferenceCoordinate(this->PositionCoordinate);
91   
92   this->TextMappers = NULL;
93   this->TextActors = NULL;
94
95   this->ScalarBar = vtkPolyData::New();
96   this->ScalarBarMapper = vtkPolyDataMapper2D::New();
97   this->ScalarBarMapper->SetInputData(this->ScalarBar);
98   this->ScalarBarActor = vtkActor2D::New();
99   this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
100   this->ScalarBarActor->GetPositionCoordinate()->
101     SetReferenceCoordinate(this->PositionCoordinate);
102   this->LastOrigin[0] = 0;
103   this->LastOrigin[1] = 0;
104   this->LastSize[0] = 0;
105   this->LastSize[1] = 0;
106
107   this->TitleRatioSize = 0;
108   this->LabelRatioWidth = 0;
109   this->BarRatioWidth = 0;
110   this->BarRatioHeight = 0;
111   
112   // RKV : Begin
113   this->Distribution = vtkDoubleArray::New();
114   this->DistributionObj = vtkDataObject::New();
115   this->DistributionActor = VISU_XYPlotActor::New();
116   this->DistributionActor->SetTitle("");
117   this->DistributionActor->SetXTitle("");
118   this->DistributionActor->SetYTitle("");
119   this->DistributionActor->GetXAxisActor2D()->LabelVisibilityOff();
120   this->DistributionActor->GetXAxisActor2D()->TitleVisibilityOff();
121   this->DistributionActor->GetXAxisActor2D()->TickVisibilityOff();
122 //  this->DistributionActor->GetXAxisActor2D()->SetFontFactor(0.);
123   this->DistributionActor->SetNumberOfYLabels(1);
124 //  this->DistributionActor->SetNumberOfXLabels(2);
125   this->DistributionActor->GetXAxisActor2D()->AdjustLabelsOff();
126   this->DistributionActor->GetYAxisActor2D()->AdjustLabelsOff();
127   this->DistributionActor->LegendOff();
128   this->DistributionActor->SetLabelFormat("%4.3f");
129   this->DistributionActor->SetXValuesToIndex();
130 //  this->DistributionActor->GetPositionCoordinate()->SetValue(0.0, 0.67, 0);
131 //  this->DistributionActor->GetPosition2Coordinate()->SetValue(1.0, 0.33, 0); // #relative to Position
132   this->DistributionActor->GetPositionCoordinate()->
133     SetReferenceCoordinate(this->PositionCoordinate);
134   this->DistributionVisibilityOff(); // Don't show the distribution curve by default
135   
136   // RKV : End
137 }
138
139 void VISU_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
140 {
141   this->TitleActor->ReleaseGraphicsResources(win);
142   if (this->TextMappers != NULL )
143     {
144     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
145       {
146       this->TextActors[i]->ReleaseGraphicsResources(win);
147       }
148     }
149   this->ScalarBarActor->ReleaseGraphicsResources(win);
150   this->DistributionActor->ReleaseGraphicsResources(win); // RKV
151 }
152
153 VISU_ScalarBarActor::~VISU_ScalarBarActor()
154 {
155   if (this->LabelFormat) 
156     {
157     delete [] this->LabelFormat;
158     this->LabelFormat = NULL;
159     }
160
161   this->TitleMapper->Delete();
162   this->TitleActor->Delete();
163
164   if (this->TextMappers != NULL )
165     {
166     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
167       {
168       this->TextMappers[i]->Delete();
169       this->TextActors[i]->Delete();
170       }
171     delete [] this->TextMappers;
172     delete [] this->TextActors;
173     }
174
175   // RKV : Begin
176   this->DistributionActor->Delete();
177   this->DistributionObj->Delete();
178   this->SetDistribution(NULL);
179   // RKV : End
180
181   this->ScalarBar->Delete();
182   this->ScalarBarMapper->Delete();
183   this->ScalarBarActor->Delete();
184   
185   if (this->Title)
186     {
187     delete [] this->Title;
188     this->Title = NULL;
189     }
190   
191   this->SetLookupTable(NULL);
192   this->SetLabelTextProperty(NULL);
193   this->SetTitleTextProperty(NULL);
194 }
195
196 int VISU_ScalarBarActor::RenderOverlay(vtkViewport *viewport)
197 {
198   int renderedSomething = 0;
199   int i;
200   
201   // Everything is built, just have to render
202   if (this->Title != NULL)
203     {
204     renderedSomething += this->TitleActor->RenderOverlay(viewport);
205     }
206   this->ScalarBarActor->RenderOverlay(viewport);
207   // RKV : Begin
208   if (this->DistributionVisibility)
209     this->DistributionActor->RenderOverlay(viewport);
210   // RKV : End
211   if( this->TextActors == NULL)
212     {
213      vtkWarningMacro(<<"Need a mapper to render a scalar bar");
214      return renderedSomething;
215     }
216   
217   for (i=0; i<this->NumberOfLabels; i++)
218     {
219     renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
220     }
221
222   renderedSomething = (renderedSomething > 0)?(1):(0);
223
224   return renderedSomething;
225 }
226
227 int VISU_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
228 {
229   int renderedSomething = 0;
230   int i;
231   int size[2];
232   
233   if (!this->LookupTable)
234     {
235     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
236     return 0;
237     }
238
239   if (!this->TitleTextProperty)
240     {
241     vtkErrorMacro(<<"Need title text property to render a scalar bar");
242     return 0;
243     }
244
245   if (!this->LabelTextProperty)
246     {
247     vtkErrorMacro(<<"Need label text property to render a scalar bar");
248     return 0;
249     }
250
251   // Check to see whether we have to rebuild everything
252   int positionsHaveChanged = 0;
253   if (viewport->GetMTime() > this->BuildTime || 
254       (viewport->GetVTKWindow() && 
255        viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
256     {
257     // if the viewport has changed we may - or may not need
258     // to rebuild, it depends on if the projected coords chage
259     int *barOrigin;
260     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
261     size[0] = 
262       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
263       barOrigin[0];
264     size[1] = 
265       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
266       barOrigin[1];
267     if (this->LastSize[0] != size[0] || 
268         this->LastSize[1] != size[1] ||
269         this->LastOrigin[0] != barOrigin[0] || 
270         this->LastOrigin[1] != barOrigin[1])
271       {
272       positionsHaveChanged = 1;
273       }
274     }
275   
276   // Check to see whether we have to rebuild everything
277   // RKV : Begin
278   if (positionsHaveChanged ||
279       this->GetMTime() > this->BuildTime || 
280       this->LookupTable->GetMTime() > this->BuildTime ||
281       this->LabelTextProperty->GetMTime() > this->BuildTime ||
282       this->TitleTextProperty->GetMTime() > this->BuildTime ||
283       this->Distribution->GetMTime() > this->BuildTime)
284   // RKV : End
285 /* RKV  if (positionsHaveChanged ||
286       this->GetMTime() > this->BuildTime || 
287       this->LookupTable->GetMTime() > this->BuildTime ||
288       this->LabelTextProperty->GetMTime() > this->BuildTime ||
289       this->TitleTextProperty->GetMTime() > this->BuildTime)*/
290     {
291
292     // Delete previously constructed objects
293     //
294     if (this->TextMappers != NULL )
295       {
296       for (i=0; i < this->NumberOfLabelsBuilt; i++)
297         {
298         this->TextMappers[i]->Delete();
299         this->TextActors[i]->Delete();
300         }
301       delete [] this->TextMappers;
302       delete [] this->TextActors;
303       }
304
305     // Build scalar bar object; determine its type
306     //
307     VISU_LookupTable *lut = this->LookupTable; //SALOME specific
308     int isLogTable = lut->GetScale() == VTK_SCALE_LOG10;
309     
310     // we hard code how many steps to display
311     int numColors = this->MaximumNumberOfColors;
312     double *range = lut->GetRange();
313
314     int numPts = 2*(numColors + 1);
315     vtkPoints *pts = vtkPoints::New();
316     pts->SetNumberOfPoints(numPts);
317     vtkCellArray *polys = vtkCellArray::New();
318     polys->Allocate(polys->EstimateSize(numColors,4));
319     vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
320     colors->SetNumberOfComponents(3);
321     colors->SetNumberOfTuples(numColors);
322
323 // RKV : Begin
324     // If the distribution is changed then recalculate the total
325     if (this->Distribution->GetMTime() > this->BuildTime) {
326           int aNbVals = this->Distribution->GetNumberOfTuples();
327       double range[2];
328       this->Distribution->GetRange(range);
329       this->DistributionActor->SetYRange(0, range[1]);
330 /*        int total = 0;
331           for(vtkIdType aValId = 0; aValId < aNbVals; aValId++){
332                 total += this->Distribution->GetValue(aValId);
333           }
334           this->DistributionActor->SetYRange(0, total);
335 */
336       }
337   
338     this->DistributionActor->SetProperty(this->GetProperty());
339     this->DistributionActor->GetProperty()->SetColor(1, 1, 1);
340     this->DistributionActor->GetProperty()->SetLineWidth(2);
341     this->DistributionActor->GetProperty()->SetDisplayLocationToForeground();
342     vtkTextProperty* tprop;
343     tprop = this->DistributionActor->GetTitleTextProperty();
344     tprop->SetColor(this->DistributionActor->GetProperty()->GetColor());
345 //  this->DistributionActor->SetAxisTitleTextProperty(tprop);
346 //  this->DistributionActor->SetAxisLabelTextProperty(tprop);
347     
348 // RKV : End
349     this->ScalarBarActor->SetProperty(this->GetProperty());
350     this->ScalarBar->Initialize();
351     this->ScalarBar->SetPoints(pts);
352     this->ScalarBar->SetPolys(polys);
353     this->ScalarBar->GetCellData()->SetScalars(colors);
354     pts->Delete(); polys->Delete(); colors->Delete();
355
356     // get the viewport size in display coordinates
357     int *barOrigin, barWidth, barHeight;
358     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
359     size[0] = 
360       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
361       barOrigin[0];
362     size[1] = 
363       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
364       barOrigin[1];
365     this->LastOrigin[0] = barOrigin[0];
366     this->LastOrigin[1] = barOrigin[1];
367     this->LastSize[0] = size[0];
368     this->LastSize[1] = size[1];
369     
370     // Update all the composing objects
371     this->TitleActor->SetProperty(this->GetProperty());
372     this->TitleMapper->SetInput(this->Title);
373     if (this->TitleTextProperty->GetMTime() > this->BuildTime)
374       {
375       // Shallow copy here so that the size of the title prop is not affected
376       // by the automatic adjustment of its text mapper's size (i.e. its
377       // mapper's text property is identical except for the font size
378       // which will be modified later). This allows text actors to
379       // share the same text property, and in that case specifically allows
380       // the title and label text prop to be the same.
381       this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
382       this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
383       }
384     
385     // find the best size for the title font
386     int titleSize[2];
387     this->SizeTitle(titleSize, size, viewport);
388     
389     // find the best size for the ticks
390     int labelSize[2];
391     this->AllocateAndSizeLabels(labelSize, size, viewport, range);
392     this->NumberOfLabelsBuilt = this->NumberOfLabels;
393     
394     this->SizeBar(barWidth, barHeight, size, viewport, range);
395
396     // generate points
397     double x[3]; x[2] = 0.0;
398     double delta, val;
399     if ( this->Orientation == VTK_ORIENT_VERTICAL )
400       {
401       delta=(double)barHeight/numColors;
402       for (i=0; i<numPts/2; i++)
403         {
404         x[0] = 0;
405         x[1] = i*delta;
406         pts->SetPoint(2*i,x);
407         x[0] = barWidth;
408         pts->SetPoint(2*i+1,x);
409         }
410       }
411     else
412       {
413       delta=(double)barWidth/numColors;
414       for (i=0; i<numPts/2; i++)
415         {
416         x[0] = i*delta;
417         x[1] = barHeight;
418         pts->SetPoint(2*i,x);
419         x[1] = 0;
420         pts->SetPoint(2*i+1,x);
421         }
422       }
423
424     //polygons & cell colors
425     unsigned char *rgba, *rgb;
426     vtkIdType ptIds[4];
427     for (i=0; i<numColors; i++)
428       {
429       ptIds[0] = 2*i;
430       ptIds[1] = ptIds[0] + 1;
431       ptIds[2] = ptIds[1] + 2;
432       ptIds[3] = ptIds[0] + 2;
433       polys->InsertNextCell(4,ptIds);
434
435       if ( isLogTable ){ //SALOME specific
436         double rgbval = log10(range[0]) + 
437           i*(log10(range[1])-log10(range[0]))/(numColors -1);
438         rgba = lut->MapValue(rgbval);
439       }else{
440         rgba = lut->MapValue(range[0] + (range[1] - range[0])*
441                              ((double)i /(numColors-1.0)));
442       }
443
444       rgb = colors->GetPointer(3*i); //write into array directly
445       rgb[0] = rgba[0];
446       rgb[1] = rgba[1];
447       rgb[2] = rgba[2];
448     }
449
450     // Now position everything properly
451     //
452     if (this->Orientation == VTK_ORIENT_VERTICAL)
453       {
454       int sizeTextData[2];
455       
456       // center the title
457       this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
458       
459       for (i=0; i < this->NumberOfLabels; i++)
460         {
461         val = (double)i/(this->NumberOfLabels-1) *barHeight;
462         this->TextMappers[i]->GetSize(viewport,sizeTextData);
463         this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
464         this->TextActors[i]->SetPosition(barWidth+3,
465                                          val - sizeTextData[1]/2);
466         }
467         
468       }
469     else
470       {
471       this->TitleActor->SetPosition(size[0]/2, 
472                                     barHeight + labelSize[1] + 0.1*size[1]);
473       for (i=0; i < this->NumberOfLabels; i++)
474         {
475         this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
476         val = (double)i/(this->NumberOfLabels-1) * barWidth;
477         this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
478         }
479         
480       }
481       
482     // Compute the position of the distribution curve
483     this->PlaceDistribution(viewport, barWidth, barHeight); // RKV
484
485     this->BuildTime.Modified();
486     }
487
488   // Everything is built, just have to render
489   if (this->Title != NULL)
490     {
491     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
492     }
493   this->ScalarBarActor->RenderOpaqueGeometry(viewport);
494   // RKV : Begin
495   if (this->DistributionVisibility)
496     this->DistributionActor->RenderOpaqueGeometry(viewport);
497   // RKV : End
498   for (i=0; i<this->NumberOfLabels; i++)
499     {
500     renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
501     }
502
503   renderedSomething = (renderedSomething > 0)?(1):(0);
504
505   return renderedSomething;
506 }
507
508 void VISU_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
509 {
510   this->Superclass::PrintSelf(os,indent);
511
512   if ( this->LookupTable )
513     {
514     os << indent << "Lookup Table:\n";
515     this->LookupTable->PrintSelf(os,indent.GetNextIndent());
516     }
517   else
518     {
519     os << indent << "Lookup Table: (none)\n";
520     }
521
522   if (this->TitleTextProperty)
523     {
524     os << indent << "Title Text Property:\n";
525     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
526     }
527   else
528     {
529     os << indent << "Title Text Property: (none)\n";
530     }
531
532   if (this->LabelTextProperty)
533     {
534     os << indent << "Label Text Property:\n";
535     this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
536     }
537   else
538     {
539     os << indent << "Label Text Property: (none)\n";
540     }
541
542   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
543   os << indent << "Maximum Number Of Colors: " 
544      << this->MaximumNumberOfColors << "\n";
545   os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
546   os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
547
548   os << indent << "Orientation: ";
549   if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
550     {
551     os << "Horizontal\n";
552     }
553   else
554     {
555     os << "Vertical\n";
556     }
557
558   os << indent << "Label Format: " << this->LabelFormat << "\n";
559 }
560
561 void VISU_ScalarBarActor::ShallowCopy(vtkProp *prop)
562 {
563   VISU_ScalarBarActor *a = VISU_ScalarBarActor::SafeDownCast(prop);
564   if ( a != NULL )
565     {
566     this->SetPosition2(a->GetPosition2());
567     this->SetLookupTable(a->GetLookupTable());
568     this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
569     this->SetOrientation(a->GetOrientation());
570     this->SetLabelTextProperty(a->GetLabelTextProperty());
571     this->SetTitleTextProperty(a->GetTitleTextProperty());
572     this->SetLabelFormat(a->GetLabelFormat());
573     this->SetTitle(a->GetTitle());
574     this->GetPositionCoordinate()->SetCoordinateSystem(
575       a->GetPositionCoordinate()->GetCoordinateSystem());    
576     this->GetPositionCoordinate()->SetValue(
577       a->GetPositionCoordinate()->GetValue());
578     this->GetPosition2Coordinate()->SetCoordinateSystem(
579       a->GetPosition2Coordinate()->GetCoordinateSystem());    
580     this->GetPosition2Coordinate()->SetValue(
581       a->GetPosition2Coordinate()->GetValue());
582     }
583
584   // Now do superclass
585   this->vtkActor2D::ShallowCopy(prop);
586 }
587
588 void VISU_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, int *size,
589                                               vtkViewport *viewport,
590                                               double *range)
591 {
592   labelSize[0] = labelSize[1] = 0;
593
594   this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
595   this->TextActors = new vtkActor2D * [this->NumberOfLabels];
596
597   char string[512];
598
599   double val;
600   int i;
601   
602   // TODO: this should be optimized, maybe by keeping a list of
603   // allocated mappers, in order to avoid creation/destruction of
604   // their underlying text properties (i.e. each time a mapper is
605   // created, text properties are created and shallow-assigned a font size
606   // which value might be "far" from the target font size).
607
608   VISU_LookupTable *lut = this->LookupTable; //SALOME specific
609   int isLogTable = lut->GetScale() == VTK_SCALE_LOG10;
610
611   for (i=0; i < this->NumberOfLabels; i++)
612     {
613     this->TextMappers[i] = vtkTextMapper::New();
614
615     if(isLogTable && 0 < i && i < this->NumberOfLabels - 1){ // SALOME specific
616       double lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
617         (log10(range[1])-log10(range[0]));
618       val = pow((double)10,(double)lval);
619     }else{
620       val = range[0] + (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
621     }
622     sprintf(string, this->LabelFormat, val);
623     this->TextMappers[i]->SetInput(string);
624
625     // Shallow copy here so that the size of the label prop is not affected
626     // by the automatic adjustment of its text mapper's size (i.e. its
627     // mapper's text property is identical except for the font size
628     // which will be modified later). This allows text actors to
629     // share the same text property, and in that case specifically allows
630     // the title and label text prop to be the same.
631     this->TextMappers[i]->GetTextProperty()->ShallowCopy(
632       this->LabelTextProperty);
633
634     this->TextActors[i] = vtkActor2D::New();
635     this->TextActors[i]->SetMapper(this->TextMappers[i]);
636     this->TextActors[i]->SetProperty(this->GetProperty());
637     this->TextActors[i]->GetPositionCoordinate()->
638       SetReferenceCoordinate(this->PositionCoordinate);
639     }
640
641   if (this->NumberOfLabels)
642     {
643     int targetWidth, targetHeight;
644
645     if(LabelRatioWidth == 0)
646       if ( this->Orientation == VTK_ORIENT_VERTICAL )
647           targetWidth = (int)(0.6*size[0]);
648         else
649           targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
650     else
651       targetWidth = (int)(0.01*LabelRatioWidth*size[0]);
652
653     if ( this->Orientation == VTK_ORIENT_VERTICAL )
654       targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
655     else
656       targetHeight = (int)(0.25*size[1]);
657
658     vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
659                                                   targetWidth, 
660                                                   targetHeight,
661                                                   this->TextMappers,
662                                                   this->NumberOfLabels,
663                                                   labelSize);
664     }
665 }
666
667 void VISU_ScalarBarActor::SizeTitle(int *titleSize, int *size, 
668                                   vtkViewport *viewport)
669 {
670   titleSize[0] = titleSize[1] = 0;
671
672   if (this->Title == NULL || !strlen(this->Title))
673     {
674     return;
675     }
676
677   int targetWidth, targetHeight;
678   
679   if(TitleRatioSize == 0)
680     targetWidth = size[0];
681   else
682     targetWidth = (int)(0.01*TitleRatioSize*size[0]);
683
684   if ( this->Orientation == VTK_ORIENT_VERTICAL )
685     targetHeight = (int)(0.1*size[1]);
686   else
687     targetHeight = (int)(0.25*size[1]);
688
689   this->TitleMapper->SetConstrainedFontSize(
690     viewport, targetWidth, targetHeight);
691
692   this->TitleMapper->GetSize(viewport, titleSize);
693 }
694
695 // RKV : Begin
696 void VISU_ScalarBarActor::SetDistributionVisibility(int v) 
697 {
698   this->DistributionVisibility = v;
699   if (v) {
700         this->DistributionActor->VisibilityOn();
701   } else {
702         this->DistributionActor->VisibilityOff();
703   }
704 }
705
706 void VISU_ScalarBarActor::SetDistribution(vtkDoubleArray *distr) 
707 {
708   this->Distribution = distr;
709   if (distr == NULL) return;
710   
711   this->DistributionObj->Initialize();
712   this->DistributionObj->GetFieldData()->AddArray(this->Distribution);
713   this->DistributionActor->AddDataObjectInput(this->DistributionObj);
714   // Set ranges of axes for the distribution curve
715   this->DistributionActor->SetXRange(0, this->Distribution->GetNumberOfTuples()-1);
716   double range[2];
717   this->Distribution->GetRange(range);
718   int aNbVals = this->Distribution->GetNumberOfTuples();
719 //  int total = 0;
720   if (this->GetDebug()) {
721   for(vtkIdType aValId = 0; aValId < aNbVals; aValId++){
722 //      if (this->GetDebug()) {
723                 if (this->Distribution->GetValue(aValId) > 0)
724               vtkDebugMacro(<< "D(" << aValId << ") = " << this->Distribution->GetValue(aValId));
725 //      }
726 //      total += this->Distribution->GetValue(aValId);
727   }
728   }
729 //  this->DistributionActor->SetYRange(0, total);
730   this->DistributionActor->SetYRange(0, range[1]);
731   vtkDebugMacro(<< "max X = " << this->Distribution->GetNumberOfTuples());
732   vtkDebugMacro(<< "Y = (" << range[0] << ", " << range[1] << ")");
733 //  vtkDebugMacro(<< "total = " << total);
734 }
735
736 void VISU_ScalarBarActor::DebugOn() {
737         this->DistributionActor->DebugOn();
738         Superclass::DebugOn();
739
740
741 void VISU_ScalarBarActor::DebugOff() {
742         this->DistributionActor->DebugOff();
743         Superclass::DebugOff();
744
745 // RKV : End
746
747 void VISU_ScalarBarActor::SetRatios(int titleRatioSize, int labelRatioWidth, 
748                                     int barRatioWidth, int barRatioHeight)
749 {
750   TitleRatioSize=titleRatioSize;
751   if(TitleRatioSize>100)
752     TitleRatioSize=100;
753   else if(TitleRatioSize<0)
754     TitleRatioSize=0;
755
756   LabelRatioWidth=labelRatioWidth;
757   if(LabelRatioWidth>100)
758     LabelRatioWidth=100;
759   else if(LabelRatioWidth<0)
760     LabelRatioWidth=0;
761
762   BarRatioWidth=barRatioWidth;
763   if(BarRatioWidth>100)
764     BarRatioWidth=100;
765   else if(BarRatioWidth<0)
766     BarRatioWidth=0;
767
768   BarRatioHeight=barRatioHeight;
769   if(BarRatioHeight>100)
770     BarRatioHeight=100;
771   else if(BarRatioHeight<0)
772     BarRatioHeight=0;
773 }
774
775 void VISU_ScalarBarActor::GetRatios(int& titleRatioSize, int& labelRatioWidth, 
776                                     int& barRatioWidth, int& barRatioHeight)
777 {
778   titleRatioSize=TitleRatioSize;
779   labelRatioWidth=LabelRatioWidth;
780   barRatioWidth=BarRatioWidth;
781   barRatioHeight=BarRatioHeight;
782 }
783
784 void VISU_ScalarBarActor::SizeBar(int& barSizeWidth, int& barSizeHeight, int *size,
785                                   vtkViewport *viewport, double *range)
786 {
787   if(BarRatioWidth == 0)
788     if ( this->Orientation == VTK_ORIENT_VERTICAL )
789       {
790         int labelSize[2];
791         this->AllocateAndSizeLabels(labelSize, size, viewport,range);
792         barSizeWidth = size[0] - 4 - labelSize[0];
793       } else
794         barSizeWidth = size[0];
795   else
796     barSizeWidth = (int)(0.01*BarRatioWidth*size[0]);
797
798   if(BarRatioHeight == 0)
799     if ( this->Orientation == VTK_ORIENT_VERTICAL )
800       barSizeHeight = (int)(0.86*size[1]);
801     else
802       barSizeHeight = (int)(0.4*size[1]);
803   else
804     barSizeHeight = (int)(0.01*BarRatioHeight*size[1]);
805 }
806 // RKV : Begin
807 //------------------------------------------------------------------------------
808 /** Place the distribution plot actor in the viewport according to the 
809  * scalar bar location and orientation */
810 void VISU_ScalarBarActor::PlaceDistribution(vtkViewport *viewport, const int barWidth, const int barHeight) {
811     vtkDebugMacro(<< "barOrigin[0]=" << this->LastOrigin[0] << "; barOrigin[1]=" << this->LastOrigin[1]);
812     // Detect the side of the viewport where the curve should be placed by the bar origin.
813     double u = (double)(this->LastOrigin[0]), v = (double)(this->LastOrigin[1]), z=0;
814     viewport->ViewportToNormalizedViewport(u, v);
815     
816     if ( this->Orientation == VTK_ORIENT_VERTICAL ) {
817       // Position the distribution curve vertically
818       if (u > 0.5) {
819         // X - UP, Y - TO THE LEFT
820         this->DistributionActor->SetPlotLocation(VISU_XYPLOT_RIGHT);
821         // Curve to be placed on the left side of the bar
822         vtkDebugMacro(<< "Curve to be placed on the left side of the bar");
823         // relative to the bar origin
824         u = 0;
825         v = 0;
826         viewport->ViewportToNormalizedViewport(u, v);
827         vtkDebugMacro(<< "u=" << u << "; v=" << v);
828         this->DistributionActor->GetPositionCoordinate()->SetValue(u, v, 0);
829         // relative to Position
830         u = - barWidth;
831         v = barHeight;
832         viewport->ViewportToNormalizedViewport(u, v);
833         vtkDebugMacro("u2=" << u << "; v2=" << v);
834         this->DistributionActor->GetPosition2Coordinate()->SetValue(u, v, 0);
835       } else {
836         // X - UP, Y - TO THE RIGHT
837         this->DistributionActor->SetPlotLocation(VISU_XYPLOT_LEFT);
838         // Curve to be placed on the right side of the bar
839         vtkDebugMacro(<< "Curve to be placed on the right side of the bar");
840         // relative to the bar origin
841         u = barWidth;
842         v = 0;
843         viewport->ViewportToNormalizedViewport(u, v);
844         vtkDebugMacro(<< "u=" << u << "; v=" << v);
845         this->DistributionActor->GetPositionCoordinate()->SetValue(u, v, 0);
846         // relative to Position
847         u = barWidth;
848         v = barHeight;
849         viewport->ViewportToNormalizedViewport(u, v);
850         vtkDebugMacro("u2=" << u << "; v2=" << v);
851         this->DistributionActor->GetPosition2Coordinate()->SetValue(u, v, 0);
852       }
853     } else {
854       // Position the distribution curve horizontally
855       if (v > 0.5) {
856         // X - TO THE LEFT, Y - DOWN
857         this->DistributionActor->SetPlotLocation(VISU_XYPLOT_TOP);
858         // Curve to be placed below the bar
859         vtkDebugMacro(<< "Curve to be placed below the bar");
860         // relative to the bar origin
861         u = 0;
862         v = 0;
863         viewport->ViewportToNormalizedViewport(u, v);
864         vtkDebugMacro(<< "u=" << u << "; v=" << v);
865         this->DistributionActor->GetPositionCoordinate()->SetValue(u, v, 0);
866         // relative to Position
867         u = barWidth;
868         v = - barHeight;
869         viewport->ViewportToNormalizedViewport(u, v);
870         vtkDebugMacro("u2=" << u << "; v2=" << v);
871         this->DistributionActor->GetPosition2Coordinate()->SetValue(u, v, 0);
872       } else {
873         // X - TO THE RIGHT, Y - UP
874         this->DistributionActor->SetPlotLocation(VISU_XYPLOT_BOTTOM);
875         // Curve to be placed on the top of the bar
876         vtkDebugMacro(<< "Curve to be placed on the top of the bar");
877         // relative to the bar origin
878         u = 0;
879         v = barHeight;
880         viewport->ViewportToNormalizedViewport(u, v);
881         vtkDebugMacro(<< "u=" << u << "; v=" << v);
882         this->DistributionActor->GetPositionCoordinate()->SetValue(u, v, 0);
883         // relative to Position
884         u = barWidth;
885         v = barHeight;
886         viewport->ViewportToNormalizedViewport(u, v);
887         vtkDebugMacro("u2=" << u << "; v2=" << v);
888         this->DistributionActor->GetPosition2Coordinate()->SetValue(u, v, 0);
889       }
890     }
891 }
892 // RKV : End
893