vtkScalarBarActor.cxx 31.6 KB
Newer Older
1
2
3
4
5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkScalarBarActor.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7
8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Will Schroeder's avatar
Will Schroeder committed
9

10
11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
13
14
15

=========================================================================*/
#include "vtkScalarBarActor.h"
16

17
18
#include "vtkCellArray.h"
#include "vtkCellData.h"
19
#include "vtkObjectFactory.h"
20
#include "vtkPolyData.h"
21
22
23
#include "vtkPolyDataMapper2D.h"
#include "vtkScalarsToColors.h"
#include "vtkTextMapper.h"
Sebastien Barre's avatar
Sebastien Barre committed
24
#include "vtkTextProperty.h"
25
26
#include "vtkViewport.h"
#include "vtkWindow.h"
27
#include "vtkLookupTable.h"
28
29
30
31
32
33
34
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkTexture.h"
#include "vtkImageData.h"
#include "vtkRenderer.h"
#include "vtkProperty2D.h"

Brad King's avatar
Brad King committed
35
vtkStandardNewMacro(vtkScalarBarActor);
36

37
vtkCxxSetObjectMacro(vtkScalarBarActor,LookupTable,vtkScalarsToColors);
Sebastien Barre's avatar
Sebastien Barre committed
38
39
vtkCxxSetObjectMacro(vtkScalarBarActor,LabelTextProperty,vtkTextProperty);
vtkCxxSetObjectMacro(vtkScalarBarActor,TitleTextProperty,vtkTextProperty);
40
41
vtkCxxSetObjectMacro(vtkScalarBarActor,BackgroundProperty,vtkProperty2D);
vtkCxxSetObjectMacro(vtkScalarBarActor,FrameProperty,vtkProperty2D);
42

Sebastien Barre's avatar
Sebastien Barre committed
43
44
//----------------------------------------------------------------------------
// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
45
46
47
48
49
// format, no title, and vertical orientation. The initial scalar bar
// size is (0.05 x 0.8) of the viewport size.
vtkScalarBarActor::vtkScalarBarActor()
{
  this->LookupTable = NULL;
50
51
52
53
54
  this->Position2Coordinate->SetValue(0.17, 0.8);
  
  this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
  this->PositionCoordinate->SetValue(0.82,0.1);
  
55
56
  this->MaximumNumberOfColors = 64;
  this->NumberOfLabels = 5;
57
  this->NumberOfLabelsBuilt = 0;
58
59
  this->Orientation = VTK_ORIENT_VERTICAL;
  this->Title = NULL;
60
  this->ComponentTitle = NULL;
61

Sebastien Barre's avatar
Sebastien Barre committed
62
63
64
65
66
67
68
69
70
71
  this->LabelTextProperty = vtkTextProperty::New();
  this->LabelTextProperty->SetFontSize(12);
  this->LabelTextProperty->SetBold(1);
  this->LabelTextProperty->SetItalic(1);
  this->LabelTextProperty->SetShadow(1);
  this->LabelTextProperty->SetFontFamilyToArial();

  this->TitleTextProperty = vtkTextProperty::New();
  this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);

72
73
74
75
76
77
  this->LabelFormat = new char[8]; 
  sprintf(this->LabelFormat,"%s","%-#6.3g");

  this->TitleMapper = vtkTextMapper::New();
  this->TitleActor = vtkActor2D::New();
  this->TitleActor->SetMapper(this->TitleMapper);
78
79
80
  this->TitleActor->GetPositionCoordinate()->
    SetReferenceCoordinate(this->PositionCoordinate);
  
81
82
83
84
85
  this->TextMappers = NULL;
  this->TextActors = NULL;

  this->ScalarBar = vtkPolyData::New();
  this->ScalarBarMapper = vtkPolyDataMapper2D::New();
86
  this->ScalarBarMapper->SetInputData(this->ScalarBar);
87
88
  this->ScalarBarActor = vtkActor2D::New();
  this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
89
90
  this->ScalarBarActor->GetPositionCoordinate()->
    SetReferenceCoordinate(this->PositionCoordinate);
Ken Martin's avatar
Ken Martin committed
91
92
93
94
  this->LastOrigin[0] = 0;
  this->LastOrigin[1] = 0;
  this->LastSize[0] = 0;
  this->LastSize[1] = 0;
95
96
97
98
99
100
101
102
  
  // If opacity is on, a jail like texture is displayed behind it..

  this->UseOpacity       = 0;
  this->TextureGridWidth = 10.0;
  
  this->TexturePolyData = vtkPolyData::New();
  vtkPolyDataMapper2D * textureMapper = vtkPolyDataMapper2D::New();
103
  textureMapper->SetInputData(this->TexturePolyData);
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  this->TextureActor = vtkActor2D::New();
  this->TextureActor->SetMapper(textureMapper);
  textureMapper->Delete();
  this->TextureActor->GetPositionCoordinate()->
    SetReferenceCoordinate(this->PositionCoordinate);
  vtkFloatArray* tc = vtkFloatArray::New();
  tc->SetNumberOfComponents(2);
  tc->SetNumberOfTuples(4);
  tc->InsertComponent(0,0, 0.0);  
  tc->InsertComponent(0,1, 0.0);
  tc->InsertComponent(1,1, 0.0);
  tc->InsertComponent(3,0, 0.0);  
  this->TexturePolyData->GetPointData()->SetTCoords(tc);
  tc->Delete();

  vtkCellArray* polys2 = vtkCellArray::New();
  polys2->InsertNextCell(4);
  polys2->InsertCellPoint(0);
  polys2->InsertCellPoint(1);
  polys2->InsertCellPoint(2);
  polys2->InsertCellPoint(3);
  this->TexturePolyData->SetPolys(polys2);
  polys2->Delete();

  vtkProperty2D *imageProperty = vtkProperty2D::New();
  imageProperty->SetOpacity(0.08);
  this->TextureActor->SetProperty(imageProperty);
  imageProperty->Delete();

  // Create the default texture. Just a "Jail" like grid

  const unsigned int dim = 128;
  vtkImageData *image = vtkImageData::New();
  image->SetDimensions(dim, dim, 1);
Berk Geveci's avatar
Berk Geveci committed
138
  image->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
139
140
141
142
143
144
145
146
147
148
149
150
151
  
  for (unsigned int y = 0; y < dim; y++)
    {
    unsigned char *ptr = 
      static_cast< unsigned char * >(image->GetScalarPointer(0, y, 0));
    for (unsigned int x = 0; x < dim; x++)
      {
      *ptr = ((x == y) || (x == (dim-y-1))) ? 255 : 0;
      ++ptr;
      }
    }

  this->Texture = vtkTexture::New();
152
  this->Texture->SetInputData( image );
153
154
  this->Texture->RepeatOn();
  image->Delete();
155
156
157
158

  // Default text position : Above scalar bar if orientation is horizontal
  //                         Right of scalar bar if orientation is vertical
  this->TextPosition = SucceedScalarBar;
159
160
161

  this->MaximumWidthInPixels = VTK_INT_MAX;
  this->MaximumHeightInPixels = VTK_INT_MAX;
162
163
164
165
166
167
168

  this->BackgroundProperty = vtkProperty2D::New();
  this->FrameProperty = vtkProperty2D::New();

  this->DrawBackground = 0;
  this->Background = vtkPolyData::New();
  this->BackgroundMapper = vtkPolyDataMapper2D::New();
169
  this->BackgroundMapper->SetInputData(this->Background);
170
171
172
173
174
175
176
  this->BackgroundActor = vtkActor2D::New();
  this->BackgroundActor->SetMapper(this->BackgroundMapper);
  this->BackgroundActor->GetPositionCoordinate()->SetReferenceCoordinate(this->PositionCoordinate);

  this->DrawFrame = 0;
  this->Frame = vtkPolyData::New();
  this->FrameMapper = vtkPolyDataMapper2D::New();
177
  this->FrameMapper->SetInputData(this->Frame);
178
179
180
  this->FrameActor = vtkActor2D::New();
  this->FrameActor->SetMapper(this->FrameMapper);
  this->FrameActor->GetPositionCoordinate()->SetReferenceCoordinate(this->PositionCoordinate);
181

182
  this->EnhancedMode = 0;
183
184
}

Sebastien Barre's avatar
Sebastien Barre committed
185
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Release any graphics resources that are being consumed by this actor.
// The parameter window could be used to determine which graphic
// resources to release.
void vtkScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
{
  this->TitleActor->ReleaseGraphicsResources(win);
  if (this->TextMappers != NULL )
    {
    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
      {
      this->TextActors[i]->ReleaseGraphicsResources(win);
      }
    }
  this->ScalarBarActor->ReleaseGraphicsResources(win);
200
201
  this->BackgroundActor->ReleaseGraphicsResources(win);
  this->FrameActor->ReleaseGraphicsResources(win);
Ken Martin's avatar
Ken Martin committed
202
203
}

Sebastien Barre's avatar
Sebastien Barre committed
204
//----------------------------------------------------------------------------
205
206
vtkScalarBarActor::~vtkScalarBarActor()
{
Ken Martin's avatar
Ken Martin committed
207
208
209
210
211
  if (this->LabelFormat) 
    {
    delete [] this->LabelFormat;
    this->LabelFormat = NULL;
    }
212
213
214
215
216
217

  this->TitleMapper->Delete();
  this->TitleActor->Delete();

  if (this->TextMappers != NULL )
    {
218
    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
219
220
221
222
223
224
225
226
227
228
229
      {
      this->TextMappers[i]->Delete();
      this->TextActors[i]->Delete();
      }
    delete [] this->TextMappers;
    delete [] this->TextActors;
    }

  this->ScalarBar->Delete();
  this->ScalarBarMapper->Delete();
  this->ScalarBarActor->Delete();
Ken Martin's avatar
Ken Martin committed
230
231
232
233
234
235

  if (this->Title)
    {
    delete [] this->Title;
    this->Title = NULL;
    }
236
237
238
239
240
241

  if ( this->ComponentTitle )
    {
    delete [] this->ComponentTitle;
    this->ComponentTitle = NULL;
    }
242
243
  
  this->SetLookupTable(NULL);
Sebastien Barre's avatar
Sebastien Barre committed
244
245
  this->SetLabelTextProperty(NULL);
  this->SetTitleTextProperty(NULL);
246
247
248
  this->Texture->Delete();
  this->TextureActor->Delete();
  this->TexturePolyData->Delete();
249
250
251
252
253
254
255
256
  this->Background->Delete();
  this->BackgroundMapper->Delete();
  this->BackgroundActor->Delete();
  this->Frame->Delete();
  this->FrameMapper->Delete();
  this->FrameActor->Delete();
  this->SetBackgroundProperty(NULL);
  this->SetFrameProperty(NULL);
257
258
}

Sebastien Barre's avatar
Sebastien Barre committed
259
//----------------------------------------------------------------------------
260
int vtkScalarBarActor::RenderOverlay(vtkViewport *viewport)
Ken Martin's avatar
Ken Martin committed
261
{
262
  int renderedSomething = 0;
Ken Martin's avatar
Ken Martin committed
263
264
  int i;
  
265
266
267
268
269
270
271
272
273
274
  if (this->DrawBackground)
    {
    renderedSomething += this->BackgroundActor->RenderOverlay(viewport);
    }
  
  if (this->DrawFrame)
    {
    renderedSomething += this->FrameActor->RenderOverlay(viewport);
    }
  
275
276
277
278
279
280
  if (this->UseOpacity)
    {
    this->Texture->Render(vtkRenderer::SafeDownCast(viewport));
    renderedSomething += this->TextureActor->RenderOverlay(viewport);
    }

Ken Martin's avatar
Ken Martin committed
281
282
283
  // Everything is built, just have to render
  if (this->Title != NULL)
    {
284
    renderedSomething += this->TitleActor->RenderOverlay(viewport);
Ken Martin's avatar
Ken Martin committed
285
286
    }
  this->ScalarBarActor->RenderOverlay(viewport);
287
288
289
290
291
292
  if( this->TextActors == NULL)
    {
     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
     return renderedSomething;
    }
  
Ken Martin's avatar
Ken Martin committed
293
294
  for (i=0; i<this->NumberOfLabels; i++)
    {
295
    renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
Ken Martin's avatar
Ken Martin committed
296
    }
297
298
299
300

  renderedSomething = (renderedSomething > 0)?(1):(0);

  return renderedSomething;
Ken Martin's avatar
Ken Martin committed
301
302
}

Sebastien Barre's avatar
Sebastien Barre committed
303
//----------------------------------------------------------------------------
304
int vtkScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
305
{
306
  int renderedSomething = 0;
307
  int i;
308
309
  int size[2];
  
Sebastien Barre's avatar
Sebastien Barre committed
310
  if (!this->LookupTable)
311
312
    {
    vtkWarningMacro(<<"Need a mapper to render a scalar bar");
313
    return 0;
314
315
    }

Sebastien Barre's avatar
Sebastien Barre committed
316
317
318
319
320
321
322
323
324
325
326
327
  if (!this->TitleTextProperty)
    {
    vtkErrorMacro(<<"Need title text property to render a scalar bar");
    return 0;
    }

  if (!this->LabelTextProperty)
    {
    vtkErrorMacro(<<"Need label text property to render a scalar bar");
    return 0;
    }

Ken Martin's avatar
Ken Martin committed
328
  // Check to see whether we have to rebuild everything
329
  int positionsHaveChanged = 0;
Sebastien Barre's avatar
Sebastien Barre committed
330
331
332
  if (viewport->GetMTime() > this->BuildTime || 
      (viewport->GetVTKWindow() && 
       viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
Ken Martin's avatar
Ken Martin committed
333
334
335
    {
    // if the viewport has changed we may - or may not need
    // to rebuild, it depends on if the projected coords chage
Bill Lorensen's avatar
Bill Lorensen committed
336
    int *barOrigin;
Ken Martin's avatar
Ken Martin committed
337
338
339
340
341
342
343
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
    size[0] = 
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
    size[1] = 
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
344
345
346
347
348
349
350

    // Check if we have bounds on the maximum size 
    size[0] = size[0] > this->MaximumWidthInPixels 
            ? this->MaximumWidthInPixels : size[0];
    size[1] = size[1] > this->MaximumHeightInPixels 
            ? this->MaximumHeightInPixels : size[1];

Sebastien Barre's avatar
Sebastien Barre committed
351
352
    if (this->LastSize[0] != size[0] || 
        this->LastSize[1] != size[1] ||
353
354
        this->LastOrigin[0] != barOrigin[0] || 
        this->LastOrigin[1] != barOrigin[1])
Ken Martin's avatar
Ken Martin committed
355
      {
356
      positionsHaveChanged = 1;
Ken Martin's avatar
Ken Martin committed
357
358
359
      }
    }
  
360
  // Check to see whether we have to rebuild everything
361
362
  if (positionsHaveChanged ||
      this->GetMTime() > this->BuildTime || 
Sebastien Barre's avatar
Sebastien Barre committed
363
364
      this->LookupTable->GetMTime() > this->BuildTime ||
      this->LabelTextProperty->GetMTime() > this->BuildTime ||
365
366
367
368
      this->TitleTextProperty->GetMTime() > this->BuildTime ||
      this->BackgroundProperty->GetMTime() > this->BuildTime ||
      this->FrameProperty->GetMTime() > this->BuildTime)

369
370
371
372
373
374
375
    {
    vtkDebugMacro(<<"Rebuilding subobjects");

    // Delete previously constructed objects
    //
    if (this->TextMappers != NULL )
      {
376
      for (i=0; i < this->NumberOfLabelsBuilt; i++)
377
378
379
380
        {
        this->TextMappers[i]->Delete();
        this->TextActors[i]->Delete();
        }
381
382
383
384
      delete [] this->TextMappers;
      delete [] this->TextActors;
      }

385
    // Build scalar bar object; determine its type
386
387
    // i.e. has scale set to log
    int isLogTable = this->LookupTable->UsingLogScale();
388
    
Ken Martin's avatar
Ken Martin committed
389
    // we hard code how many steps to display
390
    vtkScalarsToColors *lut = this->LookupTable;
Ken Martin's avatar
Ken Martin committed
391
    int numColors = this->MaximumNumberOfColors;
Ken Martin's avatar
Ken Martin committed
392
    double *range = lut->GetRange();
393
394
395
396
397
398

    int numPts = 2*(numColors + 1);
    vtkPoints *pts = vtkPoints::New();
    pts->SetNumberOfPoints(numPts);
    vtkCellArray *polys = vtkCellArray::New();
    polys->Allocate(polys->EstimateSize(numColors,4));
399
    vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
400
401
402

    unsigned int nComponents = ((this->UseOpacity) ? 4 : 3);
    colors->SetNumberOfComponents( nComponents );
403
    colors->SetNumberOfTuples(numColors);
404
405
406
407
408
409
410
411

    this->ScalarBarActor->SetProperty(this->GetProperty());
    this->ScalarBar->Initialize();
    this->ScalarBar->SetPoints(pts);
    this->ScalarBar->SetPolys(polys);
    this->ScalarBar->GetCellData()->SetScalars(colors);
    pts->Delete(); polys->Delete(); colors->Delete();

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
    // set frame structure
    vtkPoints *frPts = vtkPoints::New();
    frPts->SetNumberOfPoints(5);
    vtkCellArray *frLines = vtkCellArray::New();
    frLines->Allocate(frLines->EstimateSize(1,5));

    this->FrameActor->SetProperty(this->FrameProperty);
    this->Frame->Initialize();
    this->Frame->SetPoints(frPts);
    this->Frame->SetLines(frLines);
    frPts->Delete(); frLines->Delete();

    // set background structure
    vtkPoints *bgPts = vtkPoints::New();
    bgPts->SetNumberOfPoints(4);
    vtkCellArray *bgPolys = vtkCellArray::New();
    bgPolys->Allocate(bgPolys->EstimateSize(1,4));

    this->BackgroundActor->SetProperty(this->BackgroundProperty);
    this->Background->Initialize();
    this->Background->SetPoints(bgPts);
    this->Background->SetPolys(bgPolys);
    bgPts->Delete(); bgPolys->Delete();

436
    // get the viewport size in display coordinates
437
438
439
440
441
442
443
444
    int *barOrigin, barWidth, barHeight;
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
    size[0] = 
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
    size[1] = 
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
445
446
447
448
449
450
451

    // Check if we have bounds on the maximum size 
    size[0] = size[0] > this->MaximumWidthInPixels 
            ? this->MaximumWidthInPixels : size[0];
    size[1] = size[1] > this->MaximumHeightInPixels 
            ? this->MaximumHeightInPixels : size[1];
    
Ken Martin's avatar
Ken Martin committed
452
453
454
455
456
    this->LastOrigin[0] = barOrigin[0];
    this->LastOrigin[1] = barOrigin[1];
    this->LastSize[0] = size[0];
    this->LastSize[1] = size[1];
    
457
458
    // Update all the composing objects
    this->TitleActor->SetProperty(this->GetProperty());
459
460
461
462
463
    
    
    //update with the proper title
    if ( this->ComponentTitle && strlen(this->ComponentTitle) > 0 )
      {
464
465
      //need to account for a space between title & component and null term      
      char *combinedTitle = new char[ ( strlen(this->Title) + strlen(this->ComponentTitle) + 2) ];
466
467
468
469
470
471
472
473
474
475
476
      strcpy(combinedTitle, this->Title );
      strcat( combinedTitle, " " );
      strcat( combinedTitle, this->ComponentTitle );
      this->TitleMapper->SetInput(combinedTitle);
      delete [] combinedTitle;
      }
    else
      {
      this->TitleMapper->SetInput(this->Title);
      }

Sebastien Barre's avatar
Sebastien Barre committed
477
478
479
480
481
482
483
484
485
486
487
    if (this->TitleTextProperty->GetMTime() > this->BuildTime)
      {
      // Shallow copy here so that the size of the title prop is not affected
      // by the automatic adjustment of its text mapper's size (i.e. its
      // mapper's text property is identical except for the font size
      // which will be modified later). This allows text actors to
      // share the same text property, and in that case specifically allows
      // the title and label text prop to be the same.
      this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
      this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
      }
488
    
Ken Martin's avatar
Ken Martin committed
489
490
491
    // find the best size for the title font
    int titleSize[2];
    this->SizeTitle(titleSize, size, viewport);
492
    
Ken Martin's avatar
Ken Martin committed
493
494
495
    // find the best size for the ticks
    int labelSize[2];
    this->AllocateAndSizeLabels(labelSize, size, viewport,range);
496
    this->NumberOfLabelsBuilt = this->NumberOfLabels;
Ken Martin's avatar
Ken Martin committed
497
    
498
    // generate points
Ken Martin's avatar
Ken Martin committed
499
500
    double x[3]; x[2] = 0.0;
    double delta;
Philippe Pébay's avatar
Philippe Pébay committed
501
502
    int barX = 0;
    int barY = 0;
503
504
    if ( this->Orientation == VTK_ORIENT_VERTICAL )
      {
505
506
507
508
509
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
           this->DrawFrame ||
           this->EnhancedMode )
510
511
512
513
        {
        barX = static_cast<int>(size[0] * 0.05);
        barY = static_cast<int>(size[1] * 0.05 + labelSize[1] / 2);
        }
514
515
516

      barWidth = size[0] - 4 - labelSize[0] - 2 * barX;
      barHeight = static_cast<int>(0.86*size[1]) - barY;
517
      delta=static_cast<double>(barHeight)/numColors;
518
      for (i=0; i<numPts/2; i++)
519
        {
520
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
521
522
          ? (size[0] - barWidth - barX) : barX;
        x[1] = barY + i*delta;
523
        pts->SetPoint(2*i,x);
524
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
525
          ? size[0] - barX: barX + barWidth;
526
        pts->SetPoint(2*i+1,x);
527
        }
528
529
530
      }
    else
      {
531
532
533
534
535
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
           this->DrawFrame ||
           this->EnhancedMode )
536
        {
537
538
        barX = static_cast<int>(size[0] * 0.05) + labelSize[0] / 2;
        barY = static_cast<int>(size[1] * 0.05);
539
        }
540
541
      barWidth = size[0] - 2 * barX;
      barHeight = static_cast<int>(0.4*size[1]) - barY;
542
      delta=static_cast<double>(barWidth)/numColors;
543
      for (i=0; i<numPts/2; i++)
544
        {
545
        x[0] = barX + i*delta;
546
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
547
          ? size[1] - barY: barY + barHeight ;
548
        pts->SetPoint(2*i,x);
549
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
550
          ? (size[1]-barHeight - barY) : barY;
551
        pts->SetPoint(2*i+1,x);
552
        }
553
      }
554
    
555
556
    //polygons & cell colors
    unsigned char *rgba, *rgb;
557
    vtkIdType ptIds[4];
558
559
560
561
562
563
564
565
    for (i=0; i<numColors; i++)
      {
      ptIds[0] = 2*i;
      ptIds[1] = ptIds[0] + 1;
      ptIds[2] = ptIds[1] + 2;
      ptIds[3] = ptIds[0] + 2;
      polys->InsertNextCell(4,ptIds);

566
567
      if ( isLogTable )
        {
Ken Martin's avatar
Ken Martin committed
568
        double rgbval = log10(range[0]) + 
569
          i*(log10(range[1])-log10(range[0]))/(numColors -1);
Ken Martin's avatar
Ken Martin committed
570
        rgba = lut->MapValue(pow(10.0,rgbval));
571
572
573
574
        }
      else
        {
        rgba = lut->MapValue(range[0] + (range[1] - range[0])*
575
                             (i /(numColors-1.0)));
576
577
        }

578
      rgb = colors->GetPointer( nComponents * i); //write into array directly
579
580
581
      rgb[0] = rgba[0];
      rgb[1] = rgba[1];
      rgb[2] = rgba[2];
582
583
584
585
      if (this->UseOpacity)
        {
        rgb[3] = rgba[3];
        }
586
587
      }

588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    // generate background and frame points and cell
    x[0]=0; x[1]=0;
    bgPts->SetPoint(0,x);
    frPts->SetPoint(0,x);
    frPts->SetPoint(4,x);
    
    x[0]=0; x[1]=size[1];
    bgPts->SetPoint(1,x);
    frPts->SetPoint(1,x);
    
    x[0]=size[0]; x[1]=size[1];
    bgPts->SetPoint(2,x);
    frPts->SetPoint(2,x);
    
    x[0]=size[0]; x[1]=0;
    bgPts->SetPoint(3,x);
    frPts->SetPoint(3,x);

    vtkIdType bgIds[5] = {0,1,2,3,4};
    bgPolys->InsertNextCell(4,bgIds);
    frLines->InsertNextCell(5,bgIds);

610
611
    // Now position everything properly
    //
Ken Martin's avatar
Ken Martin committed
612
    double val;
613
    int sizeTextData[2];
614
615
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
616
      // center the title
Ken Martin's avatar
Ken Martin committed
617
      this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
618
      
Jim Miller's avatar
Style    
Jim Miller committed
619
      for (i=0; i < this->NumberOfLabels; i++)
620
        {
Ken Martin's avatar
Ken Martin committed
621
622
        if (this->NumberOfLabels > 1)
          {
623
          val = static_cast<double>(i)/(this->NumberOfLabels-1) *barHeight + barY;
Ken Martin's avatar
Ken Martin committed
624
625
626
          }
        else 
          {
627
          val = 0.5*(barHeight + barY);
Ken Martin's avatar
Ken Martin committed
628
          }
629
        this->TextMappers[i]->GetSize(viewport,sizeTextData);
Sebastien Barre's avatar
Sebastien Barre committed
630
        this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
631
632
        if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
          {
633
634
          this->TextActors[i]->SetPosition(barX, 
                                           val - 0.6*sizeTextData[1]);
635
636
637
          }
        else
          {
638
          this->TextActors[i]->SetPosition(barX + barWidth + 3,
639
                                           val - 0.6*sizeTextData[1]);
640
          }
641
        }
642
      }
643
    else // if (this->Orientation == VTK_ORIENT_VERTICAL)
644
      {
645
646
      if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
        {
647
648
        this->TitleActor->SetPosition(size[0]/2, 
                                      barY + 0.1*titleSize[1]);
649
650
651
652
        }
      else
        {
        this->TitleActor->SetPosition(size[0]/2, 
653
                                      barHeight + labelSize[1] + 0.1*size[1] + 0.15*titleSize[1]);
654
        }
Jim Miller's avatar
Style    
Jim Miller committed
655
      for (i=0; i < this->NumberOfLabels; i++)
656
        {
657
        this->TextMappers[i]->GetSize(viewport,sizeTextData);
Sebastien Barre's avatar
Sebastien Barre committed
658
        this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
Ken Martin's avatar
Ken Martin committed
659
660
        if (this->NumberOfLabels > 1)
          {
661
          val = static_cast<double>(i)/(this->NumberOfLabels-1) * barWidth + barX;
Ken Martin's avatar
Ken Martin committed
662
663
664
          }
        else
          {
665
          val = 0.5*(barWidth+barY);
Ken Martin's avatar
Ken Martin committed
666
          }
667
668
669
670
671
672
        if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
          {
          this->TextActors[i]->SetPosition(val, size[1] * 0.3);
          }
        else
          {
673
          this->TextActors[i]->SetPosition(val, barY + barHeight + 0.05*size[1]);
674
          }
675
        }
676
677
      }

678
679
680
681
682
683
    // Set the texture points
    //
    vtkPoints *texturePoints = vtkPoints::New();
    texturePoints->SetNumberOfPoints(4);
    this->TexturePolyData->SetPoints(texturePoints);
    texturePoints->SetPoint(0, 0.0, 0.0, 0.0);
684
685
686
687
688

    double p1[2], p2[2];
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
      p1[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
689
690
        ? (size[0] - barWidth - barX) : barX;
      p1[1] = barY;
691
      p2[0] = p1[0] + barWidth;
692
      p2[1] = p1[1] + barHeight;
693
694
695
      }
    else
      {
696
      p1[0] = barX;
697
      p1[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar) 
698
        ? (size[1] - barHeight - barY) : barY;
699
700
701
702
703
704
705
706
      p2[0] = p1[0] + barWidth;
      p2[1] = p1[1] + barHeight;
      }

    texturePoints->SetPoint(0, p1[0], p1[1], 0.0);
    texturePoints->SetPoint(1, p2[0], p1[1], 0.0);
    texturePoints->SetPoint(2, p2[0], p2[1], 0.0);
    texturePoints->SetPoint(3, p1[0], p2[1], 0.0);
707
708
709
710
711
    texturePoints->Delete();

    vtkDataArray * tc = this->TexturePolyData->GetPointData()->GetTCoords();
    tc->SetTuple2(1, barWidth / this->TextureGridWidth, 0.0);
    tc->SetTuple2(2, barWidth / this->TextureGridWidth, 
712
                  barHeight / this->TextureGridWidth);
713
714
    tc->SetTuple2(3, 0.0, barHeight / this->TextureGridWidth);

715
716
717
    this->BuildTime.Modified();
    }

718

719
  // Everything is built, just have to render
Jim Miller's avatar
Style    
Jim Miller committed
720
721
  if (this->Title != NULL)
    {
722
    renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
723
    }
Ken Martin's avatar
Ken Martin committed
724
  this->ScalarBarActor->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
725
726
  for (i=0; i<this->NumberOfLabels; i++)
    {
727
    renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
728
    }
729
730
731
732

  renderedSomething = (renderedSomething > 0)?(1):(0);

  return renderedSomething;
733
734
}

735
736
737
738
739
740
741
742
//-----------------------------------------------------------------------------
// Description:
// Does this prop have some translucent polygonal geometry?
int vtkScalarBarActor::HasTranslucentPolygonalGeometry()
{
  return 0;
}

Sebastien Barre's avatar
Sebastien Barre committed
743
//----------------------------------------------------------------------------
744
void vtkScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
745
{
Brad King's avatar
Brad King committed
746
  this->Superclass::PrintSelf(os,indent);
747
748
749
750
751
752
753
754
755
756
757

  if ( this->LookupTable )
    {
    os << indent << "Lookup Table:\n";
    this->LookupTable->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Lookup Table: (none)\n";
    }

Sebastien Barre's avatar
Sebastien Barre committed
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
  if (this->TitleTextProperty)
    {
    os << indent << "Title Text Property:\n";
    this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Title Text Property: (none)\n";
    }

  if (this->LabelTextProperty)
    {
    os << indent << "Label Text Property:\n";
    this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Label Text Property: (none)\n";
    }

778
  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
779
  os << indent << "ComponentTitle: " << (this->ComponentTitle ? this->ComponentTitle : "(none)") << "\n";
780
781
782
  os << indent << "Maximum Number Of Colors: " 
     << this->MaximumNumberOfColors << "\n";
  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
783
  os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
784
785

  os << indent << "Orientation: ";
Jim Miller's avatar
Style    
Jim Miller committed
786
787
788
789
790
791
792
793
  if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
    {
    os << "Horizontal\n";
    }
  else
    {
    os << "Vertical\n";
    }
794
795

  os << indent << "Label Format: " << this->LabelFormat << "\n";
796
797
798
799
  os << indent << "UseOpacity: " << this->UseOpacity << "\n";
  if (this->UseOpacity)
    {
    os << indent << "TextureGridWidth: " << this->TextureGridWidth << "\n";
Karthik Krishnan's avatar
Karthik Krishnan committed
800
801
    os << indent << "TextureActor:\n";
    this->TextureActor->PrintSelf(os, indent.GetNextIndent());
802
    }
803
804
805
806
807
808
809
810
  if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
    {
    os << indent << "TextPosition: PrecedeScalarBar\n";
    }
  else
    {
    os << indent << "TextPosition: SucceedScalarBar\n";
    }
Karthik Krishnan's avatar
Karthik Krishnan committed
811
812
813
814
815

  os << indent << "MaximumWidthInPixels: " 
     << this->MaximumWidthInPixels << endl;
  os << indent << "MaximumHeightInPixels: " 
     << this->MaximumHeightInPixels << endl;
816
817
818
819
820
821
822
823
824
825

  os << indent << "DrawBackground: " << this->DrawBackground << "\n";
  os << indent << "Background Property:\n";
  this->BackgroundProperty->PrintSelf(os,indent.GetNextIndent());
  os << indent << "DrawFrame: " << this->DrawFrame << "\n";
  os << indent << "Frame Property:\n";
  this->FrameProperty->PrintSelf(os,indent.GetNextIndent());

  os << indent << "Enhanced Mode:\n"
     << this->EnhancedMode << endl;
826
}
Ken Martin's avatar
Ken Martin committed
827

Sebastien Barre's avatar
Sebastien Barre committed
828
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
829
830
831
832
833
834
835
836
837
void vtkScalarBarActor::ShallowCopy(vtkProp *prop)
{
  vtkScalarBarActor *a = vtkScalarBarActor::SafeDownCast(prop);
  if ( a != NULL )
    {
    this->SetPosition2(a->GetPosition2());
    this->SetLookupTable(a->GetLookupTable());
    this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
    this->SetOrientation(a->GetOrientation());
Sebastien Barre's avatar
Sebastien Barre committed
838
839
    this->SetLabelTextProperty(a->GetLabelTextProperty());
    this->SetTitleTextProperty(a->GetTitleTextProperty());
Will Schroeder's avatar
Will Schroeder committed
840
841
842
843
844
845
846
847
848
849
    this->SetLabelFormat(a->GetLabelFormat());
    this->SetTitle(a->GetTitle());
    this->GetPositionCoordinate()->SetCoordinateSystem(
      a->GetPositionCoordinate()->GetCoordinateSystem());    
    this->GetPositionCoordinate()->SetValue(
      a->GetPositionCoordinate()->GetValue());
    this->GetPosition2Coordinate()->SetCoordinateSystem(
      a->GetPosition2Coordinate()->GetCoordinateSystem());    
    this->GetPosition2Coordinate()->SetValue(
      a->GetPosition2Coordinate()->GetValue());
850
851
852
853
854
    this->SetDrawBackground(a->GetDrawBackground());
    this->SetBackgroundProperty(a->GetBackgroundProperty());
    this->SetDrawFrame(a->GetDrawFrame());
    this->SetFrameProperty(a->GetFrameProperty());
    this->SetEnhancedMode(a->GetEnhancedMode());
Will Schroeder's avatar
Will Schroeder committed
855
856
857
858
859
    }

  // Now do superclass
  this->vtkActor2D::ShallowCopy(prop);
}
Ken Martin's avatar
Ken Martin committed
860

Sebastien Barre's avatar
Sebastien Barre committed
861
862
863
//----------------------------------------------------------------------------
void vtkScalarBarActor::AllocateAndSizeLabels(int *labelSize, 
                                              int *size,
Ken Martin's avatar
Ken Martin committed
864
                                              vtkViewport *viewport,
Ken Martin's avatar
Ken Martin committed
865
                                              double *range)
Ken Martin's avatar
Ken Martin committed
866
{
Sebastien Barre's avatar
Sebastien Barre committed
867
868
  labelSize[0] = labelSize[1] = 0;

Ken Martin's avatar
Ken Martin committed
869
870
  this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
  this->TextActors = new vtkActor2D * [this->NumberOfLabels];
Sebastien Barre's avatar
Sebastien Barre committed
871

Ken Martin's avatar
Ken Martin committed
872
  char string[512];
Sebastien Barre's avatar
Sebastien Barre committed
873

Ken Martin's avatar
Ken Martin committed
874
  double val;
Ken Martin's avatar
Ken Martin committed
875
876
  int i;
  
Sebastien Barre's avatar
Sebastien Barre committed
877
878
879
880
881
  // TODO: this should be optimized, maybe by keeping a list of
  // allocated mappers, in order to avoid creation/destruction of
  // their underlying text properties (i.e. each time a mapper is
  // created, text properties are created and shallow-assigned a font size
  // which value might be "far" from the target font size).
882

883
884
  // is this a vtkLookupTable or a subclass of vtkLookupTable 
  // with its scale set to log
885
  int isLogTable = this->LookupTable->UsingLogScale();
886

Ken Martin's avatar
Ken Martin committed
887
888
889
  for (i=0; i < this->NumberOfLabels; i++)
    {
    this->TextMappers[i] = vtkTextMapper::New();
Sebastien Barre's avatar
Sebastien Barre committed
890

891
892
    if ( isLogTable )
      {
Ken Martin's avatar
Ken Martin committed
893
      double lval;
Ken Martin's avatar
Ken Martin committed
894
895
      if (this->NumberOfLabels > 1)
        {
896
897
        lval = log10(range[0]) +
          static_cast<double>(i)/(this->NumberOfLabels-1) *
Ken Martin's avatar
Ken Martin committed
898
899
900
901
902
903
          (log10(range[1])-log10(range[0]));
        }
      else
        {
        lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
        }
Ken Martin's avatar
Ken Martin committed
904
      val = pow(10.0,lval);
905
906
907
      }
    else
      {
Ken Martin's avatar
Ken Martin committed
908
909
      if (this->NumberOfLabels > 1)
        {
910
911
912
        val = range[0] +
          static_cast<double>(i)/(this->NumberOfLabels-1) 
          * (range[1]-range[0]);
Ken Martin's avatar
Ken Martin committed
913
914
915
916
917
        }
      else
        {
        val = range[0] + 0.5*(range[1]-range[0]);
        }
918
919
      }

Ken Martin's avatar
Ken Martin committed
920
921
    sprintf(string, this->LabelFormat, val);
    this->TextMappers[i]->SetInput(string);
Sebastien Barre's avatar
Sebastien Barre committed
922
923
924
925
926
927
928
929
930
931

    // Shallow copy here so that the size of the label prop is not affected
    // by the automatic adjustment of its text mapper's size (i.e. its
    // mapper's text property is identical except for the font size
    // which will be modified later). This allows text actors to
    // share the same text property, and in that case specifically allows
    // the title and label text prop to be the same.
    this->TextMappers[i]->GetTextProperty()->ShallowCopy(
      this->LabelTextProperty);

Ken Martin's avatar
Ken Martin committed
932
933
934
935
936
937
    this->TextActors[i] = vtkActor2D::New();
    this->TextActors[i]->SetMapper(this->TextMappers[i]);
    this->TextActors[i]->SetProperty(this->GetProperty());
    this->TextActors[i]->GetPositionCoordinate()->
      SetReferenceCoordinate(this->PositionCoordinate);
    }
Sebastien Barre's avatar
Sebastien Barre committed
938

Ken Martin's avatar
Ken Martin committed
939
940
  if (this->NumberOfLabels)
    {
Sebastien Barre's avatar
Sebastien Barre committed
941
942
    int targetWidth, targetHeight;

Ken Martin's avatar
Ken Martin committed
943
944
    if ( this->Orientation == VTK_ORIENT_VERTICAL )
      {
945
946
      targetWidth = static_cast<int>(0.6*size[0]);
      targetHeight = static_cast<int>(0.86*size[1]/this->NumberOfLabels);
Ken Martin's avatar
Ken Martin committed
947
948
949
      }
    else
      {
950
951
      targetWidth = static_cast<int>(size[0]*0.8/this->NumberOfLabels);
      targetHeight = static_cast<int>(0.25*size[1]);
Ken Martin's avatar
Ken Martin committed
952
      }
Sebastien Barre's avatar
Sebastien Barre committed
953
954
955
956
957
958
959

    vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
                                                  targetWidth, 
                                                  targetHeight,
                                                  this->TextMappers,
                                                  this->NumberOfLabels,
                                                  labelSize);
Ken Martin's avatar
Ken Martin committed
960
961
962
    }
}

Sebastien Barre's avatar
Sebastien Barre committed
963
964
965
//----------------------------------------------------------------------------
void vtkScalarBarActor::SizeTitle(int *titleSize, 
                                  int *size, 
Ken Martin's avatar
Ken Martin committed
966
967
                                  vtkViewport *viewport)
{
Sebastien Barre's avatar
Sebastien Barre committed
968
969
970
971
972
973
974
  titleSize[0] = titleSize[1] = 0;

  if (this->Title == NULL || !strlen(this->Title))
    {
    return;
    }

Ken Martin's avatar
Ken Martin committed
975
  int targetWidth, targetHeight;
Sebastien Barre's avatar
Sebastien Barre committed
976
  if ( this->Orientation == VTK_ORIENT_VERTICAL )
Ken Martin's avatar
Ken Martin committed
977
    {
978
    targetWidth = static_cast<int>(0.9*size[0]);
979
    targetHeight = static_cast<int>(0.1*size[1]);
Sebastien Barre's avatar
Sebastien Barre committed
980
981
982
    }
  else
    {
983
    targetWidth = size[0];
984
    targetHeight = static_cast<int>(0.25*size[1]);
Ken Martin's avatar
Ken Martin committed
985
    }
Sebastien Barre's avatar
Sebastien Barre committed
986
987
988
989
990
991

  this->TitleMapper->SetConstrainedFontSize(
    viewport, targetWidth, targetHeight);

  this->TitleMapper->GetSize(viewport, titleSize);
}