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