Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.