vtkMapper.cxx 25.3 KB
Newer Older
Will Schroeder's avatar
Will Schroeder committed
1
2
/*=========================================================================

Ken Martin's avatar
Ken Martin committed
3
  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkMapper.cxx
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

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkMapper.h"
16

17
18
19
#include "vtkAbstractArray.h"
#include "vtkColorSeries.h"
#include "vtkDataArray.h"
20
#include "vtkDataSet.h"
21
#include "vtkDoubleArray.h"
Ken Martin's avatar
Ken Martin committed
22
#include "vtkExecutive.h"
Ken Martin's avatar
Ken Martin committed
23
#include "vtkLookupTable.h"
Charles Law's avatar
Charles Law committed
24
25
26
#include "vtkFloatArray.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
Ken Martin's avatar
Ken Martin committed
27
#include "vtkMath.h"
28
#include "vtkVariantArray.h"
Will Schroeder's avatar
Will Schroeder committed
29

Brad King's avatar
Brad King committed
30

Ken Martin's avatar
Ken Martin committed
31
32
33
// Initialize static member that controls global immediate mode rendering
static int vtkMapperGlobalImmediateModeRendering = 0;

34
35
36
// Initialize static member that controls global coincidence resolution
static int vtkMapperGlobalResolveCoincidentTopology = VTK_RESOLVE_OFF;
static double vtkMapperGlobalResolveCoincidentTopologyZShift = 0.01;
Ken Martin's avatar
Ken Martin committed
37
38
static double vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor = 1.0;
static double vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits = 1.0;
39
static int vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces = 1;
40

41
// Construct with initial range (0,1).
Ken Martin's avatar
Ken Martin committed
42
vtkMapper::vtkMapper()
43
{
Charles Law's avatar
Charles Law committed
44
  this->Colors = 0;
45
  this->Static = 0;
Charles Law's avatar
Charles Law committed
46
  this->LookupTable = 0;
Will Schroeder's avatar
Will Schroeder committed
47

Will Schroeder's avatar
Will Schroeder committed
48
  this->ScalarVisibility = 1;
49
  this->ScalarRange[0] = 0.0; this->ScalarRange[1] = 1.0;
50
  this->UseLookupTableScalarRange = 0;
Will Schroeder's avatar
Will Schroeder committed
51

LYMB Demo's avatar
LYMB Demo committed
52
  this->ImmediateModeRendering = 0;
53
54

  this->ColorMode = VTK_COLOR_MODE_DEFAULT;
55
  this->ScalarMode = VTK_SCALAR_MODE_DEFAULT;
56
  this->ScalarMaterialMode = VTK_MATERIALMODE_DEFAULT;
57

Ken Martin's avatar
Ken Martin committed
58
  vtkMath::UninitializeBounds(this->Bounds);
59
  this->Center[0] = this->Center[1] = this->Center[2] = 0.0;
60

61
  this->RenderTime = 0.0;
62

63
64
  strcpy(this->ArrayName, "");
  this->ArrayId = -1;
65
66
  this->ArrayComponent = 0;
  this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID;
Charles Law's avatar
Charles Law committed
67

Cory Quammen's avatar
Cory Quammen committed
68
69
  this->FieldDataTupleId = -1;

Charles Law's avatar
Charles Law committed
70
71
72
  this->InterpolateScalarsBeforeMapping = 0;
  this->ColorCoordinates = 0;
  this->ColorTextureMap = 0;
73
74

  this->ForceCompileOnly=0;
75
76
}

Ken Martin's avatar
Ken Martin committed
77
vtkMapper::~vtkMapper()
Will Schroeder's avatar
Will Schroeder committed
78
{
Ken Martin's avatar
Ken Martin committed
79
80
81
82
  if (this->LookupTable)
    {
    this->LookupTable->UnRegister(this);
    }
Charles Law's avatar
Charles Law committed
83
  if ( this->Colors != 0 )
Bill Lorensen's avatar
Bill Lorensen committed
84
    {
Charles Law's avatar
Charles Law committed
85
    this->Colors->UnRegister(this);
Bill Lorensen's avatar
Bill Lorensen committed
86
    }
Charles Law's avatar
Charles Law committed
87
88
89
90
91
92
93
94
  if ( this->ColorCoordinates != 0 )
    {
    this->ColorCoordinates->UnRegister(this);
    }
  if ( this->ColorTextureMap != 0 )
    {
    this->ColorTextureMap->UnRegister(this);
    }
Will Schroeder's avatar
Will Schroeder committed
95
96
}

97
// Get the bounds for the input of this mapper as
98
// (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
Ken Martin's avatar
Ken Martin committed
99
double *vtkMapper::GetBounds()
100
{
101
  vtkDataSet *input = this->GetInput();
102
  if ( ! input )
103
    {
104
      vtkMath::UninitializeBounds(this->Bounds);
105
106
107
    }
  else
    {
108
109
110
111
112
    if (!this->Static)
      {
      this->Update();
      }
    input->GetBounds(this->Bounds);
113
    }
114
  return this->Bounds;
115
116
}

117
vtkDataSet *vtkMapper::GetInput()
118
{
Ken Martin's avatar
Ken Martin committed
119
  if (this->GetNumberOfInputConnections(0) < 1)
120
    {
Ken Martin's avatar
Ken Martin committed
121
    return 0;
122
    }
Ken Martin's avatar
Ken Martin committed
123
124
  return vtkDataSet::SafeDownCast(
    this->GetExecutive()->GetInputData(0, 0));
125
126
}

127
128
129
130
131
132
133
134
135
136
void vtkMapper::SetForceCompileOnly(int value)
{
  if(this->ForceCompileOnly!=value)
    {
      this->ForceCompileOnly=value;
      // make sure we don't call this->Modified();
      //      this->Modified();
    }
}

Ken Martin's avatar
Ken Martin committed
137
138
void vtkMapper::SetGlobalImmediateModeRendering(int val)
{
Bill Lorensen's avatar
Bill Lorensen committed
139
140
141
142
  if (val == vtkMapperGlobalImmediateModeRendering)
    {
    return;
    }
Ken Martin's avatar
Ken Martin committed
143
144
145
146
147
148
149
150
  vtkMapperGlobalImmediateModeRendering = val;
}

int vtkMapper::GetGlobalImmediateModeRendering()
{
  return vtkMapperGlobalImmediateModeRendering;
}

151
void vtkMapper::SetResolveCoincidentTopology(int val)
152
{
153
  if (val == vtkMapperGlobalResolveCoincidentTopology)
154
155
156
    {
    return;
    }
157
158
159
160
161
162
  vtkMapperGlobalResolveCoincidentTopology = val;
}

int vtkMapper::GetResolveCoincidentTopology()
{
  return vtkMapperGlobalResolveCoincidentTopology;
163
164
}

165
void vtkMapper::SetResolveCoincidentTopologyToDefault()
166
{
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  vtkMapperGlobalResolveCoincidentTopology = VTK_RESOLVE_OFF;
}

void vtkMapper::SetResolveCoincidentTopologyZShift(double val)
{
  if (val == vtkMapperGlobalResolveCoincidentTopologyZShift)
    {
    return;
    }
  vtkMapperGlobalResolveCoincidentTopologyZShift = val;
}

double vtkMapper::GetResolveCoincidentTopologyZShift()
{
  return vtkMapperGlobalResolveCoincidentTopologyZShift;
182
183
}

184
void vtkMapper::SetResolveCoincidentTopologyPolygonOffsetParameters(
Ken Martin's avatar
Ken Martin committed
185
                                            double factor, double units)
186
187
188
189
190
191
192
{
  if (factor == vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor &&
      units == vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits )
    {
    return;
    }
  vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor = factor;
193
  vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits = units;
194
195
196
}

void vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(
Ken Martin's avatar
Ken Martin committed
197
                           double& factor, double& units)
198
199
200
201
202
{
  factor = vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFactor;
  units = vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetUnits;
}

203
204
205
206
207
208
209
210
211
212
void vtkMapper::SetResolveCoincidentTopologyPolygonOffsetFaces(int faces)
{
  vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces = faces;
}

int vtkMapper::GetResolveCoincidentTopologyPolygonOffsetFaces()
{
  return vtkMapperGlobalResolveCoincidentTopologyPolygonOffsetFaces;
}

Will Schroeder's avatar
Will Schroeder committed
213
// Overload standard modified time function. If lookup table is modified,
214
// then this object is modified as well.
Ken Martin's avatar
Ken Martin committed
215
unsigned long vtkMapper::GetMTime()
Will Schroeder's avatar
Will Schroeder committed
216
{
217
218
  //unsigned long mTime=this->MTime.GetMTime();
  unsigned long mTime=vtkAbstractMapper::GetMTime();
Will Schroeder's avatar
Will Schroeder committed
219
220
221
222
223
224
225
226
227
228
229
  unsigned long lutMTime;

  if ( this->LookupTable != NULL )
    {
    lutMTime = this->LookupTable->GetMTime();
    mTime = ( lutMTime > mTime ? lutMTime : mTime );
    }

  return mTime;
}

230
231
232
233
234
235
236
237
238
239
void vtkMapper::ShallowCopy(vtkAbstractMapper *mapper)
{
  vtkMapper *m = vtkMapper::SafeDownCast(mapper);
  if ( m != NULL )
    {
    this->SetLookupTable(m->GetLookupTable());
    this->SetScalarVisibility(m->GetScalarVisibility());
    this->SetScalarRange(m->GetScalarRange());
    this->SetColorMode(m->GetColorMode());
    this->SetScalarMode(m->GetScalarMode());
240
    this->SetScalarMaterialMode(m->GetScalarMaterialMode());
241
242
    this->SetImmediateModeRendering(m->GetImmediateModeRendering());
    this->SetUseLookupTableScalarRange(m->GetUseLookupTableScalarRange());
243
244
245
    this->SetInterpolateScalarsBeforeMapping(
      m->GetInterpolateScalarsBeforeMapping());

246
247
248
249
250
251
252
253
    if ( m->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID )
      {
      this->ColorByArrayComponent(m->GetArrayId(),m->GetArrayComponent());
      }
    else
      {
      this->ColorByArrayComponent(m->GetArrayName(),m->GetArrayComponent());
      }
254
255
256
257
258
    }

  // Now do superclass
  this->vtkAbstractMapper3D::ShallowCopy(mapper);

Will Schroeder's avatar
Will Schroeder committed
259
260
}

261
262
// a side effect of this is that this->Colors is also set
// to the return value
Ken Martin's avatar
Ken Martin committed
263
vtkUnsignedCharArray *vtkMapper::MapScalars(double alpha)
264
265
266
267
268
269
270
271
272
{
  vtkDataSet *input = this->GetInput();
  return this->MapScalars(input,alpha);
}

// a side effect of this is that this->Colors is also set
// to the return value
vtkUnsignedCharArray *vtkMapper::MapScalars(vtkDataSet *input,
                                            double alpha)
273
{
Charles Law's avatar
Charles Law committed
274
  int cellFlag = 0;
275

276
  vtkAbstractArray *scalars = vtkAbstractMapper::
277
    GetAbstractScalars(input, this->ScalarMode, this->ArrayAccessMode,
278
                       this->ArrayId, this->ArrayName, cellFlag);
Charles Law's avatar
Charles Law committed
279
280
281
282
283
284
285
286
287

  // This is for a legacy feature: selection of the array component to color by
  // from the mapper.  It is now in the lookuptable.  When this feature
  // is removed, we can remove this condition.
  if (scalars == 0 || scalars->GetNumberOfComponents() <= this->ArrayComponent)
    {
    this->ArrayComponent = 0;
    }

288
  if ( !this->ScalarVisibility || scalars==0 || input==0)
Charles Law's avatar
Charles Law committed
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    { // No scalar colors.
    if ( this->ColorCoordinates )
      {
      this->ColorCoordinates->UnRegister(this);
      this->ColorCoordinates = 0;
      }
    if ( this->ColorTextureMap )
      {
      this->ColorTextureMap->UnRegister(this);
      this->ColorTextureMap = 0;
      }
    if ( this->Colors )
      {
      this->Colors->UnRegister(this);
      this->Colors = 0;
      }
    return 0;
    }

  // Get the lookup table.
309
310
  vtkDataArray *dataArray = vtkDataArray::SafeDownCast(scalars);
  if (dataArray && dataArray->GetLookupTable())
Charles Law's avatar
Charles Law committed
311
    {
312
    this->SetLookupTable(dataArray->GetLookupTable());
Charles Law's avatar
Charles Law committed
313
314
315
316
317
318
319
320
321
322
    }
  else
    {
    // make sure we have a lookup table
    if ( this->LookupTable == 0 )
      {
      this->CreateDefaultLookupTable();
      }
    this->LookupTable->Build();
    }
323

Charles Law's avatar
Charles Law committed
324
325
326
327
328
329
330
331
332
333
334
335
  if ( !this->UseLookupTableScalarRange )
    {
    this->LookupTable->SetRange(this->ScalarRange);
    }

  // Decide betweeen texture color or vertex color.
  // Cell data always uses vertext color.
  // Only point data can use both texture and vertext coloring.
  if (this->InterpolateScalarsBeforeMapping && ! cellFlag)
    {
    // Only use texture color if we are mapping scalars.
    // Directly coloring with RGB unsigned chars should not use texture.
336
    if (dataArray && (this->ColorMode != VTK_COLOR_MODE_DEFAULT ||
337
338
          (vtkUnsignedCharArray::SafeDownCast(scalars)) == 0) &&
         this->ColorMode != VTK_COLOR_MODE_DIRECT_SCALARS)
Charles Law's avatar
Charles Law committed
339
      { // Texture color option.
340
      this->MapScalarsToTexture(dataArray, alpha);
Charles Law's avatar
Charles Law committed
341
342
343
      return 0;
      }
    }
344

Charles Law's avatar
Charles Law committed
345
  // Vertex colors are being used.
346
347
  // Get rid of texure Color arrays.  Only texture or vertex coloring
  // can be active at one time.  The existence of the array is the
Charles Law's avatar
Charles Law committed
348
349
350
351
352
353
354
355
356
357
358
359
  // signal to use that technique.
  if ( this->ColorCoordinates )
    {
    this->ColorCoordinates->UnRegister(this);
    this->ColorCoordinates = 0;
    }
  if ( this->ColorTextureMap )
    {
    this->ColorTextureMap->UnRegister(this);
    this->ColorTextureMap = 0;
    }

Charles Law's avatar
Charles Law committed
360
  // Lets try to resuse the old colors.
Charles Law's avatar
Charles Law committed
361
  if (this->Colors)
Charles Law's avatar
Charles Law committed
362
    {
Charles Law's avatar
Charles Law committed
363
    if (this->LookupTable && this->LookupTable->GetAlpha() == alpha)
Charles Law's avatar
Charles Law committed
364
      {
Charles Law's avatar
Charles Law committed
365
      if (this->GetMTime() < this->Colors->GetMTime() &&
366
          input->GetMTime() < this->Colors->GetMTime() &&
Charles Law's avatar
Charles Law committed
367
          this->LookupTable->GetMTime() < this->Colors->GetMTime())
Charles Law's avatar
Charles Law committed
368
369
370
        {
        return this->Colors;
        }
Charles Law's avatar
Charles Law committed
371
372
      }
    }
373

374
375
  // Get rid of old colors
  if ( this->Colors )
Ken Martin's avatar
Ken Martin committed
376
    {
377
    this->Colors->UnRegister(this);
Charles Law's avatar
Charles Law committed
378
    this->Colors = 0;
Ken Martin's avatar
Ken Martin committed
379
    }
380

Charles Law's avatar
Charles Law committed
381
  // map scalars
382
  double orig_alpha = this->LookupTable->GetAlpha();
383
  this->LookupTable->SetAlpha(alpha);
Charles Law's avatar
Charles Law committed
384
385
  this->Colors = this->LookupTable->
    MapScalars(scalars, this->ColorMode, this->ArrayComponent);
386
  this->LookupTable->SetAlpha(orig_alpha);
Charles Law's avatar
Charles Law committed
387
388
389
  // Consistent register and unregisters
  this->Colors->Register(this);
  this->Colors->Delete();
Ken Martin's avatar
Ken Martin committed
390

391
  return this->Colors;
Will Schroeder's avatar
Will Schroeder committed
392
}
Will Schroeder's avatar
Will Schroeder committed
393

394
395
396
397
398

void vtkMapper::SelectColorArray(int arrayNum)
{
  this->ColorByArrayComponent(arrayNum, -1);
}
399

400
401
402
403
404
405
406

void vtkMapper::SelectColorArray(const char* arrayName)
{
  this->ColorByArrayComponent(arrayName, -1);
}


407
408
void vtkMapper::ColorByArrayComponent(int arrayNum, int component)
{
Charles Law's avatar
Charles Law committed
409
410
411
412
413
414
  if (this->ArrayId == arrayNum && component == this->ArrayComponent &&
      this->ArrayAccessMode == VTK_GET_ARRAY_BY_ID)
    {
    return;
    }
  this->Modified();
415

416
417
418
419
420
  this->ArrayId = arrayNum;
  this->ArrayComponent = component;
  this->ArrayAccessMode = VTK_GET_ARRAY_BY_ID;
}

421
void vtkMapper::ColorByArrayComponent(const char* arrayName, int component)
422
{
423
  if (!arrayName ||
424
425
      ( strcmp(this->ArrayName, arrayName) == 0 &&
        component == this->ArrayComponent &&
426
        this->ArrayAccessMode == VTK_GET_ARRAY_BY_NAME ))
Charles Law's avatar
Charles Law committed
427
428
429
430
    {
    return;
    }
  this->Modified();
431

432
433
434
435
436
  strcpy(this->ArrayName, arrayName);
  this->ArrayComponent = component;
  this->ArrayAccessMode = VTK_GET_ARRAY_BY_NAME;
}

Will Schroeder's avatar
Will Schroeder committed
437
// Specify a lookup table for the mapper to use.
Ken Martin's avatar
Ken Martin committed
438
void vtkMapper::SetLookupTable(vtkScalarsToColors *lut)
Will Schroeder's avatar
Will Schroeder committed
439
{
440
  if ( this->LookupTable != lut )
Will Schroeder's avatar
Will Schroeder committed
441
    {
442
    if ( this->LookupTable)
Ken Martin's avatar
Ken Martin committed
443
444
445
      {
      this->LookupTable->UnRegister(this);
      }
Will Schroeder's avatar
Will Schroeder committed
446
    this->LookupTable = lut;
Ken Martin's avatar
Ken Martin committed
447
448
449
450
    if (lut)
      {
      lut->Register(this);
      }
Will Schroeder's avatar
Will Schroeder committed
451
452
453
454
    this->Modified();
    }
}

Ken Martin's avatar
Ken Martin committed
455
vtkScalarsToColors *vtkMapper::GetLookupTable()
456
{
Charles Law's avatar
Charles Law committed
457
  if ( this->LookupTable == 0 )
Bill Lorensen's avatar
Bill Lorensen committed
458
459
460
    {
    this->CreateDefaultLookupTable();
    }
461
462
463
  return this->LookupTable;
}

Ken Martin's avatar
Ken Martin committed
464
void vtkMapper::CreateDefaultLookupTable()
Will Schroeder's avatar
Will Schroeder committed
465
{
466
  if ( this->LookupTable)
Ken Martin's avatar
Ken Martin committed
467
468
469
    {
    this->LookupTable->UnRegister(this);
    }
470
471
  vtkLookupTable* table = vtkLookupTable::New();
  this->LookupTable = table;
Charles Law's avatar
Charles Law committed
472
473
  this->LookupTable->Register(this);
  this->LookupTable->Delete();
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

  int cellFlag = 0; // not used
  vtkAbstractArray* abstractArray = vtkAbstractMapper::
    GetAbstractScalars(this->GetInput(), this->ScalarMode, this->ArrayAccessMode,
                       this->ArrayId, this->ArrayName, cellFlag);

  vtkDataArray *dataArray = vtkDataArray::SafeDownCast(abstractArray);
  if (abstractArray && !dataArray)
    {
    // Use indexed lookup for non-numeric arrays
    this->LookupTable->IndexedLookupOn();

    // Get prominent values from array and set them up as annotations in the color map.
    vtkVariantArray* prominentValues = vtkVariantArray::New();
    abstractArray->GetProminentComponentValues(0, prominentValues);
    vtkIdType numProminentValues = prominentValues->GetNumberOfValues();
    table->SetNumberOfTableValues(numProminentValues);
    for (vtkIdType i = 0; i < numProminentValues; ++i)
      {
      vtkVariant & variant = prominentValues->GetValue(i);
      this->LookupTable->SetAnnotation(variant, variant.ToString());
      }
    prominentValues->Delete();

    // Set colors for annotations
    vtkColorSeries* colorSeries = vtkColorSeries::New();
    colorSeries->SetColorScheme(vtkColorSeries::BREWER_QUALITATIVE_PAIRED);
    colorSeries->BuildLookupTable(table, vtkColorSeries::CATEGORICAL);
    colorSeries->Delete();
    }
Will Schroeder's avatar
Will Schroeder committed
504
}
Will Schroeder's avatar
Will Schroeder committed
505

506
// Return the method of coloring scalar data.
507
const char *vtkMapper::GetColorModeAsString(void)
Will Schroeder's avatar
Will Schroeder committed
508
{
509
  if ( this->ColorMode == VTK_COLOR_MODE_MAP_SCALARS )
Will Schroeder's avatar
Will Schroeder committed
510
    {
511
    return "MapScalars";
Will Schroeder's avatar
Will Schroeder committed
512
    }
513
  else
514
    {
515
    return "Default";
516
    }
517
}
518

519
// Return the method for obtaining scalar data.
Bill Lorensen's avatar
Bill Lorensen committed
520
const char *vtkMapper::GetScalarModeAsString(void)
521
522
523
524
525
{
  if ( this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA )
    {
    return "UseCellData";
    }
526
  else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_POINT_DATA )
527
528
529
    {
    return "UsePointData";
    }
530
531
532
533
534
535
536
537
  else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
    {
    return "UsePointFieldData";
    }
  else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA )
    {
    return "UseCellFieldData";
    }
Cory Quammen's avatar
Cory Quammen committed
538
539
540
541
  else if ( this->ScalarMode == VTK_SCALAR_MODE_USE_FIELD_DATA )
    {
    return "UseFieldData";
    }
542
  else
543
544
545
546
547
    {
    return "Default";
    }
}

548
549
const char *vtkMapper::GetScalarMaterialModeAsString(void)
{
Charles Law's avatar
Charles Law committed
550
  if ( this->ScalarMaterialMode == VTK_MATERIALMODE_AMBIENT )
551
552
553
    {
    return "Ambient";
    }
Charles Law's avatar
Charles Law committed
554
  else if ( this->ScalarMaterialMode == VTK_MATERIALMODE_DIFFUSE )
555
556
557
    {
    return "Diffuse";
    }
Charles Law's avatar
Charles Law committed
558
  else if ( this->ScalarMaterialMode == VTK_MATERIALMODE_AMBIENT_AND_DIFFUSE )
559
560
561
562
563
564
565
566
567
    {
    return "Ambient and Diffuse";
    }
  else
    {
    return "Default";
    }
}

568
569
570
// anonymous namespace
namespace {

571
572
//-----------------------------------------------------------------------------
template<class T>
573
574
575
576
577
578
void ScalarToTextureCoordinate(
                               T scalar_value,         // Input scalar
                               double range_min,       // range[0]
                               double inv_range_width, // 1/(range[1]-range[0])
                               float &tex_coord_s,     // 1st tex coord
                               float &tex_coord_t)     // 2nd tex coord
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
{
  if (vtkMath::IsNan(scalar_value))
    {
    tex_coord_s = 0.5;  // Scalar value is arbitrary when NaN
    tex_coord_t = 1.0;  // 1.0 in t coordinate means NaN
    }
  else
    {
    // 0.0 in t coordinate means not NaN.  So why am I setting it to 0.49?
    // Because when you are mapping scalars and you have a NaN adjacent to
    // anything else, the interpolation everywhere should be NaN.  Thus, I
    // want the NaN color everywhere except right on the non-NaN neighbors.
    // To simulate this, I set the t coord for the real numbers close to
    // the threshold so that the interpolation almost immediately looks up
    // the NaN value.
    tex_coord_t = 0.49;

    double ranged_scalar = (scalar_value - range_min) * inv_range_width;
597
598
599
600
601
602
603
604
605
606
607
    tex_coord_s = static_cast<float>(ranged_scalar);
    }

    // Some implementations apparently don't handle relatively large
    // numbers (compared to the range [0.0, 1.0]) very well. In fact,
    // values above 1122.0f appear to cause texture wrap-around on
    // some systems even when edge clamping is enabled. Why 1122.0f? I
    // don't know. For safety, we'll clamp at +/- 1000. This will
    // result in incorrect images when the texture value should be
    // above or below 1000, but I don't have a better solution.
    if (tex_coord_s > 1000.0f)
608
      {
609
      tex_coord_s = 1000.0f;
610
      }
611
    else if (tex_coord_s < -1000.0f)
612
      {
613
      tex_coord_s = -1000.0f;
614
615
      }
}
Charles Law's avatar
Charles Law committed
616

617
//-----------------------------------------------------------------------------
Charles Law's avatar
Charles Law committed
618
template<class T>
619
620
621
622
void CreateColorTextureCoordinates(T* input, float* output,
                                   vtkIdType numScalars, int numComps,
                                   int component, double* range,
                                   const double* table_range,
623
                                   int tableNumberOfColors,
624
                                   bool use_log_scale)
Charles Law's avatar
Charles Law committed
625
{
626
627
628
629
630
631
632
633
634
  // We have to change the range used for computing texture
  // coordinates slightly to accomodate the special above- and
  // below-range colors that are the first and last texels,
  // respectively.
  double scalar_texel_width = (range[1] - range[0]) / static_cast<double>(tableNumberOfColors);
  double padded_range[2];
  padded_range[0] = range[0] - scalar_texel_width;
  padded_range[1] = range[1] + scalar_texel_width;
  double inv_range_width = 1.0 / (padded_range[1] - padded_range[0]);
Charles Law's avatar
Charles Law committed
635
636
637

  if (component < 0 || component >= numComps)
    {
638
    for (vtkIdType scalarIdx = 0; scalarIdx < numScalars; ++scalarIdx)
Charles Law's avatar
Charles Law committed
639
      {
640
641
      double sum = 0;
      for (int compIdx = 0; compIdx < numComps; ++compIdx)
Charles Law's avatar
Charles Law committed
642
        {
643
        double tmp = static_cast<double>(*input);
Charles Law's avatar
Charles Law committed
644
645
646
        sum += (tmp * tmp);
        ++input;
        }
647
648
      double magnitude = sqrt(sum);
      if (use_log_scale)
Charles Law's avatar
Charles Law committed
649
        {
650
651
        magnitude = vtkLookupTable::ApplyLogScale(
          magnitude, table_range, range);
Charles Law's avatar
Charles Law committed
652
        }
653
      ScalarToTextureCoordinate(magnitude, padded_range[0], inv_range_width,
654
                                output[0], output[1]);
655
      output += 2;
Charles Law's avatar
Charles Law committed
656
      }
657
    }
Charles Law's avatar
Charles Law committed
658
659
660
  else
    {
    input += component;
661
    for (vtkIdType scalarIdx = 0; scalarIdx < numScalars; ++scalarIdx)
Charles Law's avatar
Charles Law committed
662
      {
663
664
      double input_value = static_cast<double>(*input);
      if (use_log_scale)
Charles Law's avatar
Charles Law committed
665
        {
666
667
        input_value = vtkLookupTable::ApplyLogScale(
          input_value, table_range, range);
Charles Law's avatar
Charles Law committed
668
        }
669
      ScalarToTextureCoordinate(input_value, padded_range[0], inv_range_width,
670
                                output[0], output[1]);
671
      output += 2;
Charles Law's avatar
Charles Law committed
672
      input = input + numComps;
673
      }
Charles Law's avatar
Charles Law committed
674
675
676
    }
}

677
} // end anonymous namespace
Charles Law's avatar
Charles Law committed
678

679
// a side effect of this is that this->ColorCoordinates and
Charles Law's avatar
Charles Law committed
680
// this->ColorTexture are set.
681
void vtkMapper::MapScalarsToTexture(vtkDataArray* scalars, double alpha)
Charles Law's avatar
Charles Law committed
682
{
683
684
685
686
687
688
689
690
691
692
  double range[2];
  range[0] = this->LookupTable->GetRange()[0];
  range[1] = this->LookupTable->GetRange()[1];
  bool use_log_scale = (this->LookupTable->UsingLogScale() != 0);
  if (use_log_scale)
    {
    // convert range to log.
    vtkLookupTable::GetLogRange(range, range);
    }

693
  double orig_alpha = this->LookupTable->GetAlpha();
694
695
696

  // Get rid of vertex color array.  Only texture or vertex coloring
  // can be active at one time.  The existence of the array is the
Charles Law's avatar
Charles Law committed
697
698
699
700
701
702
703
704
705
  // signal to use that technique.
  if ( this->Colors )
    {
    this->Colors->UnRegister(this);
    this->Colors = 0;
    }

  // If the lookup table has changed, the recreate the color texture map.
  // Set a new lookup table changes this->MTime.
706
  if (this->ColorTextureMap == 0 ||
Charles Law's avatar
Charles Law committed
707
      this->GetMTime() > this->ColorTextureMap->GetMTime() ||
708
709
      this->LookupTable->GetMTime() > this->ColorTextureMap->GetMTime() ||
      this->LookupTable->GetAlpha() != alpha)
Charles Law's avatar
Charles Law committed
710
    {
711
    this->LookupTable->SetAlpha(alpha);
Charles Law's avatar
Charles Law committed
712
713
714
715
716
717
718
719
    if ( this->ColorTextureMap )
      {
      this->ColorTextureMap->UnRegister(this);
      this->ColorTextureMap = 0;
      }
    // Get the texture map from the lookup table.
    // Create a dummy ramp of scalars.
    // In the future, we could extend vtkScalarsToColors.
720
721
722
723
724
725
726
    vtkIdType numberOfColors = this->LookupTable->GetNumberOfAvailableColors();
    numberOfColors += 2;
    double k = (range[1]-range[0]) / (numberOfColors-1-2);
    vtkDoubleArray* tmp = vtkDoubleArray::New();
    tmp->SetNumberOfTuples(numberOfColors*2);
    double* ptr = tmp->GetPointer(0);
    for (int i = 0; i < numberOfColors; ++i)
Charles Law's avatar
Charles Law committed
727
      {
728
729
730
731
732
      *ptr = range[0] + i * k - k; // minus k to start at below range color
      if (use_log_scale)
        {
        *ptr = pow(10.0, *ptr);
        }
Charles Law's avatar
Charles Law committed
733
734
      ++ptr;
      }
735
736
    // Dimension on NaN.
    double nan = vtkMath::Nan();
737
    for (int i = 0; i < numberOfColors; ++i)
738
739
740
741
      {
      *ptr = nan;
      ++ptr;
      }
Charles Law's avatar
Charles Law committed
742
    this->ColorTextureMap = vtkImageData::New();
743
    this->ColorTextureMap->SetExtent(0,numberOfColors-1,
744
                                     0,1, 0,0);
Charles Law's avatar
Charles Law committed
745
746
    this->ColorTextureMap->GetPointData()->SetScalars(
         this->LookupTable->MapScalars(tmp, this->ColorMode, 0));
747
    this->LookupTable->SetAlpha(orig_alpha);
Charles Law's avatar
Charles Law committed
748
749
750
751
752
753
754
755
756
757
758
    // Do we need to delete the scalars?
    this->ColorTextureMap->GetPointData()->GetScalars()->Delete();
    // Consistent register and unregisters
    this->ColorTextureMap->Register(this);
    this->ColorTextureMap->Delete();
    tmp->Delete();
    }

  // Create new coordinates if necessary.
  // Need to compare lookup table incase the range has changed.
  if (this->ColorCoordinates == 0 ||
759
      this->GetMTime() > this->ColorCoordinates->GetMTime() ||
760
761
      this->GetExecutive()->GetInputData(0, 0)->GetMTime() >
      this->ColorCoordinates->GetMTime() ||
Charles Law's avatar
Charles Law committed
762
763
764
765
766
767
768
769
      this->LookupTable->GetMTime() > this->ColorCoordinates->GetMTime())
    {
    // Get rid of old colors
    if ( this->ColorCoordinates )
      {
      this->ColorCoordinates->UnRegister(this);
      this->ColorCoordinates = 0;
      }
770

Charles Law's avatar
Charles Law committed
771
772
773
774
775
    // Now create the color texture coordinates.
    int numComps = scalars->GetNumberOfComponents();
    void* input = scalars->GetVoidPointer(0);
    vtkIdType num = scalars->GetNumberOfTuples();
    this->ColorCoordinates = vtkFloatArray::New();
776
    this->ColorCoordinates->SetNumberOfComponents(2);
Charles Law's avatar
Charles Law committed
777
778
779
    this->ColorCoordinates->SetNumberOfTuples(num);
    float* output = this->ColorCoordinates->GetPointer(0);
    int scalarComponent;
780
781
782
783
    // Although I like the feature of applying magnitude to single component
    // scalars, it is not how the old MapScalars for vertex coloring works.
    if (this->LookupTable->GetVectorMode() == vtkScalarsToColors::MAGNITUDE &&
        scalars->GetNumberOfComponents() > 1)
Charles Law's avatar
Charles Law committed
784
785
786
787
788
789
790
791
792
      {
      scalarComponent = -1;
      }
    else
      {
      scalarComponent = this->LookupTable->GetVectorComponent();
      }
    switch (scalars->GetDataType())
      {
793
      vtkTemplateMacro(
794
        CreateColorTextureCoordinates(static_cast<VTK_TT*>(input),
795
796
797
798
799
          output, num, numComps,
          scalarComponent, range,
          this->LookupTable->GetRange(),
          this->LookupTable->GetNumberOfAvailableColors(),
          use_log_scale)
800
        );
Charles Law's avatar
Charles Law committed
801
802
803
804
805
806
807
808
809
810
      case VTK_BIT:
        vtkErrorMacro("Cannot color by bit array.");
        break;
      default:
        vtkErrorMacro(<< "Unknown input ScalarType");
        return;
      }
    }
}

811
void vtkMapper::PrintSelf(ostream& os, vtkIndent indent)
812
{
Brad King's avatar
Brad King committed
813
  this->Superclass::PrintSelf(os,indent);
814

815
816
817
818
819
820
821
822
823
  if ( this->LookupTable )
    {
    os << indent << "Lookup Table:\n";
    this->LookupTable->PrintSelf(os,indent.GetNextIndent());
    }
  else
    {
    os << indent << "Lookup Table: (none)\n";
    }
824

825
  os << indent << "Immediate Mode Rendering: "
LYMB Demo's avatar
LYMB Demo committed
826
    << (this->ImmediateModeRendering ? "On\n" : "Off\n");
827

828
   os << indent << "Force compile only for display lists: "
829
830
    << (this->ForceCompileOnly ? "On\n" : "Off\n");

831
  os << indent << "Global Immediate Mode Rendering: " <<
Ken Martin's avatar
Ken Martin committed
832
    (vtkMapperGlobalImmediateModeRendering ? "On\n" : "Off\n");
833

834
  os << indent << "Scalar Visibility: "
Will Schroeder's avatar
Will Schroeder committed
835
    << (this->ScalarVisibility ? "On\n" : "Off\n");
836

837
  os << indent << "Static: "
838
839
    << (this->Static ? "On\n" : "Off\n");

Ken Martin's avatar
Ken Martin committed
840
  double *range = this->GetScalarRange();
841
  os << indent << "Scalar Range: (" << range[0] << ", " << range[1] << ")\n";
842

843
  os << indent << "UseLookupTableScalarRange: "
844
     << this->UseLookupTableScalarRange << "\n";
845

846
  os << indent << "Color Mode: " << this->GetColorModeAsString() << endl;
847
  os << indent << "InterpolateScalarsBeforeMapping: "
Charles Law's avatar
Charles Law committed
848
     << (this->InterpolateScalarsBeforeMapping ? "On\n" : "Off\n");
849

850
  os << indent << "Scalar Mode: " << this->GetScalarModeAsString() << endl;
851

852
  os << indent << "LM Color Mode: "
853
854
     << this->GetScalarMaterialModeAsString() << endl;

855
  os << indent << "RenderTime: " << this->RenderTime << endl;
856

857
858
859
860
861
862
863
864
865
  os << indent << "Resolve Coincident Topology: ";
  if ( vtkMapperGlobalResolveCoincidentTopology == VTK_RESOLVE_OFF )
    {
    os << "Off" << endl;
    }
  else if ( vtkMapperGlobalResolveCoincidentTopology == VTK_RESOLVE_POLYGON_OFFSET )
    {
    os << "Polygon Offset" << endl;
    }
866
  else
867
868
869
    {
    os << "Shift Z-Buffer" << endl;
    }
Will Schroeder's avatar
Will Schroeder committed
870
}