-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathctf_lut.cpp
More file actions
236 lines (202 loc) · 8.19 KB
/
Copy pathctf_lut.cpp
File metadata and controls
236 lines (202 loc) · 8.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*
Demonstrates how to assign colors to cells in a vtkPolyData structure using
lookup tables.
Two techniques are demonstrated:
1) Using a lookup table of predefined colors.
2) Using a lookup table generated from a color transfer function.
The resultant display shows in the left-hand column, the cells in a plane
colored by the two lookup tables and in the right-hand column, the same
polydata that has been read in from a file demonstrating that the structures
are identical.
The top row of the display uses the color transfer function to create a
green to tan transition in a diverging color space.
Note that the central square is white indicating the midpoint.
The bottom row of the display uses a lookup table of predefined colors.
*/
#include <vtkActor.h>
#include <vtkCellData.h>
#include <vtkColorTransferFunction.h>
#include <vtkLookupTable.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlaneSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkUnsignedCharArray.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkXMLPolyDataWriter.h>
#include <iostream>
//! Make a lookup table from a set of named colors.
void MakeLUT(int tableSize, vtkLookupTable* lut)
{
vtkNew<vtkNamedColors> nc;
lut->SetNumberOfTableValues(static_cast<vtkIdType>(tableSize));
lut->Build();
// Fill in a few known colors, the rest will be generated if needed.
lut->SetTableValue(0, nc->GetColor4d("Black").GetData());
lut->SetTableValue(1, nc->GetColor4d("Banana").GetData());
lut->SetTableValue(2, nc->GetColor4d("Tomato").GetData());
lut->SetTableValue(3, nc->GetColor4d("Wheat").GetData());
lut->SetTableValue(4, nc->GetColor4d("Lavender").GetData());
lut->SetTableValue(5, nc->GetColor4d("Flesh").GetData());
lut->SetTableValue(6, nc->GetColor4d("Raspberry").GetData());
lut->SetTableValue(7, nc->GetColor4d("Salmon").GetData());
lut->SetTableValue(8, nc->GetColor4d("Mint").GetData());
lut->SetTableValue(9, nc->GetColor4d("Peacock").GetData());
}
//! Use a color transfer Function to generate the colors in the lookup table.
void MakeLUTFromCTF(int tableSize, vtkLookupTable* lut)
{
vtkNew<vtkColorTransferFunction> ctf;
ctf->SetColorSpaceToDiverging();
// Green to tan.
ctf->AddRGBPoint(0.0, 0.085, 0.532, 0.201);
ctf->AddRGBPoint(0.5, 0.865, 0.865, 0.865);
ctf->AddRGBPoint(1.0, 0.677, 0.492, 0.093);
lut->SetNumberOfTableValues(static_cast<vtkIdType>(tableSize));
lut->Build();
for (auto i = 0; i < tableSize; ++i)
{
double* rgb;
rgb = ctf->GetColor(static_cast<double>(i) / tableSize);
lut->SetTableValue(static_cast<vtkIdType>(i), rgb);
}
}
//! Create the cell data using the colors from the lookup table.
void MakeCellData(int tableSize, vtkLookupTable* lut, vtkUnsignedCharArray* colors)
{
for (auto i = 1; i < tableSize; i++)
{
double rgb[3];
unsigned char ucrgb[3];
// Get the interpolated color.
// Of course you can use any function whose range is [0...1]
// to get the required color and assign it to a cell Id.
// In this case we are just using the cell (Id + 1)/(tableSize - 1)
// to get the interpolated color.
lut->GetColor(static_cast<double>(i) / (tableSize - 1), rgb);
for (auto j = 0; j < 3; j++)
ucrgb[j] = static_cast<unsigned char>(rgb[j] * 255);
colors->InsertNextTuple3(ucrgb[0], ucrgb[1], ucrgb[2]);
// Print out what we have.
std::cout << "(" << rgb[0] << ", " << rgb[1] << ", " << rgb[2] << ") (" << +ucrgb[0] << ", " << +ucrgb[1]
<< ", " << +ucrgb[2] << ")\n";
}
}
int main(int, char*[])
{
vtkNew<vtkNamedColors> nc;
// Provide some geometry.
int resolution = 3;
vtkNew<vtkPlaneSource> plane11;
plane11->SetXResolution(resolution);
plane11->SetYResolution(resolution);
vtkNew<vtkPlaneSource> plane12;
plane12->SetXResolution(resolution);
plane12->SetYResolution(resolution);
// Create a lookup table to map cell data to colors.
vtkNew<vtkLookupTable> lut1;
vtkNew<vtkLookupTable> lut2;
int tableSize = resolution * resolution + 1;
// Force an update so we can set cell data.
plane11->Update();
plane12->Update();
MakeLUT(tableSize, lut1);
MakeLUTFromCTF(tableSize, lut2);
vtkNew<vtkUnsignedCharArray> colorData1;
colorData1->SetName("colors"); // Any name will work here.
colorData1->SetNumberOfComponents(3);
std::cout << "Using a lookup table from a set of named colors." << std::endl;
MakeCellData(tableSize, lut1, colorData1);
// Then use SetScalars() to add it to the vtkPolyData structure,
// this will then be interpreted as a color table.
plane11->GetOutput()->GetCellData()->SetScalars(colorData1);
vtkNew<vtkUnsignedCharArray> colorData2;
colorData2->SetName("colors");
colorData2->SetNumberOfComponents(3);
std::cout << "Using a lookup table created from a color transfer function." << std::endl;
MakeCellData(tableSize, lut2, colorData2);
plane12->GetOutput()->GetCellData()->SetScalars(colorData2);
// Setup actor and mapper.
vtkNew<vtkPolyDataMapper> mapper11;
mapper11->SetInputConnection(plane11->GetOutputPort());
// Now, instead of doing this:
// mapper11->SetScalarRange(0, tableSize - 1);
// mapper11->SetLookupTable(lut1);
// We can just use the color data that we created from the lookup table and
// assigned to the cells:
mapper11->SetScalarModeToUseCellData();
mapper11->Update();
vtkNew<vtkPolyDataMapper> mapper12;
mapper12->SetInputConnection(plane12->GetOutputPort());
mapper12->SetScalarModeToUseCellData();
mapper12->Update();
vtkNew<vtkXMLPolyDataWriter> writer;
writer->SetFileName("pdlut.vtp");
writer->SetInputData(mapper11->GetInput());
// This is set so we can see the data in a text editor.
writer->SetDataModeToAscii();
writer->Write();
writer->SetFileName("pdctf.vtp");
writer->SetInputData(mapper12->GetInput());
writer->Write();
vtkNew<vtkActor> actor11;
actor11->SetMapper(mapper11);
vtkNew<vtkActor> actor12;
actor12->SetMapper(mapper12);
// Let's read in the data we wrote out.
vtkNew<vtkXMLPolyDataReader> reader1;
reader1->SetFileName("pdlut.vtp");
vtkNew<vtkXMLPolyDataReader> reader2;
reader2->SetFileName("pdctf.vtp");
vtkNew<vtkPolyDataMapper> mapper21;
mapper21->SetInputConnection(reader1->GetOutputPort());
mapper21->SetScalarModeToUseCellData();
mapper21->Update();
vtkNew<vtkActor> actor21;
actor21->SetMapper(mapper21);
vtkNew<vtkPolyDataMapper> mapper22;
mapper22->SetInputConnection(reader2->GetOutputPort());
mapper22->SetScalarModeToUseCellData();
mapper22->Update();
vtkNew<vtkActor> actor22;
actor22->SetMapper(mapper22);
// Define viewport ranges.
// (xmin, ymin, xmax, ymax)
double viewport11[4] = {0.0, 0.0, 0.5, 0.5};
double viewport12[4] = {0.0, 0.5, 0.5, 1.0};
double viewport21[4] = {0.5, 0.0, 1.0, 0.5};
double viewport22[4] = {0.5, 0.5, 1.0, 1.0};
// Set up the renderers.
vtkNew<vtkRenderer> ren11;
vtkNew<vtkRenderer> ren12;
vtkNew<vtkRenderer> ren21;
vtkNew<vtkRenderer> ren22;
// Setup the render windows.
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(600, 600);
renWin->SetWindowName("AssignCellColorsFromLUT");
renWin->AddRenderer(ren11);
renWin->AddRenderer(ren12);
renWin->AddRenderer(ren21);
renWin->AddRenderer(ren22);
ren11->SetViewport(viewport11);
ren12->SetViewport(viewport12);
ren21->SetViewport(viewport21);
ren22->SetViewport(viewport22);
ren11->SetBackground(nc->GetColor3d("MidnightBlue").GetData());
ren12->SetBackground(nc->GetColor3d("MidnightBlue").GetData());
ren21->SetBackground(nc->GetColor3d("MidnightBlue").GetData());
ren22->SetBackground(nc->GetColor3d("MidnightBlue").GetData());
ren11->AddActor(actor11);
ren12->AddActor(actor12);
ren21->AddActor(actor21);
ren22->AddActor(actor22);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}