vtkScalarBarActor.cxx 37.4 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
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkTexture.h"
#include "vtkImageData.h"
#include "vtkRenderer.h"
33
#include "vtkMathTextActor.h"
34
35
#include "vtkProperty2D.h"

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

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

Sebastien Barre's avatar
Sebastien Barre committed
44
45
//----------------------------------------------------------------------------
// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
46
47
48
49
50
// 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;
51
  this->Position2Coordinate->SetValue(0.17, 0.8);
52

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

56
57
  this->MaximumNumberOfColors = 64;
  this->NumberOfLabels = 5;
58
  this->NumberOfLabelsBuilt = 0;
59
60
  this->Orientation = VTK_ORIENT_VERTICAL;
  this->Title = NULL;
61
  this->ComponentTitle = NULL;
62

Sebastien Barre's avatar
Sebastien Barre committed
63
64
65
66
67
68
69
70
71
72
  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);

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

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

82
83
84
85
86
  this->TextMappers = NULL;
  this->TextActors = NULL;

  this->ScalarBar = vtkPolyData::New();
  this->ScalarBarMapper = vtkPolyDataMapper2D::New();
87
  this->ScalarBarMapper->SetInputData(this->ScalarBar);
88
89
  this->ScalarBarActor = vtkActor2D::New();
  this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
90
91
  this->ScalarBarActor->GetPositionCoordinate()->
    SetReferenceCoordinate(this->PositionCoordinate);
Ken Martin's avatar
Ken Martin committed
92
93
94
95
  this->LastOrigin[0] = 0;
  this->LastOrigin[1] = 0;
  this->LastSize[0] = 0;
  this->LastSize[1] = 0;
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  this->AnnotationBoxes = vtkPolyData::New();
  this->AnnotationBoxesMapper = vtkPolyDataMapper2D::New();
  this->AnnotationBoxesActor = vtkActor2D::New();
  this->AnnotationBoxesMapper->SetInputData( this->AnnotationBoxes );
  this->AnnotationBoxesActor->SetMapper( this->AnnotationBoxesMapper );
  this->AnnotationBoxesActor->GetPositionCoordinate()->
    SetReferenceCoordinate( this->PositionCoordinate );
  this->AnnotationLeaders = vtkPolyData::New();
  this->AnnotationLeadersMapper = vtkPolyDataMapper2D::New();
  this->AnnotationLeadersActor = vtkActor2D::New();
  this->AnnotationLeadersMapper->SetInputData( this->AnnotationLeaders );
  this->AnnotationLeadersActor->SetMapper( this->AnnotationLeadersMapper );
  this->AnnotationLeadersActor->GetPositionCoordinate()->
    SetReferenceCoordinate( this->PositionCoordinate );
  this->AnnotationLabels = 0; // Can't allocate until we have a lookup table.
  this->NumberOfAnnotationLabelsBuilt = 0;

114
115
116
117
  // If opacity is on, a jail like texture is displayed behind it..

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

119
120
  this->TexturePolyData = vtkPolyData::New();
  vtkPolyDataMapper2D * textureMapper = vtkPolyDataMapper2D::New();
121
  textureMapper->SetInputData(this->TexturePolyData);
122
123
124
125
126
127
128
129
  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);
130
  tc->InsertComponent(0,0, 0.0);
131
132
  tc->InsertComponent(0,1, 0.0);
  tc->InsertComponent(1,1, 0.0);
133
  tc->InsertComponent(3,0, 0.0);
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  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
156
  image->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
157

158
159
  for (unsigned int y = 0; y < dim; y++)
    {
160
    unsigned char *ptr =
161
162
163
164
165
166
167
168
169
      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();
170
  this->Texture->SetInputData( image );
171
172
  this->Texture->RepeatOn();
  image->Delete();
173
174
175
176

  // Default text position : Above scalar bar if orientation is horizontal
  //                         Right of scalar bar if orientation is vertical
  this->TextPosition = SucceedScalarBar;
177
178
179

  this->MaximumWidthInPixels = VTK_INT_MAX;
  this->MaximumHeightInPixels = VTK_INT_MAX;
180
181
182
183
184
185
186

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

  this->DrawBackground = 0;
  this->Background = vtkPolyData::New();
  this->BackgroundMapper = vtkPolyDataMapper2D::New();
187
  this->BackgroundMapper->SetInputData(this->Background);
188
189
190
191
192
193
194
  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();
195
  this->FrameMapper->SetInputData(this->Frame);
196
197
198
  this->FrameActor = vtkActor2D::New();
  this->FrameActor->SetMapper(this->FrameMapper);
  this->FrameActor->GetPositionCoordinate()->SetReferenceCoordinate(this->PositionCoordinate);
199
200
}

Sebastien Barre's avatar
Sebastien Barre committed
201
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
202
203
204
205
206
207
208
209
210
211
212
213
214
// 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);
      }
    }
215
216
217
218
219
220
221
  if ( this->AnnotationLabels != NULL )
    {
    for ( int i = 0; i < this->NumberOfAnnotationLabelsBuilt; ++ i )
      {
      this->AnnotationLabels[i]->ReleaseGraphicsResources(win);
      }
    }
Ken Martin's avatar
Ken Martin committed
222
  this->ScalarBarActor->ReleaseGraphicsResources(win);
223
224
  this->AnnotationBoxesActor->ReleaseGraphicsResources(win);
  this->AnnotationLeadersActor->ReleaseGraphicsResources(win);
225
226
  this->BackgroundActor->ReleaseGraphicsResources(win);
  this->FrameActor->ReleaseGraphicsResources(win);
Ken Martin's avatar
Ken Martin committed
227
228
}

Sebastien Barre's avatar
Sebastien Barre committed
229
//----------------------------------------------------------------------------
230
231
vtkScalarBarActor::~vtkScalarBarActor()
{
232
  if (this->LabelFormat)
Ken Martin's avatar
Ken Martin committed
233
234
235
236
    {
    delete [] this->LabelFormat;
    this->LabelFormat = NULL;
    }
237
238
239
240
241
242

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

  if (this->TextMappers != NULL )
    {
243
    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
244
245
246
247
248
249
250
251
      {
      this->TextMappers[i]->Delete();
      this->TextActors[i]->Delete();
      }
    delete [] this->TextMappers;
    delete [] this->TextActors;
    }

252
253
254
255
256
257
258
259
260
  if ( this->AnnotationLabels != NULL )
    {
    for ( int i = 0; i < this->NumberOfAnnotationLabelsBuilt; ++ i )
      {
      this->AnnotationLabels[i]->Delete();
      }
    delete [] this->AnnotationLabels;
    }

261
262
263
  this->ScalarBar->Delete();
  this->ScalarBarMapper->Delete();
  this->ScalarBarActor->Delete();
Ken Martin's avatar
Ken Martin committed
264

265
266
267
268
269
270
271
272
  this->AnnotationBoxes->Delete();
  this->AnnotationBoxesMapper->Delete();
  this->AnnotationBoxesActor->Delete();

  this->AnnotationLeaders->Delete();
  this->AnnotationLeadersMapper->Delete();
  this->AnnotationLeadersActor->Delete();

Ken Martin's avatar
Ken Martin committed
273
274
275
276
277
  if (this->Title)
    {
    delete [] this->Title;
    this->Title = NULL;
    }
278
279
280
281
282
283

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

285
  this->SetLookupTable(NULL);
Sebastien Barre's avatar
Sebastien Barre committed
286
287
  this->SetLabelTextProperty(NULL);
  this->SetTitleTextProperty(NULL);
288
289
290
  this->Texture->Delete();
  this->TextureActor->Delete();
  this->TexturePolyData->Delete();
291
292
293
294
295
296
297
298
  this->Background->Delete();
  this->BackgroundMapper->Delete();
  this->BackgroundActor->Delete();
  this->Frame->Delete();
  this->FrameMapper->Delete();
  this->FrameActor->Delete();
  this->SetBackgroundProperty(NULL);
  this->SetFrameProperty(NULL);
299
300
}

Sebastien Barre's avatar
Sebastien Barre committed
301
//----------------------------------------------------------------------------
302
int vtkScalarBarActor::RenderOverlay(vtkViewport *viewport)
Ken Martin's avatar
Ken Martin committed
303
{
304
  int renderedSomething = 0;
Ken Martin's avatar
Ken Martin committed
305
  int i;
306

307
308
309
310
  if (this->DrawBackground)
    {
    renderedSomething += this->BackgroundActor->RenderOverlay(viewport);
    }
311

312
313
314
315
  if (this->DrawFrame)
    {
    renderedSomething += this->FrameActor->RenderOverlay(viewport);
    }
316

317
318
319
320
321
322
  if (this->UseOpacity)
    {
    this->Texture->Render(vtkRenderer::SafeDownCast(viewport));
    renderedSomething += this->TextureActor->RenderOverlay(viewport);
    }

Ken Martin's avatar
Ken Martin committed
323
324
325
  // Everything is built, just have to render
  if (this->Title != NULL)
    {
326
    renderedSomething += this->TitleActor->RenderOverlay(viewport);
Ken Martin's avatar
Ken Martin committed
327
    }
328
329
330
331

  // Draw either the scalar bar (non-indexed mode) or the annotated value boxes (indexed mode).
  vtkLookupTable* lkup = vtkLookupTable::SafeDownCast( this->LookupTable );
  if ( ! lkup || ( lkup && ! lkup->GetIndexedLookup() ) )
332
    {
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    this->ScalarBarActor->RenderOverlay(viewport);

    if( this->TextActors == NULL)
      {
      vtkWarningMacro(<<"Need a mapper to render a scalar bar");
      return renderedSomething;
      }

    for (i=0; i<this->NumberOfLabels; i++)
      {
      renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
      }
    }
  else
    {
    this->AnnotationBoxesActor->RenderOverlay(viewport);
349
    }
350

351
  if ( this->AnnotationLabels == NULL && this->NumberOfAnnotationLabelsBuilt )
Ken Martin's avatar
Ken Martin committed
352
    {
353
354
    vtkWarningMacro(<<"Need a mapper to render the scalar bar");
    return renderedSomething;
Ken Martin's avatar
Ken Martin committed
355
    }
356

357
358
359
360
  for ( i = 0; i < this->NumberOfAnnotationLabelsBuilt; ++ i )
    {
    renderedSomething += this->AnnotationLabels[i]->RenderOverlay( viewport );
    }
361

362
  renderedSomething = (renderedSomething > 0)?(1):(0);
363
  return renderedSomething;
Ken Martin's avatar
Ken Martin committed
364
365
}

Sebastien Barre's avatar
Sebastien Barre committed
366
//----------------------------------------------------------------------------
367
int vtkScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
368
{
369
  int renderedSomething = 0;
370
  int i;
371
  int size[2];
372

Sebastien Barre's avatar
Sebastien Barre committed
373
  if (!this->LookupTable)
374
375
    {
    vtkWarningMacro(<<"Need a mapper to render a scalar bar");
376
    return 0;
377
378
    }

Sebastien Barre's avatar
Sebastien Barre committed
379
380
381
382
383
384
385
386
387
388
389
390
  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
391
  // Check to see whether we have to rebuild everything
392
  int positionsHaveChanged = 0;
393
394
  if (viewport->GetMTime() > this->BuildTime ||
      (viewport->GetVTKWindow() &&
Sebastien Barre's avatar
Sebastien Barre committed
395
       viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
Ken Martin's avatar
Ken Martin committed
396
397
398
    {
    // 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
399
    int *barOrigin;
Ken Martin's avatar
Ken Martin committed
400
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
401
    size[0] =
Ken Martin's avatar
Ken Martin committed
402
403
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
404
    size[1] =
Ken Martin's avatar
Ken Martin committed
405
406
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
407

408
409
    // Check if we have bounds on the maximum size
    size[0] = size[0] > this->MaximumWidthInPixels
410
            ? this->MaximumWidthInPixels : size[0];
411
    size[1] = size[1] > this->MaximumHeightInPixels
412
413
            ? this->MaximumHeightInPixels : size[1];

414
    if (this->LastSize[0] != size[0] ||
Sebastien Barre's avatar
Sebastien Barre committed
415
        this->LastSize[1] != size[1] ||
416
        this->LastOrigin[0] != barOrigin[0] ||
417
        this->LastOrigin[1] != barOrigin[1])
Ken Martin's avatar
Ken Martin committed
418
      {
419
      positionsHaveChanged = 1;
Ken Martin's avatar
Ken Martin committed
420
421
      }
    }
422

423
  // Check to see whether we have to rebuild everything
424
  if (positionsHaveChanged ||
425
      this->GetMTime() > this->BuildTime ||
Sebastien Barre's avatar
Sebastien Barre committed
426
427
      this->LookupTable->GetMTime() > this->BuildTime ||
      this->LabelTextProperty->GetMTime() > this->BuildTime ||
428
429
430
431
      this->TitleTextProperty->GetMTime() > this->BuildTime ||
      this->BackgroundProperty->GetMTime() > this->BuildTime ||
      this->FrameProperty->GetMTime() > this->BuildTime)

432
433
434
435
436
437
438
    {
    vtkDebugMacro(<<"Rebuilding subobjects");

    // Delete previously constructed objects
    //
    if (this->TextMappers != NULL )
      {
439
      for (i=0; i < this->NumberOfLabelsBuilt; i++)
440
441
442
443
        {
        this->TextMappers[i]->Delete();
        this->TextActors[i]->Delete();
        }
444
445
446
447
      delete [] this->TextMappers;
      delete [] this->TextActors;
      }

448
449
450
451
452
453
454
455
456
457
    if ( this->AnnotationLabels != NULL )
      {
      for ( i = 0; i < this->NumberOfAnnotationLabelsBuilt; ++ i )
        {
        this->AnnotationLabels[i]->Delete();
        }
      delete [] this->AnnotationLabels;
      this->AnnotationLabels = 0;
      }

458
    // Build scalar bar object; determine its type
459
    // i.e. is scale set to log, is categorical or continuous?
460
    int isLogTable = this->LookupTable->UsingLogScale();
461
462
    vtkLookupTable* lkup = vtkLookupTable::SafeDownCast( this->LookupTable );
    int isCategorical = lkup && lkup->GetIndexedLookup();
463

Ken Martin's avatar
Ken Martin committed
464
    // we hard code how many steps to display
465
    vtkScalarsToColors *lut = this->LookupTable;
Ken Martin's avatar
Ken Martin committed
466
    int numColors = this->MaximumNumberOfColors;
Ken Martin's avatar
Ken Martin committed
467
    double *range = lut->GetRange();
468
469
470
471
472
473

    int numPts = 2*(numColors + 1);
    vtkPoints *pts = vtkPoints::New();
    pts->SetNumberOfPoints(numPts);
    vtkCellArray *polys = vtkCellArray::New();
    polys->Allocate(polys->EstimateSize(numColors,4));
474
    vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
475
476
477

    unsigned int nComponents = ((this->UseOpacity) ? 4 : 3);
    colors->SetNumberOfComponents( nComponents );
478
    colors->SetNumberOfTuples(numColors);
479
480
481
482
483
484
485
486

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

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
    // 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();

511
    // get the viewport size in display coordinates
512
513
    int *barOrigin, barWidth, barHeight;
    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
514
    size[0] =
515
516
      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
      barOrigin[0];
517
    size[1] =
518
519
      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
      barOrigin[1];
520

521
522
    // Check if we have bounds on the maximum size
    size[0] = size[0] > this->MaximumWidthInPixels
523
            ? this->MaximumWidthInPixels : size[0];
524
    size[1] = size[1] > this->MaximumHeightInPixels
525
            ? this->MaximumHeightInPixels : size[1];
526

Ken Martin's avatar
Ken Martin committed
527
528
529
530
    this->LastOrigin[0] = barOrigin[0];
    this->LastOrigin[1] = barOrigin[1];
    this->LastSize[0] = size[0];
    this->LastSize[1] = size[1];
531

532
533
    // Update all the composing objects
    this->TitleActor->SetProperty(this->GetProperty());
534
535


536
537
538
    //update with the proper title
    if ( this->ComponentTitle && strlen(this->ComponentTitle) > 0 )
      {
539
      //need to account for a space between title & component and null term
540
      char *combinedTitle = new char[ ( strlen(this->Title) + strlen(this->ComponentTitle) + 2) ];
541
542
543
544
545
546
547
548
549
550
551
      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
552
553
554
555
556
557
558
559
560
561
562
    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();
      }
563

Ken Martin's avatar
Ken Martin committed
564
565
566
    // find the best size for the title font
    int titleSize[2];
    this->SizeTitle(titleSize, size, viewport);
567

Ken Martin's avatar
Ken Martin committed
568
569
570
    // find the best size for the ticks
    int labelSize[2];
    this->AllocateAndSizeLabels(labelSize, size, viewport,range);
571
    this->NumberOfLabelsBuilt = this->NumberOfLabels;
572

573
    // generate points
Ken Martin's avatar
Ken Martin committed
574
575
    double x[3]; x[2] = 0.0;
    double delta;
Philippe Pébay's avatar
Philippe Pébay committed
576
577
    int barX = 0;
    int barY = 0;
578
579
    if ( this->Orientation == VTK_ORIENT_VERTICAL )
      {
580
581
582
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
583
           this->DrawFrame )
584
585
586
587
        {
        barX = static_cast<int>(size[0] * 0.05);
        barY = static_cast<int>(size[1] * 0.05 + labelSize[1] / 2);
        }
588
589
590

      barWidth = size[0] - 4 - labelSize[0] - 2 * barX;
      barHeight = static_cast<int>(0.86*size[1]) - barY;
591
      delta=static_cast<double>(barHeight)/numColors;
592
      for (i=0; i<numPts/2; i++)
593
        {
594
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
595
596
          ? (size[0] - barWidth - barX) : barX;
        x[1] = barY + i*delta;
597
        pts->SetPoint(2*i,x);
598
        x[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
599
          ? size[0] - barX: barX + barWidth;
600
        pts->SetPoint(2*i+1,x);
601
        }
602
603
604
      }
    else
      {
605
606
607
      // Adjust height and width only in enhanced more or if at least
      // one amongst the frame and the background was requested
      if ( this->DrawBackground ||
608
           this->DrawFrame )
609
        {
610
611
        barX = static_cast<int>(size[0] * 0.05) + labelSize[0] / 2;
        barY = static_cast<int>(size[1] * 0.05);
612
        }
613
614
      barWidth = size[0] - 2 * barX;
      barHeight = static_cast<int>(0.4*size[1]) - barY;
615
      delta=static_cast<double>(barWidth)/numColors;
616
      for (i=0; i<numPts/2; i++)
617
        {
618
        x[0] = barX + i*delta;
619
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
620
          ? size[1] - barY: barY + barHeight ;
621
        pts->SetPoint(2*i,x);
622
        x[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
623
          ? (size[1]-barHeight - barY) : barY;
624
        pts->SetPoint(2*i+1,x);
625
        }
626
      }
627

628
629
    //polygons & cell colors
    unsigned char *rgba, *rgb;
630
    vtkIdType ptIds[4];
631
632
633
634
635
636
637
638
    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);

639
640
      if ( isLogTable )
        {
641
        double rgbval = log10(range[0]) +
642
          i*(log10(range[1])-log10(range[0]))/(numColors -1);
Ken Martin's avatar
Ken Martin committed
643
        rgba = lut->MapValue(pow(10.0,rgbval));
644
645
646
647
        }
      else
        {
        rgba = lut->MapValue(range[0] + (range[1] - range[0])*
648
                             (i /(numColors-1.0)));
649
650
        }

651
      rgb = colors->GetPointer( nComponents * i); //write into array directly
652
653
654
      rgb[0] = rgba[0];
      rgb[1] = rgba[1];
      rgb[2] = rgba[2];
655
656
657
658
      if (this->UseOpacity)
        {
        rgb[3] = rgba[3];
        }
659
660
      }

661
662
663
664
665
    // 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);
666

667
668
669
    x[0]=0; x[1]=size[1];
    bgPts->SetPoint(1,x);
    frPts->SetPoint(1,x);
670

671
672
673
    x[0]=size[0]; x[1]=size[1];
    bgPts->SetPoint(2,x);
    frPts->SetPoint(2,x);
674

675
676
677
678
679
680
681
682
    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);

683
684
    // Now position everything properly
    //
Ken Martin's avatar
Ken Martin committed
685
    double val;
686
    int sizeTextData[2];
687
688
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
689
      // center the title
Ken Martin's avatar
Ken Martin committed
690
      this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
691

Jim Miller's avatar
Style    
Jim Miller committed
692
      for (i=0; i < this->NumberOfLabels; i++)
693
        {
Ken Martin's avatar
Ken Martin committed
694
695
        if (this->NumberOfLabels > 1)
          {
696
          val = static_cast<double>(i)/(this->NumberOfLabels-1) *barHeight + barY;
Ken Martin's avatar
Ken Martin committed
697
          }
698
        else
Ken Martin's avatar
Ken Martin committed
699
          {
700
          val = 0.5*(barHeight + barY);
Ken Martin's avatar
Ken Martin committed
701
          }
702
        this->TextMappers[i]->GetSize(viewport,sizeTextData);
Sebastien Barre's avatar
Sebastien Barre committed
703
        this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
704
705
        if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
          {
706
          this->TextActors[i]->SetPosition(barX,
707
                                           val - 0.6*sizeTextData[1]);
708
709
710
          }
        else
          {
711
          this->TextActors[i]->SetPosition(barX + barWidth + 3,
712
                                           val - 0.6*sizeTextData[1]);
713
          }
714
        }
715
      }
716
    else // if (this->Orientation == VTK_ORIENT_VERTICAL)
717
      {
718
719
      if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
        {
720
        this->TitleActor->SetPosition(size[0]/2,
721
                                      barY + 0.1*titleSize[1]);
722
723
724
        }
      else
        {
725
        this->TitleActor->SetPosition(size[0]/2,
726
                                      barHeight + labelSize[1] + 0.1*size[1] + 0.15*titleSize[1]);
727
        }
Jim Miller's avatar
Style    
Jim Miller committed
728
      for (i=0; i < this->NumberOfLabels; i++)
729
        {
730
        this->TextMappers[i]->GetSize(viewport,sizeTextData);
Sebastien Barre's avatar
Sebastien Barre committed
731
        this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
Ken Martin's avatar
Ken Martin committed
732
733
        if (this->NumberOfLabels > 1)
          {
734
          val = static_cast<double>(i)/(this->NumberOfLabels-1) * barWidth + barX;
Ken Martin's avatar
Ken Martin committed
735
736
737
          }
        else
          {
738
          val = 0.5*(barWidth+barY);
Ken Martin's avatar
Ken Martin committed
739
          }
740
741
742
743
744
745
        if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
          {
          this->TextActors[i]->SetPosition(val, size[1] * 0.3);
          }
        else
          {
746
          this->TextActors[i]->SetPosition(val, barY + barHeight + 0.05*size[1]);
747
          }
748
        }
749
750
      }

751
752
753
754
755
756
    // Set the texture points
    //
    vtkPoints *texturePoints = vtkPoints::New();
    texturePoints->SetNumberOfPoints(4);
    this->TexturePolyData->SetPoints(texturePoints);
    texturePoints->SetPoint(0, 0.0, 0.0, 0.0);
757
758
759
760

    double p1[2], p2[2];
    if (this->Orientation == VTK_ORIENT_VERTICAL)
      {
761
      p1[0] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
762
763
        ? (size[0] - barWidth - barX) : barX;
      p1[1] = barY;
764
      p2[0] = p1[0] + barWidth;
765
      p2[1] = p1[1] + barHeight;
766
767
768
      }
    else
      {
769
      p1[0] = barX;
770
      p1[1] = (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
771
        ? (size[1] - barHeight - barY) : barY;
772
773
774
775
776
777
778
779
      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);
780
781
782
783
    texturePoints->Delete();

    vtkDataArray * tc = this->TexturePolyData->GetPointData()->GetTCoords();
    tc->SetTuple2(1, barWidth / this->TextureGridWidth, 0.0);
784
    tc->SetTuple2(2, barWidth / this->TextureGridWidth,
785
                  barHeight / this->TextureGridWidth);
786
787
    tc->SetTuple2(3, 0.0, barHeight / this->TextureGridWidth);

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    if ( isCategorical )
      {
      // this->ScalarBar will not be drawn; instead, draw padded boxes
      // and leaders to labels for each annotated value.
      // Since labels are user-provided, we render with vtkMathTextActor to allow fancy-ness.
      int numNotes = lkup->GetNumberOfAnnotatedValues();
      int numPts = 4 * numNotes; // 2 triangles per annotation: half-opaque, half-translucent.
      pts = vtkPoints::New();
      pts->SetNumberOfPoints( numPts );
      polys = vtkCellArray::New();
      polys->Allocate( polys->EstimateSize( 2 * numNotes, 3 ) );
      colors = vtkUnsignedCharArray::New();
      colors->SetNumberOfComponents( 4 ); // RGBA
      colors->SetNumberOfTuples( 2 * numNotes );

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

      // Use the nicely-provided scalar bar position to place
      // the annotated value swatches.
      if ( this->Orientation == VTK_ORIENT_VERTICAL )
        {
        barWidth = size[0] - 4 - labelSize[0] - 2 * barX;
        barHeight = static_cast<int>(0.86*size[1]) - barY;
        delta = static_cast<double>(barHeight) / numNotes;
        for ( i = 0; i < numNotes; ++ i )
          {
          x[0] = barX;
          x[1] = barY + i * delta + 4; // 4 = swatchPad
          pts->SetPoint( 4 * i, x );
          x[0] = barX + barWidth;
          pts->SetPoint( 4 * i + 1, x );
          x[1] += delta - 4 * 2;
          pts->SetPoint( 4 * i + 2, x );
          x[0] = barX;
          pts->SetPoint( 4 * i + 3, x );
          }
        }
      else
        {
        barWidth = size[0] - 2 * barX;
        barHeight = static_cast<int>( 0.4 * size[1] ) - barY;
        delta = static_cast<double>(barWidth) / numNotes;
        for ( i = 0; i < numNotes; ++ i )
          {
          x[0] = barX + i * delta + 4; // 4 = swatchPad;
          x[1] = barY;
          pts->SetPoint( 4 * i, x );
          x[0] += delta - 4 * 2;
          pts->SetPoint( 4 * i + 1, x );
          x[1] += barHeight;
          pts->SetPoint( 4 * i + 2, x );
          x[0] -= delta - 4 * 2;
          pts->SetPoint( 4 * i + 3, x );
          }
        }
      for ( i = 0; i < numNotes; ++ i )
        {
        ptIds[0] = 4 * i;
        ptIds[1] = ptIds[0] + 1;
        ptIds[2] = ptIds[0] + 2;
        polys->InsertNextCell( 3, ptIds );

        ptIds[1] = ptIds[2];
        ptIds[2] = ptIds[0] + 3;
        polys->InsertNextCell( 3, ptIds );

        // We could just call lkup->GetTableValue( i % lkup->GetNumberOfTableValues() ), but
        // that would draw colors even when an annotation did not have a valid conversion to/from a double...
        rgba = lkup->MapValue( lkup->GetAnnotatedValue( i ).ToDouble() );
        rgb = colors->GetPointer( /* numComponents */ 4 * /* numCells/swatch */ 2 * /* swatch */ i ); //write into array directly
        rgb[0] = rgba[0]; rgb[1] = rgba[1]; rgb[2] = rgba[2]; rgb[3] = rgba[3];
        rgb[4] = rgba[0]; rgb[5] = rgba[1]; rgb[6] = rgba[2]; rgb[7] = 255; // second triangle is always opaque
        }
      //vtkIndent foo;
      //pts->PrintSelf( cout, foo );
      //polys->PrintSelf( cout, foo );
      //colors->PrintSelf( cout, foo );
      }
871
872
873
874
    this->BuildTime.Modified();
    }

  // Everything is built, just have to render
Jim Miller's avatar
Style    
Jim Miller committed
875
876
  if (this->Title != NULL)
    {
877
    renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
878
    }
Ken Martin's avatar
Ken Martin committed
879
  this->ScalarBarActor->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
880
881
  for (i=0; i<this->NumberOfLabels; i++)
    {
882
    renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
Jim Miller's avatar
Style    
Jim Miller committed
883
    }
884
885
886
887

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

  return renderedSomething;
888
889
}

890
891
892
893
894
895
896
897
//-----------------------------------------------------------------------------
// Description:
// Does this prop have some translucent polygonal geometry?
int vtkScalarBarActor::HasTranslucentPolygonalGeometry()
{
  return 0;
}

Sebastien Barre's avatar
Sebastien Barre committed
898
//----------------------------------------------------------------------------
899
void vtkScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
900
{
Brad King's avatar
Brad King committed
901
  this->Superclass::PrintSelf(os,indent);
902
903
904
905
906
907
908
909
910
911
912

  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
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  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";
    }

933
  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
934
  os << indent << "ComponentTitle: " << (this->ComponentTitle ? this->ComponentTitle : "(none)") << "\n";
935
  os << indent << "Maximum Number Of Colors: "
936
937
     << this->MaximumNumberOfColors << "\n";
  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
938
  os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
939
940

  os << indent << "Orientation: ";
Jim Miller's avatar
Style    
Jim Miller committed
941
942
943
944
945
946
947
948
  if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
    {
    os << "Horizontal\n";
    }
  else
    {
    os << "Vertical\n";
    }
949
950

  os << indent << "Label Format: " << this->LabelFormat << "\n";
951
952
953
954
  os << indent << "UseOpacity: " << this->UseOpacity << "\n";
  if (this->UseOpacity)
    {
    os << indent << "TextureGridWidth: " << this->TextureGridWidth << "\n";
Karthik Krishnan's avatar
Karthik Krishnan committed
955
956
    os << indent << "TextureActor:\n";
    this->TextureActor->PrintSelf(os, indent.GetNextIndent());
957
    }
958
959
960
961
962
963
964
965
  if (this->TextPosition == vtkScalarBarActor::PrecedeScalarBar)
    {
    os << indent << "TextPosition: PrecedeScalarBar\n";
    }
  else
    {
    os << indent << "TextPosition: SucceedScalarBar\n";
    }
Karthik Krishnan's avatar
Karthik Krishnan committed
966

967
  os << indent << "MaximumWidthInPixels: "
Karthik Krishnan's avatar
Karthik Krishnan committed
968
     << this->MaximumWidthInPixels << endl;
969
  os << indent << "MaximumHeightInPixels: "
Karthik Krishnan's avatar
Karthik Krishnan committed
970
     << this->MaximumHeightInPixels << endl;
971
972
973
974
975
976
977

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

Sebastien Barre's avatar
Sebastien Barre committed
980
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
981
982
983
984
985
986
987
988
989
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
990
991
    this->SetLabelTextProperty(a->GetLabelTextProperty());
    this->SetTitleTextProperty(a->GetTitleTextProperty());
Will Schroeder's avatar
Will Schroeder committed
992
993
994
    this->SetLabelFormat(a->GetLabelFormat());
    this->SetTitle(a->GetTitle());
    this->GetPositionCoordinate()->SetCoordinateSystem(
995
      a->GetPositionCoordinate()->GetCoordinateSystem());
Will Schroeder's avatar
Will Schroeder committed
996
997
998
    this->GetPositionCoordinate()->SetValue(
      a->GetPositionCoordinate()->GetValue());
    this->GetPosition2Coordinate()->SetCoordinateSystem(
999
      a->GetPosition2Coordinate()->GetCoordinateSystem());
Will Schroeder's avatar
Will Schroeder committed
1000
1001
    this->GetPosition2Coordinate()->SetValue(
      a->GetPosition2Coordinate()->GetValue());
1002
1003
1004
1005
    this->SetDrawBackground(a->GetDrawBackground());
    this->SetBackgroundProperty(a->GetBackgroundProperty());
    this->SetDrawFrame(a->GetDrawFrame());
    this->SetFrameProperty(a->GetFrameProperty());
Will Schroeder's avatar
Will Schroeder committed
1006
1007
1008
1009
1010
    }

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

Sebastien Barre's avatar
Sebastien Barre committed
1012
//----------------------------------------------------------------------------
1013
void vtkScalarBarActor::AllocateAndSizeLabels(int *labelSize,
Sebastien Barre's avatar
Sebastien Barre committed
1014
                                              int *size,
Ken Martin's avatar
Ken Martin committed
1015
                                              vtkViewport *viewport,
Ken Martin's avatar
Ken Martin committed
1016
                                              double *range)
Ken Martin's avatar
Ken Martin committed
1017
{
Sebastien Barre's avatar
Sebastien Barre committed
1018
1019
  labelSize[0] = labelSize[1] = 0;

Ken Martin's avatar
Ken Martin committed
1020
1021
  this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
  this->TextActors = new vtkActor2D * [this->NumberOfLabels];
Sebastien Barre's avatar
Sebastien Barre committed
1022

Ken Martin's avatar
Ken Martin committed
1023
  char string[512];
Sebastien Barre's avatar
Sebastien Barre committed
1024

Ken Martin's avatar
Ken Martin committed
1025
  double val;
Ken Martin's avatar
Ken Martin committed
1026
  int i;
1027

Sebastien Barre's avatar
Sebastien Barre committed
1028
1029
1030
1031
1032
  // 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).
1033

1034
  // is this a vtkLookupTable or a subclass of vtkLookupTable
1035
  // with its scale set to log
1036
  int isLogTable = this->LookupTable->UsingLogScale();
1037

Ken Martin's avatar
Ken Martin committed
1038
1039
1040
  for (i=0