Medical Imaging Interaction Toolkit  2018.4.99-dfa0c14e
Medical Imaging Interaction Toolkit
mitkLookupTablePropertySerializer.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include "mitkStringsToNumbers.h"
15 #include <mitkLocaleSwitch.h>
17 
19 {
20  if (const auto *prop = dynamic_cast<const LookupTableProperty *>(m_Property.GetPointer()))
21  {
22  LocaleSwitch localeSwitch("C");
23 
24  LookupTable::Pointer mitkLut = const_cast<LookupTableProperty *>(prop)->GetLookupTable();
25  if (mitkLut.IsNull())
26  return nullptr; // really?
27 
28  vtkLookupTable *lut = mitkLut->GetVtkLookupTable();
29  if (!lut)
30  return nullptr;
31 
32  auto element = new TiXmlElement("LookupTable");
33 
34  double *range;
35  double *rgba;
36 
37  element->SetAttribute("NumberOfColors", lut->GetNumberOfTableValues());
38  element->SetAttribute("Scale", lut->GetScale());
39  element->SetAttribute("Ramp", lut->GetRamp());
40 
41  range = lut->GetHueRange();
42  auto child = new TiXmlElement("HueRange");
43  element->LinkEndChild(child);
44  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
45  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
46 
47  range = lut->GetValueRange();
48  child = new TiXmlElement("ValueRange");
49  element->LinkEndChild(child);
50  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
51  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
52 
53  range = lut->GetSaturationRange();
54  child = new TiXmlElement("SaturationRange");
55  element->LinkEndChild(child);
56  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
57  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
58 
59  range = lut->GetAlphaRange();
60  child = new TiXmlElement("AlphaRange");
61  element->LinkEndChild(child);
62  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
63  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
64 
65  range = lut->GetTableRange();
66  child = new TiXmlElement("TableRange");
67  element->LinkEndChild(child);
68  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
69  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
70 
71  child = new TiXmlElement("Table");
72  element->LinkEndChild(child);
73  for (int index = 0; index < lut->GetNumberOfTableValues(); ++index)
74  {
75  auto grandChild = new TiXmlElement("RgbaColor");
76  rgba = lut->GetTableValue(index);
77  grandChild->SetAttribute("R", boost::lexical_cast<std::string>(rgba[0]));
78  grandChild->SetAttribute("G", boost::lexical_cast<std::string>(rgba[1]));
79  grandChild->SetAttribute("B", boost::lexical_cast<std::string>(rgba[2]));
80  grandChild->SetAttribute("A", boost::lexical_cast<std::string>(rgba[3]));
81  child->LinkEndChild(grandChild);
82  }
83  return element;
84  }
85  else
86  return nullptr;
87 }
88 
90 {
91  if (!element)
92  return nullptr;
93 
94  LocaleSwitch localeSwitch("C");
95 
96  double range[2];
97  double rgba[4];
98 
99  std::string double_strings[4];
100 
101  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
102 
103  int numberOfColors;
104  int scale;
105  int ramp; // hope the int values don't change betw. vtk versions...
106  if (element->QueryIntAttribute("NumberOfColors", &numberOfColors) == TIXML_SUCCESS)
107  {
108  lut->SetNumberOfTableValues(numberOfColors);
109  }
110  else
111  return nullptr;
112  if (element->QueryIntAttribute("Scale", &scale) == TIXML_SUCCESS)
113  {
114  lut->SetScale(scale);
115  }
116  else
117  return nullptr;
118  if (element->QueryIntAttribute("Ramp", &ramp) == TIXML_SUCCESS)
119  {
120  lut->SetRamp(ramp);
121  }
122  else
123  return nullptr;
124 
125  try
126  {
127  TiXmlElement *child = element->FirstChildElement("HueRange");
128  if (child)
129  {
130  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
131  return nullptr;
132  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
133  return nullptr;
134  StringsToNumbers<double>(2, double_strings, range);
135  lut->SetHueRange(range);
136  }
137 
138  child = element->FirstChildElement("ValueRange");
139  if (child)
140  {
141  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
142  return nullptr;
143  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
144  return nullptr;
145  StringsToNumbers<double>(2, double_strings, range);
146  lut->SetValueRange(range);
147  }
148 
149  child = element->FirstChildElement("SaturationRange");
150  if (child)
151  {
152  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
153  return nullptr;
154  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
155  return nullptr;
156  StringsToNumbers<double>(2, double_strings, range);
157  lut->SetSaturationRange(range);
158  }
159 
160  child = element->FirstChildElement("AlphaRange");
161  if (child)
162  {
163  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
164  return nullptr;
165  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
166  return nullptr;
167  StringsToNumbers<double>(2, double_strings, range);
168  lut->SetAlphaRange(range);
169  }
170 
171  child = element->FirstChildElement("TableRange");
172  if (child)
173  {
174  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
175  return nullptr;
176  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
177  return nullptr;
178  StringsToNumbers<double>(2, double_strings, range);
179  lut->SetTableRange(range);
180  }
181 
182  child = element->FirstChildElement("Table");
183  if (child)
184  {
185  unsigned int index(0);
186  for (TiXmlElement *grandChild = child->FirstChildElement("RgbaColor"); grandChild;
187  grandChild = grandChild->NextSiblingElement("RgbaColor"))
188  {
189  if (grandChild->QueryStringAttribute("R", &double_strings[0]) != TIXML_SUCCESS)
190  return nullptr;
191  if (grandChild->QueryStringAttribute("G", &double_strings[1]) != TIXML_SUCCESS)
192  return nullptr;
193  if (grandChild->QueryStringAttribute("B", &double_strings[2]) != TIXML_SUCCESS)
194  return nullptr;
195  if (grandChild->QueryStringAttribute("A", &double_strings[3]) != TIXML_SUCCESS)
196  return nullptr;
197  StringsToNumbers<double>(4, double_strings, rgba);
198  lut->SetTableValue(index, rgba);
199  ++index;
200  }
201  }
202  }
203  catch (boost::bad_lexical_cast &e)
204  {
205  MITK_ERROR << "Could not parse string as number: " << e.what();
206  return nullptr;
207  }
208 
210  mitkLut->SetVtkLookupTable(lut);
211 
212  return LookupTableProperty::New(mitkLut).GetPointer();
213 }
#define MITK_ERROR
Definition: mitkLogMacros.h:20
BaseProperty::Pointer Deserialize(TiXmlElement *element) override
Deserializes given TiXmlElement.
The LookupTableProperty class Property to associate mitk::LookupTable to an mitk::DataNode.
Convenience class to temporarily change the current locale.
static Pointer New()
BaseProperty::ConstPointer m_Property
static Pointer New()
TiXmlElement * Serialize() override
Serializes given BaseData object.