vtkVolumeProperty.cxx 16 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkVolumeProperty.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.
Ken Martin's avatar
Ken Martin 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.
Ken Martin's avatar
Ken Martin committed
13 14

=========================================================================*/
15
#include "vtkVolumeProperty.h"
Andy Cedilnik's avatar
Andy Cedilnik committed
16

17
#include "vtkObjectFactory.h"
Andy Cedilnik's avatar
Andy Cedilnik committed
18 19
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
20

Lisa Avila's avatar
Lisa Avila committed
21
vtkCxxRevisionMacro(vtkVolumeProperty, "1.40");
Brad King's avatar
Brad King committed
22
vtkStandardNewMacro(vtkVolumeProperty);
23 24 25 26

// Construct a new vtkVolumeProperty with default values
vtkVolumeProperty::vtkVolumeProperty()
{
Sebastien Barre's avatar
ENH:  
Sebastien Barre committed
27 28
  this->IndependentComponents = 1;

29
  this->InterpolationType               = VTK_NEAREST_INTERPOLATION;
30

31
  for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
32 33
    {
    this->ColorChannels[i]                   = 1;
34

35 36 37
    this->GrayTransferFunction[i]            = NULL;
    this->RGBTransferFunction[i]             = NULL;
    this->ScalarOpacity[i]                   = NULL;
38
    this->ScalarOpacityUnitDistance[i]       = 1.0;
39
    this->GradientOpacity[i]                 = NULL;
40 41
    this->DefaultGradientOpacity[i]          = NULL;
    this->DisableGradientOpacity[i]          = 0;
42
    
43
    this->ComponentWeight[i]                 = 1.0;
Sebastien Barre's avatar
Sebastien Barre committed
44

45 46 47 48 49 50
    this->Shade[i]                           = 0;  
    this->Ambient[i]                         = 0.1;
    this->Diffuse[i]                         = 0.7;
    this->Specular[i]                        = 0.2;
    this->SpecularPower[i]                   = 10.0;
    }
51 52 53 54 55
}

// Destruct a vtkVolumeProperty
vtkVolumeProperty::~vtkVolumeProperty()
{
56
  for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
Charles Law's avatar
Charles Law committed
57
    {
58 59 60 61
    if (this->GrayTransferFunction[i] != NULL)
      {
      this->GrayTransferFunction[i]->UnRegister(this);
      }
62

63 64 65 66
    if (this->RGBTransferFunction[i] != NULL)
      {
      this->RGBTransferFunction[i]->UnRegister(this);
      }
67

68 69 70 71
    if (this->ScalarOpacity[i] != NULL)
      {
      this->ScalarOpacity[i]->UnRegister(this);
      }
72

73 74 75 76
    if (this->GradientOpacity[i] != NULL)
      {
      this->GradientOpacity[i]->UnRegister(this);
      }
77 78 79 80 81

    if (this->DefaultGradientOpacity[i] != NULL)
      {
      this->DefaultGradientOpacity[i]->UnRegister(this);
      }
Charles Law's avatar
Charles Law committed
82
    }
83 84
}

85 86 87
void vtkVolumeProperty::UpdateMTimes() 
{
  this->Modified();
88

89
  for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
90 91 92 93 94 95
    {
    this->GrayTransferFunctionMTime[i].Modified();
    this->RGBTransferFunctionMTime[i].Modified();
    this->ScalarOpacityMTime[i].Modified();
    this->GradientOpacityMTime[i].Modified();
    }
96
}
97 98 99 100 101

unsigned long int vtkVolumeProperty::GetMTime()
{
  unsigned long mTime=this->vtkObject::GetMTime();
  unsigned long time;
102
  
103
  for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
104
    {
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
    // Color MTimes
    if (this->ColorChannels[i] == 1)
      {
      if (this->GrayTransferFunction[i])
        {
        // time that Gray transfer function pointer was set
        time = this->GrayTransferFunctionMTime[i];
        mTime = (mTime > time ? mTime : time);
        
        // time that Gray transfer function was last modified
        time = this->GrayTransferFunction[i]->GetMTime();
        mTime = (mTime > time ? mTime : time);
        }
      }
    else if (this->ColorChannels[i] == 3)
120
      {
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
      if (this->RGBTransferFunction[i])
        {
        // time that RGB transfer function pointer was set
        time = this->RGBTransferFunctionMTime[i];
        mTime = (mTime > time ? mTime : time);
        
        // time that RGB transfer function was last modified
        time = this->RGBTransferFunction[i]->GetMTime();
        mTime = (mTime > time ? mTime : time);
        }
      }
    
    // Opacity MTimes
    if (this->ScalarOpacity[i])
      {
      // time that Scalar opacity transfer function pointer was set
      time = this->ScalarOpacityMTime[i];
138
      mTime = (mTime > time ? mTime : time);
139 140 141
      
      // time that Scalar opacity transfer function was last modified
      time = this->ScalarOpacity[i]->GetMTime();
142 143
      mTime = (mTime > time ? mTime : time);
      }
144 145

    if (this->GradientOpacity[i])
146
      {
147 148
      // time that Gradient opacity transfer function pointer was set
      time = this->GradientOpacityMTime[i];
149
      mTime = (mTime > time ? mTime : time);
150 151 152 153 154 155 156

      if (!this->DisableGradientOpacity[i])
        {
        // time that Gradient opacity transfer function was last modified
        time = this->GradientOpacity[i]->GetMTime();
        mTime = (mTime > time ? mTime : time);
        }
157 158
      }
    }
159 160 161
  
  return mTime;
}
162

163 164 165
int vtkVolumeProperty::GetColorChannels( int index )
{
  if ( index < 0 || index > 3 )
166
    {
167 168
    vtkErrorMacro("Bad index - must be between 0 and 3");
    return 0;
169
    }
170 171
  
  return this->ColorChannels[index];
172 173 174
}


175
// Set the color of a volume to a gray transfer function
176
void vtkVolumeProperty::SetColor( int index, vtkPiecewiseFunction *function )
177
{
178
  if (this->GrayTransferFunction[index] != function )
179
    {
180
    if (this->GrayTransferFunction[index] != NULL) 
Charles Law's avatar
Charles Law committed
181
      {
182
      this->GrayTransferFunction[index]->UnRegister(this);
Charles Law's avatar
Charles Law committed
183
      }
184 185
    this->GrayTransferFunction[index]  = function;
    if (this->GrayTransferFunction[index] != NULL) 
Charles Law's avatar
Charles Law committed
186
      {
187
      this->GrayTransferFunction[index]->Register(this);
Charles Law's avatar
Charles Law committed
188 189
      }

190
    this->GrayTransferFunctionMTime[index].Modified();
191 192
    this->Modified();
    }
193

194
  if (this->ColorChannels[index] != 1 )
195
    {
196
    this->ColorChannels[index]         = 1;
197 198
    this->Modified();
    }
199 200
}

201
// Get the currently set gray transfer function. Create one if none set.
202
vtkPiecewiseFunction *vtkVolumeProperty::GetGrayTransferFunction( int index )
203
{
204
  if (this->GrayTransferFunction[index] == NULL )
205
    {
206 207 208 209 210
    this->GrayTransferFunction[index] = vtkPiecewiseFunction::New();
    this->GrayTransferFunction[index]->Register(this);
    this->GrayTransferFunction[index]->Delete();
    this->GrayTransferFunction[index]->AddPoint(    0, 0.0 );
    this->GrayTransferFunction[index]->AddPoint( 1024, 1.0 );
211 212
    }

213
  return this->GrayTransferFunction[index];
214 215
}

216
// Set the color of a volume to an RGB transfer function
217
void vtkVolumeProperty::SetColor( int index, vtkColorTransferFunction *function )
218
{
219
  if (this->RGBTransferFunction[index] != function )
220
    {
221
    if (this->RGBTransferFunction[index] != NULL) 
Charles Law's avatar
Charles Law committed
222
      {
223
      this->RGBTransferFunction[index]->UnRegister(this);
Charles Law's avatar
Charles Law committed
224
      }
225 226
    this->RGBTransferFunction[index]   = function;
    if (this->RGBTransferFunction[index] != NULL) 
Charles Law's avatar
Charles Law committed
227
      {
228
      this->RGBTransferFunction[index]->Register(this);
Charles Law's avatar
Charles Law committed
229
      }
230
    this->RGBTransferFunctionMTime[index].Modified();
231 232
    this->Modified();
    }
233

234
  if (this->ColorChannels[index] != 3 )
235
    {
236
    this->ColorChannels[index]         = 3;
237 238
    this->Modified();
    }
239 240
}

241
// Get the currently set RGB transfer function. Create one if none set.
242
vtkColorTransferFunction *vtkVolumeProperty::GetRGBTransferFunction( int index )
243
{
244
  if (this->RGBTransferFunction[index] == NULL )
245
    {
246 247 248 249 250
    this->RGBTransferFunction[index] = vtkColorTransferFunction::New();
    this->RGBTransferFunction[index]->Register(this);
    this->RGBTransferFunction[index]->Delete();
    this->RGBTransferFunction[index]->AddRGBPoint(      0, 0.0, 0.0, 0.0 );
    this->RGBTransferFunction[index]->AddRGBPoint(   1024, 1.0, 1.0, 1.0 );
251 252
    }

253
  return this->RGBTransferFunction[index];
254 255
}

256
// Set the scalar opacity of a volume to a transfer function
257
void vtkVolumeProperty::SetScalarOpacity( int index, vtkPiecewiseFunction *function )
258
{
259
  if ( this->ScalarOpacity[index] != function )
260
    {
261
    if (this->ScalarOpacity[index] != NULL) 
Charles Law's avatar
Charles Law committed
262
      {
263
      this->ScalarOpacity[index]->UnRegister(this);
Charles Law's avatar
Charles Law committed
264
      }
265 266
    this->ScalarOpacity[index] = function;
    if (this->ScalarOpacity[index] != NULL) 
Charles Law's avatar
Charles Law committed
267
      {
268
      this->ScalarOpacity[index]->Register(this);
Charles Law's avatar
Charles Law committed
269
      }
270

271
    this->ScalarOpacityMTime[index].Modified();
272 273
    this->Modified();
    }
274 275
}

276
// Get the scalar opacity transfer function. Create one if none set.
277
vtkPiecewiseFunction *vtkVolumeProperty::GetScalarOpacity( int index )
278
{
279
  if( this->ScalarOpacity[index] == NULL )
280
    {
281 282 283 284 285
    this->ScalarOpacity[index] = vtkPiecewiseFunction::New();
    this->ScalarOpacity[index]->Register(this);
    this->ScalarOpacity[index]->Delete();
    this->ScalarOpacity[index]->AddPoint(    0, 1.0 );
    this->ScalarOpacity[index]->AddPoint( 1024, 1.0 );
286 287
    }

288
  return this->ScalarOpacity[index];
289 290
}

Lisa Avila's avatar
Lisa Avila committed
291
void vtkVolumeProperty::SetScalarOpacityUnitDistance( int index, double distance )
292 293 294 295 296 297 298 299 300 301 302 303 304 305
{
  if ( index < 0 || index > 3 )
    {
    vtkErrorMacro("Bad index - must be between 0 and 3");
    return;
    }

  if ( this->ScalarOpacityUnitDistance[index] != distance )
    {
    this->ScalarOpacityUnitDistance[index] = distance;
    this->Modified();
    }
}

Lisa Avila's avatar
Lisa Avila committed
306
double vtkVolumeProperty::GetScalarOpacityUnitDistance( int index )
307 308 309 310 311 312 313 314 315 316 317
{
  if ( index < 0 || index > 3 )
    {
    vtkErrorMacro("Bad index - must be between 0 and 3");
    return 0;
    }

  return  this->ScalarOpacityUnitDistance[index];
}

  
318
// Set the gradient opacity transfer function 
319
void vtkVolumeProperty::SetGradientOpacity( int index, vtkPiecewiseFunction *function )
320
{
321
  if ( this->GradientOpacity[index] != function )
322
    {
323
    if (this->GradientOpacity[index] != NULL) 
Charles Law's avatar
Charles Law committed
324
      {
325
      this->GradientOpacity[index]->UnRegister(this);
Charles Law's avatar
Charles Law committed
326
      }
327 328
    this->GradientOpacity[index]       = function;
    if (this->GradientOpacity[index] != NULL) 
Charles Law's avatar
Charles Law committed
329
      {
330
      this->GradientOpacity[index]->Register(this);
Charles Law's avatar
Charles Law committed
331 332
      }
    
333
    this->GradientOpacityMTime[index].Modified();
334 335 336 337
    this->Modified();
    }
}

338 339 340 341 342 343 344 345 346 347 348 349 350 351
void vtkVolumeProperty::CreateDefaultGradientOpacity( int index )
{
  if ( this->DefaultGradientOpacity[index] == NULL )
    {
    this->DefaultGradientOpacity[index] = vtkPiecewiseFunction::New();
    this->DefaultGradientOpacity[index]->Register(this);
    this->DefaultGradientOpacity[index]->Delete();
    }

  this->DefaultGradientOpacity[index]->RemoveAllPoints();
  this->DefaultGradientOpacity[index]->AddPoint(   0, 1.0 );
  this->DefaultGradientOpacity[index]->AddPoint( 255, 1.0 );
}

352
vtkPiecewiseFunction *vtkVolumeProperty::GetGradientOpacity( int index )
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
{
  if (this->DisableGradientOpacity[index])
    {
    if ( this->DefaultGradientOpacity[index] == NULL )
      {
      this->CreateDefaultGradientOpacity(index);
      }
    return this->DefaultGradientOpacity[index];
    }

  return this->GetStoredGradientOpacity(index);
}

// Get the gradient opacity transfer function. Create one if none set.
vtkPiecewiseFunction *vtkVolumeProperty::GetStoredGradientOpacity( int index )
368
{
369
  if ( this->GradientOpacity[index] == NULL )
370
    {
371 372 373 374 375
    this->GradientOpacity[index] = vtkPiecewiseFunction::New();
    this->GradientOpacity[index]->Register(this);
    this->GradientOpacity[index]->Delete();
    this->GradientOpacity[index]->AddPoint(   0, 1.0 );
    this->GradientOpacity[index]->AddPoint( 255, 1.0 );
376 377
    }

378
  return this->GradientOpacity[index];
379 380
}

381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
void vtkVolumeProperty::SetDisableGradientOpacity( int index, int value )
{
  if (this->DisableGradientOpacity[index] == value)
    {
    return;
    }

  this->DisableGradientOpacity[index] = value;

  // Make sure the default function is up-to-date (since the user
  // could have modified the default function)

  if (value)
    {
    this->CreateDefaultGradientOpacity(index);
    }

  // Since this Ivar basically "sets" the gradient opacity function to be
  // either a default one or the user-specified one, update the MTime
  // accordingly

  this->GradientOpacityMTime[index].Modified();

  this->Modified();
}

int vtkVolumeProperty::GetDisableGradientOpacity( int index )
{
  return this->DisableGradientOpacity[index];
}

Lisa Avila's avatar
Lisa Avila committed
412
void vtkVolumeProperty::SetComponentWeight(int index, double value)
Sebastien Barre's avatar
Sebastien Barre committed
413 414 415 416 417 418 419
{
  if (index < 0 || index >= VTK_MAX_VRCOMP)
    {
    vtkErrorMacro("Invalid index");
    return;
    }

420
  if (this->ComponentWeight[index] == value)
Sebastien Barre's avatar
Sebastien Barre committed
421 422 423 424
    {
    return;
    }

425 426
  this->ComponentWeight[index] = value;
  this->Modified();
Sebastien Barre's avatar
Sebastien Barre committed
427 428
}

Lisa Avila's avatar
Lisa Avila committed
429
double vtkVolumeProperty::GetComponentWeight(int index)
Sebastien Barre's avatar
Sebastien Barre committed
430 431 432 433 434 435 436 437 438 439
{
  if (index < 0 || index >= VTK_MAX_VRCOMP)
    {
    vtkErrorMacro("Invalid index");
    return 0.0;
    }
  
  return this->ComponentWeight[index];
}

440
void vtkVolumeProperty::SetShade( int index, int value )
441
{
442 443 444 445 446 447 448 449 450 451 452 453
  if ( value != 0 && value != 1 )
    {
    vtkErrorMacro("SetShade accepts values 0 or 1");
    return;
    }
  
  if ( this->Shade[index] != value )
    {
    this->Shade[index] = value;
    this->Modified();
    }
}
454

455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
void vtkVolumeProperty::ShadeOn( int index )
{
  this->SetShade( index, 1 );
}


void vtkVolumeProperty::ShadeOff( int index )
{
  this->SetShade( index, 0 );
}


int vtkVolumeProperty::GetShade( int index )
{
  return this->Shade[index];
}

Lisa Avila's avatar
Lisa Avila committed
472
void vtkVolumeProperty::SetAmbient( int index, double value )
473 474 475 476 477 478 479
{
  if ( this->Ambient[index] != value )
    {
    this->Ambient[index] = value;
    this->Modified();
    }
}
480

Lisa Avila's avatar
Lisa Avila committed
481
double vtkVolumeProperty::GetAmbient( int index )
482 483 484
{
  return this->Ambient[index];
}
485

Lisa Avila's avatar
Lisa Avila committed
486
void vtkVolumeProperty::SetDiffuse( int index, double value )
487 488
{
  if ( this->Diffuse[index] != value )
489
    {
490 491
    this->Diffuse[index] = value;
    this->Modified();
492
    }
493 494
}

Lisa Avila's avatar
Lisa Avila committed
495
double vtkVolumeProperty::GetDiffuse( int index )
496 497 498 499
{
  return this->Diffuse[index];
}

Lisa Avila's avatar
Lisa Avila committed
500
void vtkVolumeProperty::SetSpecular( int index, double value )
501 502
{
  if ( this->Specular[index] != value )
503
    {
504 505
    this->Specular[index] = value;
    this->Modified();
506
    }
507
}
508

Lisa Avila's avatar
Lisa Avila committed
509
double vtkVolumeProperty::GetSpecular( int index )
510 511 512
{
  return this->Specular[index];
}
513

Lisa Avila's avatar
Lisa Avila committed
514
void vtkVolumeProperty::SetSpecularPower( int index, double value )
515 516 517 518 519 520 521
{
  if ( this->SpecularPower[index] != value )
    {
    this->SpecularPower[index] = value;
    this->Modified();
    }
}
522

Lisa Avila's avatar
Lisa Avila committed
523
double vtkVolumeProperty::GetSpecularPower( int index )
524 525 526
{
  return this->SpecularPower[index];
}
527

528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
vtkTimeStamp vtkVolumeProperty::GetScalarOpacityMTime( int index )
{
  return this->ScalarOpacityMTime[index];
}

vtkTimeStamp vtkVolumeProperty::GetGradientOpacityMTime( int index )
{
  return this->GradientOpacityMTime[index];
}

vtkTimeStamp vtkVolumeProperty::GetRGBTransferFunctionMTime( int index )
{
  return this->RGBTransferFunctionMTime[index];
}

vtkTimeStamp vtkVolumeProperty::GetGrayTransferFunctionMTime( int index )
{
  return this->GrayTransferFunctionMTime[index];
}

// Print the state of the volume property.
void vtkVolumeProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
552

Sebastien Barre's avatar
ENH:  
Sebastien Barre committed
553 554 555
  os << indent << "Independent Components: " << 
    (this->IndependentComponents ? "On\n" : "Off\n");
  
556 557 558
  os << indent << "Interpolation Type: "
     << this->GetInterpolationTypeAsString() << "\n";

559
  for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
    {
    os << indent << "Properties for material " << i << endl;
    
    os << indent << "Color Channels: " << this->ColorChannels[i] << "\n";

    if( this->ColorChannels[i] == 1 )
      {
      os << indent << "Gray Color Transfer Function: "
         << this->GrayTransferFunction[i] << "\n";
      }
    else if( this->ColorChannels[i] == 3 )
      {
      os << indent << "RGB Color Transfer Function: "
         << this->RGBTransferFunction[i] << "\n";
      }
    
    os << indent << "Scalar Opacity Transfer Function: "
       << this->ScalarOpacity[i] << "\n";
    
    os << indent << "Gradient Opacity Transfer Function: "
       << this->GradientOpacity[i] << "\n";
581 582 583 584

    os << indent << "DisableGradientOpacity: "
       << (this->DisableGradientOpacity[i] ? "On" : "Off") << "\n";

585
    
Sebastien Barre's avatar
Sebastien Barre committed
586 587 588
    os << indent << "ComponentWeight: " 
       << this->ComponentWeight[i] << "\n";

589 590 591 592 593 594 595
    os << indent << "Shade: " << this->Shade[i] << "\n";
    os << indent << indent << "Ambient: " << this->Ambient[i] << "\n";
    os << indent << indent << "Diffuse: " << this->Diffuse[i] << "\n";
    os << indent << indent << "Specular: " << this->Specular[i] << "\n";
    os << indent << indent << "SpecularPower: " << this->SpecularPower[i] << "\n";
    }
  
596 597 598 599 600 601
  // These variables should not be printed to the user:
  // this->GradientOpacityMTime
  // this->GrayTransferFunctionMTime
  // this->RGBTransferFunctionMTime
  // this->ScalarOpacityMTime

602 603
}