1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkVolumeProperty.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkVolumeProperty.h"
16
17 #include "vtkObjectFactory.h"
18 #include "vtkPiecewiseFunction.h"
19 #include "vtkColorTransferFunction.h"
20
21 vtkStandardNewMacro(vtkVolumeProperty);
22
23 // Construct a new vtkVolumeProperty with default values
vtkVolumeProperty()24 vtkVolumeProperty::vtkVolumeProperty()
25 {
26 this->IndependentComponents = 1;
27
28 this->InterpolationType = VTK_NEAREST_INTERPOLATION;
29
30 for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
31 {
32 this->ColorChannels[i] = 1;
33
34 this->GrayTransferFunction[i] = NULL;
35 this->RGBTransferFunction[i] = NULL;
36 this->ScalarOpacity[i] = NULL;
37 this->ScalarOpacityUnitDistance[i] = 1.0;
38 this->GradientOpacity[i] = NULL;
39 this->DefaultGradientOpacity[i] = NULL;
40 this->DisableGradientOpacity[i] = 0;
41
42 this->ComponentWeight[i] = 1.0;
43
44 this->Shade[i] = 0;
45 this->Ambient[i] = 0.1;
46 this->Diffuse[i] = 0.7;
47 this->Specular[i] = 0.2;
48 this->SpecularPower[i] = 10.0;
49 }
50 }
51
52 // Destruct a vtkVolumeProperty
~vtkVolumeProperty()53 vtkVolumeProperty::~vtkVolumeProperty()
54 {
55 for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
56 {
57 if (this->GrayTransferFunction[i] != NULL)
58 {
59 this->GrayTransferFunction[i]->UnRegister(this);
60 }
61
62 if (this->RGBTransferFunction[i] != NULL)
63 {
64 this->RGBTransferFunction[i]->UnRegister(this);
65 }
66
67 if (this->ScalarOpacity[i] != NULL)
68 {
69 this->ScalarOpacity[i]->UnRegister(this);
70 }
71
72 if (this->GradientOpacity[i] != NULL)
73 {
74 this->GradientOpacity[i]->UnRegister(this);
75 }
76
77 if (this->DefaultGradientOpacity[i] != NULL)
78 {
79 this->DefaultGradientOpacity[i]->UnRegister(this);
80 }
81 }
82 }
83
DeepCopy(vtkVolumeProperty * p)84 void vtkVolumeProperty::DeepCopy(vtkVolumeProperty *p)
85 {
86 if (!p)
87 {
88 return;
89 }
90
91 this->SetIndependentComponents(p->GetIndependentComponents());
92
93 this->SetInterpolationType(p->GetInterpolationType());
94
95 for (int i = 0; i < VTK_MAX_VRCOMP; i++)
96 {
97 this->SetComponentWeight(i, p->GetComponentWeight(i));
98
99 // Force ColorChannels to the right value and/or create a default tfunc
100 // then DeepCopy all the points
101
102 if (p->GetColorChannels(i) > 1)
103 {
104 this->SetColor(i, this->GetRGBTransferFunction(i));
105 this->GetRGBTransferFunction(i)->DeepCopy(
106 p->GetRGBTransferFunction(i));
107 }
108 else
109 {
110 this->SetColor(i, this->GetGrayTransferFunction(i));
111 this->GetGrayTransferFunction(i)->DeepCopy(
112 p->GetGrayTransferFunction(i));
113 }
114
115 this->GetScalarOpacity(i)->DeepCopy(p->GetScalarOpacity(i));
116
117 this->SetScalarOpacityUnitDistance(i, p->GetScalarOpacityUnitDistance(i));
118
119 this->GetGradientOpacity(i)->DeepCopy(p->GetGradientOpacity(i));
120
121 this->SetDisableGradientOpacity(i, p->GetDisableGradientOpacity(i));
122
123 this->SetShade(i, p->GetShade(i));
124 this->SetAmbient(i, p->GetAmbient(i));
125 this->SetDiffuse(i, p->GetDiffuse(i));
126 this->SetSpecular(i, p->GetSpecular(i));
127 this->SetSpecularPower(i, p->GetSpecularPower(i));
128 }
129
130 this->Modified();
131 }
132
UpdateMTimes()133 void vtkVolumeProperty::UpdateMTimes()
134 {
135 this->Modified();
136
137 for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
138 {
139 this->GrayTransferFunctionMTime[i].Modified();
140 this->RGBTransferFunctionMTime[i].Modified();
141 this->ScalarOpacityMTime[i].Modified();
142 this->GradientOpacityMTime[i].Modified();
143 }
144 }
145
GetMTime()146 unsigned long int vtkVolumeProperty::GetMTime()
147 {
148 unsigned long mTime=this->vtkObject::GetMTime();
149 unsigned long time;
150
151 for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
152 {
153 // Color MTimes
154 if (this->ColorChannels[i] == 1)
155 {
156 if (this->GrayTransferFunction[i])
157 {
158 // time that Gray transfer function pointer was set
159 time = this->GrayTransferFunctionMTime[i];
160 mTime = (mTime > time ? mTime : time);
161
162 // time that Gray transfer function was last modified
163 time = this->GrayTransferFunction[i]->GetMTime();
164 mTime = (mTime > time ? mTime : time);
165 }
166 }
167 else if (this->ColorChannels[i] == 3)
168 {
169 if (this->RGBTransferFunction[i])
170 {
171 // time that RGB transfer function pointer was set
172 time = this->RGBTransferFunctionMTime[i];
173 mTime = (mTime > time ? mTime : time);
174
175 // time that RGB transfer function was last modified
176 time = this->RGBTransferFunction[i]->GetMTime();
177 mTime = (mTime > time ? mTime : time);
178 }
179 }
180
181 // Opacity MTimes
182 if (this->ScalarOpacity[i])
183 {
184 // time that Scalar opacity transfer function pointer was set
185 time = this->ScalarOpacityMTime[i];
186 mTime = (mTime > time ? mTime : time);
187
188 // time that Scalar opacity transfer function was last modified
189 time = this->ScalarOpacity[i]->GetMTime();
190 mTime = (mTime > time ? mTime : time);
191 }
192
193 if (this->GradientOpacity[i])
194 {
195 // time that Gradient opacity transfer function pointer was set
196 time = this->GradientOpacityMTime[i];
197 mTime = (mTime > time ? mTime : time);
198
199 if (!this->DisableGradientOpacity[i])
200 {
201 // time that Gradient opacity transfer function was last modified
202 time = this->GradientOpacity[i]->GetMTime();
203 mTime = (mTime > time ? mTime : time);
204 }
205 }
206 }
207
208 return mTime;
209 }
210
GetColorChannels(int index)211 int vtkVolumeProperty::GetColorChannels( int index )
212 {
213 if ( index < 0 || index > 3 )
214 {
215 vtkErrorMacro("Bad index - must be between 0 and 3");
216 return 0;
217 }
218
219 return this->ColorChannels[index];
220 }
221
222
223 // Set the color of a volume to a gray transfer function
SetColor(int index,vtkPiecewiseFunction * function)224 void vtkVolumeProperty::SetColor( int index, vtkPiecewiseFunction *function )
225 {
226 if (this->GrayTransferFunction[index] != function )
227 {
228 if (this->GrayTransferFunction[index] != NULL)
229 {
230 this->GrayTransferFunction[index]->UnRegister(this);
231 }
232 this->GrayTransferFunction[index] = function;
233 if (this->GrayTransferFunction[index] != NULL)
234 {
235 this->GrayTransferFunction[index]->Register(this);
236 }
237
238 this->GrayTransferFunctionMTime[index].Modified();
239 this->Modified();
240 }
241
242 if (this->ColorChannels[index] != 1)
243 {
244 this->ColorChannels[index] = 1;
245 this->Modified();
246 }
247 }
248
249 // Get the currently set gray transfer function. Create one if none set.
GetGrayTransferFunction(int index)250 vtkPiecewiseFunction *vtkVolumeProperty::GetGrayTransferFunction( int index )
251 {
252 if (this->GrayTransferFunction[index] == NULL )
253 {
254 this->GrayTransferFunction[index] = vtkPiecewiseFunction::New();
255 this->GrayTransferFunction[index]->Register(this);
256 this->GrayTransferFunction[index]->Delete();
257 this->GrayTransferFunction[index]->AddPoint( 0, 0.0 );
258 this->GrayTransferFunction[index]->AddPoint( 1024, 1.0 );
259 if (this->ColorChannels[index] != 1)
260 {
261 this->ColorChannels[index] = 1;
262 }
263 this->Modified();
264 }
265
266 return this->GrayTransferFunction[index];
267 }
268
269 // Set the color of a volume to an RGB transfer function
SetColor(int index,vtkColorTransferFunction * function)270 void vtkVolumeProperty::SetColor( int index, vtkColorTransferFunction *function )
271 {
272 if (this->RGBTransferFunction[index] != function )
273 {
274 if (this->RGBTransferFunction[index] != NULL)
275 {
276 this->RGBTransferFunction[index]->UnRegister(this);
277 }
278 this->RGBTransferFunction[index] = function;
279 if (this->RGBTransferFunction[index] != NULL)
280 {
281 this->RGBTransferFunction[index]->Register(this);
282 }
283 this->RGBTransferFunctionMTime[index].Modified();
284 this->Modified();
285 }
286
287 if (this->ColorChannels[index] != 3)
288 {
289 this->ColorChannels[index] = 3;
290 this->Modified();
291 }
292 }
293
294 // Get the currently set RGB transfer function. Create one if none set.
GetRGBTransferFunction(int index)295 vtkColorTransferFunction *vtkVolumeProperty::GetRGBTransferFunction( int index )
296 {
297 if (this->RGBTransferFunction[index] == NULL )
298 {
299 this->RGBTransferFunction[index] = vtkColorTransferFunction::New();
300 this->RGBTransferFunction[index]->Register(this);
301 this->RGBTransferFunction[index]->Delete();
302 this->RGBTransferFunction[index]->AddRGBPoint( 0, 0.0, 0.0, 0.0 );
303 this->RGBTransferFunction[index]->AddRGBPoint( 1024, 1.0, 1.0, 1.0 );
304 if (this->ColorChannels[index] != 3)
305 {
306 this->ColorChannels[index] = 3;
307 }
308 this->Modified();
309 }
310
311 return this->RGBTransferFunction[index];
312 }
313
314 // Set the scalar opacity of a volume to a transfer function
SetScalarOpacity(int index,vtkPiecewiseFunction * function)315 void vtkVolumeProperty::SetScalarOpacity( int index, vtkPiecewiseFunction *function )
316 {
317 if ( this->ScalarOpacity[index] != function )
318 {
319 if (this->ScalarOpacity[index] != NULL)
320 {
321 this->ScalarOpacity[index]->UnRegister(this);
322 }
323 this->ScalarOpacity[index] = function;
324 if (this->ScalarOpacity[index] != NULL)
325 {
326 this->ScalarOpacity[index]->Register(this);
327 }
328
329 this->ScalarOpacityMTime[index].Modified();
330 this->Modified();
331 }
332 }
333
334 // Get the scalar opacity transfer function. Create one if none set.
GetScalarOpacity(int index)335 vtkPiecewiseFunction *vtkVolumeProperty::GetScalarOpacity( int index )
336 {
337 if( this->ScalarOpacity[index] == NULL )
338 {
339 this->ScalarOpacity[index] = vtkPiecewiseFunction::New();
340 this->ScalarOpacity[index]->Register(this);
341 this->ScalarOpacity[index]->Delete();
342 this->ScalarOpacity[index]->AddPoint( 0, 1.0 );
343 this->ScalarOpacity[index]->AddPoint( 1024, 1.0 );
344 }
345
346 return this->ScalarOpacity[index];
347 }
348
SetScalarOpacityUnitDistance(int index,double distance)349 void vtkVolumeProperty::SetScalarOpacityUnitDistance( int index, double distance )
350 {
351 if ( index < 0 || index > 3 )
352 {
353 vtkErrorMacro("Bad index - must be between 0 and 3");
354 return;
355 }
356
357 if ( this->ScalarOpacityUnitDistance[index] != distance )
358 {
359 this->ScalarOpacityUnitDistance[index] = distance;
360 this->Modified();
361 }
362 }
363
GetScalarOpacityUnitDistance(int index)364 double vtkVolumeProperty::GetScalarOpacityUnitDistance( int index )
365 {
366 if ( index < 0 || index > 3 )
367 {
368 vtkErrorMacro("Bad index - must be between 0 and 3");
369 return 0;
370 }
371
372 return this->ScalarOpacityUnitDistance[index];
373 }
374
375
376 // Set the gradient opacity transfer function
SetGradientOpacity(int index,vtkPiecewiseFunction * function)377 void vtkVolumeProperty::SetGradientOpacity( int index, vtkPiecewiseFunction *function )
378 {
379 if ( this->GradientOpacity[index] != function )
380 {
381 if (this->GradientOpacity[index] != NULL)
382 {
383 this->GradientOpacity[index]->UnRegister(this);
384 }
385 this->GradientOpacity[index] = function;
386 if (this->GradientOpacity[index] != NULL)
387 {
388 this->GradientOpacity[index]->Register(this);
389 }
390
391 this->GradientOpacityMTime[index].Modified();
392 this->Modified();
393 }
394 }
395
CreateDefaultGradientOpacity(int index)396 void vtkVolumeProperty::CreateDefaultGradientOpacity( int index )
397 {
398 if ( this->DefaultGradientOpacity[index] == NULL )
399 {
400 this->DefaultGradientOpacity[index] = vtkPiecewiseFunction::New();
401 this->DefaultGradientOpacity[index]->Register(this);
402 this->DefaultGradientOpacity[index]->Delete();
403 }
404
405 this->DefaultGradientOpacity[index]->RemoveAllPoints();
406 this->DefaultGradientOpacity[index]->AddPoint( 0, 1.0 );
407 this->DefaultGradientOpacity[index]->AddPoint( 255, 1.0 );
408 }
409
GetGradientOpacity(int index)410 vtkPiecewiseFunction *vtkVolumeProperty::GetGradientOpacity( int index )
411 {
412 if (this->DisableGradientOpacity[index])
413 {
414 if ( this->DefaultGradientOpacity[index] == NULL )
415 {
416 this->CreateDefaultGradientOpacity(index);
417 }
418 return this->DefaultGradientOpacity[index];
419 }
420
421 return this->GetStoredGradientOpacity(index);
422 }
423
424 // Get the gradient opacity transfer function. Create one if none set.
GetStoredGradientOpacity(int index)425 vtkPiecewiseFunction *vtkVolumeProperty::GetStoredGradientOpacity( int index )
426 {
427 if ( this->GradientOpacity[index] == NULL )
428 {
429 this->GradientOpacity[index] = vtkPiecewiseFunction::New();
430 this->GradientOpacity[index]->Register(this);
431 this->GradientOpacity[index]->Delete();
432 this->GradientOpacity[index]->AddPoint( 0, 1.0 );
433 this->GradientOpacity[index]->AddPoint( 255, 1.0 );
434 }
435
436 return this->GradientOpacity[index];
437 }
438
SetDisableGradientOpacity(int index,int value)439 void vtkVolumeProperty::SetDisableGradientOpacity( int index, int value )
440 {
441 if (this->DisableGradientOpacity[index] == value)
442 {
443 return;
444 }
445
446 this->DisableGradientOpacity[index] = value;
447
448 // Make sure the default function is up-to-date (since the user
449 // could have modified the default function)
450
451 if (value)
452 {
453 this->CreateDefaultGradientOpacity(index);
454 }
455
456 // Since this Ivar basically "sets" the gradient opacity function to be
457 // either a default one or the user-specified one, update the MTime
458 // accordingly
459
460 this->GradientOpacityMTime[index].Modified();
461
462 this->Modified();
463 }
464
GetDisableGradientOpacity(int index)465 int vtkVolumeProperty::GetDisableGradientOpacity( int index )
466 {
467 return this->DisableGradientOpacity[index];
468 }
469
SetComponentWeight(int index,double value)470 void vtkVolumeProperty::SetComponentWeight(int index, double value)
471 {
472 if (index < 0 || index >= VTK_MAX_VRCOMP)
473 {
474 vtkErrorMacro("Invalid index");
475 return;
476 }
477
478 if (this->ComponentWeight[index] == value)
479 {
480 return;
481 }
482
483 this->ComponentWeight[index] = value;
484 this->Modified();
485 }
486
GetComponentWeight(int index)487 double vtkVolumeProperty::GetComponentWeight(int index)
488 {
489 if (index < 0 || index >= VTK_MAX_VRCOMP)
490 {
491 vtkErrorMacro("Invalid index");
492 return 0.0;
493 }
494
495 return this->ComponentWeight[index];
496 }
497
SetShade(int index,int value)498 void vtkVolumeProperty::SetShade( int index, int value )
499 {
500 if ( value != 0 && value != 1 )
501 {
502 vtkErrorMacro("SetShade accepts values 0 or 1");
503 return;
504 }
505
506 if ( this->Shade[index] != value )
507 {
508 this->Shade[index] = value;
509 this->Modified();
510 }
511 }
512
ShadeOn(int index)513 void vtkVolumeProperty::ShadeOn( int index )
514 {
515 this->SetShade( index, 1 );
516 }
517
518
ShadeOff(int index)519 void vtkVolumeProperty::ShadeOff( int index )
520 {
521 this->SetShade( index, 0 );
522 }
523
524
GetShade(int index)525 int vtkVolumeProperty::GetShade( int index )
526 {
527 return this->Shade[index];
528 }
529
SetAmbient(int index,double value)530 void vtkVolumeProperty::SetAmbient( int index, double value )
531 {
532 if ( this->Ambient[index] != value )
533 {
534 this->Ambient[index] = value;
535 this->Modified();
536 }
537 }
538
GetAmbient(int index)539 double vtkVolumeProperty::GetAmbient( int index )
540 {
541 return this->Ambient[index];
542 }
543
SetDiffuse(int index,double value)544 void vtkVolumeProperty::SetDiffuse( int index, double value )
545 {
546 if ( this->Diffuse[index] != value )
547 {
548 this->Diffuse[index] = value;
549 this->Modified();
550 }
551 }
552
GetDiffuse(int index)553 double vtkVolumeProperty::GetDiffuse( int index )
554 {
555 return this->Diffuse[index];
556 }
557
SetSpecular(int index,double value)558 void vtkVolumeProperty::SetSpecular( int index, double value )
559 {
560 if ( this->Specular[index] != value )
561 {
562 this->Specular[index] = value;
563 this->Modified();
564 }
565 }
566
GetSpecular(int index)567 double vtkVolumeProperty::GetSpecular( int index )
568 {
569 return this->Specular[index];
570 }
571
SetSpecularPower(int index,double value)572 void vtkVolumeProperty::SetSpecularPower( int index, double value )
573 {
574 if ( this->SpecularPower[index] != value )
575 {
576 this->SpecularPower[index] = value;
577 this->Modified();
578 }
579 }
580
GetSpecularPower(int index)581 double vtkVolumeProperty::GetSpecularPower( int index )
582 {
583 return this->SpecularPower[index];
584 }
585
GetScalarOpacityMTime(int index)586 vtkTimeStamp vtkVolumeProperty::GetScalarOpacityMTime( int index )
587 {
588 return this->ScalarOpacityMTime[index];
589 }
590
GetGradientOpacityMTime(int index)591 vtkTimeStamp vtkVolumeProperty::GetGradientOpacityMTime( int index )
592 {
593 return this->GradientOpacityMTime[index];
594 }
595
GetRGBTransferFunctionMTime(int index)596 vtkTimeStamp vtkVolumeProperty::GetRGBTransferFunctionMTime( int index )
597 {
598 return this->RGBTransferFunctionMTime[index];
599 }
600
GetGrayTransferFunctionMTime(int index)601 vtkTimeStamp vtkVolumeProperty::GetGrayTransferFunctionMTime( int index )
602 {
603 return this->GrayTransferFunctionMTime[index];
604 }
605
606 // Print the state of the volume property.
PrintSelf(ostream & os,vtkIndent indent)607 void vtkVolumeProperty::PrintSelf(ostream& os, vtkIndent indent)
608 {
609 this->Superclass::PrintSelf(os,indent);
610
611 os << indent << "Independent Components: " <<
612 (this->IndependentComponents ? "On\n" : "Off\n");
613
614 os << indent << "Interpolation Type: "
615 << this->GetInterpolationTypeAsString() << "\n";
616
617 for ( int i = 0; i < VTK_MAX_VRCOMP; i++ )
618 {
619 os << indent << "Properties for material " << i << endl;
620
621 os << indent << "Color Channels: " << this->ColorChannels[i] << "\n";
622
623 if( this->ColorChannels[i] == 1 )
624 {
625 os << indent << "Gray Color Transfer Function: "
626 << this->GrayTransferFunction[i] << "\n";
627 }
628 else if( this->ColorChannels[i] == 3 )
629 {
630 os << indent << "RGB Color Transfer Function: "
631 << this->RGBTransferFunction[i] << "\n";
632 }
633
634 os << indent << "Scalar Opacity Transfer Function: "
635 << this->ScalarOpacity[i] << "\n";
636
637 os << indent << "Gradient Opacity Transfer Function: "
638 << this->GradientOpacity[i] << "\n";
639
640 os << indent << "DisableGradientOpacity: "
641 << (this->DisableGradientOpacity[i] ? "On" : "Off") << "\n";
642
643
644 os << indent << "ComponentWeight: "
645 << this->ComponentWeight[i] << "\n";
646
647 os << indent << "Shade: " << this->Shade[i] << "\n";
648 os << indent << indent << "Ambient: " << this->Ambient[i] << "\n";
649 os << indent << indent << "Diffuse: " << this->Diffuse[i] << "\n";
650 os << indent << indent << "Specular: " << this->Specular[i] << "\n";
651 os << indent << indent << "SpecularPower: " << this->SpecularPower[i] << "\n";
652 }
653
654 // These variables should not be printed to the user:
655 // this->GradientOpacityMTime
656 // this->GrayTransferFunctionMTime
657 // this->RGBTransferFunctionMTime
658 // this->ScalarOpacityMTime
659
660 }
661
662