You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
391 lines
13 KiB
C++
391 lines
13 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkLightKit.h
|
|
|
|
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.
|
|
|
|
=========================================================================*/
|
|
/**
|
|
* @class vtkLightKit
|
|
* @brief a simple but quality lighting kit
|
|
*
|
|
* vtkLightKit is designed to make general purpose lighting of vtk
|
|
* scenes simple, flexible, and attractive (or at least not horribly
|
|
* ugly without significant effort). Use a LightKit when you want
|
|
* more control over your lighting than you can get with the default
|
|
* vtk light, which is a headlight located at the camera. (HeadLights
|
|
* are very simple to use, but they don't show the shape of objects very
|
|
* well, don't give a good sense of "up" and "down", and don't evenly
|
|
* light the object.)
|
|
*
|
|
* A LightKit consists of three lights, a key light, a fill light, and
|
|
* a headlight. The main light is the key light. It is usually
|
|
* positioned so that it appears like an overhead light (like the sun,
|
|
* or a ceiling light). It is generally positioned to shine down on the
|
|
* scene from about a 45 degree angle vertically and at least a little
|
|
* offset side to side. The key light usually at least about twice as
|
|
* bright as the total of all other lights in the scene to provide good
|
|
* modeling of object features.
|
|
*
|
|
* The other lights in the kit (the fill light, headlight, and a pair of
|
|
* back lights) are weaker sources that provide extra
|
|
* illumination to fill in the spots that the key light misses. The
|
|
* fill light is usually positioned across from or opposite from the
|
|
* key light (though still on the same side of the object as the
|
|
* camera) in order to simulate diffuse reflections from other objects
|
|
* in the scene. The headlight, always located at the position of the
|
|
* camera, reduces the contrast between areas lit by the key and fill
|
|
* light. The two back lights, one on the left of the object as seen
|
|
* from the observer and one on the right, fill on the high-contrast
|
|
* areas behind the object. To enforce the relationship between the
|
|
* different lights, the intensity of the fill, back and headlights
|
|
* are set as a ratio to the key light brightness. Thus, the
|
|
* brightness of all the lights in the scene can be changed by
|
|
* changing the key light intensity.
|
|
*
|
|
* All lights are directional lights (infinitely far away with no
|
|
* falloff). Lights move with the camera.
|
|
*
|
|
* For simplicity, the position of lights in the LightKit can only be
|
|
* specified using angles: the elevation (latitude) and azimuth
|
|
* (longitude) of each light with respect to the camera, expressed in
|
|
* degrees. (Lights always shine on the camera's lookat point.) For
|
|
* example, a light at (elevation=0, azimuth=0) is located at the
|
|
* camera (a headlight). A light at (elevation=90, azimuth=0) is
|
|
* above the lookat point, shining down. Negative azimuth values move
|
|
* the lights clockwise as seen above, positive values
|
|
* counter-clockwise. So, a light at (elevation=45, azimuth=-20) is
|
|
* above and in front of the object and shining slightly from the left
|
|
* side.
|
|
*
|
|
* vtkLightKit limits the colors that can be assigned to any light to
|
|
* those of incandescent sources such as light bulbs and sunlight. It
|
|
* defines a special color spectrum called "warmth" from which light
|
|
* colors can be chosen, where 0 is cold blue, 0.5 is neutral white,
|
|
* and 1 is deep sunset red. Colors close to 0.5 are "cool whites" and
|
|
* "warm whites," respectively.
|
|
*
|
|
* Since colors far from white on the warmth scale appear less bright,
|
|
* key-to-fill and key-to-headlight ratios are skewed by
|
|
* key, fill, and headlight colors. If the flag MaintainLuminance
|
|
* is set, vtkLightKit will attempt to compensate for these perceptual
|
|
* differences by increasing the brightness of more saturated colors.
|
|
*
|
|
* A LightKit is not explicitly part of the vtk pipeline. Rather, it
|
|
* is a composite object that controls the behavior of lights using a
|
|
* unified user interface. Every time a parameter of vtkLightKit is
|
|
* adjusted, the properties of its lights are modified.
|
|
*
|
|
* @par Credits:
|
|
* vtkLightKit was originally written and contributed to vtk by
|
|
* Michael Halle (mhalle@bwh.harvard.edu) at the Surgical Planning
|
|
* Lab, Brigham and Women's Hospital.
|
|
*/
|
|
|
|
#ifndef vtkLightKit_h
|
|
#define vtkLightKit_h
|
|
|
|
#include "vtkObject.h"
|
|
#include "vtkRenderingCoreModule.h" // For export macro
|
|
|
|
class vtkLight;
|
|
class vtkPiecewiseFunction;
|
|
class vtkRenderer;
|
|
|
|
class VTKRENDERINGCORE_EXPORT vtkLightKit : public vtkObject
|
|
{
|
|
public:
|
|
static vtkLightKit* New();
|
|
vtkTypeMacro(vtkLightKit, vtkObject);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
enum LightKitType
|
|
{
|
|
TKeyLight,
|
|
TFillLight,
|
|
TBackLight,
|
|
THeadLight
|
|
};
|
|
|
|
enum LightKitSubType
|
|
{
|
|
Warmth,
|
|
Intensity,
|
|
Elevation,
|
|
Azimuth,
|
|
KFRatio,
|
|
KBRatio,
|
|
KHRatio
|
|
};
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the intensity of the key light. The key light is the
|
|
* brightest light in the scene. The intensities of the other two
|
|
* lights are ratios of the key light's intensity.
|
|
*/
|
|
vtkSetMacro(KeyLightIntensity, double);
|
|
vtkGetMacro(KeyLightIntensity, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the key-to-fill ratio. This ratio controls
|
|
* how bright the fill light is compared to the key light: larger
|
|
* values correspond to a dimmer fill light. The purpose of the
|
|
* fill light is to light parts of the object not lit by the key
|
|
* light, while still maintaining contrast. This type of lighting
|
|
* may correspond to indirect illumination from the key light, bounced
|
|
* off a wall, floor, or other object. The fill light should never
|
|
* be brighter than the key light: a good range for the key-to-fill
|
|
* ratio is between 2 and 10.
|
|
*/
|
|
vtkSetClampMacro(KeyToFillRatio, double, 0.5, VTK_DOUBLE_MAX);
|
|
vtkGetMacro(KeyToFillRatio, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the key-to-headlight ratio. Similar to the key-to-fill
|
|
* ratio, this ratio controls how bright the headlight light is
|
|
* compared to the key light: larger values correspond to a dimmer
|
|
* headlight light. The headlight is special kind of fill light,
|
|
* lighting only the parts of the object that the camera can see.
|
|
* As such, a headlight tends to reduce the contrast of a scene. It
|
|
* can be used to fill in "shadows" of the object missed by the key
|
|
* and fill lights. The headlight should always be significantly
|
|
* dimmer than the key light: ratios of 2 to 15 are typical.
|
|
*/
|
|
vtkSetClampMacro(KeyToHeadRatio, double, 0.5, VTK_DOUBLE_MAX);
|
|
vtkGetMacro(KeyToHeadRatio, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the key-to-back light ratio. This ratio controls
|
|
* how bright the back lights are compared to the key light: larger
|
|
* values correspond to dimmer back lights. The back lights fill
|
|
* in the remaining high-contrast regions behind the object.
|
|
* Values between 2 and 10 are good.
|
|
*/
|
|
vtkSetClampMacro(KeyToBackRatio, double, 0.5, VTK_DOUBLE_MAX);
|
|
vtkGetMacro(KeyToBackRatio, double);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set the warmth of each the lights. Warmth is a parameter that
|
|
* varies from 0 to 1, where 0 is "cold" (looks icy or lit by a very
|
|
* blue sky), 1 is "warm" (the red of a very red sunset, or the
|
|
* embers of a campfire), and 0.5 is a neutral white. The warmth
|
|
* scale is non-linear. Warmth values close to 0.5 are subtly
|
|
* "warmer" or "cooler," much like a warmer tungsten incandescent
|
|
* bulb, a cooler halogen, or daylight (cooler still). Moving
|
|
* further away from 0.5, colors become more quickly varying towards
|
|
* blues and reds. With regards to aesthetics, extremes of warmth
|
|
* should be used sparingly.
|
|
*/
|
|
vtkSetMacro(KeyLightWarmth, double);
|
|
vtkGetMacro(KeyLightWarmth, double);
|
|
//@}
|
|
|
|
vtkSetMacro(FillLightWarmth, double);
|
|
vtkGetMacro(FillLightWarmth, double);
|
|
|
|
vtkSetMacro(HeadLightWarmth, double);
|
|
vtkGetMacro(HeadLightWarmth, double);
|
|
|
|
vtkSetMacro(BackLightWarmth, double);
|
|
vtkGetMacro(BackLightWarmth, double);
|
|
|
|
//@{
|
|
/**
|
|
* Returns the floating-point RGB values of each of the light's color.
|
|
*/
|
|
vtkGetVectorMacro(KeyLightColor, double, 3);
|
|
vtkGetVectorMacro(FillLightColor, double, 3);
|
|
vtkGetVectorMacro(HeadLightColor, double, 3);
|
|
vtkGetVectorMacro(BackLightColor, double, 3);
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* If MaintainLuminance is set, the LightKit will attempt to maintain
|
|
* the apparent intensity of lights based on their perceptual brightnesses.
|
|
* By default, MaintainLuminance is off.
|
|
*/
|
|
vtkBooleanMacro(MaintainLuminance, vtkTypeBool);
|
|
vtkGetMacro(MaintainLuminance, vtkTypeBool);
|
|
vtkSetMacro(MaintainLuminance, vtkTypeBool);
|
|
//@}
|
|
|
|
/**
|
|
* Get/Set the position of the key, fill, and back lights
|
|
* using angular methods. Elevation corresponds to latitude,
|
|
* azimuth to longitude. It is recommended that the key light
|
|
* always be on the viewer's side of the object and above the
|
|
* object, while the fill light generally lights the part of the object
|
|
* not lit by the fill light. The headlight, which is always located
|
|
* at the viewer, can then be used to reduce the contrast in the image.
|
|
* There are a pair of back lights. They are located at the same
|
|
* elevation and at opposing azimuths (ie, one to the left, and one to
|
|
* the right). They are generally set at the equator (elevation = 0),
|
|
* and at approximately 120 degrees (lighting from each side and behind).
|
|
*/
|
|
void SetKeyLightAngle(double elevation, double azimuth);
|
|
void SetKeyLightAngle(double angle[2]) { this->SetKeyLightAngle(angle[0], angle[1]); }
|
|
|
|
void SetKeyLightElevation(double x) { this->SetKeyLightAngle(x, this->KeyLightAngle[1]); }
|
|
|
|
void SetKeyLightAzimuth(double x) { this->SetKeyLightAngle(this->KeyLightAngle[0], x); }
|
|
|
|
vtkGetVectorMacro(KeyLightAngle, double, 2);
|
|
double GetKeyLightElevation()
|
|
{
|
|
double ang[2];
|
|
this->GetKeyLightAngle(ang);
|
|
return ang[0];
|
|
}
|
|
|
|
double GetKeyLightAzimuth()
|
|
{
|
|
double ang[2];
|
|
this->GetKeyLightAngle(ang);
|
|
return ang[1];
|
|
}
|
|
|
|
void SetFillLightAngle(double elevation, double azimuth);
|
|
void SetFillLightAngle(double angle[2]) { this->SetFillLightAngle(angle[0], angle[1]); }
|
|
|
|
void SetFillLightElevation(double x) { this->SetFillLightAngle(x, this->FillLightAngle[1]); }
|
|
|
|
void SetFillLightAzimuth(double x) { this->SetFillLightAngle(this->FillLightAngle[0], x); }
|
|
|
|
vtkGetVectorMacro(FillLightAngle, double, 2);
|
|
double GetFillLightElevation()
|
|
{
|
|
double ang[2];
|
|
this->GetFillLightAngle(ang);
|
|
return ang[0];
|
|
}
|
|
|
|
double GetFillLightAzimuth()
|
|
{
|
|
double ang[2];
|
|
this->GetFillLightAngle(ang);
|
|
return ang[1];
|
|
}
|
|
|
|
void SetBackLightAngle(double elevation, double azimuth);
|
|
void SetBackLightAngle(double angle[2]) { this->SetBackLightAngle(angle[0], angle[1]); }
|
|
|
|
void SetBackLightElevation(double x) { this->SetBackLightAngle(x, this->BackLightAngle[1]); }
|
|
|
|
void SetBackLightAzimuth(double x) { this->SetBackLightAngle(this->BackLightAngle[0], x); }
|
|
|
|
vtkGetVectorMacro(BackLightAngle, double, 2);
|
|
double GetBackLightElevation()
|
|
{
|
|
double ang[2];
|
|
this->GetBackLightAngle(ang);
|
|
return ang[0];
|
|
}
|
|
|
|
double GetBackLightAzimuth()
|
|
{
|
|
double ang[2];
|
|
this->GetBackLightAngle(ang);
|
|
return ang[1];
|
|
}
|
|
|
|
//@{
|
|
/**
|
|
* Add lights to, or remove lights from, a renderer.
|
|
* Lights may be added to more than one renderer, if desired.
|
|
*/
|
|
void AddLightsToRenderer(vtkRenderer* renderer);
|
|
void RemoveLightsFromRenderer(vtkRenderer* renderer);
|
|
//@}
|
|
|
|
void DeepCopy(vtkLightKit* kit);
|
|
|
|
void Modified() override;
|
|
void Update();
|
|
|
|
/**
|
|
* Helper method to go from a enum type to a string type
|
|
*/
|
|
static const char* GetStringFromType(int type);
|
|
|
|
/**
|
|
* Helper method to go from a enum subtype to a string subtype
|
|
*/
|
|
static const char* GetStringFromSubType(int type);
|
|
|
|
/**
|
|
* Helper method to go from a enum subtype to a string subtype
|
|
* The difference from GetStringFromSubType is that it returns
|
|
* a shorter strings (useful for GUI with minimum space)
|
|
*/
|
|
static const char* GetShortStringFromSubType(int subtype);
|
|
|
|
/**
|
|
* Return the possible subtype from a given type. You have to pass
|
|
* in a number i [0,3] no check is done.
|
|
*/
|
|
static LightKitSubType GetSubType(LightKitType type, int i);
|
|
|
|
protected:
|
|
vtkLightKit();
|
|
~vtkLightKit() override;
|
|
|
|
void WarmthToRGBI(double w, double rgb[3], double& i);
|
|
void WarmthToRGB(double w, double rgb[3]);
|
|
void InitializeWarmthFunctions();
|
|
double WarmthToIntensity(double w);
|
|
|
|
double KeyLightIntensity;
|
|
double KeyToFillRatio;
|
|
double KeyToHeadRatio;
|
|
double KeyToBackRatio;
|
|
|
|
vtkLight* KeyLight;
|
|
double KeyLightWarmth;
|
|
double KeyLightAngle[2];
|
|
double KeyLightColor[3];
|
|
|
|
vtkLight* FillLight;
|
|
double FillLightWarmth;
|
|
double FillLightAngle[2];
|
|
double FillLightColor[3];
|
|
|
|
double BackLightWarmth;
|
|
double BackLightColor[3];
|
|
|
|
vtkLight* BackLight0;
|
|
vtkLight* BackLight1;
|
|
|
|
double BackLightAngle[2];
|
|
|
|
vtkLight* HeadLight;
|
|
double HeadLightWarmth;
|
|
double HeadLightColor[3];
|
|
|
|
vtkTypeBool MaintainLuminance;
|
|
|
|
vtkPiecewiseFunction* WarmthFunction[4]; // r, g, b, perceptual length
|
|
|
|
private:
|
|
vtkLightKit(const vtkLightKit&) = delete;
|
|
void operator=(const vtkLightKit&) = delete;
|
|
};
|
|
|
|
#endif
|