Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkTransferFunctionPropertySerializer.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 <boost/lexical_cast.hpp>
19 #include <mitkLocaleSwitch.h>
20 
21 namespace mitk
22 {
26  {
27  if (const TransferFunctionProperty *prop =
28  dynamic_cast<const TransferFunctionProperty *>(mitk::BasePropertySerializer::m_Property.GetPointer()))
29  {
30  LocaleSwitch localeSwitch("C");
31 
32  TransferFunction *transferfunction = prop->GetValue();
33  if (!transferfunction)
34  return nullptr;
35 
36  auto element = new TiXmlElement("TransferFunction");
37 
38  // serialize scalar opacity function
39  auto scalarOpacityPointlist = new TiXmlElement("ScalarOpacity");
40 
41  TransferFunction::ControlPoints scalarOpacityPoints = transferfunction->GetScalarOpacityPoints();
42  for (auto iter = scalarOpacityPoints.begin(); iter != scalarOpacityPoints.end(); ++iter)
43  {
44  auto pointel = new TiXmlElement("point");
45  pointel->SetAttribute("x", boost::lexical_cast<std::string>(iter->first));
46  pointel->SetAttribute("y", boost::lexical_cast<std::string>(iter->second));
47  scalarOpacityPointlist->LinkEndChild(pointel);
48  }
49  element->LinkEndChild(scalarOpacityPointlist);
50  // serialize gradient opacity function
51  auto gradientOpacityPointlist = new TiXmlElement("GradientOpacity");
52  TransferFunction::ControlPoints gradientOpacityPoints = transferfunction->GetGradientOpacityPoints();
53  for (auto iter = gradientOpacityPoints.begin(); iter != gradientOpacityPoints.end(); ++iter)
54  {
55  auto pointel = new TiXmlElement("point");
56  pointel->SetAttribute("x", boost::lexical_cast<std::string>(iter->first));
57  pointel->SetAttribute("y", boost::lexical_cast<std::string>(iter->second));
58  gradientOpacityPointlist->LinkEndChild(pointel);
59  }
60  element->LinkEndChild(gradientOpacityPointlist);
61 
62  // serialize color function
63  vtkColorTransferFunction *ctf = transferfunction->GetColorTransferFunction();
64  if (ctf == nullptr)
65  return nullptr;
66  auto pointlist = new TiXmlElement("Color");
67  for (int i = 0; i < ctf->GetSize(); i++)
68  {
69  double myVal[6];
70  ctf->GetNodeValue(i, myVal);
71  auto pointel = new TiXmlElement("point");
72  pointel->SetAttribute("x", boost::lexical_cast<std::string>(myVal[0]));
73  pointel->SetAttribute("r", boost::lexical_cast<std::string>(myVal[1]));
74  pointel->SetAttribute("g", boost::lexical_cast<std::string>(myVal[2]));
75  pointel->SetAttribute("b", boost::lexical_cast<std::string>(myVal[3]));
76  pointel->SetAttribute("midpoint", boost::lexical_cast<std::string>(myVal[4]));
77  pointel->SetAttribute("sharpness", boost::lexical_cast<std::string>(myVal[5]));
78  pointlist->LinkEndChild(pointel);
79  }
80  element->LinkEndChild(pointlist);
81  return element;
82  }
83  else
84  return nullptr;
85  }
86 
89  {
91  tfps->SetProperty(TransferFunctionProperty::New(tf));
92  TiXmlElement *s = tfps->Serialize();
93 
94  if (!s)
95  {
96  MITK_ERROR << "cant serialize transfer function";
97 
98  return false;
99  }
100 
101  TiXmlDocument document;
102  auto decl = new TiXmlDeclaration(
103  "1.0",
104  "UTF-8",
105  ""); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere...
106  document.LinkEndChild(decl);
107 
108  auto version = new TiXmlElement("Version");
109  version->SetAttribute("TransferfunctionVersion", 1);
110 
111  document.LinkEndChild(version);
112  document.LinkEndChild(s);
113 
114  if (!document.SaveFile(filename))
115  {
116  MITK_ERROR << "Could not write scene to " << filename << "\nTinyXML reports '" << document.ErrorDesc() << "'";
117  return false;
118  }
119  return true;
120  }
121 
123  {
124  if (!element)
125  return nullptr;
126 
127  mitk::LocaleSwitch localeSwitch("C");
128 
130 
131  // deserialize scalar opacity function
132  TiXmlElement *scalarOpacityPointlist = element->FirstChildElement("ScalarOpacity");
133  if (scalarOpacityPointlist == nullptr)
134  {
135  return nullptr;
136  }
137 
138  tf->ClearScalarOpacityPoints();
139 
140  try
141  {
142  for (TiXmlElement *pointElement = scalarOpacityPointlist->FirstChildElement("point"); pointElement != nullptr;
143  pointElement = pointElement->NextSiblingElement("point"))
144  {
145  std::string x;
146  std::string y;
147  if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS)
148  return nullptr;
149  if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS)
150  return nullptr;
151  tf->AddScalarOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
152  }
153 
154  TiXmlElement *gradientOpacityPointlist = element->FirstChildElement("GradientOpacity");
155  if (gradientOpacityPointlist == nullptr)
156  {
157  return nullptr;
158  }
159 
160  tf->ClearGradientOpacityPoints();
161 
162  for (TiXmlElement *pointElement = gradientOpacityPointlist->FirstChildElement("point"); pointElement != nullptr;
163  pointElement = pointElement->NextSiblingElement("point"))
164  {
165  std::string x;
166  std::string y;
167  if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS)
168  return nullptr;
169  if (pointElement->QueryStringAttribute("y", &y) != TIXML_SUCCESS)
170  return nullptr;
171  tf->AddGradientOpacityPoint(boost::lexical_cast<double>(x), boost::lexical_cast<double>(y));
172  }
173 
174  TiXmlElement *rgbPointlist = element->FirstChildElement("Color");
175  if (rgbPointlist == nullptr)
176  {
177  return nullptr;
178  }
179  vtkColorTransferFunction *ctf = tf->GetColorTransferFunction();
180  if (ctf == nullptr)
181  {
182  return nullptr;
183  }
184 
185  ctf->RemoveAllPoints();
186 
187  for (TiXmlElement *pointElement = rgbPointlist->FirstChildElement("point"); pointElement != nullptr;
188  pointElement = pointElement->NextSiblingElement("point"))
189  {
190  std::string x;
191  std::string r, g, b, midpoint, sharpness;
192  if (pointElement->QueryStringAttribute("x", &x) != TIXML_SUCCESS)
193  return nullptr;
194  if (pointElement->QueryStringAttribute("r", &r) != TIXML_SUCCESS)
195  return nullptr;
196  if (pointElement->QueryStringAttribute("g", &g) != TIXML_SUCCESS)
197  return nullptr;
198  if (pointElement->QueryStringAttribute("b", &b) != TIXML_SUCCESS)
199  return nullptr;
200  if (pointElement->QueryStringAttribute("midpoint", &midpoint) != TIXML_SUCCESS)
201  return nullptr;
202  if (pointElement->QueryStringAttribute("sharpness", &sharpness) != TIXML_SUCCESS)
203  return nullptr;
204  ctf->AddRGBPoint(boost::lexical_cast<double>(x),
205  boost::lexical_cast<double>(r),
206  boost::lexical_cast<double>(g),
207  boost::lexical_cast<double>(b),
208  boost::lexical_cast<double>(midpoint),
209  boost::lexical_cast<double>(sharpness));
210  }
211  }
212  catch (boost::bad_lexical_cast &e)
213  {
214  MITK_ERROR << "Could not parse string as number: " << e.what();
215 
216  return nullptr;
217  }
218 
219  return TransferFunctionProperty::New(tf).GetPointer();
220  }
221 
223  const char *filePath)
224  {
225  TiXmlDocument document(filePath);
226 
227  if (!document.LoadFile())
228  {
229  MITK_ERROR << "Could not open/read/parse " << filePath << "\nTinyXML reports: " << document.ErrorDesc()
230  << std::endl;
231  return nullptr;
232  }
233 
234  // find version node --> note version in some variable
235  int fileVersion = 1;
236  TiXmlElement *versionObject = document.FirstChildElement("Version");
237  if (versionObject)
238  {
239  if (versionObject->QueryIntAttribute("TransferfunctionVersion", &fileVersion) != TIXML_SUCCESS)
240  {
241  MITK_WARN << "Transferfunction file " << filePath
242  << " does not contain version information! Trying version 1 format.";
243  }
244  }
245 
246  TiXmlElement *input = document.FirstChildElement("TransferFunction");
247 
249  BaseProperty::Pointer bp = tfpd->Deserialize(input);
250  TransferFunctionProperty::Pointer tfp = dynamic_cast<TransferFunctionProperty *>(bp.GetPointer());
251 
252  if (tfp.IsNotNull())
253  {
254  TransferFunction::Pointer tf = tfp->GetValue();
255  return tf;
256  }
257  MITK_WARN << "Can't deserialize transfer function";
258  return nullptr;
259  }
260 
261 } // namespace
262 
263 // important to put this into the GLOBAL namespace (because it starts with 'namespace mitk')
264 MITK_REGISTER_SERIALIZER(TransferFunctionPropertySerializer);
virtual vtkColorTransferFunction * GetColorTransferFunction()
Get/Set wrapped vtk transfer function.
The TransferFunctionProperty class Property class for the mitk::TransferFunction. ...
static bool SerializeTransferFunction(const char *filename, TransferFunction::Pointer tf)
itk::SmartPointer< Self > Pointer
virtual BaseProperty::Pointer Deserialize(TiXmlElement *element) override
Deserializes given TiXmlElement.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual TiXmlElement * Serialize() override
Serializes given BaseProperty object.
The TransferFunction class A wrapper class for VTK scalar opacity, gradient opacity, and color transfer functions.Holds a copy of each of the three standard VTK transfer functions (scalar opacity, gradient opacity, color) and provides an interface for manipulating their control points. Each original function can be retrieved by a Get() method.
DataCollection - Class to facilitate loading/accessing structured data.
static TransferFunction::Pointer DeserializeTransferFunction(const char *filePath)
TransferFunction::ControlPoints & GetScalarOpacityPoints()
Get a copy of the scalar opacity transfer function control-points.
#define MITK_WARN
Definition: mitkLogMacros.h:23
Convenience class to temporarily change the current locale.
static const std::string filename
static Pointer New()
MITK_REGISTER_SERIALIZER(TransferFunctionPropertySerializer)
std::vector< std::pair< double, double > > ControlPoints
BaseProperty::ConstPointer m_Property
TransferFunction::ControlPoints & GetGradientOpacityPoints()
Get a copy of the gradient opacity transfer function control-points.