Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include "mitkStringsToNumbers.h"
19 #include <mitkLocaleSwitch.h>
21 
23 {
24  if (const LookupTableProperty *prop = dynamic_cast<const LookupTableProperty *>(m_Property.GetPointer()))
25  {
26  LocaleSwitch localeSwitch("C");
27 
28  LookupTable::Pointer mitkLut = const_cast<LookupTableProperty *>(prop)->GetLookupTable();
29  if (mitkLut.IsNull())
30  return nullptr; // really?
31 
32  vtkLookupTable *lut = mitkLut->GetVtkLookupTable();
33  if (!lut)
34  return nullptr;
35 
36  auto element = new TiXmlElement("LookupTable");
37 
38  double *range;
39  double *rgba;
40 
41  element->SetAttribute("NumberOfColors", lut->GetNumberOfTableValues());
42  element->SetAttribute("Scale", lut->GetScale());
43  element->SetAttribute("Ramp", lut->GetRamp());
44 
45  range = lut->GetHueRange();
46  auto child = new TiXmlElement("HueRange");
47  element->LinkEndChild(child);
48  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
49  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
50 
51  range = lut->GetValueRange();
52  child = new TiXmlElement("ValueRange");
53  element->LinkEndChild(child);
54  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
55  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
56 
57  range = lut->GetSaturationRange();
58  child = new TiXmlElement("SaturationRange");
59  element->LinkEndChild(child);
60  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
61  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
62 
63  range = lut->GetAlphaRange();
64  child = new TiXmlElement("AlphaRange");
65  element->LinkEndChild(child);
66  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
67  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
68 
69  range = lut->GetTableRange();
70  child = new TiXmlElement("TableRange");
71  element->LinkEndChild(child);
72  child->SetAttribute("min", boost::lexical_cast<std::string>(range[0]));
73  child->SetAttribute("max", boost::lexical_cast<std::string>(range[1]));
74 
75  child = new TiXmlElement("Table");
76  element->LinkEndChild(child);
77  for (int index = 0; index < lut->GetNumberOfTableValues(); ++index)
78  {
79  auto grandChild = new TiXmlElement("RgbaColor");
80  rgba = lut->GetTableValue(index);
81  grandChild->SetAttribute("R", boost::lexical_cast<std::string>(rgba[0]));
82  grandChild->SetAttribute("G", boost::lexical_cast<std::string>(rgba[1]));
83  grandChild->SetAttribute("B", boost::lexical_cast<std::string>(rgba[2]));
84  grandChild->SetAttribute("A", boost::lexical_cast<std::string>(rgba[3]));
85  child->LinkEndChild(grandChild);
86  }
87  return element;
88  }
89  else
90  return nullptr;
91 }
92 
94 {
95  if (!element)
96  return nullptr;
97 
98  LocaleSwitch localeSwitch("C");
99 
100  double range[2];
101  double rgba[4];
102 
103  std::string double_strings[4];
104 
105  vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
106 
107  int numberOfColors;
108  int scale;
109  int ramp; // hope the int values don't change betw. vtk versions...
110  if (element->QueryIntAttribute("NumberOfColors", &numberOfColors) == TIXML_SUCCESS)
111  {
112  lut->SetNumberOfTableValues(numberOfColors);
113  }
114  else
115  return nullptr;
116  if (element->QueryIntAttribute("Scale", &scale) == TIXML_SUCCESS)
117  {
118  lut->SetScale(scale);
119  }
120  else
121  return nullptr;
122  if (element->QueryIntAttribute("Ramp", &ramp) == TIXML_SUCCESS)
123  {
124  lut->SetRamp(ramp);
125  }
126  else
127  return nullptr;
128 
129  try
130  {
131  TiXmlElement *child = element->FirstChildElement("HueRange");
132  if (child)
133  {
134  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
135  return nullptr;
136  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
137  return nullptr;
138  StringsToNumbers<double>(2, double_strings, range);
139  lut->SetHueRange(range);
140  }
141 
142  child = element->FirstChildElement("ValueRange");
143  if (child)
144  {
145  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
146  return nullptr;
147  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
148  return nullptr;
149  StringsToNumbers<double>(2, double_strings, range);
150  lut->SetValueRange(range);
151  }
152 
153  child = element->FirstChildElement("SaturationRange");
154  if (child)
155  {
156  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
157  return nullptr;
158  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
159  return nullptr;
160  StringsToNumbers<double>(2, double_strings, range);
161  lut->SetSaturationRange(range);
162  }
163 
164  child = element->FirstChildElement("AlphaRange");
165  if (child)
166  {
167  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
168  return nullptr;
169  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
170  return nullptr;
171  StringsToNumbers<double>(2, double_strings, range);
172  lut->SetAlphaRange(range);
173  }
174 
175  child = element->FirstChildElement("TableRange");
176  if (child)
177  {
178  if (child->QueryStringAttribute("min", &double_strings[0]) != TIXML_SUCCESS)
179  return nullptr;
180  if (child->QueryStringAttribute("max", &double_strings[1]) != TIXML_SUCCESS)
181  return nullptr;
182  StringsToNumbers<double>(2, double_strings, range);
183  lut->SetTableRange(range);
184  }
185 
186  child = element->FirstChildElement("Table");
187  if (child)
188  {
189  unsigned int index(0);
190  for (TiXmlElement *grandChild = child->FirstChildElement("RgbaColor"); grandChild;
191  grandChild = grandChild->NextSiblingElement("RgbaColor"))
192  {
193  if (grandChild->QueryStringAttribute("R", &double_strings[0]) != TIXML_SUCCESS)
194  return nullptr;
195  if (grandChild->QueryStringAttribute("G", &double_strings[1]) != TIXML_SUCCESS)
196  return nullptr;
197  if (grandChild->QueryStringAttribute("B", &double_strings[2]) != TIXML_SUCCESS)
198  return nullptr;
199  if (grandChild->QueryStringAttribute("A", &double_strings[3]) != TIXML_SUCCESS)
200  return nullptr;
201  StringsToNumbers<double>(4, double_strings, rgba);
202  lut->SetTableValue(index, rgba);
203  ++index;
204  }
205  }
206  }
207  catch (boost::bad_lexical_cast &e)
208  {
209  MITK_ERROR << "Could not parse string as number: " << e.what();
210  return nullptr;
211  }
212 
214  mitkLut->SetVtkLookupTable(lut);
215 
216  return LookupTableProperty::New(mitkLut).GetPointer();
217 }
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual 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()
virtual TiXmlElement * Serialize() override
Serializes given BaseData object.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.