Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkTool.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 
17 #include "mitkTool.h"
18 
19 #include "mitkDisplayInteractor.h"
20 #include "mitkImageReadAccessor.h"
21 #include "mitkImageWriteAccessor.h"
22 #include "mitkLabelSetImage.h"
25 #include "mitkProperties.h"
26 #include "mitkProperties.h"
28 
29 // us
30 #include <usGetModuleContext.h>
31 #include <usModuleResource.h>
32 
33 // itk
34 #include <itkObjectFactory.h>
35 
36 mitk::Tool::Tool(const char *type)
37  : m_PredicateImages(NodePredicateDataType::New("Image")) // for reference images
38  ,
39  m_PredicateDim3(NodePredicateDimension::New(3, 1)),
40  m_PredicateDim4(NodePredicateDimension::New(4, 1)),
41  m_PredicateDimension(mitk::NodePredicateOr::New(m_PredicateDim3, m_PredicateDim4)),
42  m_PredicateImage3D(NodePredicateAnd::New(m_PredicateImages, m_PredicateDimension)),
43  m_PredicateBinary(NodePredicateProperty::New("binary", BoolProperty::New(true))),
44  m_PredicateNotBinary(NodePredicateNot::New(m_PredicateBinary)),
45  m_PredicateSegmentation(NodePredicateProperty::New("segmentation", BoolProperty::New(true))),
46  m_PredicateNotSegmentation(NodePredicateNot::New(m_PredicateSegmentation)),
47  m_PredicateHelper(NodePredicateProperty::New("helper object", BoolProperty::New(true))),
48  m_PredicateNotHelper(NodePredicateNot::New(m_PredicateHelper)),
49  m_PredicateImageColorful(NodePredicateAnd::New(m_PredicateNotBinary, m_PredicateNotSegmentation)),
50  m_PredicateImageColorfulNotHelper(NodePredicateAnd::New(m_PredicateImageColorful, m_PredicateNotHelper)),
51  m_PredicateReference(NodePredicateAnd::New(m_PredicateImage3D, m_PredicateImageColorfulNotHelper)),
52  m_IsSegmentationPredicate(
53  NodePredicateAnd::New(NodePredicateOr::New(m_PredicateBinary, m_PredicateSegmentation), m_PredicateNotHelper)),
54  m_InteractorType(type),
55  m_DisplayInteractorConfigs(),
56  m_EventConfig("DisplayConfigMITK.xml")
57 {
58 }
59 
61 {
62 }
63 
65 {
66  return true;
67 }
68 
70 {
71  if (m_InteractorType.empty())
72  return;
73 
74  m_InteractorType += ".xml";
75 
76  try
77  {
78  LoadStateMachine(m_InteractorType, us::GetModuleContext()->GetModule());
79  SetEventConfig("SegmentationToolsConfig.xml", us::GetModuleContext()->GetModule());
80  }
81  catch (const std::exception &e)
82  {
83  MITK_ERROR << "Could not load statemachine pattern " << m_InteractorType << " with exception: " << e.what();
84  }
85 }
86 
87 void mitk::Tool::Notify(InteractionEvent *interactionEvent, bool isHandled)
88 {
89  // to use the state machine pattern,
90  // the event is passed to the state machine interface to be handled
91  if (!isHandled)
92  {
93  this->HandleEvent(interactionEvent, nullptr);
94  }
95 }
96 
98 {
99 }
100 
102 {
103  return true;
104 }
105 
106 const char *mitk::Tool::GetGroup() const
107 {
108  return "default";
109 }
110 
112 {
113  m_ToolManager = manager;
114 }
115 
117 {
118  // As a legacy solution the display interaction of the new interaction framework is disabled here to avoid conflicts
119  // with tools
120  // Note: this only affects InteractionEventObservers (formerly known as Listeners) all DataNode specific interaction
121  // will still be enabled
122  m_DisplayInteractorConfigs.clear();
123  std::vector<us::ServiceReference<InteractionEventObserver>> listEventObserver =
125  for (std::vector<us::ServiceReference<InteractionEventObserver>>::iterator it = listEventObserver.begin();
126  it != listEventObserver.end();
127  ++it)
128  {
129  DisplayInteractor *displayInteractor =
131  if (displayInteractor != nullptr)
132  {
133  // remember the original configuration
134  m_DisplayInteractorConfigs.insert(std::make_pair(*it, displayInteractor->GetEventConfig()));
135  // here the alternative configuration is loaded
136  displayInteractor->SetEventConfig(m_EventConfig.c_str());
137  }
138  }
139 }
140 
142 {
143  // Re-enabling InteractionEventObservers that have been previously disabled for legacy handling of Tools
144  // in new interaction framework
145  for (std::map<us::ServiceReferenceU, EventConfig>::iterator it = m_DisplayInteractorConfigs.begin();
146  it != m_DisplayInteractorConfigs.end();
147  ++it)
148  {
149  if (it->first)
150  {
151  DisplayInteractor *displayInteractor =
153  if (displayInteractor != nullptr)
154  {
155  // here the regular configuration is loaded again
156  displayInteractor->SetEventConfig(it->second);
157  }
158  }
159  }
160  m_DisplayInteractorConfigs.clear();
161 }
162 
163 itk::Object::Pointer mitk::Tool::GetGUI(const std::string &toolkitPrefix, const std::string &toolkitPostfix)
164 {
165  itk::Object::Pointer object;
166 
167  std::string classname = this->GetNameOfClass();
168  std::string guiClassname = toolkitPrefix + classname + toolkitPostfix;
169 
170  std::list<itk::LightObject::Pointer> allGUIs = itk::ObjectFactoryBase::CreateAllInstance(guiClassname.c_str());
171  for (std::list<itk::LightObject::Pointer>::iterator iter = allGUIs.begin(); iter != allGUIs.end(); ++iter)
172  {
173  if (object.IsNull())
174  {
175  object = dynamic_cast<itk::Object *>(iter->GetPointer());
176  }
177  else
178  {
179  MITK_ERROR << "There is more than one GUI for " << classname << " (several factories claim ability to produce a "
180  << guiClassname << " ) " << std::endl;
181  return nullptr; // people should see and fix this error
182  }
183  }
184 
185  return object;
186 }
187 
189 {
190  return m_PredicateReference.GetPointer();
191 }
192 
194 {
195  return m_IsSegmentationPredicate.GetPointer();
196 }
197 
199  const std::string &organName,
200  const mitk::Color &color)
201 {
202  // we NEED a reference image for size etc.
203  if (!original)
204  return nullptr;
205 
206  // actually create a new empty segmentation
207  PixelType pixelType(mitk::MakeScalarPixelType<DefaultSegmentationDataType>());
209 
210  if (original->GetDimension() == 2)
211  {
212  const unsigned int dimensions[] = {original->GetDimension(0), original->GetDimension(1), 1};
213  segmentation->Initialize(pixelType, 3, dimensions);
214  segmentation->AddLayer();
215  }
216  else
217  {
218  segmentation->Initialize(original);
219  }
220 
222  label->SetName(organName);
223  label->SetColor(color);
224  label->SetValue(1);
225  segmentation->GetActiveLabelSet()->AddLabel(label);
226  segmentation->GetActiveLabelSet()->SetActiveLabel(1);
227 
228  unsigned int byteSize = sizeof(mitk::Label::PixelType);
229 
230  if (segmentation->GetDimension() < 4)
231  {
232  for (unsigned int dim = 0; dim < segmentation->GetDimension(); ++dim)
233  {
234  byteSize *= segmentation->GetDimension(dim);
235  }
236 
237  mitk::ImageWriteAccessor writeAccess(segmentation.GetPointer(), segmentation->GetVolumeData(0));
238 
239  memset(writeAccess.GetData(), 0, byteSize);
240  }
241  else
242  {
243  // if we have a time-resolved image we need to set memory to 0 for each time step
244  for (unsigned int dim = 0; dim < 3; ++dim)
245  {
246  byteSize *= segmentation->GetDimension(dim);
247  }
248 
249  for (unsigned int volumeNumber = 0; volumeNumber < segmentation->GetDimension(3); volumeNumber++)
250  {
251  mitk::ImageWriteAccessor writeAccess(segmentation.GetPointer(), segmentation->GetVolumeData(volumeNumber));
252 
253  memset(writeAccess.GetData(), 0, byteSize);
254  }
255  }
256 
257  if (original->GetTimeGeometry())
258  {
259  TimeGeometry::Pointer originalGeometry = original->GetTimeGeometry()->Clone();
260  segmentation->SetTimeGeometry(originalGeometry);
261  }
262  else
263  {
264  Tool::ErrorMessage("Original image does not have a 'Time sliced geometry'! Cannot create a segmentation.");
265  return nullptr;
266  }
267 
268  return CreateSegmentationNode(segmentation, organName, color);
269 }
270 
272  const std::string &organName,
273  const mitk::Color &color)
274 {
275  if (!image)
276  return nullptr;
277 
278  // decorate the datatreenode with some properties
279  DataNode::Pointer segmentationNode = DataNode::New();
280  segmentationNode->SetData(image);
281 
282  // name
283  segmentationNode->SetProperty("name", StringProperty::New(organName));
284 
285  // visualization properties
286  segmentationNode->SetProperty("binary", BoolProperty::New(true));
287  segmentationNode->SetProperty("color", ColorProperty::New(color));
289  lut->SetType(mitk::LookupTable::MULTILABEL);
291  lutProp->SetLookupTable(lut);
292  segmentationNode->SetProperty("LookupTable", lutProp);
293  segmentationNode->SetProperty("texture interpolation", BoolProperty::New(false));
294  segmentationNode->SetProperty("layer", IntProperty::New(10));
295  segmentationNode->SetProperty("levelwindow", LevelWindowProperty::New(LevelWindow(0.5, 1)));
296  segmentationNode->SetProperty("opacity", FloatProperty::New(0.3));
297  segmentationNode->SetProperty("segmentation", BoolProperty::New(true));
298  segmentationNode->SetProperty("reslice interpolation",
299  VtkResliceInterpolationProperty::New()); // otherwise -> segmentation appears in 2
300  // slices sometimes (only visual effect, not
301  // different data)
302  // For MITK-3M3 release, the volume of all segmentations should be shown
303  segmentationNode->SetProperty("showVolume", BoolProperty::New(true));
304 
305  return segmentationNode;
306 }
307 
309 {
310  // Each specific tool should load its own resource. This one will be invalid
311  return us::ModuleResource();
312 }
313 
315 {
316  // Each specific tool should load its own resource. This one will be invalid
317  return us::ModuleResource();
318 }
virtual void Notify(InteractionEvent *interactionEvent, bool isHandled) override
Definition: mitkTool.cpp:87
DataNode::Pointer CreateSegmentationNode(Image *image, const std::string &organName, const mitk::Color &color)
Definition: mitkTool.cpp:271
Predicate that evaluates if the given DataNode has a specific property. If the second parameter is NU...
Composite predicate that negates its child predicate Changed: NodePredicateNot now derives from NodeP...
Base class to implement InteractionEventObservers.
itk::SmartPointer< Self > Pointer
Observer that manages the interaction with the display.
virtual void Activated()
Called when the tool gets activated.
Definition: mitkTool.cpp:116
Base of all data objects.
Definition: mitkBaseData.h:39
Predicate that evaluates if the given DataNodes data object has the specified dimension, for datasets where dimension is applicable.
static Pointer New()
virtual void SetToolManager(ToolManager *)
Definition: mitkTool.cpp:111
#define MITK_ERROR
Definition: mitkLogMacros.h:24
static Pointer New()
virtual ~Tool()
Definition: mitkTool.cpp:60
DataCollection - Class to facilitate loading/accessing structured data.
EventConfig GetEventConfig() const
Returns the current configuration.
Message1< std::string > ErrorMessage
To send error messages (to be shown by some GUI)
Definition: mitkTool.h:105
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
virtual NodePredicateBase::ConstPointer GetWorkingDataPreference() const
Definition: mitkTool.cpp:193
void * GetService(const ServiceReferenceBase &reference)
The LevelWindow class Class to store level/window values.
static Pointer New()
static Pointer New()
virtual void Deactivated()
Called when the tool gets deactivated.
Definition: mitkTool.cpp:141
static Pointer New()
virtual us::ModuleResource GetCursorIconResource() const
Returns the path of a cursor icon.
Definition: mitkTool.cpp:314
static Pointer New()
virtual void InitializeStateMachine()
Definition: mitkTool.cpp:69
Image class for storing images.
Definition: mitkImage.h:76
virtual NodePredicateBase::ConstPointer GetReferenceDataPreference() const
Definition: mitkTool.cpp:188
static Pointer New()
std::vector< ServiceReferenceU > GetServiceReferences(const std::string &clazz, const std::string &filter=std::string())
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
static Pointer New()
static Pointer New()
virtual const char * GetGroup() const
Name of a group.
Definition: mitkTool.cpp:106
virtual us::ModuleResource GetIconResource() const
Returns the tool button icon of the tool wrapped by a usModuleResource.
Definition: mitkTool.cpp:308
void ConnectActionsAndFunctions() override
Definition: mitkTool.cpp:97
unsigned short PixelType
Definition: mitkLabel.h:40
bool FilterEvents(InteractionEvent *, DataNode *) override
Definition: mitkTool.cpp:101
Pointer Clone() const
ImageWriteAccessor class to get locked write-access for a particular image part.
virtual itk::Object::Pointer GetGUI(const std::string &toolkitPrefix, const std::string &toolkitPostfix)
Interface for GUI creation.
Definition: mitkTool.cpp:163
Predicate that evaluates if the given DataNodes data object is of a specific data type...
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:110
static Pointer New()
virtual bool CanHandle(BaseData *referenceData) const
Definition: mitkTool.cpp:64
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
static Pointer New()
Composite predicate that forms a logical AND relation from its child predicates.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
Composite predicate that forms a logical OR relation from its child predicates.
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
Manages and coordinates instances of mitk::Tool.
bool SetEventConfig(const std::string &filename, const us::Module *module=nullptr)
Loads a configuration from an XML resource.
DataNode::Pointer CreateEmptySegmentationNode(Image *original, const std::string &organName, const mitk::Color &color)
Definition: mitkTool.cpp:198
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.