28 const std::vector<double> &colorMap,
29 const double *nanColor,
31 const double range[2],
33 const int threadNumber) {
34 const size_t nKeys = colorMap.size() / 4;
35 const double valueDelta = range[1] - range[0];
37#ifdef TTK_ENABLE_OPENMP
38#pragma omp parallel for num_threads(threadNumber)
40 for(
size_t i = 0; i < nPixels; i++) {
42 const double value = (double)array[i];
43 if(std::isnan(value)) {
44 size_t const idx = i * 3;
45 color[idx + 0] = 255.0 * nanColor[0];
46 color[idx + 1] = 255.0 * nanColor[1];
47 color[idx + 2] = 255.0 * nanColor[2];
51 const double normalizedValue
52 = std::max(0.0, std::min(1.0, (value - range[0]) / valueDelta));
55 for(
size_t k = 1; k < nKeys; k++) {
56 if(normalizedValue <= colorMap[k * 4]) {
62 double const lambda = (normalizedValue - colorMap[ki * 4])
63 / (colorMap[(ki + 1) * 4] - colorMap[ki * 4]);
64 double const lambdaInv = 1 - lambda;
66 size_t const idx = i * 3;
67 size_t const idx2 = ki * 4;
69 = 255.0 * (lambdaInv * colorMap[idx2 + 1] + lambda * colorMap[idx2 + 5]);
71 = 255.0 * (lambdaInv * colorMap[idx2 + 2] + lambda * colorMap[idx2 + 6]);
73 = 255.0 * (lambdaInv * colorMap[idx2 + 3] + lambda * colorMap[idx2 + 7]);
82 vtkInformationVector **inputVector,
83 vtkInformationVector *outputVector) {
89 auto input = vtkImageData::GetData(inputVector[0]);
90 auto output = vtkImageData::GetData(outputVector);
91 output->ShallowCopy(input);
93 auto scalarArray = this->GetInputArrayToProcess(0, output);
94 if(!scalarArray || this->GetInputArrayAssociation(0, output) != 0
95 || scalarArray->GetNumberOfComponents() != 1) {
96 this->
printErr(
"Unable to retrieve point scalar array.");
100 size_t const nPixels = scalarArray->GetNumberOfTuples();
103 scalarArray->GetRange(range);
106 colorArray->SetName(
"Diffuse");
107 colorArray->SetNumberOfComponents(3);
108 colorArray->SetNumberOfTuples(nPixels);
109 output->GetPointData()->AddArray(colorArray);
113 std::vector<double> manualColorMap;
114 const std::vector<double> *colorMap{
nullptr};
116 if(this->ColorMap == -1) {
117 manualColorMap.resize(8);
118 manualColorMap[0] = 0;
119 manualColorMap[1] = this->SingleColor[0];
120 manualColorMap[2] = this->SingleColor[1];
121 manualColorMap[3] = this->SingleColor[2];
122 manualColorMap[4] = 1;
123 manualColorMap[5] = this->SingleColor[0];
124 manualColorMap[6] = this->SingleColor[1];
125 manualColorMap[7] = this->SingleColor[2];
126 colorMap = &manualColorMap;
127 }
else if(this->ColorMap == -2) {
129 this->ManualColorMap, manualColorMap);
130 if(!status || manualColorMap.size() < 8 || manualColorMap.size() % 4 != 0) {
131 this->
printErr(
"Invalid manual color map input.");
134 colorMap = &manualColorMap;
136 if(this->ColorMap < 0 || this->ColorMap >= (
int)this->ColorMaps.size()) {
137 this->
printErr(
"Invalid color map index: "
138 + std::to_string(this->ColorMap));
141 colorMap = &this->ColorMaps[this->ColorMap];
144 switch(scalarArray->GetDataType()) {
145 vtkTemplateMacro(mapScalarsToColor<VTK_TT>(
146 colorArrayData, *colorMap, this->NANColor,
152 "Applying Color Map", 1, timer.
getElapsedTime(), this->threadNumber_);
int mapScalarsToColor(unsigned char *color, const std::vector< double > &colorMap, const double *nanColor, const DT *array, const double range[2], const size_t nPixels, const int threadNumber)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)