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