1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkColorSeries.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #include "vtkColorSeries.h"
17 
18 #include "vtkLookupTable.h"
19 #include "vtkObjectFactory.h"
20 
21 #include <vector>
22 #include <sstream>
23 
24 //-----------------------------------------------------------------------------
25 class vtkColorSeriesPalette
26 {
27 public:
28   std::vector<vtkColor3ub> Colors;
29   vtkStdString Name;
30 };
31 
32 //-----------------------------------------------------------------------------
33 class vtkColorSeries::Private
34 {
35 public:
36   Private();
37 
38   void SetScheme(int idx);
39   int SetSchemeByName(const vtkStdString& name, bool& modified);
40 
41   std::vector<vtkColorSeriesPalette> Palettes; // All palettes
42   int Palette; // Currently-selected entry in Palettes
43   std::vector<vtkColor3ub>* Colors; // Pointer to colors in current scheme
44 };
45 
46 //-----------------------------------------------------------------------------
vtkColor3ubFromHex3(vtkTypeUInt32 hex)47 inline vtkColor3ub vtkColor3ubFromHex3(vtkTypeUInt32 hex)
48 {
49   int b = hex & 0xff; hex >>= 8;
50   int g = hex & 0xff; hex >>= 8;
51   int r = hex & 0xff;
52   return vtkColor3ub(r, g, b);
53 }
54 
55 //-----------------------------------------------------------------------------
Private()56 vtkColorSeries::Private::Private()
57 {
58   this->Palettes.resize(vtkColorSeries::CUSTOM);
59   vtkTypeUInt32 colors[] =
60     {
61     // Original vtkColorSeries palettes, not part of the Brewer schemes
62     vtkColorSeries::SPECTRUM,
63     0x000000, 0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xA65628,
64     vtkColorSeries::WARM,
65     0x791717, 0xB50101, 0xEF4719, 0xF98324, 0xFFB400, 0xFFE506,
66     vtkColorSeries::COOL,
67     0x75B101, 0x588029, 0x50D7BF, 0x1C95CD, 0x3B68AB, 0x9A68FF, 0x5F3380,
68     vtkColorSeries::BLUES,
69     0x3B68AB, 0x1C95CD, 0x4ED9EA, 0x739AD5, 0x423DA9, 0x505487, 0x102A52,
70     vtkColorSeries::WILD_FLOWER,
71     0x1C95CD, 0x3B68AB, 0x663EB7, 0xA254CF, 0xDE61CE, 0xDC6195, 0x3D1052,
72     vtkColorSeries::CITRUS,
73     0x657C37, 0x75B101, 0xB2BA30, 0xFFE506, 0xFFB400, 0xF98324,
74 
75 /*
76 The following palettes are colors from www.ColorBrewer2.org by
77 Cynthia A. Brewer, Geography, Pennsylvania State University.
78 Use the sentence above or the following bibliography entry to credit her:
79 
80 + Brewer, Cynthia A. and Mark Harrower and Andy Woodruff and David Heyman,
81   2010. http://ColorBrewer2.org, accessed 2010-Nov-9.
82 
83 The color schemes below are copyright under the following license, excerpted
84 from http://www.personal.psu.edu/cab38/ColorBrewer/ColorBrewer_updates.html
85 on August 13, 2012:
86 
87     Apache-Style Software License for ColorBrewer software and
88     ColorBrewer Color Schemes
89 
90     Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania
91     State University.
92 
93     Licensed under the Apache License, Version 2.0 (the "License"); you may not
94     use this file except in compliance with the License.
95     You may obtain a copy of the License at
96 
97     http://www.apache.org/licenses/LICENSE-2.0
98 
99     Unless required by applicable law or agreed to in writing, software
100     distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
101     WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
102     License for the specific language governing permissions and limitations
103     under the License.
104 
105 This text from my earlier Apache License Version 1.1 also remains in place for
106 guidance on attribution and permissions:
107 
108     Redistribution and use in source and binary forms, with or without
109     modification, are permitted provided that the following conditions are met:
110     1. Redistributions as source code must retain the above copyright notice,
111        this list of conditions and the following disclaimer.
112     2. The end-user documentation included with the redistribution, if any, must
113        include the following acknowledgment:
114        "This product includes color specifications and designs developed by
115        Cynthia Brewer (http://colorbrewer.org/)."
116        Alternately, this acknowledgment may appear in the software itself, if
117        and wherever such third-party acknowledgments normally appear.
118     4. The name "ColorBrewer" must not be used to endorse or promote products
119        derived from this software without prior written permission. For written
120        permission, please contact Cynthia Brewer at cbrewer@psu.edu.
121     5. Products derived from this software may not be called "ColorBrewer", nor
122        may "ColorBrewer" appear in their name, without prior written permission
123        of Cynthia Brewer.
124 */
125     // Diverging
126     //   Purple-Orange
127     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_11,
128     0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
129     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_10,
130     0x7F3B08, 0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788, 0x2D004B,
131     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_9,
132     0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
133     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_8,
134     0xB35806, 0xE08214, 0xFDB863, 0xFEE0B6, 0xD8DAEB, 0xB2ABD2, 0x8073AC, 0x542788,
135     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_7,
136     0xB35806, 0xF1A340, 0xFEE0B6, 0xF7F7F7, 0xD8DAEB, 0x998EC3, 0x542788,
137     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_6,
138     0xB35806, 0xF1A340, 0xFEE0B6, 0xD8DAEB, 0x998EC3, 0x542788,
139     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_5,
140     0xE66101, 0xFDB863, 0xF7F7F7, 0xB2ABD2, 0x5E3C99,
141     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_4,
142     0xE66101, 0xFDB863, 0xB2ABD2, 0x5E3C99,
143     vtkColorSeries::BREWER_DIVERGING_PURPLE_ORANGE_3,
144     0xF1A340, 0xF7F7F7, 0x998EC3,
145     //   Spectral
146     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_11,
147     0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
148     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_10,
149     0x9E0142, 0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD, 0x5E4FA2,
150     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_9,
151     0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
152     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_8,
153     0xD53E4F, 0xF46D43, 0xFDAE61, 0xFEE08B, 0xE6F598, 0xABDDA4, 0x66C2A5, 0x3288BD,
154     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_7,
155     0xD53E4F, 0xFC8D59, 0xFEE08B, 0xFFFFBF, 0xE6F598, 0x99D594, 0x3288BD,
156     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_6,
157     0xD53E4F, 0xFC8D59, 0xFEE08B, 0xE6F598, 0x99D594, 0x3288BD,
158     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_5,
159     0xD7191C, 0xFDAE61, 0xFFFFBF, 0xABDDA4, 0x2B83BA,
160     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_4,
161     0xD7191C, 0xFDAE61, 0xABDDA4, 0x2B83BA,
162     vtkColorSeries::BREWER_DIVERGING_SPECTRAL_3,
163     0xFC8D59, 0xFFFFBF, 0x99D594,
164     //   Brown-Blue-Green
165     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_11,
166     0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
167     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_10,
168     0x543005, 0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E, 0x003C30,
169     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_9,
170     0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
171     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_8,
172     0x8C510A, 0xBF812D, 0xDFC27D, 0xF6E8C3, 0xC7EAE5, 0x80CDC1, 0x35978F, 0x01665E,
173     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_7,
174     0x8C510A, 0xD8B365, 0xF6E8C3, 0xF5F5F5, 0xC7EAE5, 0x5AB4AC, 0x01665E,
175     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_6,
176     0x8C510A, 0xD8B365, 0xF6E8C3, 0xC7EAE5, 0x5AB4AC, 0x01665E,
177     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_5,
178     0xA6611A, 0xDFC27D, 0xF5F5F5, 0x80CDC1, 0x018571,
179     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_4,
180     0xA6611A, 0xDFC27D, 0x80CDC1, 0x018571,
181     vtkColorSeries::BREWER_DIVERGING_BROWN_BLUE_GREEN_3,
182     0xD8B365, 0xF5F5F5, 0x5AB4AC,
183     // Sequential Palettes
184     //   Blue-Green
185     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_9,
186     0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x006D2C, 0x00441B,
187     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_8,
188     0xF7FCFD, 0xE5F5F9, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
189     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_7,
190     0xEDF8FB, 0xCCECE6, 0xCCECE6, 0x66C2A4, 0x41AE76, 0x238B45, 0x005824,
191     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_6,
192     0xEDF8FB, 0xCCECE6, 0x99D8C9, 0x66C2A4, 0x2CA25F, 0x006D2C,
193     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_5,
194     0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x2CA25F, 0x006D2C,
195     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_4,
196     0xEDF8FB, 0xB2E2E2, 0x66C2A4, 0x238B45,
197     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_GREEN_3,
198     0xE5F5F9, 0x99D8C9, 0x2CA25F,
199     //   Yellow-Orange-Brown
200     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_9,
201     0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x993404, 0x662506,
202     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_8,
203     0xFFFFE5, 0xFFF7BC, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
204     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_7,
205     0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xEC7014, 0xCC4C02, 0x8C2D04,
206     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_6,
207     0xFFFFD4, 0xFEE391, 0xFEC44F, 0xFE9929, 0xD95F0E, 0x993404,
208     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_5,
209     0xFFFFD4, 0xFED98E, 0xFE9929, 0xD95F0E, 0x993404,
210     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_4,
211     0xFFFFD4, 0xFED98E, 0xFE9929, 0xCC4C02,
212     vtkColorSeries::BREWER_SEQUENTIAL_YELLOW_ORANGE_BROWN_3,
213     0xFFF7BC, 0xFEC44F, 0xD95F0E,
214     //   Blue-Purple
215     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_9,
216     0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x810F7C, 0x4D004B,
217     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_8,
218     0xF7FCFD, 0xE0ECF4, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
219     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_7,
220     0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8C6BB1, 0x88419D, 0x6E016B,
221     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_6,
222     0xEDF8FB, 0xBFD3E6, 0x9EBCDA, 0x8C96C6, 0x8856A7, 0x810F7C,
223     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_5,
224     0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x8856A7, 0x810F7C,
225     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_4,
226     0xEDF8FB, 0xB3CDE3, 0x8C96C6, 0x88419D,
227     vtkColorSeries::BREWER_SEQUENTIAL_BLUE_PURPLE_3,
228     0xE0ECF4, 0x9EBCDA, 0x8856A7,
229     // Qualitative Palettes
230     //   Accent
231     vtkColorSeries::BREWER_QUALITATIVE_ACCENT,
232     0x7FC97F, 0xBEAED4, 0xFDC086, 0xFFFF99, 0x386CB0, 0xF0027F, 0xBF5B17, 0x666666,
233     //   Dark2
234     vtkColorSeries::BREWER_QUALITATIVE_DARK2,
235     0x1B9E77, 0xD95F02, 0x7570B3, 0xE7298A, 0x66A61E, 0xE6AB02, 0xA6761D, 0x666666,
236     //   Set2
237     vtkColorSeries::BREWER_QUALITATIVE_SET2,
238     0x66C2A5, 0xFC8D62, 0x8DA0CB, 0xE78AC3, 0xA6D854, 0xFFD92F, 0xE5C494, 0xB3B3B3,
239     //   Pastel2
240     vtkColorSeries::BREWER_QUALITATIVE_PASTEL2,
241     0xB3E2CD, 0xFDCDAC, 0xCBD5E8, 0xF4CAE4, 0xE6F5C9, 0xFFF2AE, 0xF1E2CC, 0xCCCCCC,
242     //   Pastel1
243     vtkColorSeries::BREWER_QUALITATIVE_PASTEL1,
244     0xFBB4AE, 0xB3CDE3, 0xCCEBC5, 0xDECBE4, 0xFED9A6, 0xFFFFCC, 0xE5D8BD, 0xFDDAEC, 0xF2F2F2,
245     //   Set1
246     vtkColorSeries::BREWER_QUALITATIVE_SET1,
247     0xE41A1C, 0x377EB8, 0x4DAF4A, 0x984EA3, 0xFF7F00, 0xFFFF33, 0xA65628, 0xF781BF, 0x999999,
248     //   Paired
249     vtkColorSeries::BREWER_QUALITATIVE_PAIRED,
250     0xA6CEE3, 0x1F78B4, 0xB2DF8A, 0x33A02C, 0xFB9A99, 0xE31A1C, 0xFDBF6F, 0xFF7F00, 0xCAB2D6, 0x6A3D9A, 0xFFFF99,
251     //   Set3
252     vtkColorSeries::BREWER_QUALITATIVE_SET3,
253     0x8DD3C7, 0xFFFFB3, 0xBEBADA, 0xFB8072, 0x80B1D3, 0xFDB462, 0xB3DE69, 0xFCCDE5, 0xD9D9D9, 0xBC80BD, 0xCCEBC5, 0xFFED6F,
254     };
255   const char* names[] =
256     {
257     "Spectrum",
258     "Warm",
259     "Cool",
260     "Blues",
261     "Wild Flower",
262     "Citrus",
263 
264     "Brewer Diverging Purple-Orange",
265     "Brewer Diverging Spectral",
266     "Brewer Diverging Brown-Blue-Green",
267 
268     "Brewer Sequential Blue-Green",
269     "Brewer Sequential Yellow-Orange-Brown",
270     "Brewer Sequential Blue-Purple",
271 
272     "Brewer Qualitative Accent",
273     "Brewer Qualitative Dark2",
274     "Brewer Qualitative Set2",
275     "Brewer Qualitative Pastel2",
276     "Brewer Qualitative Pastel1",
277     "Brewer Qualitative Set1",
278     "Brewer Qualitative Paired",
279     "Brewer Qualitative Set3"
280     };
281   int sizes[][2] =
282     {
283       {  7,  7 },
284       {  6,  6 },
285       {  7,  7 },
286       {  7,  7 },
287       {  7,  7 },
288       {  6,  6 },
289 
290       { 11,  3 },
291       { 11,  3 },
292       { 11,  3 },
293       {  9,  3 },
294       {  9,  3 },
295       {  9,  3 },
296       {  8,  8 },
297       {  8,  8 },
298       {  8,  8 },
299       {  8,  8 },
300       {  9,  9 },
301       {  9,  9 },
302       { 11, 11 },
303       { 12, 12 }
304     };
305   vtkTypeUInt32* color = colors;
306   vtkColorSeriesPalette* pal;
307   for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); ++i)
308     {
309     int start = sizes[i][0];
310     int stop  = sizes[i][1];
311     int step = start > stop ? -1 : 1;
312     for (int n = start; n != stop + step; n += step)
313       {
314       int paletteIndex = *(color++);
315       pal = &(this->Palettes[paletteIndex]);
316       std::ostringstream os;
317       os << names[i];
318       if (start != stop)
319         {
320         os << " (" << n << ")";
321         }
322       pal->Name = os.str();
323       for (int j = 0; j < n; ++j)
324         {
325         pal->Colors.push_back(vtkColor3ubFromHex3(*(color++)));
326         }
327       }
328     }
329   this->Colors = 0;
330   this->Palette = vtkColorSeries::SPECTRUM;
331   this->Colors = &(this->Palettes[this->Palette].Colors);
332 }
333 
334 //-----------------------------------------------------------------------------
SetScheme(int idx)335 void vtkColorSeries::Private::SetScheme(int idx)
336 {
337   this->Colors = &(this->Palettes[idx].Colors);
338   this->Palette = idx;
339 }
340 
341 //-----------------------------------------------------------------------------
SetSchemeByName(const vtkStdString & name,bool & modified)342 int vtkColorSeries::Private::SetSchemeByName(
343   const vtkStdString& name, bool& modified)
344 {
345   modified = false;
346   int idx = 0;
347   std::vector<vtkColorSeriesPalette>::iterator it;
348   for (it = this->Palettes.begin(); it != this->Palettes.end(); ++it, ++idx)
349     {
350     if (it->Name == name)
351       {
352       this->SetScheme(idx);
353       return idx;
354       }
355     }
356   // OK, we could not find such a palette. Create one.
357   modified = true;
358   vtkColorSeriesPalette blank;
359   blank.Name = name;
360   idx = static_cast<int>(this->Palettes.size());
361   this->Palettes.push_back(blank);
362   this->SetScheme(idx);
363   return idx;
364 }
365 
366 //-----------------------------------------------------------------------------
367 //-----------------------------------------------------------------------------
368 vtkStandardNewMacro(vtkColorSeries);
369 
370 //-----------------------------------------------------------------------------
vtkColorSeries()371 vtkColorSeries::vtkColorSeries()
372 {
373   this->Storage = new vtkColorSeries::Private;
374   this->SetColorScheme(vtkColorSeries::SPECTRUM);
375 }
376 
377 //-----------------------------------------------------------------------------
~vtkColorSeries()378 vtkColorSeries::~vtkColorSeries()
379 {
380   delete this->Storage;
381   this->Storage = NULL;
382 }
383 
384 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)385 void vtkColorSeries::PrintSelf(ostream &os, vtkIndent indent)
386 {
387   this->Superclass::PrintSelf(os, indent);
388   int pidx = this->Storage->Palette;
389   vtkColorSeriesPalette* palette = &(this->Storage->Palettes[pidx]);
390   os
391     << indent << "ColorScheme: " << pidx << endl
392     << indent << "ColorSchemeName : "
393     << (palette->Name.empty() ? "(empty)" : palette->Name.c_str()) << endl;
394 }
395 
396 //-----------------------------------------------------------------------------
SetColorScheme(int scheme)397 void vtkColorSeries::SetColorScheme(int scheme)
398 {
399   if (this->Storage->Palette == scheme)
400     {
401     return;
402     }
403 
404   if (scheme < 0 || scheme >= this->GetNumberOfColorSchemes())
405     {
406     vtkWarningMacro(<< "Scheme " << scheme << " out of range. Ignoring.");
407     return;
408     }
409 
410   this->Storage->SetScheme(scheme);
411   this->Modified();
412 }
413 
414 //-----------------------------------------------------------------------------
SetColorSchemeByName(const vtkStdString & schemeName)415 int vtkColorSeries::SetColorSchemeByName(const vtkStdString& schemeName)
416 {
417   bool modified;
418   int index = this->Storage->SetSchemeByName(schemeName, modified);
419   if (modified)
420     {
421     this->Modified();
422     }
423   return index;
424 }
425 
426 //-----------------------------------------------------------------------------
GetNumberOfColorSchemes() const427 int vtkColorSeries::GetNumberOfColorSchemes() const
428 {
429   return static_cast<int>(this->Storage->Palettes.size());
430 }
431 
432 //-----------------------------------------------------------------------------
GetColorSchemeName() const433 vtkStdString vtkColorSeries::GetColorSchemeName() const
434 {
435   return this->Storage->Palettes[this->Storage->Palette].Name;
436 }
437 
438 //-----------------------------------------------------------------------------
SetColorSchemeName(const vtkStdString & name)439 void vtkColorSeries::SetColorSchemeName(const vtkStdString& name)
440 {
441   // Ignore empty names
442   // TODO: Should we prohibit duplicate names? If not,
443   // how about searching backwards through palettes in
444   // SetColorSchemeByName() so users can override
445   // system defaults?
446   if ( name.empty() )
447     {
448     return;
449     }
450 
451   this->CopyOnWrite();
452   if (this->Storage->Palettes[this->Storage->Palette].Name != name)
453     {
454     this->Storage->Palettes[this->Storage->Palette].Name = name;
455     this->Modified();
456     }
457 }
458 
459 //-----------------------------------------------------------------------------
GetColorScheme() const460 int vtkColorSeries::GetColorScheme() const
461 {
462   return this->Storage->Palette;
463 }
464 
465 //-----------------------------------------------------------------------------
GetNumberOfColors() const466 int vtkColorSeries::GetNumberOfColors() const
467 {
468   return static_cast<int>(this->Storage->Colors->size());
469 }
470 
471 //-----------------------------------------------------------------------------
SetNumberOfColors(int numColors)472 void vtkColorSeries::SetNumberOfColors(int numColors)
473 {
474   this->CopyOnWrite();
475   this->Storage->Colors->resize(numColors);
476 }
477 
478 //-----------------------------------------------------------------------------
GetColor(int index) const479 vtkColor3ub vtkColorSeries::GetColor(int index) const
480 {
481   if (index >=0 && index < static_cast<int>(this->Storage->Colors->size()))
482     {
483     return (*this->Storage->Colors)[index];
484     }
485   else
486     {
487     return vtkColor3ub(0,0,0);
488     }
489 }
490 
491 //-----------------------------------------------------------------------------
GetColorRepeating(int index) const492 vtkColor3ub vtkColorSeries::GetColorRepeating(int index) const
493 {
494   vtkColor3ub color;
495   int numColors = this->GetNumberOfColors();
496   // If we have an empty palette, index % numColors generates a divide-by-zero
497   // fault, and if it did return a valid value, looking up the resulting color
498   // would be an access violation. So, be careful here:
499   color = numColors ?
500     (*this->Storage->Colors)[index % numColors] :
501     vtkColor3ub(0,0,0);
502   return color;
503 }
504 
505 //-----------------------------------------------------------------------------
SetColor(int index,const vtkColor3ub & color)506 void vtkColorSeries::SetColor(int index, const vtkColor3ub &color)
507 {
508   if (index >=0 && index < static_cast<int>(this->Storage->Colors->size()))
509     {
510     this->CopyOnWrite();
511     (*this->Storage->Colors)[index] = color;
512     this->Modified();
513     }
514 }
515 
516 //-----------------------------------------------------------------------------
AddColor(const vtkColor3ub & color)517 void vtkColorSeries::AddColor(const vtkColor3ub &color)
518 {
519   this->CopyOnWrite();
520   this->Storage->Colors->push_back(color);
521   this->Modified();
522 }
523 
524 //-----------------------------------------------------------------------------
InsertColor(int index,const vtkColor3ub & color)525 void vtkColorSeries::InsertColor(int index, const vtkColor3ub &color)
526 {
527   if (index >=0 && index < static_cast<int>(this->Storage->Colors->size()))
528     {
529     this->CopyOnWrite();
530     this->Storage->Colors->insert(
531       this->Storage->Colors->begin() + index, color);
532     this->Modified();
533     }
534 }
535 
536 //-----------------------------------------------------------------------------
RemoveColor(int index)537 void vtkColorSeries::RemoveColor(int index)
538 {
539   if (index >=0 && index < static_cast<int>(this->Storage->Colors->size()))
540     {
541     this->CopyOnWrite();
542     this->Storage->Colors->erase(this->Storage->Colors->begin() + index);
543     this->Modified();
544     }
545 }
546 
547 //-----------------------------------------------------------------------------
ClearColors()548 void vtkColorSeries::ClearColors()
549 {
550   this->CopyOnWrite();
551   this->Storage->Colors->clear();
552   this->Modified();
553 }
554 
555 //-----------------------------------------------------------------------------
DeepCopy(vtkColorSeries * colors)556 void vtkColorSeries::DeepCopy(vtkColorSeries* colors)
557 {
558   if (! colors)
559     {
560     return;
561     }
562 
563   this->Storage->Palettes = colors->Storage->Palettes;
564   this->Storage->Palette = colors->Storage->Palette;
565   this->Storage->Colors =
566     &(this->Storage->Palettes[this->Storage->Palette].Colors);
567   this->Modified();
568 }
569 
570 //-----------------------------------------------------------------------------
BuildLookupTable(vtkLookupTable * lkup,int lutIndexing)571 void vtkColorSeries::BuildLookupTable(vtkLookupTable* lkup, int lutIndexing)
572 {
573   if (lkup)
574     {
575     lkup->SetNumberOfTableValues(this->GetNumberOfColors());
576     lkup->SetIndexedLookup((lutIndexing == ORDINAL) ? 0 : 1);
577     for (int i = 0; i < this->GetNumberOfColors(); ++i)
578       {
579       vtkColor3ub colr = this->GetColor(i);
580       lkup->SetTableValue(
581         i, colr.GetRed()/255., colr.GetGreen()/255., colr.GetBlue()/255., 1.);
582       }
583     }
584 }
585 
586 //-----------------------------------------------------------------------------
CreateLookupTable(int lutIndexing)587 vtkLookupTable* vtkColorSeries::CreateLookupTable(int lutIndexing)
588 {
589   vtkLookupTable *lkup = vtkLookupTable::New();
590   this->BuildLookupTable(lkup, lutIndexing);
591   return lkup;
592 }
593 
594 //-----------------------------------------------------------------------------
CopyOnWrite()595 void vtkColorSeries::CopyOnWrite()
596 {
597   // If the current scheme is predefined, copy it to a new, custom scheme.
598   int prevScheme = this->Storage->Palette;
599   if (prevScheme < CUSTOM)
600     {
601     int nextScheme = static_cast<int>(this->Storage->Palettes.size());
602     vtkColorSeriesPalette blank;
603     blank.Name = this->Storage->Palettes[prevScheme].Name + " copy";
604     this->Storage->Palettes.push_back(blank);
605     this->Storage->SetScheme(nextScheme);
606     *this->Storage->Colors = this->Storage->Palettes[prevScheme].Colors;
607     this->Modified();
608     }
609 }
610