CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxTransferFunctions3DPresets.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 
14 
15 #include <iostream>
16 #include <vtkColorTransferFunction.h>
17 #include <QStringList>
18 #include <QDomElement>
19 #include <QDomDocument>
20 #include <QColor>
21 #include "cxTypeConversions.h"
22 #include "cxXmlOptionItem.h"
23 #include "cxImageTF3D.h"
24 #include "cxImageLUT2D.h"
25 #include "cxImageTFData.h"
26 #include "cxEnumConversion.h"
27 
28 namespace cx
29 {
30 
32  Presets(presetFile, customFile)
33 {
34 }
35 
36 void TransferFunctions3DPresets::save(QString name, ImagePtr image, bool _2D, bool _3D)
37 {
38  if (_2D)
39  this->save2D(name, image);
40  if (_3D)
41  this->save3D(name, image);
42 }
43 
45 {
46  XmlOptionFile file = this->getCustomFile();
47  file = file.descend("Preset", "name", name);
48 
49  QDomNode tf2DNode = file.getElement("lookuptable2D");
50  while (tf2DNode.hasChildNodes())
51  tf2DNode.removeChild(tf2DNode.firstChild());
52 
53  ImageLUT2DPtr LUT2D = image->getLookupTable2D();
54 
55  // For unsigned CT: Modify transfer function values temporarily prior to save
56  if ((0 <= image->getMin()) && (imCT == image->getModality()))
57  {
58  LUT2D->unsignedCT(false);
59  }
60 
61  LUT2D->addXml(file.getElement("lookuptable2D"));
62 
63  // Revert the transfer function values back again
64  if ((0 <= image->getMin()) && (imCT == image->getModality()))
65  {
66  LUT2D->unsignedCT(true);
67  }
68 
69  file.getElement().setAttribute("modality", enum2string(image->getModality()));
70  file.save();
71 
72 // emit changed();
73 }
74 
76 {
77  //create the node to be saved
78  XmlOptionFile file = this->getCustomFile();
79  file = file.descend("Preset", "name", name);
80 
81  QDomNode tf3DNode = file.getElement("transferfunctions");
82  while (tf3DNode.hasChildNodes())
83  tf3DNode.removeChild(tf3DNode.firstChild());
84 
85  ImageTF3DPtr transferFunctions = image->getTransferFunctions3D();
86 
87  // For unsigned CT: Modify transfer function values temporarily prior to save
88  if ((0 <= image->getMin()) && (imCT == image->getModality()))
89  {
90  transferFunctions->unsignedCT(false);
91  }
92 
93  transferFunctions->addXml(file.getElement("transferfunctions"));
94  image->getShading().addXml(file.getElement("shading"));
95 
96  // Revert the transfer function values back again
97  if ((0 <= image->getMin()) && (imCT == image->getModality()))
98  {
99  transferFunctions->unsignedCT(true);
100  }
101 
102  file.getElement().setAttribute("modality", enum2string(image->getModality()));
103  file.save();
104 }
105 
106 void TransferFunctions3DPresets::load(QString name, ImagePtr image, bool _2D, bool _3D)
107 {
108  if (_2D)
109  this->load2D(name, image);
110  if (_3D)
111  this->load3D(name, image);
112 }
113 
115 {
116  if(!image)
117  return;
118 
119  //Make sure transfer functions are reset in case something is missing from the preset
120  image->resetTransferFunctions(true, false);
121 
122  ImageLUT2DPtr LUT2D = image->getLookupTable2D();
123  XmlOptionFile node = this->getPresetNode(name);
124 
125  LUT2D->parseXml(node.getElement().namedItem("lookuptable2D"));
126 
127  // Transfer functions for CT data are signed, so these have to be converted if they are to be used for unsigned CT
128  if ((0 <= image->getMin()) && (imCT == image->getModality()) && (name != "Transfer function preset...") )
129  {
130  LUT2D->unsignedCT(true);
131  }
132 }
133 
135 {
136  //Make sure transfer functions are reset in case something is missing from the preset
137  image->resetTransferFunctions(false, true);
138 
139  ImageTF3DPtr transferFunctions = image->getTransferFunctions3D();
140  XmlOptionFile node = this->getPresetNode(name);
141 
142  transferFunctions->parseXml(node.getElement().namedItem("transferfunctions"));
143 
144  Image::ShadingStruct shading = image->getShading();
145  shading.parseXml(node.getElement().namedItem("shading"));
146  image->setShading(shading);
147 
148  // Transfer functions for CT data are signed, so these have to be converted if they are to be used for unsigned CT
149  if ((0 <= image->getMin()) && (imCT == image->getModality()) && (name != "Transfer function preset...") )
150  {
151  transferFunctions->unsignedCT(true);
152  }
153 }
154 
155 QStringList TransferFunctions3DPresets::generatePresetList(IMAGE_MODALITY modality)
156 {
157  QStringList presetList;
158 
159  QDomNodeList presetNodeList = mPresetFile.getElement().elementsByTagName("Preset");
160  for (int i = 0; i < presetNodeList.count(); ++i)
161  {
162  QString presetName = presetNodeList.item(i).toElement().attribute("name");
163  if (presetName == "Default")
164  continue;
165  else
166  {
167  QString sourceModality = presetNodeList.item(i).toElement().attribute("modality");
168  if ( (modality == string2enum<IMAGE_MODALITY>(sourceModality)) || (imUNKNOWN == modality) || imCOUNT == modality )
169  presetList << presetName;
170  }
171  }
172 
173  XmlOptionFile customFile = this->getCustomFile();
174  presetNodeList = customFile.getElement().elementsByTagName("Preset");
175  for (int i = 0; i < presetNodeList.count(); ++i)
176  {
177  QString presetName = presetNodeList.item(i).toElement().attribute("name");
178  QString presetModality = presetNodeList.item(i).toElement().attribute("modality");
179  if ( (string2enum<IMAGE_MODALITY>(presetModality) == modality) || (imUNKNOWN == modality) || imCOUNT == modality )
180  presetList << presetName;
181  }
182 
183  return presetList;
184 }
185 
186 void TransferFunctions3DPresets::deletePresetData(QString name, bool _2D, bool _3D)
187 {
188  //todo rewrite
189  std::cout << "TODO rewrite TransferFunctions3DPresets::deletePresetData(QString name, bool _2D, bool _3D)" << std::endl;
190  XmlOptionFile node = this->getPresetNode(name);
191 
192  if (_2D)
193  node.descend("lookuptable2D").deleteNode();
194  if (_3D)
195  node.descend("transferfunctions").deleteNode();
196  if (_2D && _3D)
197  node.deleteNode();
198 
199  emit changed();
200 }
201 
202 }
void load2D(QString name, ImagePtr image)
void load(QString name, ImagePtr image, bool _2D=true, bool _3D=true)
void parseXml(QDomNode dataNode)
Definition: cxImage.cpp:80
Base class for a group of presets in the system.
Definition: cxPresets.h:41
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
void load3D(QString name, ImagePtr image)
virtual void save()
saves the presets to file
Definition: cxPresets.cpp:44
QDomElement getElement()
return the current element
virtual QStringList generatePresetList(IMAGE_MODALITY modality)
internally generate the preset list
void save3D(QString name, ImagePtr image)
XmlOptionFile mPresetFile
< the name of the last custom preset removed
Definition: cxPresets.h:75
void deletePresetData(QString name, bool _2D=true, bool _3D=true)
Delete the preset data node.
XmlOptionFile getCustomFile()
Definition: cxPresets.cpp:74
TransferFunctions3DPresets(XmlOptionFile presetFile, XmlOptionFile customFile)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
void save2D(QString name, ImagePtr image)
void changed()
void deleteNode()
Delete the current node.
imUNKNOWN
void save()
save entire document.
XmlOptionFile getPresetNode(const QString &presetName)
Look for a preset with the given name. Create one if not found.
Definition: cxPresets.cpp:79
imCT
QString enum2string(const ENUM &val)
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr
Helper class for xml files used to store ssc/cx data.
XmlOptionFile descend(QString element) const
step one level down in the xml tree
Namespace for all CustusX production code.