You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
518 lines
16 KiB
518 lines
16 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkLightKit.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkLightKit.h"
|
|
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkLight.h"
|
|
#include "vtkPiecewiseFunction.h"
|
|
#include "vtkRenderer.h"
|
|
|
|
vtkCxxRevisionMacro(vtkLightKit, "$Revision: 1.25.6.1 $");
|
|
vtkStandardNewMacro(vtkLightKit);
|
|
|
|
static const char *vtkLightKitTypeStrings[] = {
|
|
"KeyLight",
|
|
"FillLight",
|
|
"BackLight",
|
|
"HeadLight",
|
|
NULL
|
|
};
|
|
|
|
static const char *vtkLightKitSubTypeStrings[] = {
|
|
"Warmth",
|
|
"Intensity",
|
|
"Elevation",
|
|
"Azimuth",
|
|
"K:F Ratio",
|
|
"K:B Ratio",
|
|
"K:H Ratio",
|
|
NULL
|
|
};
|
|
|
|
// These are the same as vtkLightKitSubTypeStrings but shorter
|
|
// usefull for a GUI with minimum space
|
|
static const char *vtkLightKitSubTypeShortStrings[] = {
|
|
"War.",
|
|
"Int. ",
|
|
"Ele.",
|
|
"Azi.",
|
|
"K:F",
|
|
"K:B",
|
|
"K:H",
|
|
NULL
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkLightKit::vtkLightKit()
|
|
{
|
|
// create members
|
|
this->KeyLight = vtkLight::New();
|
|
this->FillLight = vtkLight::New();
|
|
this->HeadLight = vtkLight::New();
|
|
this->BackLight0 = vtkLight::New();
|
|
this->BackLight1 = vtkLight::New();
|
|
|
|
for(int i = 0; i < 4; i++)
|
|
{
|
|
this->WarmthFunction[i] = vtkPiecewiseFunction::New();
|
|
}
|
|
this->InitializeWarmthFunctions();
|
|
|
|
// initialize values
|
|
this->KeyLight->SetLightTypeToCameraLight();
|
|
this->FillLight->SetLightTypeToCameraLight();
|
|
this->BackLight0->SetLightTypeToCameraLight();
|
|
this->BackLight1->SetLightTypeToCameraLight();
|
|
|
|
this->HeadLight->SetLightTypeToHeadlight();
|
|
|
|
this->SetKeyLightAngle(50.0, 10.0);
|
|
this->SetFillLightAngle(-75.0, -10.0);
|
|
this->SetBackLightAngle(0.0, 110.0);
|
|
|
|
this->KeyLightWarmth = 0.6;
|
|
this->FillLightWarmth = 0.4;
|
|
this->HeadLightWarmth = 0.5;
|
|
this->BackLightWarmth = 0.5;
|
|
|
|
this->KeyLightIntensity = 0.75;
|
|
this->KeyToFillRatio = 3.0;
|
|
this->KeyToBackRatio = 3.5;
|
|
this->KeyToHeadRatio = 3.0;
|
|
|
|
this->MaintainLuminance = 0;
|
|
this->Update();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkLightKit::~vtkLightKit()
|
|
{
|
|
this->KeyLight->Delete();
|
|
this->FillLight->Delete();
|
|
this->HeadLight->Delete();
|
|
this->BackLight0->Delete();
|
|
this->BackLight1->Delete();
|
|
|
|
for(int i = 0; i < 4; i++)
|
|
{
|
|
this->WarmthFunction[i]->Delete();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::SetKeyLightAngle(double elevation, double azimuth)
|
|
{
|
|
this->KeyLightAngle[0] = elevation;
|
|
this->KeyLightAngle[1] = azimuth;
|
|
|
|
this->KeyLight->SetDirectionAngle(elevation, azimuth);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::SetFillLightAngle(double elevation, double azimuth)
|
|
{
|
|
this->FillLightAngle[0] = elevation;
|
|
this->FillLightAngle[1] = azimuth;
|
|
|
|
this->FillLight->SetDirectionAngle(elevation, azimuth);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::SetBackLightAngle(double elevation, double azimuth)
|
|
{
|
|
this->BackLightAngle[0] = elevation;
|
|
this->BackLightAngle[1] = azimuth;
|
|
|
|
this->BackLight0->SetDirectionAngle(elevation, azimuth);
|
|
this->BackLight1->SetDirectionAngle(elevation, -azimuth);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::WarmthToRGB(double w, double rgb[3])
|
|
{
|
|
rgb[0] = this->WarmthFunction[0]->GetValue(w);
|
|
rgb[1] = this->WarmthFunction[1]->GetValue(w);
|
|
rgb[2] = this->WarmthFunction[2]->GetValue(w);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double vtkLightKit::WarmthToIntensity(double w)
|
|
{
|
|
return this->WarmthFunction[3]->GetValue(w);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::WarmthToRGBI(double w, double rgb[3], double& i)
|
|
{
|
|
rgb[0] = this->WarmthFunction[0]->GetValue(w);
|
|
rgb[1] = this->WarmthFunction[1]->GetValue(w);
|
|
rgb[2] = this->WarmthFunction[2]->GetValue(w);
|
|
i = this->WarmthFunction[3]->GetValue(w);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::AddLightsToRenderer(vtkRenderer *renderer)
|
|
{
|
|
if(renderer != NULL)
|
|
{
|
|
renderer->AddLight(this->HeadLight);
|
|
renderer->AddLight(this->KeyLight);
|
|
renderer->AddLight(this->FillLight);
|
|
renderer->AddLight(this->BackLight0);
|
|
renderer->AddLight(this->BackLight1);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::RemoveLightsFromRenderer(vtkRenderer *renderer)
|
|
{
|
|
if(renderer != NULL)
|
|
{
|
|
renderer->RemoveLight(this->HeadLight);
|
|
renderer->RemoveLight(this->KeyLight);
|
|
renderer->RemoveLight(this->FillLight);
|
|
renderer->RemoveLight(this->BackLight0);
|
|
renderer->RemoveLight(this->BackLight1);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::Modified()
|
|
{
|
|
this->Update();
|
|
this->MTime.Modified();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::Update()
|
|
{
|
|
double *fillLightColor = this->FillLightColor;
|
|
double fillLightPI;
|
|
|
|
double *keyLightColor = this->KeyLightColor;
|
|
double keyLightPI;
|
|
|
|
double *headlightColor = this->HeadLightColor;
|
|
double headlightPI;
|
|
|
|
double *backLightColor = this->BackLightColor;
|
|
double backLightPI;
|
|
|
|
double fillLightIntensity, keyLightIntensity, headlightIntensity;
|
|
double backLightIntensity;
|
|
|
|
this->WarmthToRGBI(this->KeyLightWarmth, keyLightColor, keyLightPI);
|
|
this->WarmthToRGBI(this->FillLightWarmth, fillLightColor, fillLightPI);
|
|
this->WarmthToRGBI(this->HeadLightWarmth, headlightColor, headlightPI);
|
|
this->WarmthToRGBI(this->BackLightWarmth, backLightColor, backLightPI);
|
|
|
|
keyLightIntensity = this->KeyLightIntensity;
|
|
|
|
fillLightIntensity = keyLightIntensity / this->KeyToFillRatio;
|
|
headlightIntensity = keyLightIntensity / this->KeyToHeadRatio;
|
|
backLightIntensity = keyLightIntensity / this->KeyToBackRatio;
|
|
|
|
// This is sort of interesting: the fill light intensity is weighted
|
|
// by the perceptual brightness of the color of each light. Since
|
|
// the fill light will often be a cooler color than the key light,
|
|
// the bluer color would otherwise seem less bright than the neutral
|
|
// and this bias the key-to-fill ratio. This factor compensates for
|
|
// this problem. Note we always do this correction, no matter what
|
|
// the MaintainLuminance flag says. That flag's for controlling
|
|
// the intensity of the entire scene, not just the fill light.
|
|
|
|
if(this->MaintainLuminance)
|
|
{
|
|
fillLightIntensity /= fillLightPI;
|
|
headlightIntensity /= headlightPI;
|
|
keyLightIntensity /= keyLightPI;
|
|
backLightIntensity /= backLightPI;
|
|
}
|
|
this->KeyLight->SetColor(keyLightColor);
|
|
this->KeyLight->SetIntensity(keyLightIntensity);
|
|
|
|
this->FillLight->SetColor(fillLightColor);
|
|
this->FillLight->SetIntensity(fillLightIntensity);
|
|
|
|
this->HeadLight->SetColor(headlightColor);
|
|
this->HeadLight->SetIntensity(headlightIntensity);
|
|
|
|
this->BackLight0->SetColor(backLightColor);
|
|
this->BackLight0->SetIntensity(backLightIntensity);
|
|
|
|
this->BackLight1->SetColor(backLightColor);
|
|
this->BackLight1->SetIntensity(backLightIntensity);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "KeyLightIntensity: " << this->KeyLightIntensity << "\n";
|
|
os << indent << "KeyToFillRatio: " << this->KeyToFillRatio << "\n";
|
|
os << indent << "KeyToHeadRatio: " << this->KeyToHeadRatio << "\n";
|
|
os << indent << "KeyToBackRatio: " << this->KeyToBackRatio << "\n";
|
|
|
|
os << indent << "KeyLightWarmth: " << this->KeyLightWarmth << "\n";
|
|
os << indent << "KeyLightAngle: ("
|
|
<< this->KeyLightAngle[0] << ", "
|
|
<< this->KeyLightAngle[1] << ")\n";
|
|
|
|
os << indent << "FillLightWarmth: " << this->FillLightWarmth << "\n";
|
|
os << indent << "FillLightAngle: ("
|
|
<< this->FillLightAngle[0] << ", "
|
|
<< this->FillLightAngle[1] << ")\n";
|
|
|
|
os << indent << "BackLightWarmth: " << this->BackLightWarmth << "\n";
|
|
os << indent << "BackLightAngle: ("
|
|
<< this->BackLightAngle[0] << ", "
|
|
<< this->BackLightAngle[1] << ")\n";
|
|
|
|
os << indent << "HeadLightWarmth: " << this->HeadLightWarmth << "\n";
|
|
|
|
os << indent << "MaintainLuminance: " <<
|
|
(this->MaintainLuminance ? "On" : "Off") << "\n";
|
|
|
|
// here, but commented out to satisfy validation tests....
|
|
// os << indent << "KeyLightColor: ("
|
|
// << this->KeyLightColor[0] << ", "
|
|
// << this->KeyLightColor[1] << ", "
|
|
// << this->KeyLightColor[2] << ")\n";
|
|
|
|
// os << indent << "FillLightColor: ("
|
|
// << this->FillLightColor[0] << ", "
|
|
// << this->FillLightColor[1] << ", "
|
|
// << this->FillLightColor[2] << ")\n";
|
|
|
|
// os << indent << "HeadLightColor: ("
|
|
// << this->HeadLightColor[0] << ", "
|
|
// << this->HeadLightColor[1] << ", "
|
|
// << this->HeadLightColor[2] << ")\n";
|
|
|
|
// os << indent << "BackLightColor: ("
|
|
// << this->BackLightColor[0] << ", "
|
|
// << this->BackLightColor[1] << ", "
|
|
// << this->BackLightColor[2] << ")\n";
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::DeepCopy( vtkLightKit *k )
|
|
{
|
|
this->KeyLightIntensity = k->KeyLightIntensity;
|
|
this->KeyToFillRatio = k->KeyToFillRatio;
|
|
this->KeyToHeadRatio = k->KeyToHeadRatio;
|
|
this->KeyToBackRatio = k->KeyToBackRatio;
|
|
|
|
this->KeyLightWarmth = k->KeyLightWarmth;
|
|
this->FillLightWarmth = k->FillLightWarmth;
|
|
this->HeadLightWarmth = k->HeadLightWarmth;
|
|
this->BackLightWarmth = k->BackLightWarmth;
|
|
|
|
this->KeyLightAngle[0] = k->KeyLightAngle[0];
|
|
this->KeyLightAngle[1] = k->KeyLightAngle[1];
|
|
|
|
this->FillLightAngle[0] = k->FillLightAngle[0];
|
|
this->FillLightAngle[1] = k->FillLightAngle[1];
|
|
|
|
this->BackLightAngle[0] = k->BackLightAngle[0];
|
|
this->BackLightAngle[1] = k->BackLightAngle[1];
|
|
|
|
this->MaintainLuminance = k->MaintainLuminance;
|
|
|
|
this->KeyLight->DeepCopy(k->KeyLight);
|
|
this->FillLight->DeepCopy(k->FillLight);
|
|
this->HeadLight->DeepCopy(k->HeadLight);
|
|
this->BackLight0->DeepCopy(k->BackLight0);
|
|
this->BackLight1->DeepCopy(k->BackLight1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// r, g, b, sqrt(color length)
|
|
static double warmthTable[] = {
|
|
0.1674, 0.3065, 1.0000, 0.5865,
|
|
0.1798, 0.3204, 1.0000, 0.5965,
|
|
0.1935, 0.3352, 1.0000, 0.6071,
|
|
0.2083, 0.3511, 1.0000, 0.6184,
|
|
0.2245, 0.3679, 1.0000, 0.6302,
|
|
0.2422, 0.3859, 1.0000, 0.6426,
|
|
0.2614, 0.4050, 1.0000, 0.6556,
|
|
0.2822, 0.4252, 1.0000, 0.6693,
|
|
0.3049, 0.4467, 1.0000, 0.6837,
|
|
0.3293, 0.4695, 1.0000, 0.6986,
|
|
0.3557, 0.4935, 1.0000, 0.7142,
|
|
0.3841, 0.5188, 1.0000, 0.7303,
|
|
0.4144, 0.5454, 1.0000, 0.7470,
|
|
0.4468, 0.5731, 1.0000, 0.7642,
|
|
0.4811, 0.6020, 1.0000, 0.7818,
|
|
0.5173, 0.6320, 1.0000, 0.7998,
|
|
0.5551, 0.6628, 1.0000, 0.8179,
|
|
0.5943, 0.6942, 1.0000, 0.8362,
|
|
0.6346, 0.7261, 1.0000, 0.8544,
|
|
0.6756, 0.7581, 1.0000, 0.8724,
|
|
0.7168, 0.7898, 1.0000, 0.8899,
|
|
0.7575, 0.8209, 1.0000, 0.9068,
|
|
0.7972, 0.8508, 1.0000, 0.9229,
|
|
0.8351, 0.8791, 1.0000, 0.9379,
|
|
0.8705, 0.9054, 1.0000, 0.9517,
|
|
0.9026, 0.9290, 1.0000, 0.9640,
|
|
0.9308, 0.9497, 1.0000, 0.9746,
|
|
0.9546, 0.9671, 1.0000, 0.9834,
|
|
0.9734, 0.9808, 1.0000, 0.9903,
|
|
0.9872, 0.9907, 1.0000, 0.9954,
|
|
0.9958, 0.9970, 1.0000, 0.9985,
|
|
0.9996, 0.9997, 1.0000, 0.9999,
|
|
1.0000, 0.9999, 0.9996, 0.9999,
|
|
1.0000, 0.9988, 0.9958, 0.9994,
|
|
1.0000, 0.9964, 0.9871, 0.9982,
|
|
1.0000, 0.9925, 0.9730, 0.9962,
|
|
1.0000, 0.9869, 0.9532, 0.9935,
|
|
1.0000, 0.9796, 0.9275, 0.9898,
|
|
1.0000, 0.9705, 0.8959, 0.9853,
|
|
1.0000, 0.9595, 0.8584, 0.9798,
|
|
1.0000, 0.9466, 0.8150, 0.9734,
|
|
1.0000, 0.9317, 0.7660, 0.9660,
|
|
1.0000, 0.9147, 0.7116, 0.9576,
|
|
1.0000, 0.8956, 0.6522, 0.9482,
|
|
1.0000, 0.8742, 0.5881, 0.9377,
|
|
1.0000, 0.8506, 0.5199, 0.9261,
|
|
1.0000, 0.8247, 0.4483, 0.9134,
|
|
1.0000, 0.7964, 0.3739, 0.8995,
|
|
1.0000, 0.7656, 0.2975, 0.8845,
|
|
1.0000, 0.7324, 0.2201, 0.8683,
|
|
1.0000, 0.6965, 0.1426, 0.8509,
|
|
1.0000, 0.6580, 0.0662, 0.8323,
|
|
1.0000, 0.6179, 0.0000, 0.8134,
|
|
1.0000, 0.5832, 0.0000, 0.8008,
|
|
1.0000, 0.5453, 0.0000, 0.7868,
|
|
1.0000, 0.5042, 0.0000, 0.7713,
|
|
1.0000, 0.4595, 0.0000, 0.7541,
|
|
1.0000, 0.4111, 0.0000, 0.7350,
|
|
1.0000, 0.3588, 0.0000, 0.7139,
|
|
1.0000, 0.3025, 0.0000, 0.6904,
|
|
1.0000, 0.2423, 0.0000, 0.6643,
|
|
1.0000, 0.1782, 0.0000, 0.6353,
|
|
1.0000, 0.1104, 0.0000, 0.6032,
|
|
1.0000, 0.0396, 0.0000, 0.5677,
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkLightKit::InitializeWarmthFunctions()
|
|
{
|
|
const int len = sizeof(warmthTable) / sizeof(double) / 4;
|
|
|
|
for(int i = 0; i < 4; i++)
|
|
{
|
|
this->WarmthFunction[i]->BuildFunctionFromTable(0.0, 1.0, len,
|
|
&warmthTable[i], 4);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char *vtkLightKit::GetStringFromType(int type)
|
|
{
|
|
static const int n = sizeof(vtkLightKitTypeStrings)/sizeof(char*);
|
|
if( type < n )
|
|
{
|
|
return vtkLightKitTypeStrings[type];
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char *vtkLightKit::GetStringFromSubType(int subtype)
|
|
{
|
|
static const int n = sizeof(vtkLightKitSubTypeStrings)/sizeof(char*);
|
|
if( subtype < n )
|
|
{
|
|
return vtkLightKitSubTypeStrings[subtype];
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char *vtkLightKit::GetShortStringFromSubType(int subtype)
|
|
{
|
|
static const int n = sizeof(vtkLightKitSubTypeShortStrings)/sizeof(char*);
|
|
if( subtype < n )
|
|
{
|
|
return vtkLightKitSubTypeShortStrings[subtype];
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
vtkLightKit::LightKitSubType vtkLightKit::GetSubType(vtkLightKit::LightKitType type, int i)
|
|
{
|
|
//return subtype
|
|
const LightKitSubType KeyLightSubType[4] = { Warmth, Intensity, Elevation, Azimuth };
|
|
const LightKitSubType FillLightSubType[4] = { Warmth, KFRatio, Elevation, Azimuth };
|
|
const LightKitSubType BackLightSubType[4] = { Warmth, KBRatio, Elevation, Azimuth };
|
|
const LightKitSubType HeadLightSubType[2] = { Warmth, KHRatio };
|
|
|
|
LightKitSubType subtype = Warmth; // please VS6
|
|
switch(type)
|
|
{
|
|
case TKeyLight:
|
|
subtype = KeyLightSubType[i];
|
|
break;
|
|
case TFillLight:
|
|
subtype = FillLightSubType[i];
|
|
break;
|
|
case TBackLight:
|
|
subtype = BackLightSubType[i];
|
|
break;
|
|
case THeadLight:
|
|
subtype = HeadLightSubType[i];
|
|
break;
|
|
}
|
|
|
|
return subtype;
|
|
}
|
|
|
|
// The following methods are deprecated:
|
|
|
|
#ifndef VTK_LEGACY_REMOVE
|
|
void vtkLightKit::SetHeadlightWarmth(double v)
|
|
{
|
|
VTK_LEGACY_REPLACED_BODY(vtkLightKit::SetHeadlightWarmth, "VTK 5.0",
|
|
vtkLightKit::SetHeadLightWarmth);
|
|
this->SetHeadLightWarmth(v);
|
|
}
|
|
|
|
double vtkLightKit::GetHeadlightWarmth()
|
|
{
|
|
VTK_LEGACY_REPLACED_BODY(vtkLightKit::GetHeadlightWarmth, "VTK 5.0",
|
|
vtkLightKit::GetHeadLightWarmth);
|
|
return this->GetHeadLightWarmth();
|
|
}
|
|
|
|
void vtkLightKit::GetHeadlightColor(double *color)
|
|
{
|
|
VTK_LEGACY_REPLACED_BODY(vtkLightKit::SetHeadlightColor, "VTK 5.0",
|
|
vtkLightKit::SetHeadLightColor);
|
|
this->GetHeadLightColor(color);
|
|
}
|
|
#endif
|
|
|
|
|