/*========================================================================= medInria Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkTransferFunctionPresets.h" #include #include #include #include #include #include vtkStandardNewMacro(vtkTransferFunctionPresets); #include "lut/Spectrum.h" #include "lut/HotMetal.h" #include "lut/HotGreen.h" #include "lut/HotIron.h" #include "lut/GEColor.h" #include "lut/Flow.h" #include "lut/LONI.h" #include "lut/LONI2.h" #include "lut/Asymmetry.h" #include "lut/VRMusclesBones.h" #include "lut/VRBones.h" #include "lut/VRRedVessels.h" #include "lut/Cardiac.h" #include "lut/GrayRainbow.h" #include "lut/Stern.h" #include "lut/BlackBody.h" vtkTransferFunctionPresets::vtkTransferFunctionPresets() {} vtkTransferFunctionPresets::~vtkTransferFunctionPresets() {} std::vector< std::string > vtkTransferFunctionPresets::GetAvailablePresets() { std::vector< std::string > presetNames; presetNames.resize( 32 ); // size >= #names std::vector< std::string >::iterator it = presetNames.begin(); // it's save to just comment lines if you feel like * it = "Default"; ++it; * it = "Black & White"; ++it; * it = "Black & White Inversed"; ++it; * it = "Spectrum"; ++it; * it = "Hot Metal"; ++it; * it = "Hot Green"; ++it; * it = "Hot Iron"; ++it; * it = "GE"; ++it; * it = "Flow"; ++it; * it = "Loni"; ++it; * it = "Loni Inversed"; ++it; * it = "Loni 2"; ++it; * it = "Asymmetry"; ++it; * it = "P-Value"; ++it; // * it = "Segmentation"; ++it; * it = "Red Black Alpha"; ++it; * it = "Green Black Alpha"; ++it; * it = "Blue Black Alpha"; ++it; * it = "Muscles & Bones"; ++it; * it = "Bones"; ++it; * it = "Red Vessels"; ++it; * it = "Cardiac"; ++it; * it = "Gray Rainbow"; ++it; * it = "Stern"; ++it; * it = "Black Body"; ++it; * it = "Binary Map"; ++it; presetNames.erase( it, presetNames.end() ); return presetNames; } void vtkTransferFunctionPresets::GetTransferFunction( const std::string & name, vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { if ( rgb == nullptr ) { rgb = vtkColorTransferFunction::New(); } else { rgb->RemoveAllPoints(); } if ( alpha == nullptr ) { alpha = vtkPiecewiseFunction::New(); } else { alpha->RemoveAllPoints(); } typedef vtkTransferFunctionPresets Self; if ( name == "Default" ) Self::GetBWTransferFunction( rgb, alpha ); else if ( name == "Black & White" ) Self::GetBWTransferFunction( rgb, alpha ); else if ( name == "Black & White Inversed" ) Self::GetBWInverseTransferFunction( rgb, alpha ); else if ( name == "Spectrum" ) Self::GetSpectrumTransferFunction( rgb, alpha ); else if ( name == "Hot Metal" ) Self::GetHotMetalTransferFunction( rgb, alpha ); else if ( name == "Hot Green" ) Self::GetHotGreenTransferFunction( rgb, alpha ); else if ( name == "Hot Iron" ) Self::GetHotIronTransferFunction( rgb, alpha ); else if ( name == "GE" ) Self::GetGEColorTransferFunction( rgb, alpha ); else if ( name == "Flow" ) Self::GetFlowTransferFunction( rgb, alpha ); else if ( name == "Loni" ) Self::GetLONITransferFunction( rgb, alpha ); else if ( name == "Loni Inversed" ) Self::GetLONIInversedTransferFunction( rgb, alpha ); else if ( name == "Loni 2" ) Self::GetLONI2TransferFunction( rgb, alpha ); else if ( name == "Asymmetry" ) Self::GetAsymmetryTransferFunction( rgb, alpha ); else if ( name == "P-Value" ) Self::GetPValueTransferFunction( rgb, alpha ); else if ( name == "Red Black Alpha" ) Self::GetRedBlackAlphaTransferFunction( rgb, alpha ); else if ( name == "Green Black Alpha" ) Self::GetGreenBlackAlphaTransferFunction( rgb, alpha ); else if ( name == "Blue Black Alpha" ) Self::GetBlueBlackAlphaTransferFunction( rgb, alpha ); else if ( name == "Muscles & Bones" ) Self::GetVRMusclesBonesTransferFunction( rgb, alpha ); else if ( name == "Bones" ) Self::GetVRBonesTransferFunction( rgb, alpha ); else if ( name == "Red Vessels" ) Self::GetVRRedVesselsTransferFunction( rgb, alpha ); else if ( name == "Cardiac" ) Self::GetCardiacTransferFunction( rgb, alpha ); else if ( name == "Gray Rainbow" ) Self::GetGrayRainbowTransferFunction( rgb, alpha ); else if ( name == "Stern" ) Self::GetSternTransferFunction( rgb, alpha ); else if ( name == "Black Body" ) Self::GetBlackBodyTransferFunction( rgb, alpha ); else if (name == "Binary Map") Self::GetBinaryMapTransferFunction( rgb, alpha ); else Self::GetBWTransferFunction( rgb, alpha ); } void vtkTransferFunctionPresets::GetTransferFunctionFromTable( unsigned int size, const int * table, bool logAlpha, vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { double * rgbTable = new double[3 * size]; double * alphaTable = new double[size]; double normFactor = static_cast< double >( size - 1 ); for ( unsigned int i = 0; i < size; ++i ) { for ( unsigned int j = 0; j < 3; ++j ) rgbTable[3 * i + j] = static_cast< double >( table[j * size + i] ) / 255.0; alphaTable[i] = static_cast< double >( i ) / normFactor; if ( logAlpha ) alphaTable[i] = log( 1.0 + 9.0 * alphaTable[i] ) / log( 10.0 ); } rgb->BuildFunctionFromTable( 0.0, 1.0, size, rgbTable ); delete [] rgbTable; alpha->BuildFunctionFromTable( 0.0, 1.0, size, alphaTable ); delete [] alphaTable; } void vtkTransferFunctionPresets::GetTransferFunctionFromTable( unsigned int size, const float table[][3], bool logAlpha, vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { double * rgbTable = new double[3 * size]; double * alphaTable = new double[size]; double normFactor = static_cast< double >( size - 1 ); for ( unsigned int i = 0; i < size; ++i ) { for ( unsigned int j = 0; j < 3; ++j ) rgbTable[3 * i + j] = static_cast< double >( table[i][j] ); alphaTable[i] = static_cast< double >( i ) / normFactor; if ( logAlpha ) alphaTable[i] = log( 1.0 + 9.0 * alphaTable[i] ) / log( 10.0 ); } rgb->BuildFunctionFromTable( 0.0, 1.0, size, rgbTable ); delete [] rgbTable; alpha->BuildFunctionFromTable( 0.0, 1.0, size, alphaTable ); delete [] alphaTable; } void vtkTransferFunctionPresets::GetTransferFunctionFromInversedTable( unsigned int size, const float table[][3], bool logAlpha, vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { double * rgbTable = new double[3 * size]; double * alphaTable = new double[size]; double normFactor = static_cast< double >( size - 1 ); for ( unsigned int i = 0; i < size; ++i ) { for ( unsigned int j = 0; j < 3; ++j ) rgbTable[3 * i + j] = static_cast< double >( table[size-i-1][j] ); alphaTable[i] = static_cast< double >( i ) / normFactor; if ( logAlpha ) alphaTable[i] = log( 1.0 + 9.0 * alphaTable[i] ) / log( 10.0 ); } rgb->BuildFunctionFromTable( 0.0, 1.0, size, rgbTable ); delete [] rgbTable; alpha->BuildFunctionFromTable( 0.0, 1.0, size, alphaTable ); delete [] alphaTable; } void vtkTransferFunctionPresets::GetBWTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); rgb->AddRGBPoint( 1.0, 1.0, 1.0, 1.0 ); alpha->AddPoint( 0.0, 0.0 ); alpha->AddPoint( 1.0, 1.0 ); } void vtkTransferFunctionPresets::GetBWInverseTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 1.0, 1.0, 1.0 ); rgb->AddRGBPoint( 1.0, 0.0, 0.0, 0.0 ); alpha->AddPoint( 0.0, 1.0 ); alpha->AddPoint( 1.0, 0.0 ); } void vtkTransferFunctionPresets::GetSpectrumTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 1.0, 0.0, 1.0 ); rgb->AddRGBPoint( 0.2, 0.0, 0.0, 1.0 ); rgb->AddRGBPoint( 0.4, 0.0, 1.0, 1.0 ); rgb->AddRGBPoint( 0.6, 0.0, 1.0, 0.0 ); rgb->AddRGBPoint( 0.8, 1.0, 1.0, 0.0 ); rgb->AddRGBPoint( 1.0, 1.0, 0.0, 0.0 ); alpha->AddPoint( 0.0, 1.0 ); alpha->AddPoint( 0.2, 1.0 ); alpha->AddPoint( 0.4, 1.0 ); alpha->AddPoint( 0.6, 1.0 ); alpha->AddPoint( 0.8, 1.0 ); alpha->AddPoint( 1.0, 1.0 ); } void vtkTransferFunctionPresets::GetHotMetalTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, HotMetal, false, rgb, alpha ); // double * table = new double[3 * 256]; // for ( unsigned int i = 0; i < 256; ++i ) // for ( unsigned int j = 0; j < 3; ++j ) // table[3 * i + j] = // static_cast< double >( HotMetal[j * 256 + i] ) / 255.0; // // lut->SetTableValue(i, (double)HotMetal[i]/255.0, // // (double)HotMetal[256+i]/255.0, // // (double)HotMetal[256*2+i]/255.0, (double)i/255.0 ); // rgb->BuildFunctionFromTable( 0.0, 1.0, 256, table ); // delete [] table; // alpha->AddPoint( 0.0, 0.0 ); // alpha->AddPoint( 1.0, 1.0 ); } void vtkTransferFunctionPresets::GetHotGreenTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, HotGreen, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetHotIronTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, HotIron, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetGEColorTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); rgb->AddRGBPoint( 0.25, 0.0, 0.5, 0.5 ); rgb->AddRGBPoint( 0.5, 0.5, 0.0, 1.0 ); rgb->AddRGBPoint( 0.75, 1.0, 0.5, 0.0 ); rgb->AddRGBPoint( 1.0, 1.0, 1.0, 1.0 ); alpha->AddPoint( 0.0, 0.0 ); alpha->AddPoint( 0.25, 0.25 ); alpha->AddPoint( 0.5, 0.5 ); alpha->AddPoint( 0.75, 0.75 ); alpha->AddPoint( 1.0, 1.0 ); } void vtkTransferFunctionPresets::GetFlowTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, Flow, false, rgb, alpha ); } void vtkTransferFunctionPresets::GetLONITransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 203, LONI, false, rgb, alpha ); // double * rgbTable = new double[3 * 203]; // double * alphaTable = new double[203]; // for ( unsigned int i = 0; i < 203; ++i ) // { // for ( unsigned int j = 0; j < 3; ++j ) // table[3 * i + j] = static_cast< double >( LONI[i][j] ); // alphaTable[i] = static_cast< double >( i ) / 202.0; // } // // lut->SetTableValue( // // i, (double)LONI[i][0], (double)LONI[i][1], (double)LONI[i][2], // // (double)i/202.0); // rgb->BuildFunctionFromTable( 0.0, 1.0, size, rgbTable ); // delete [] rgbTable; // alpha->BuildFunctionFromTable( 0.0, 1.0, size, alphaTable ); // delete [] alphaTable; } void vtkTransferFunctionPresets::GetLONIInversedTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromInversedTable( 203, LONI, false, rgb, alpha ); } void vtkTransferFunctionPresets::GetLONI2TransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 120, LONI2, false, rgb, alpha ); // double * rgbTable = new double[3 * 120]; // double * alphaTable = new double[120]; // for ( unsigned int i = 0; i < 120; ++i ) // { // for ( unsigned int j = 0; j < 3; ++j ) // table[3 * i + j] = static_cast< double >( LONI2[i][j] ); // alphaTable[i] = static_cast< double >( i ) / 119.0; // } // // lut->SetTableValue( // // i, (double)LONI2[i][0], (double)LONI2[i][1], (double)LONI2[i][2], // // (double)i/119.0); // rgb->BuildFunctionFromTable( 0.0, 1.0, size, rgbTable ); // delete [] rgbTable; // alpha->BuildFunctionFromTable( 0.0, 1.0, size, alphaTable ); // delete [] alphaTable; } void vtkTransferFunctionPresets::GetAsymmetryTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 1.0 ); rgb->AddRGBPoint( 0.2, 0.0, 1.0, 1.0 ); rgb->AddRGBPoint( 0.4, 0.0, 1.0, 0.0 ); rgb->AddRGBPoint( 0.6, 1.0, 1.0, 0.0 ); rgb->AddRGBPoint( 0.8, 1.0, 0.0, 0.0 ); rgb->AddRGBPoint( 1.0, 1.0, 0.0, 1.0 ); alpha->AddPoint( 0.0, 1.0 ); alpha->AddPoint( 0.2, 1.0 ); alpha->AddPoint( 0.4, 1.0 ); alpha->AddPoint( 0.6, 1.0 ); alpha->AddPoint( 0.8, 1.0 ); alpha->AddPoint( 1.0, 1.0 ); } void vtkTransferFunctionPresets::GetPValueTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->SetColorSpaceToHSV(); rgb->AddHSVPoint( 0.0, 0.6667, 0.5, 0.5 ); rgb->AddHSVPoint( 1.0, 0.8333, 1.0, 1.0 ); // rgb->AddHSVPoint(0, 0, 1, 1); // rgb->AddHSVPoint(0.05, 0.27, 0.6, 0.97, 0, 1); // rgb->AddHSVPoint(1, 0.6, 1, 1); alpha->AddPoint( 0.0, 0.0 ); alpha->AddPoint( 1.0, 1.0 ); // vtkLookupTable* lut = vtkLookupTable::New(); // lut->SetTableRange (0, 1); // lut->SetSaturationRange (1.0, 1.5); // lut->SetHueRange (0.666, 0.8333); // //lut->SetHueRange (0.666, 0.0); // lut->SetValueRange (0.5, 1.0); // lut->SetAlphaRange (0, 1); // lut->Build(); } void vtkTransferFunctionPresets::GetRedBlackAlphaTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); rgb->AddRGBPoint( 1.0, 1.0, 0.0, 0.0 ); alpha->AddPoint( 0.0, 0.7333 ); alpha->AddPoint( 1.0, 1.0 ); // lut->SetTableValue(i, i/255.0, 0.0, 0.0, (i/255.0*68.0 + 187)/255.0); } void vtkTransferFunctionPresets::GetGreenBlackAlphaTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); rgb->AddRGBPoint( 1.0, 0.0, 1.0, 0.0 ); alpha->AddPoint( 0.0, 0.7333 ); alpha->AddPoint( 1.0, 1.0 ); // lut->SetTableValue(i, 0.0, i/255.0, 0.0, (i/255.0*68.0 + 187)/255.0); } void vtkTransferFunctionPresets::GetBlueBlackAlphaTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { rgb->AddRGBPoint( 0.0, 0.0, 0.0, 0.0 ); rgb->AddRGBPoint( 1.0, 0.0, 0.0, 1.0 ); alpha->AddPoint( 0.0, 0.7333 ); alpha->AddPoint( 1.0, 1.0 ); // lut->SetTableValue(i, 0.0, 0.0, i/255.0, (i/255.0*68.0 + 187)/255.0); } // void vtkTransferFunctionPresets::GetROITransferFunction( // vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) // { // vtkLookupTable* lut = vtkLookupTable::New(); // lut->SetNumberOfTableValues (256); // lut->SetTableValue ( 0, 0.0, 0.0, 0.0, 0.0); // erase color // double colors[15][3] = { // { 1.0, 0.0, 0.0 }, // red // { 0.0, 1.0, 0.0 }, // green // { 0.0, 0.0, 1.0 }, // blue // { 1.0, 1.0, 0.0 }, // yellow // { 0.0, 1.0, 1.0 }, // cyan // { 1.0, 0.0, 1.0 }, // magenta // { 1.0, 0.5, 0.0 }, // orange // { 0.0, 1.0, 0.5 }, // pale green // { 0.5, 0.0, 1.0 }, // violet // { 1.0, 1.0, 0.5 }, // pale yellow // { 0.5, 1.0, 1.0 }, // pale cyan // { 1.0, 0.5, 1.0 }, // pale magenta // { 0.5, 1.0, 0.0 }, // yellow green // { 0.0, 0.5, 1.0 }, // light blue // { 1.0, 0.0, 0.5 } // pink // }; // for ( unsigned int i = 1; i < 256; i++) // { // double c = colors[(i - 1) % 15]; // lut->SetTableValue( i, c[0], c[1], c[2], 0.5 ); // } // } void vtkTransferFunctionPresets::GetVRMusclesBonesTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, VRMusclesBones, true, rgb, alpha ); // double * rgbTable = new double[3 * 256]; // double * alphaTable = new double[256]; // for ( unsigned int i = 0; i < 256; ++i ) // { // for ( unsigned int j = 0; j < 3; ++j ) // rgbTable[3 * i + j] = // static_cast< double >( VRMusclesBones[j * 256 + i] ) / 255.0; // alphaTable[i] = log( 1.0 + 9.0 * static_cast< double >( i ) / 255.0 ) // / log( 10.0 ); // } // // lut->SetTableValue(i, // // (double)VRMusclesBones[ i] / 255.0, // // (double)VRMusclesBones[ 256+i] / 255.0, // // (double)VRMusclesBones[2*256+i] / 255.0, // // // (double)(i)/255.0 // // log( 1.0 + 9.0 * (double)(i) / 255.0) / log( 10.0 ) ); // rgb->BuildFunctionFromTable( 0.0, 1.0, 256, rgbTable ); // delete [] rgbTable; // alpha->BuildFunctionFromTable( 0.0, 1.0, 256, alphaTable ); // delete [] alphaTable; } void vtkTransferFunctionPresets::GetVRBonesTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, VRBones, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetVRRedVesselsTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, VRRedVessels, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetCardiacTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, Cardiac, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetGrayRainbowTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, GrayRainbow, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetSternTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, Stern, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetBlackBodyTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { vtkTransferFunctionPresets::GetTransferFunctionFromTable( 256, BlackBody, true, rgb, alpha ); } void vtkTransferFunctionPresets::GetBinaryMapTransferFunction( vtkColorTransferFunction * rgb, vtkPiecewiseFunction * alpha ) { double realHueValue = 0; double factor = (1.0 + sqrt(5.0)) / 2.0; float rgbValue[3]; float hsv[3]; hsv[1] = 1.0; hsv[2] = 1.0; rgb->AddRGBPoint(0.0,0.0,0.0,0.0); for (unsigned int i = 1;i < 256;++i) { hsv[0] = realHueValue; vtkMath::HSVToRGB(hsv, rgbValue); rgb->AddRGBPoint(i / 255.0,rgbValue[0],rgbValue[1],rgbValue[2]); realHueValue += 1.0 / factor; if (realHueValue > 1.0) realHueValue -= 1.0; } alpha->AddPoint(0.0, 1.0); alpha->AddPoint(1.0, 1.0); }