vtkScalarBarActor.cxx 31.3 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
  this->Position2Coordinate->SetValue(0.17, 0.8);
51

52
53
  this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
  this->PositionCoordinate->SetValue(0.82,0.1);
54

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
  this->LabelFormat = new char[8];
73
74
75
76
77
  sprintf(this->LabelFormat,"%s","%-#6.3g");

  this->TitleMapper = vtkTextMapper::New();
  this->TitleActor = vtkActor2D::New();
  this->TitleActor->SetMapper(this->TitleMapper);
78
79
  this->TitleActor->GetPositionCoordinate()->
    SetReferenceCoordinate(this->PositionCoordinate);
80

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
  // If opacity is on, a jail like texture is displayed behind it..

  this->UseOpacity       = 0;
  this->TextureGridWidth = 10.0;
100

101
102
  this->TexturePolyData = vtkPolyData::New();
  vtkPolyDataMapper2D * textureMapper = vtkPolyDataMapper2D::New();
103
  textureMapper->SetInputData(this->TexturePolyData);
104
105
106
107
108
109
110
111
  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);
112
  tc->InsertComponent(0,0, 0.0);
113
114
  tc->InsertComponent(0,1, 0.0);
  tc->InsertComponent(1,1, 0.0);
115
  tc->InsertComponent(3,0, 0.0);
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  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
  for (unsigned int y = 0; y < dim; y++)
    {
142
    unsigned char *ptr =
143
144
145
146
147
148
149
150
151
      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
}

Sebastien Barre's avatar
Sebastien Barre committed
183
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// 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);
198
199
  this->BackgroundActor->ReleaseGraphicsResources(win);
  this->FrameActor->ReleaseGraphicsResources(win);
Ken Martin's avatar
Ken Martin committed
200
201
}

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

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

  if (this->TextMappers != NULL )
    {
216
    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
217
218
219
220
221
222
223
224
225
226
227
      {
      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
228
229
230
231
232
233

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

  if ( this->ComponentTitle )
    {
    delete [] this->ComponentTitle;
    this->ComponentTitle = NULL;
    }
240

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

Sebastien Barre's avatar
Sebastien Barre committed
257
//----------------------------------------------------------------------------
258
int vtkScalarBarActor::RenderOverlay(vtkViewport *viewport)
Ken Martin's avatar
Ken Martin committed
259
{
260
  int renderedSomething = 0;
Ken Martin's avatar
Ken Martin committed
261
  int i;
262

263
264
265
266
  if (this->DrawBackground)
    {
    renderedSomething += this->BackgroundActor->RenderOverlay(viewport);
    }
267

268
269
270
271
  if (this->DrawFrame)
    {
    renderedSomething += this->FrameActor->RenderOverlay(viewport);
    }
272

273
274
275
276
277
278
  if (this->UseOpacity)
    {
    this->Texture->Render(vtkRenderer::SafeDownCast(viewport));
    renderedSomething += this->TextureActor->RenderOverlay(viewport);
    }

Ken Martin's avatar
Ken Martin committed
279
280
281
  // Everything is built, just have to render
  if (this->Title != NULL)
    {
282
    renderedSomething += this->TitleActor->RenderOverlay(viewport);
Ken Martin's avatar
Ken Martin committed
283
284
    }
  this->ScalarBarActor->RenderOverlay(viewport);
285
286
287
288
289
  if( this->TextActors == NULL)
    {
     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
     return renderedSomething;
    }
290

Ken Martin's avatar
Ken Martin committed
291
292
  for (i=0; i<this->NumberOfLabels; i++)
    {
293
    renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
Ken Martin's avatar
Ken Martin committed
294
    }
295
296
297
298

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

  return renderedSomething;
Ken Martin's avatar
Ken Martin committed
299
300
}

Sebastien Barre's avatar
Sebastien Barre committed
301
//----------------------------------------------------------------------------
302
int vtkScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
303
{
304
  int renderedSomething = 0;
305
  int i;
306
  int size[2];
307

Sebastien Barre's avatar
Sebastien Barre committed
308
  if (!this->LookupTable)
309
310
    {
    vtkWarningMacro(<<"Need a mapper to render a scalar bar");
311
    return 0;
312
313
    }

Sebastien Barre's avatar
Sebastien Barre committed
314
315
316
317
318
319
320
321
322
323
324
325
  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
326
  // Check to see whether we have to rebuild everything
327
  int positionsHaveChanged = 0;
328
329
  if (viewport->GetMTime() > this->BuildTime ||
      (viewport->GetVTKWindow() &&
Sebastien Barre's avatar
Sebastien Barre committed
330
       viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
Ken Martin's avatar
Ken Martin committed
331
332
333
    {
    // 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
334
    int *barOrigin;
Ken Martin's avatar
Ken Martin committed
335
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
336
    size[0] =
Ken Martin's avatar
Ken Martin committed
337
338
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
339
    size[1] =
Ken Martin's avatar
Ken Martin committed
340
341
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
342

343
344
    // Check if we have bounds on the maximum size
    size[0] = size[0] > this->MaximumWidthInPixels
345
            ? this->MaximumWidthInPixels : size[0];
346
    size[1] = size[1] > this->MaximumHeightInPixels
347
348
            ? this->MaximumHeightInPixels : size[1];

349
    if (this->LastSize[0] != size[0] ||
Sebastien Barre's avatar
Sebastien Barre committed
350
        this->LastSize[1] != size[1] ||
351
        this->LastOrigin[0] != barOrigin[0] ||
352
        this->LastOrigin[1] != barOrigin[1])
Ken Martin's avatar
Ken Martin committed
353
      {
354
      positionsHaveChanged = 1;
Ken Martin's avatar
Ken Martin committed
355
356
      }
    }
357

358
  // Check to see whether we have to rebuild everything
359
  if (positionsHaveChanged ||
360
      this->GetMTime() > this->BuildTime ||
Sebastien Barre's avatar
Sebastien Barre committed
361
362
      this->LookupTable->GetMTime() > this->BuildTime ||
      this->LabelTextProperty->GetMTime() > this->BuildTime ||
363
364
365
366
      this->TitleTextProperty->GetMTime() > this->BuildTime ||
      this->BackgroundProperty->GetMTime() > this->BuildTime ||
      this->FrameProperty->GetMTime() > this->BuildTime)

367
368
369
370
371
372
373
    {
    vtkDebugMacro(<<"Rebuilding subobjects");

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

383
    // Build scalar bar object; determine its type
384
385
    // i.e. has scale set to log
    int isLogTable = this->LookupTable->UsingLogScale();
386

Ken Martin's avatar
Ken Martin committed
387
    // we hard code how many steps to display
388
    vtkScalarsToColors *lut = this->LookupTable;
Ken Martin's avatar
Ken Martin committed
389
    int numColors = this->MaximumNumberOfColors;
Ken Martin's avatar
Ken Martin committed
390
    double *range = lut->GetRange();
391
392
393
394
395
396

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

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

    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();

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
    // 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();

434
    // get the viewport size in display coordinates
435
436
    int *barOrigin, barWidth, barHeight;
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
437
    size[0] =
438
439
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
440
    size[1] =
441
442
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
443

444
445
    // Check if we have bounds on the maximum size
    size[0] = size[0] > this->MaximumWidthInPixels
446
            ? this->MaximumWidthInPixels : size[0];
447
    size[1] = size[1] > this->MaximumHeightInPixels
448
            ? this->MaximumHeightInPixels : size[1];
449

Ken Martin's avatar
Ken Martin committed
450
451
452
453
    this->LastOrigin[0] = barOrigin[0];
    this->LastOrigin[1] = barOrigin[1];
    this->LastSize[0] = size[0];
    this->LastSize[1] = size[1];
454

455
456
    // Update all the composing objects
    this->TitleActor->SetProperty(this->GetProperty());
457
458


459
460
461
    //update with the proper title
    if ( this->ComponentTitle && strlen(this->ComponentTitle) > 0 )
      {
462
      //need to account for a space between title & component and null term
463
      char *combinedTitle = new char[ ( strlen(this->Title) + strlen(this->ComponentTitle) + 2) ];
464
465
466
467
468
469
470
471
472
473
474
      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
475
476
477
478
479
480
481
482
483
484
485
    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();
      }
486

Ken Martin's avatar
Ken Martin committed
487
488
489
    // find the best size for the title font
    int titleSize[2];
    this->SizeTitle(titleSize, size, viewport);
490

Ken Martin's avatar
Ken Martin committed
491
492
493
    // find the best size for the ticks
    int labelSize[2];
    this->AllocateAndSizeLabels(labelSize, size, viewport,range);
494
    this->NumberOfLabelsBuilt = this->NumberOfLabels;
495

496
    // generate points
Ken Martin's avatar
Ken Martin committed
497
498
    double x[3]; x[2] = 0.0;
    double delta;
Philippe Pébay's avatar
Philippe Pébay committed
499
500
    int barX = 0;
    int barY = 0;
501
502
    if ( this->Orientation == VTK_ORIENT_VERTICAL )
      {
503
504
505
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
506
           this->DrawFrame )
507
508
509
510
        {
        barX = static_cast<int>(size[0] * 0.05);
        barY = static_cast<int>(size[1] * 0.05 + labelSize[1] / 2);
        }
511
512
513

      barWidth = size[0] - 4 - labelSize[0] - 2 * barX;
      barHeight = static_cast<int>(0.86*size[1]) - barY;
514
      delta=static_cast<double>(barHeight)/numColors;
515
      for (i=0; i<numPts/2; i++)
516
        {
517
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
518
519
          ? (size[0] - barWidth - barX) : barX;
        x[1] = barY + i*delta;
520
        pts->SetPoint(2*i,x);
521
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
522
          ? size[0] - barX: barX + barWidth;
523
        pts->SetPoint(2*i+1,x);
524
        }
525
526
527
      }
    else
      {
528
529
530
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
531
           this->DrawFrame )
532
        {
533
534
        barX = static_cast<int>(size[0] * 0.05) + labelSize[0] / 2;
        barY = static_cast<int>(size[1] * 0.05);
535
        }
536
537
      barWidth = size[0] - 2 * barX;
      barHeight = static_cast<int>(0.4*size[1]) - barY;
538
      delta=static_cast<double>(barWidth)/numColors;
539
      for (i=0; i<numPts/2; i++)
540
        {
541
        x[0] = barX + i*delta;
542
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
543
          ? size[1] - barY: barY + barHeight ;
544
        pts->SetPoint(2*i,x);
545
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
546
          ? (size[1]-barHeight - barY) : barY;
547
        pts->SetPoint(2*i+1,x);
548
        }
549
      }
550

551
552
    //polygons & cell colors
    unsigned char *rgba, *rgb;
553
    vtkIdType ptIds[4];
554
555
556
557
558
559
560
561
    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);

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

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

584
585
586
587
588
    // 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);
589

590
591
592
    x[0]=0; x[1]=size[1];
    bgPts->SetPoint(1,x);
    frPts->SetPoint(1,x);
593

594
595
596
    x[0]=size[0]; x[1]=size[1];
    bgPts->SetPoint(2,x);
    frPts->SetPoint(2,x);
597

598
599
600
601
602
603
604
605
    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);

606
607
    // Now position everything properly
    //
Ken Martin's avatar
Ken Martin committed
608
    double val;
609
    int sizeTextData[2];
610
611
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
612
      // center the title
Ken Martin's avatar
Ken Martin committed
613
      this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
614

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

674
675
676
677
678
679
    // Set the texture points
    //
    vtkPoints *texturePoints = vtkPoints::New();
    texturePoints->SetNumberOfPoints(4);
    this->TexturePolyData->SetPoints(texturePoints);
    texturePoints->SetPoint(0, 0.0, 0.0, 0.0);
680
681
682
683

    double p1[2], p2[2];
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
684
      p1[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
685
686
        ? (size[0] - barWidth - barX) : barX;
      p1[1] = barY;
687
      p2[0] = p1[0] + barWidth;
688
      p2[1] = p1[1] + barHeight;
689
690
691
      }
    else
      {
692
      p1[0] = barX;
693
      p1[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
694
        ? (size[1] - barHeight - barY) : barY;
695
696
697
698
699
700
701
702
      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);
703
704
705
706
    texturePoints->Delete();

    vtkDataArray * tc = this->TexturePolyData->GetPointData()->GetTCoords();
    tc->SetTuple2(1, barWidth / this->TextureGridWidth, 0.0);
707
    tc->SetTuple2(2, barWidth / this->TextureGridWidth,
708
                  barHeight / this->TextureGridWidth);
709
710
    tc->SetTuple2(3, 0.0, barHeight / this->TextureGridWidth);

711
712
713
    this->BuildTime.Modified();
    }

714

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

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

  return renderedSomething;
729
730
}

731
732
733
734
735
736
737
738
//-----------------------------------------------------------------------------
// Description:
// Does this prop have some translucent polygonal geometry?
int vtkScalarBarActor::HasTranslucentPolygonalGeometry()
{
  return 0;
}

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

  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
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
  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";
    }

774
  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
775
  os << indent << "ComponentTitle: " << (this->ComponentTitle ? this->ComponentTitle : "(none)") << "\n";
776
  os << indent << "Maximum Number Of Colors: "
777
778
     << this->MaximumNumberOfColors << "\n";
  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
779
  os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
780
781

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

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

808
  os << indent << "MaximumWidthInPixels: "
Karthik Krishnan's avatar
Karthik Krishnan committed
809
     << this->MaximumWidthInPixels << endl;
810
  os << indent << "MaximumHeightInPixels: "
Karthik Krishnan's avatar
Karthik Krishnan committed
811
     << this->MaximumHeightInPixels << endl;
812
813
814
815
816
817
818

  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());
819
}
Ken Martin's avatar
Ken Martin committed
820

Sebastien Barre's avatar
Sebastien Barre committed
821
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
822
823
824
825
826
827
828
829
830
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
831
832
    this->SetLabelTextProperty(a->GetLabelTextProperty());
    this->SetTitleTextProperty(a->GetTitleTextProperty());
Will Schroeder's avatar
Will Schroeder committed
833
834
835
    this->SetLabelFormat(a->GetLabelFormat());
    this->SetTitle(a->GetTitle());
    this->GetPositionCoordinate()->SetCoordinateSystem(
836
      a->GetPositionCoordinate()->GetCoordinateSystem());
Will Schroeder's avatar
Will Schroeder committed
837
838
839
    this->GetPositionCoordinate()->SetValue(
      a->GetPositionCoordinate()->GetValue());
    this->GetPosition2Coordinate()->SetCoordinateSystem(
840
      a->GetPosition2Coordinate()->GetCoordinateSystem());
Will Schroeder's avatar
Will Schroeder committed
841
842
    this->GetPosition2Coordinate()->SetValue(
      a->GetPosition2Coordinate()->GetValue());
843
844
845
846
    this->SetDrawBackground(a->GetDrawBackground());
    this->SetBackgroundProperty(a->GetBackgroundProperty());
    this->SetDrawFrame(a->GetDrawFrame());
    this->SetFrameProperty(a->GetFrameProperty());
Will Schroeder's avatar
Will Schroeder committed
847
848
849
850
851
    }

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

Sebastien Barre's avatar
Sebastien Barre committed
853
//----------------------------------------------------------------------------
854
void vtkScalarBarActor::AllocateAndSizeLabels(int *labelSize,
Sebastien Barre's avatar
Sebastien Barre committed
855
                                              int *size,
Ken Martin's avatar
Ken Martin committed
856
                                              vtkViewport *viewport,
Ken Martin's avatar
Ken Martin committed
857
                                              double *range)
Ken Martin's avatar
Ken Martin committed
858
{
Sebastien Barre's avatar
Sebastien Barre committed
859
860
  labelSize[0] = labelSize[1] = 0;

Ken Martin's avatar
Ken Martin committed
861
862
  this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
  this->TextActors = new vtkActor2D * [this->NumberOfLabels];
Sebastien Barre's avatar
Sebastien Barre committed
863

Ken Martin's avatar
Ken Martin committed
864
  char string[512];
Sebastien Barre's avatar
Sebastien Barre committed
865

Ken Martin's avatar
Ken Martin committed
866
  double val;
Ken Martin's avatar
Ken Martin committed
867
  int i;
868

Sebastien Barre's avatar
Sebastien Barre committed
869
870
871
872
873
  // 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).
874

875
  // is this a vtkLookupTable or a subclass of vtkLookupTable
876
  // with its scale set to log
877
  int isLogTable = this->LookupTable->UsingLogScale();
878

Ken Martin's avatar
Ken Martin committed
879
880
881
  for (i=0; i < this->NumberOfLabels; i++)
    {
    this->TextMappers[i] = vtkTextMapper::New();
Sebastien Barre's avatar
Sebastien Barre committed
882

883
884
    if ( isLogTable )
      {
Ken Martin's avatar
Ken Martin committed
885
      double lval;
Ken Martin's avatar
Ken Martin committed
886
887
      if (this->NumberOfLabels > 1)
        {
888
889
        lval = log10(range[0]) +
          static_cast<double>(i)/(this->NumberOfLabels-1) *
Ken Martin's avatar
Ken Martin committed
890
891
892
893
894
895
          (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
896
      val = pow(10.0,lval);
897
898
899
      }
    else
      {
Ken Martin's avatar
Ken Martin committed
900
901
      if (this->NumberOfLabels > 1)
        {
902
        val = range[0] +
903
          static_cast<double>(i)/(this->NumberOfLabels-1)
904
          * (range[1]-range[0]);
Ken Martin's avatar
Ken Martin committed
905
906
907
908
909
        }
      else
        {
        val = range[0] + 0.5*(range[1]-range[0]);
        }
910
911
      }

Ken Martin's avatar
Ken Martin committed
912
913
    sprintf(string, this->LabelFormat, val);
    this->TextMappers[i]->SetInput(string);
Sebastien Barre's avatar
Sebastien Barre committed
914
915
916
917
918
919
920
921
922
923

    // 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
924
925
926
927
928
929
    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
930

Ken Martin's avatar
Ken Martin committed
931
932
  if (this->NumberOfLabels)
    {
Sebastien Barre's avatar
Sebastien Barre committed
933
934
    int targetWidth, targetHeight;

Ken Martin's avatar
Ken Martin committed
935
936
    if ( this->Orientation == VTK_ORIENT_VERTICAL )
      {
937
938
      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
939
940
941
      }
    else
      {
942
943
      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
944
      }
Sebastien Barre's avatar
Sebastien Barre committed
945

946
947
    vtkTextMapper::SetMultipleConstrainedFontSize(viewport,
                                                  targetWidth,
Sebastien Barre's avatar
Sebastien Barre committed
948
949
950
951
                                                  targetHeight,
                                                  this->TextMappers,
                                                  this->NumberOfLabels,
                                                  labelSize);
Ken Martin's avatar
Ken Martin committed
952
953
954
    }
}

Sebastien Barre's avatar
Sebastien Barre committed
955
//----------------------------------------------------------------------------
956
957
void vtkScalarBarActor::SizeTitle(int *titleSize,
                                  int *size,
Ken Martin's avatar
Ken Martin committed
958
959
                                  vtkViewport *viewport)
{
Sebastien Barre's avatar
Sebastien Barre committed
960
961
962
963
964
965
966
  titleSize[0] = titleSize[1] = 0;

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

Ken Martin's avatar
Ken Martin committed
967
  int targetWidth, targetHeight;
Sebastien Barre's avatar
Sebastien Barre committed
968
  if ( this->Orientation == VTK_ORIENT_VERTICAL )
Ken Martin's avatar
Ken Martin committed
969
    {
970
    targetWidth = static_cast<int>(0.9*size[0]);
971
    targetHeight = static_cast<int>(0.1*size[1]);
Sebastien Barre's avatar
Sebastien Barre committed
972
973
974
    }
  else
    {
975
    targetWidth = size[0];