vtkLookupTable.h 15 KB
Newer Older
1
 /*=========================================================================
Will Schroeder's avatar
Will Schroeder committed
2

Ken Martin's avatar
Ken Martin committed
3
  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkLookupTable.h
Will Schroeder's avatar
Will Schroeder committed
5

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.
Will Schroeder's avatar
Will Schroeder committed
13 14

=========================================================================*/
15 16 17 18 19
/**
 * @class   vtkLookupTable
 * @brief   map scalar values into colors via a lookup table
 *
 * vtkLookupTable is an object that is used by mapper objects to map scalar
20
 * values into RGBA (red-green-blue-alpha) color specification,
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
 * or RGBA into scalar values. The color table can be created by direct
 * insertion of color values, or by specifying a hue, saturation, value, and
 * alpha range and generating a table.
 *
 * A special color for NaN values in the data can be specified via
 * SetNanColor(). In addition, a color for data values below the
 * lookup table range minimum can be specified with
 * SetBelowRangeColor(), and that color will be used for values below
 * the range minimum when UseBelowRangeColor is on.  Likewise, a color
 * for data values above the lookup table range maximum can be
 * specified with SetAboveRangeColor(), and it is used when
 * UseAboveRangeColor is on.
 *
 * This class behaves differently depending on how \a IndexedLookup is set.
 * When true, vtkLookupTable enters a mode for representing categorical color maps.
 * By setting \a IndexedLookup to true, you indicate that the annotated
 * values are the only valid values for which entries in the color table
 * should be returned. The colors in the lookup \a Table are assigned
 * to annotated values by taking the modulus of their index in the list
 * of annotations. \a IndexedLookup changes the behavior of \a GetIndex,
 * which in turn changes the way \a MapScalarsThroughTable2 behaves;
 * when \a IndexedLookup is true, \a MapScalarsThroughTable2 will search for
 * scalar values in \a AnnotatedValues and use the resulting index to
 * determine the color. If a scalar value is not present in \a AnnotatedValues,
 * then \a NanColor will be used.
 *
 * @warning
 * You need to explicitly call Build() when constructing the LUT by hand.
 *
 * @sa
 * vtkLogLookupTable vtkWindowLevelLookupTable
*/
Will Schroeder's avatar
Will Schroeder committed
53

54 55
#ifndef vtkLookupTable_h
#define vtkLookupTable_h
Ken Martin's avatar
Ken Martin committed
56

57
#include "vtkCommonCoreModule.h" // For export macro
Ken Martin's avatar
Ken Martin committed
58
#include "vtkScalarsToColors.h"
Ken Martin's avatar
Ken Martin committed
59

60 61
#include "vtkUnsignedCharArray.h" // Needed for inline method

62 63
#define VTK_RAMP_LINEAR 0
#define VTK_RAMP_SCURVE 1
Bill Hoffman's avatar
Bill Hoffman committed
64
#define VTK_RAMP_SQRT 2
65 66 67
#define VTK_SCALE_LINEAR 0
#define VTK_SCALE_LOG10 1

68
class VTKCOMMONCORE_EXPORT vtkLookupTable : public vtkScalarsToColors
Ken Martin's avatar
Ken Martin committed
69 70
{
public:
71 72 73 74
  //@{
  /**
   * Constants for offsets of special colors (e.g., NanColor, BelowRangeColor,
   * AboveRangeColor) from the maximum index in the lookup table.
75
   * These should be considered private and not be used by clients of this class.
76
   */
77
  static const vtkIdType REPEATED_LAST_COLOR_INDEX;
78 79 80 81
  static const vtkIdType BELOW_RANGE_COLOR_INDEX;
  static const vtkIdType ABOVE_RANGE_COLOR_INDEX;
  static const vtkIdType NAN_COLOR_INDEX;
  static const vtkIdType NUMBER_OF_SPECIAL_COLORS;
82
  //@}
83

84 85 86 87
  /**
   * Construct with range=[0,1]; and hsv ranges set up for rainbow color table
   * (from red to blue).
   */
88
  static vtkLookupTable *New();
89

90
  vtkTypeMacro(vtkLookupTable,vtkScalarsToColors);
91
  void PrintSelf(ostream& os, vtkIndent indent) override;
92

93 94 95 96
  /**
   * Return true if all of the values defining the mapping have an opacity
   * equal to 1.
   */
97
  int IsOpaque() override;
98

99 100
  /**
   * Allocate a color table of specified size.
101
   * Note that ext is no longer used.
102
   */
Will Schroeder's avatar
Will Schroeder committed
103
  int Allocate(int sz=256, int ext=256);
104

105 106 107 108
  /**
   * Generate lookup table from hue, saturation, value, alpha min/max values.
   * Table is built from linear ramp of each value.
   */
109
  void Build() override;
110

111 112 113 114 115 116 117
  /**
   * Force the lookup table to regenerate from hue, saturation, value,
   * and alpha min/max values.  Table is built from a linear ramp of
   * each value.  ForceBuild() is useful if a lookup table has been
   * defined manually (using SetTableValue) and then an application
   * decides to rebuild the lookup table using the implicit process.
   */
118 119
  virtual void ForceBuild();

120 121 122
  /**
   * Copies the "special" colors into the given table.
   */
123 124
  void BuildSpecialColors();

125 126
  //@{
  /**
127
   * Set the shape of the table ramp to either S-curve, linear, or sqrt.
128
   * The default is S-curve, which tails off gradually at either end.
129
   *
130
   * The equation used for the S-curve is y = (sin((x - 1/2)*pi) + 1)/2,
131 132 133 134 135
   * For an S-curve greyscale ramp, you should set NumberOfTableValues
   * to 402 (which is 256*pi/2) to provide room for the tails of the ramp.
   *
   * The equation for the linear ramp is simply y = x.
   *
136 137
   * The equation for the SQRT is y = sqrt(x).
   */
138
  vtkSetMacro(Ramp,int);
139 140 141
  void SetRampToLinear() { this->SetRamp(VTK_RAMP_LINEAR); }
  void SetRampToSCurve() { this->SetRamp(VTK_RAMP_SCURVE); }
  void SetRampToSQRT() { this->SetRamp(VTK_RAMP_SQRT); }
142
  vtkGetMacro(Ramp,int);
143 144 145 146 147 148 149 150
  //@}

  //@{
  /**
   * Set the type of scale to use, linear or logarithmic.  The default
   * is linear.  If the scale is logarithmic, then the TableRange must not
   * cross the value zero.
   */
151
  void SetScale(int scale);
152 153
  void SetScaleToLinear() { this->SetScale(VTK_SCALE_LINEAR); }
  void SetScaleToLog10() { this->SetScale(VTK_SCALE_LOG10); }
154
  vtkGetMacro(Scale,int);
155 156 157 158 159 160 161 162
  //@}

  //@{
  /**
   * Set/Get the minimum/maximum scalar values for scalar mapping. Scalar
   * values less than minimum range value are clamped to minimum range value.
   * Scalar values greater than maximum range value are clamped to maximum
   * range value.
Will Schroeder's avatar
Will Schroeder committed
163

164 165
   * The \a TableRange values are only used when \a IndexedLookup is false.
   */
166
  virtual void SetTableRange(const double r[2]);
Ken Martin's avatar
Ken Martin committed
167 168
  virtual void SetTableRange(double min, double max);
  vtkGetVectorMacro(TableRange,double,2);
169
  //@}
170

171 172 173 174 175
  //@{
  /**
   * Set the range in hue (using automatic generation). Hue ranges
   * between [0,1].
   */
Ken Martin's avatar
Ken Martin committed
176 177
  vtkSetVector2Macro(HueRange,double);
  vtkGetVector2Macro(HueRange,double);
178
  //@}
179

180 181 182 183 184
  //@{
  /**
   * Set the range in saturation (using automatic generation). Saturation
   * ranges between [0,1].
   */
Ken Martin's avatar
Ken Martin committed
185 186
  vtkSetVector2Macro(SaturationRange,double);
  vtkGetVector2Macro(SaturationRange,double);
187
  //@}
188

189 190 191 192 193
  //@{
  /**
   * Set the range in value (using automatic generation). Value ranges
   * between [0,1].
   */
Ken Martin's avatar
Ken Martin committed
194 195
  vtkSetVector2Macro(ValueRange,double);
  vtkGetVector2Macro(ValueRange,double);
196
  //@}
197

198 199 200 201 202
  //@{
  /**
   * Set the range in alpha (using automatic generation). Alpha ranges from
   * [0,1].
   */
Ken Martin's avatar
Ken Martin committed
203 204
  vtkSetVector2Macro(AlphaRange,double);
  vtkGetVector2Macro(AlphaRange,double);
205
  //@}
Will Schroeder's avatar
Will Schroeder committed
206

207 208 209 210 211
  //@{
  /**
   * Set the color to use when a NaN (not a number) is encountered.  This is an
   * RGBA 4-tuple of doubles in the range [0,1].
   */
212 213
  vtkSetVector4Macro(NanColor, double);
  vtkGetVector4Macro(NanColor, double);
214
  //@}
215

216 217 218 219
  /**
   * Return the \a NanColor as a pointer to 4 unsigned chars. This
   * will overwrite any data returned by previous calls to MapValue.
   */
220 221
  unsigned char* GetNanColorAsUnsignedChars();

222
  /**
223
   * Given an RGBA[4] color in the [0,1] range, convert it to RGBA[4] in the [0,255] range.
224
   */
225 226 227
  static void GetColorAsUnsignedChars(const double colorIn[4],
                                      unsigned char colorOut[4]);

228 229 230 231 232
  //@{
  /**
   * Set the color to use when a value below the range is
   * encountered. This is an RGBA 4-tuple of doubles in the range [0, 1].
   */
233 234
  vtkSetVector4Macro(BelowRangeColor, double);
  vtkGetVector4Macro(BelowRangeColor, double);
235
  //@}
236

237 238 239 240
  //@{
  /**
   * Set whether the below range color should be used.
   */
241 242 243
  vtkSetMacro(UseBelowRangeColor, int);
  vtkGetMacro(UseBelowRangeColor, int);
  vtkBooleanMacro(UseBelowRangeColor, int);
244
  //@}
245

246 247 248 249 250
  //@{
  /**
   * Set the color to use when a value above the range is
   * encountered. This is an RGBA 4-tuple of doubles in the range [0, 1].
   */
251 252
  vtkSetVector4Macro(AboveRangeColor, double);
  vtkGetVector4Macro(AboveRangeColor, double);
253
  //@}
254

255 256
  //@{
  /**
257
   * Set whether the above range color should be used.
258
   */
259 260 261
  vtkSetMacro(UseAboveRangeColor, int);
  vtkGetMacro(UseAboveRangeColor, int);
  vtkBooleanMacro(UseAboveRangeColor, int);
262
  //@}
263

264
  /**
265
   * Map one value through the lookup table, returning an RBGA[4] color.
266
   */
267
  const unsigned char* MapValue(double v) override;
268

269 270
  /**
   * Map one value through the lookup table and return the color as
271
   * an RGB[3] array of doubles between 0 and 1. Note lack of alpha.
272
   */
273
  void GetColor(double x, double rgb[3]) override;
274

275 276 277 278
  /**
   * Map one value through the lookup table and return the alpha value
   * (the opacity) as a double between 0 and 1.
   */
279
  double GetOpacity(double v) override;
280

281 282
  /**
   * Return the table index associated with a particular value.
283
   * Returns -1 if \a v is NaN.
284 285 286 287 288 289

   * Do not use this function when \a IndexedLookup is true:
   * in that case, the set of values \a v may take on is exactly the integers
   * from 0 to \a GetNumberOfTableValues() - 1;
   * and \a v serves directly as an index into \a TableValues.
   */
Ken Martin's avatar
Ken Martin committed
290
  virtual vtkIdType GetIndex(double v);
291

292 293
  //@{
  /**
294
   * Specify the number of values (i.e., colors) in the lookup table.
295
   */
296
  void SetNumberOfTableValues(vtkIdType number);
297
  vtkIdType GetNumberOfTableValues() { return this->NumberOfColors; }
298 299 300 301 302 303 304 305
  //@}

  /**
   * Directly load color into lookup table. Use [0,1] double values for color
   * component specification. Make sure that you've either used the
   * Build() method or used SetNumberOfTableValues() prior to using this
   * method.
   */
306
  virtual void SetTableValue(vtkIdType indx, const double rgba[4]);
307

308 309
  /**
   * Directly load color into lookup table. Use [0,1] double values for color
310
   * component specification. Alpha defaults to 1 if unspecified.
311
   */
312 313
  virtual void SetTableValue(vtkIdType indx,
                              double r, double g, double b, double a=1.0);
314

315
  /**
316
   * Return an RGBA color value for the given index into the lookup table. Color
317 318
   * components are expressed as [0,1] double values.
   */
Ben Boeckel's avatar
Ben Boeckel committed
319
  double *GetTableValue(vtkIdType id) VTK_SIZEHINT(4);
320

321
  /**
322
   * Return an RGBA color value for the given index into the lookup table. Color
323 324
   * components are expressed as [0,1] double values.
   */
Ken Martin's avatar
Ken Martin committed
325
  void GetTableValue(vtkIdType id, double rgba[4]);
326

327 328
  /**
   * Get pointer to color table data. Format is array of unsigned char
329
   * R-G-B-A...R-G-B-A.
330
   */
331 332
  unsigned char *GetPointer(vtkIdType id) {
    return this->Table->GetPointer(4*id); }
333

334 335 336 337 338 339 340 341 342 343
  /**
   * Get pointer to data. Useful for direct writes into object. MaxId is bumped
   * by number (and memory allocated if necessary). Id is the location you
   * wish to write into; number is the number of rgba values to write.

   * \warning If you modify the table data via the pointer returned by this
   * member function, you must call vtkLookupTable::BuildSpecialColors()
   * afterwards to ensure that the special colors (below/above range and NaN
   * value) are up-to-date.
   */
344
  unsigned char *WritePointer(vtkIdType id, int number);
Ken Martin's avatar
Ken Martin committed
345

346 347 348 349 350
  //@{
  /**
   * Sets/Gets the range of scalars which will be mapped.  This is a duplicate
   * of Get/SetTableRange.
   */
Ben Boeckel's avatar
Ben Boeckel committed
351
  double *GetRange() VTK_SIZEHINT(2) override
352
    { return this->GetTableRange(); }
353
  void SetRange(double min, double max) override
354 355
    { this->SetTableRange(min, max); }
  void SetRange(const double rng[2]) override { this->SetRange(rng[0], rng[1]); }
356 357 358 359 360 361 362 363
  //@}

  /**
   * Returns the log of \c range in \c log_range.
   * There is a little more to this than simply taking the log10 of the
   * two range values: we do conversion of negative ranges to positive
   * ranges, and conversion of zero to a 'very small number'.
   */
364 365
  static void GetLogRange(const double range[2], double log_range[2]);

366 367 368
  /**
   * Apply log to value, with appropriate constraints.
   */
369 370 371
  static double ApplyLogScale(double v, const double range[2],
    const double log_range[2]);

372 373 374 375 376 377 378
  //@{
  /**
   * Set the number of colors in the lookup table.  Use
   * SetNumberOfTableValues() instead, it can be used both before and
   * after the table has been built whereas SetNumberOfColors() has no
   * effect after the table has been built.
   */
379
  vtkSetClampMacro(NumberOfColors,vtkIdType,2,VTK_ID_MAX);
380
  vtkGetMacro(NumberOfColors,vtkIdType);
381 382 383 384 385 386 387 388
  //@}

  //@{
  /**
   * Set/Get the internal table array that is used to map the scalars
   * to colors.  The table array is an unsigned char array with 4
   * components representing RGBA.
   */
Mathieu Malaterre's avatar
Mathieu Malaterre committed
389 390
  void SetTable(vtkUnsignedCharArray *);
  vtkGetObjectMacro(Table,vtkUnsignedCharArray);
391
  //@}
392

393
  /**
394
   * Map a set of scalars through the lookup table.
395 396 397

   * This member function is thread safe.
   */
398 399 400 401 402
  void MapScalarsThroughTable2(void *input,
                               unsigned char *output,
                               int inputDataType,
                               int numberOfValues,
                               int inputIncrement,
403
                               int outputIncrement) override;
Ken Martin's avatar
Ken Martin committed
404

405
  /**
406
   * Copy the contents from another LookupTable.
407
   */
408
  void DeepCopy(vtkScalarsToColors *lut) override;
409

410
  /**
411
   * This should return 1 if the subclass is using log scale for mapping scalars
412 413
   * to colors. Returns 1 is scale == VTK_SCALE_LOG10.
   */
414
  int UsingLogScale() override
415
  {
416
    return (this->GetScale() == VTK_SCALE_LOG10) ? 1 : 0;
417
  }
418

419 420 421
  /**
   * Get the number of available colors for mapping to.
   */
422
  vtkIdType GetNumberOfAvailableColors() override;
423

424 425 426 427 428 429 430
  /**
   * Return a color given an integer index.

   * This is used to assign colors to annotations (given an offset into the
   * list of annotations).
   * If the table is empty or \a idx < 0, then NanColor is returned.
   */
431
  void GetIndexedColor(vtkIdType idx, double rgba[4]) override;
432

Ken Martin's avatar
Ken Martin committed
433
protected:
434
  vtkLookupTable(int sze=256, int ext=256);
435
  ~vtkLookupTable() override;
436

437
  vtkIdType NumberOfColors;
438
  vtkUnsignedCharArray *Table;
Ken Martin's avatar
Ken Martin committed
439 440 441 442 443
  double TableRange[2];
  double HueRange[2];
  double SaturationRange[2];
  double ValueRange[2];
  double AlphaRange[2];
444
  double NanColor[4];
445 446 447 448 449
  double BelowRangeColor[4];
  int    UseBelowRangeColor;
  double AboveRangeColor[4];
  int    UseAboveRangeColor;

450 451
  int Scale;
  int Ramp;
Ken Martin's avatar
Ken Martin committed
452 453
  vtkTimeStamp InsertTime;
  vtkTimeStamp BuildTime;
Ken Martin's avatar
Ken Martin committed
454
  double RGBA[4]; //used during conversion process
455
  unsigned char NanColorChar[4];
456

457 458
  int OpaqueFlag;
  vtkTimeStamp OpaqueFlagBuildTime;
459
  vtkTimeStamp SpecialColorsBuildTime;
460

461 462 463
  /**
   * Resize the LookupTable to have enough room for the out-of-range colors
   */
464
  void ResizeTableForSpecialColors();
465

466
private:
467 468
  vtkLookupTable(const vtkLookupTable&) = delete;
  void operator=(const vtkLookupTable&) = delete;
Ken Martin's avatar
Ken Martin committed
469 470
};

471
//----------------------------------------------------------------------------
472 473
inline unsigned char *vtkLookupTable::WritePointer(vtkIdType id,
                                                   int number)
Will Schroeder's avatar
Will Schroeder committed
474
{
475
  this->InsertTime.Modified();
476
  return this->Table->WritePointer(4*id, 4*number);
Will Schroeder's avatar
Will Schroeder committed
477 478
}

Ken Martin's avatar
Ken Martin committed
479
#endif