Medical Imaging Interaction Toolkit  2018.4.99-93926fb8
Medical Imaging Interaction Toolkit
mitkCoreObjectFactory.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 
13 #include "mitkCoreObjectFactory.h"
14 #include "mitkConfig.h"
15 
16 #include "mitkColorProperty.h"
17 #include "mitkDataNode.h"
19 #include "mitkGeometry3D.h"
20 #include "mitkGeometryData.h"
21 #include "mitkImage.h"
23 #include "mitkLookupTable.h"
25 #include "mitkPlaneGeometry.h"
26 #include "mitkPlaneGeometryData.h"
29 #include "mitkPointSet.h"
32 #include "mitkProperties.h"
33 #include "mitkPropertyList.h"
34 #include "mitkSlicedGeometry3D.h"
36 #include "mitkStringProperty.h"
37 #include "mitkSurface.h"
38 #include "mitkSurface.h"
39 #include "mitkSurfaceVtkMapper2D.h"
40 #include "mitkSurfaceVtkMapper3D.h"
41 #include "mitkTimeGeometry.h"
46 #include <mitkImageVtkMapper2D.h>
47 
48 // Legacy Support:
49 #include <mitkCoreServices.h>
52 
54 {
55  MITK_DEBUG << "CoreObjectFactory: registering extra factory of type " << factory->GetNameOfClass();
57  // Register Legacy Reader and Writer
58  this->RegisterLegacyReaders(factory);
59  this->RegisterLegacyWriters(factory);
60 }
61 
63 {
64  MITK_DEBUG << "CoreObjectFactory: un-registering extra factory of type " << factory->GetNameOfClass();
65  this->UnRegisterLegacyWriters(factory);
66  this->UnRegisterLegacyReaders(factory);
67  try
68  {
69  m_ExtraFactories.erase(factory);
70  }
71  catch ( const std::exception &e )
72  {
73  MITK_ERROR << "Caugt exception while unregistering: " << e.what();
74  }
75 }
76 
78 {
79  static mitk::CoreObjectFactory::Pointer instance;
80  if (instance.IsNull())
81  {
82  instance = mitk::CoreObjectFactory::New();
83  }
84  return instance;
85 }
86 
88 {
89  for (auto iter =
90  m_LegacyReaders.begin();
91  iter != m_LegacyReaders.end();
92  ++iter)
93  {
94  for (auto &elem : iter->second)
95  {
96  delete elem;
97  }
98  }
99 
100  for (auto iter =
101  m_LegacyWriters.begin();
102  iter != m_LegacyWriters.end();
103  ++iter)
104  {
105  for (auto &elem : iter->second)
106  {
107  delete elem;
108  }
109  }
110 }
111 
113 {
114  if (node == nullptr)
115  return;
116 
117  mitk::DataNode::Pointer nodePointer = node;
118 
119  mitk::Image::Pointer image = dynamic_cast<mitk::Image *>(node->GetData());
120  if (image.IsNotNull() && image->IsInitialized())
121  {
123  }
124 
125  mitk::PlaneGeometryData::Pointer planeGeometry = dynamic_cast<mitk::PlaneGeometryData *>(node->GetData());
126  if (planeGeometry.IsNotNull())
127  {
129  }
130 
131  mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface *>(node->GetData());
132  if (surface.IsNotNull())
133  {
136  }
137 
138  mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet *>(node->GetData());
139  if (pointSet.IsNotNull())
140  {
143  }
144  for (auto it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); ++it)
145  {
146  (*it)->SetDefaultProperties(node);
147  }
148 }
149 
151 {
152  static bool alreadyDone = false;
153  if (!alreadyDone)
154  {
156 
157  // RegisterLegacyReaders(this);
158  // RegisterLegacyWriters(this);
159 
160  alreadyDone = true;
161  }
162 }
163 
165 {
166  mitk::Mapper::Pointer newMapper = nullptr;
167  mitk::Mapper::Pointer tmpMapper = nullptr;
168 
169  // check whether extra factories provide mapper
170  for (auto it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); ++it)
171  {
172  tmpMapper = (*it)->CreateMapper(node, id);
173  if (tmpMapper.IsNotNull())
174  newMapper = tmpMapper;
175  }
176 
177  if (newMapper.IsNull())
178  {
179  mitk::BaseData *data = node->GetData();
180 
182  {
183  if ((dynamic_cast<Image *>(data) != nullptr))
184  {
185  newMapper = mitk::ImageVtkMapper2D::New();
186  newMapper->SetDataNode(node);
187  }
188  else if ((dynamic_cast<PlaneGeometryData *>(data) != nullptr))
189  {
191  newMapper->SetDataNode(node);
192  }
193  else if ((dynamic_cast<Surface *>(data) != nullptr))
194  {
195  newMapper = mitk::SurfaceVtkMapper2D::New();
196  // cast because SetDataNode is not virtual
197  auto *castedMapper = dynamic_cast<mitk::SurfaceVtkMapper2D *>(newMapper.GetPointer());
198  castedMapper->SetDataNode(node);
199  }
200  else if ((dynamic_cast<PointSet *>(data) != nullptr))
201  {
202  newMapper = mitk::PointSetVtkMapper2D::New();
203  newMapper->SetDataNode(node);
204  }
205  }
206  else if (id == mitk::BaseRenderer::Standard3D)
207  {
208  if ((dynamic_cast<PlaneGeometryData *>(data) != nullptr))
209  {
211  newMapper->SetDataNode(node);
212  }
213  else if ((dynamic_cast<Surface *>(data) != nullptr))
214  {
215  newMapper = mitk::SurfaceVtkMapper3D::New();
216  newMapper->SetDataNode(node);
217  }
218  else if ((dynamic_cast<PointSet *>(data) != nullptr))
219  {
220  newMapper = mitk::PointSetVtkMapper3D::New();
221  newMapper->SetDataNode(node);
222  }
223  }
224  }
225 
226  return newMapper;
227 }
228 
230 {
231  MultimapType aMap;
232  for (auto it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); ++it)
233  {
234  aMap = (*it)->GetFileExtensionsMap();
236  }
238  return m_FileExtensions.c_str();
239 }
240 
242 {
243  std::pair<MultimapType::iterator, MultimapType::iterator> pairOfIter;
244  for (auto it = inputMap.begin(); it != inputMap.end(); ++it)
245  {
246  bool duplicateFound = false;
247  pairOfIter = fileExtensionsMap.equal_range((*it).first);
248  for (auto it2 = pairOfIter.first; it2 != pairOfIter.second; ++it2)
249  {
250  // cout << " [" << (*it).first << ", " << (*it).second << "]" << endl;
251  std::string aString = (*it2).second;
252  if (aString.compare((*it).second) == 0)
253  {
254  // cout << " DUP!! [" << (*it).first << ", " << (*it).second << "]" << endl;
255  duplicateFound = true;
256  break;
257  }
258  }
259  if (!duplicateFound)
260  {
261  fileExtensionsMap.insert(std::pair<std::string, std::string>((*it).first, (*it).second));
262  }
263  }
264 }
265 
267 {
268  return m_FileExtensionsMap;
269 }
270 
272 {
273  /*
274  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dcm", "DICOM files"));
275  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.DCM", "DICOM files"));
276  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dc3", "DICOM files"));
277  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.DC3", "DICOM files"));
278  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.gdcm", "DICOM files"));
279  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.seq", "DKFZ Pic"));
280  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.seq.gz", "DKFZ Pic"));
281  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.dcm", "Sets of 2D slices"));
282  m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.gdcm", "Sets of 2D slices"));
283  */
284 }
285 
287 {
288  MultimapType aMap;
289  for (auto it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); ++it)
290  {
291  aMap = (*it)->GetSaveFileExtensionsMap();
293  }
295  return m_SaveFileExtensions.c_str();
296 }
297 
299 {
301 }
302 
304 {
305  FileWriterList allWriters = m_FileWriters;
306  // sort to merge lists later on
307  typedef std::set<mitk::FileWriterWithInformation::Pointer> FileWriterSet;
308  FileWriterSet fileWritersSet;
309 
310  fileWritersSet.insert(allWriters.begin(), allWriters.end());
311 
312  // collect all extra factories
313  for (auto it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); ++it)
314  {
315  FileWriterList list2 = (*it)->GetFileWriters();
316 
317  // add them to the sorted set
318  fileWritersSet.insert(list2.begin(), list2.end());
319  }
320 
321  // write back to allWriters to return a list
322  allWriters.clear();
323  allWriters.insert(allWriters.end(), fileWritersSet.begin(), fileWritersSet.end());
324 
325  return allWriters;
326 }
327 
328 void mitk::CoreObjectFactory::MapEvent(const mitk::Event *, const int)
329 {
330 }
331 
332 std::string mitk::CoreObjectFactory::GetDescriptionForExtension(const std::string &extension)
333 {
334  std::multimap<std::string, std::string> fileExtensionMap = GetSaveFileExtensionsMap();
335  for (auto it = fileExtensionMap.begin(); it != fileExtensionMap.end();
336  ++it)
337  if (it->first == extension)
338  return it->second;
339  return ""; // If no matching extension was found, return emtpy string
340 }
341 
342 void mitk::CoreObjectFactory::RegisterLegacyReaders(mitk::CoreObjectFactoryBase *factory)
343 {
344  // We are not really interested in the string, just call the method since
345  // many readers initialize the map the first time when this method is called
346  factory->GetFileExtensions();
347 
348  std::map<std::string, std::vector<std::string>> extensionsByCategories;
349  std::multimap<std::string, std::string> fileExtensionMap = factory->GetFileExtensionsMap();
350  for (auto it = fileExtensionMap.begin(); it != fileExtensionMap.end();
351  ++it)
352  {
353  std::string extension = it->first;
354  // remove "*."
355  extension = extension.erase(0, 2);
356 
357  extensionsByCategories[it->second].push_back(extension);
358  }
359 
360  for (auto &extensionsByCategorie : extensionsByCategories)
361  {
362  m_LegacyReaders[factory].push_back(
363  new mitk::LegacyFileReaderService(extensionsByCategorie.second, extensionsByCategorie.first));
364  }
365 }
366 
367 void mitk::CoreObjectFactory::UnRegisterLegacyReaders(mitk::CoreObjectFactoryBase *factory)
368 {
369  auto iter =
370  m_LegacyReaders.find(factory);
371  if (iter != m_LegacyReaders.end())
372  {
373  for (auto &elem : iter->second)
374  {
375  delete elem;
376  }
377 
378  m_LegacyReaders.erase(iter);
379  }
380 }
381 
382 void mitk::CoreObjectFactory::RegisterLegacyWriters(mitk::CoreObjectFactoryBase *factory)
383 {
384  // Get all external Writers
386 
387  // We are not really interested in the string, just call the method since
388  // many writers initialize the map the first time when this method is called
389  factory->GetSaveFileExtensions();
390 
391  MultimapType fileExtensionMap = factory->GetSaveFileExtensionsMap();
392 
393  for (auto it = writers.begin(); it != writers.end(); ++it)
394  {
395  std::vector<std::string> extensions = (*it)->GetPossibleFileExtensions();
396  if (extensions.empty())
397  continue;
398 
399  std::string description;
400  for (auto ext = extensions.begin(); ext != extensions.end(); ++ext)
401  {
402  if (ext->empty())
403  continue;
404 
405  std::string extension = *ext;
406  std::string extensionWithStar = extension;
407  if (extension.find_first_of('*') == 0)
408  {
409  // remove "*."
410  extension = extension.substr(0, extension.size() - 2);
411  }
412  else
413  {
414  extensionWithStar.insert(extensionWithStar.begin(), '*');
415  }
416 
417  for (auto fileExtensionIter = fileExtensionMap.begin();
418  fileExtensionIter != fileExtensionMap.end();
419  ++fileExtensionIter)
420  {
421  if (fileExtensionIter->first == extensionWithStar)
422  {
423  description = fileExtensionIter->second;
424  break;
425  }
426  }
427  if (!description.empty())
428  break;
429  }
430  if (description.empty())
431  {
432  description = std::string("Legacy ") + (*it)->GetNameOfClass() + " Reader";
433  }
434 
435  mitk::FileWriter::Pointer fileWriter(it->GetPointer());
436  mitk::LegacyFileWriterService *lfws = new mitk::LegacyFileWriterService(fileWriter, description);
437  m_LegacyWriters[factory].push_back(lfws);
438  }
439 }
440 
441 void mitk::CoreObjectFactory::UnRegisterLegacyWriters(mitk::CoreObjectFactoryBase *factory)
442 {
443  auto iter =
444  m_LegacyWriters.find(factory);
445  if (iter != m_LegacyWriters.end())
446  {
447  for (auto &elem : iter->second)
448  {
449  delete elem;
450  }
451 
452  m_LegacyWriters.erase(iter);
453  }
454 }
Vtk-based mapper for cutting 2D slices out of Surfaces.
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
set the default properties for this mapper
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
virtual void MapEvent(const mitk::Event *event, const int eventID)
ExtraFactoriesContainer m_ExtraFactories
Base of all data objects.
Definition: mitkBaseData.h:42
#define MITK_ERROR
Definition: mitkLogMacros.h:20
virtual MultimapType GetFileExtensionsMap()=0
virtual void UnRegisterExtraFactory(CoreObjectFactoryBase *factory)
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
std::string GetDescriptionForExtension(const std::string &extension)
virtual MultimapType GetSaveFileExtensionsMap()=0
virtual void SetDataNode(DataNode *_arg)
Set the DataNode containing the data to map.
void SetDefaultProperties(mitk::DataNode *node) override
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
set the default properties for this mapper
virtual MultimapType GetFileExtensionsMap() override
get the defined (open) file extension map
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
virtual std::string GetFileExtensions() override
This method gets the supported (open) file extensions as string.
virtual std::string GetSaveFileExtensions()=0
static Pointer New()
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
static Pointer New()
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:75
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
set the default properties for this mapper
virtual std::string GetSaveFileExtensions() override
This method gets the supported (save) file extensions as string.
void CreateFileExtensionsMap()
initialize the file extension entries for open and save
MultimapType GetSaveFileExtensionsMap() override
get the defined (save) file extension map
Image class for storing images.
Definition: mitkImage.h:72
virtual void RegisterExtraFactory(CoreObjectFactoryBase *factory)
Data class containing PlaneGeometry objects.
mitk::Image::Pointer image
static void CreateFileExtensions(MultimapType fileExtensionsMap, std::string &fileExtensions)
create a string from a map that contains the file extensions
static void SetDefaultProperties(mitk::DataNode *node, mitk::BaseRenderer *renderer=nullptr, bool overwrite=false)
Set the default properties for general image rendering.
virtual FileWriterList GetFileWriters()
static Pointer New()
Mapper::Pointer CreateMapper(mitk::DataNode *node, MapperSlotId slotId) override
void MergeFileExtensions(MultimapType &fileExtensionsMap, MultimapType inputMap)
Merge the input map into the fileExtensionsMap. Duplicate entries are removed.
static Pointer New()
static Pointer New()
unsigned int MapperSlotId
Definition: mitkCommon.h:33
std::multimap< std::string, std::string > MultimapType
std::list< mitk::FileWriterWithInformation::Pointer > FileWriterList
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
static Pointer New()
virtual std::string GetFileExtensions()=0