Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkSurfaceVtkXmlIO.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 "mitkSurfaceVtkXmlIO.h"
14 
15 #include "mitkIOMimeTypes.h"
16 #include "mitkSurface.h"
17 
18 #include <vtkErrorCode.h>
19 #include <vtkSmartPointer.h>
20 #include <vtkXMLPolyDataReader.h>
21 #include <vtkXMLPolyDataWriter.h>
22 
23 namespace mitk
24 {
25  class VtkXMLPolyDataReader : public ::vtkXMLPolyDataReader
26  {
27  public:
28  static VtkXMLPolyDataReader *New() { return new VtkXMLPolyDataReader(); }
29  vtkTypeMacro(VtkXMLPolyDataReader, vtkXMLPolyDataReader)
30 
31  void SetStream(std::istream *is)
32  {
33  this->Stream = is;
34  }
35  std::istream *GetStream() const { return this->Stream; }
36  };
37 
38  class VtkXMLPolyDataWriter : public ::vtkXMLPolyDataWriter
39  {
40  public:
41  static VtkXMLPolyDataWriter *New() { return new VtkXMLPolyDataWriter(); }
42  vtkTypeMacro(VtkXMLPolyDataWriter, vtkXMLPolyDataWriter)
43 
44  void SetStream(std::ostream *os)
45  {
46  this->Stream = os;
47  }
48  std::ostream *GetStream() const { return this->Stream; }
49  };
50 
52  : SurfaceVtkIO(Surface::GetStaticNameOfClass(), IOMimeTypes::VTK_POLYDATA_MIMETYPE(), "VTK XML PolyData")
53  {
54  this->RegisterService();
55  }
56 
57  std::vector<itk::SmartPointer<BaseData>> SurfaceVtkXmlIO::Read()
58  {
60 
61  vtkSmartPointer<VtkXMLPolyDataReader> reader = vtkSmartPointer<VtkXMLPolyDataReader>::New();
62  if (this->GetInputStream())
63  {
64  reader->SetStream(this->GetInputStream());
65  }
66  else
67  {
68  reader->SetFileName(this->GetInputLocation().c_str());
69  }
70  reader->Update();
71 
72  if (reader->GetOutput() != nullptr)
73  {
74  output->SetVtkPolyData(reader->GetOutput());
75  }
76  else
77  {
78  mitkThrow() << "vtkXMLPolyDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode());
79  }
80 
81  std::vector<BaseData::Pointer> result;
82  result.push_back(output.GetPointer());
83  return result;
84  }
85 
87  {
89  return Unsupported;
90  if (this->GetInputStream() == nullptr)
91  {
92  // check if the xml vtk reader can handle the file
93  vtkSmartPointer<VtkXMLPolyDataReader> xmlReader = vtkSmartPointer<VtkXMLPolyDataReader>::New();
94  if (xmlReader->CanReadFile(this->GetInputLocation().c_str()) != 0)
95  {
96  return Supported;
97  }
98  return Unsupported;
99  }
100  // in case of an input stream, VTK does not seem to have methods for
101  // validating it
102  return Supported;
103  }
104 
106  {
108 
109  const auto *input = dynamic_cast<const Surface *>(this->GetInput());
110 
111  const unsigned int timesteps = input->GetTimeGeometry()->CountTimeSteps();
112  for (unsigned int t = 0; t < timesteps; ++t)
113  {
114  std::string fileName;
115  vtkSmartPointer<vtkPolyData> polyData = this->GetPolyData(t, fileName);
116  if (polyData.Get() == nullptr)
117  {
118  mitkThrow() << "Cannot write empty surface";
119  }
120 
121  vtkSmartPointer<VtkXMLPolyDataWriter> writer = vtkSmartPointer<VtkXMLPolyDataWriter>::New();
122  writer->SetInputData(polyData);
123 
124  if (this->GetOutputStream())
125  {
126  if (input->GetTimeGeometry()->CountTimeSteps() > 1)
127  {
128  MITK_WARN << "Writing multiple time-steps to output streams is not supported. "
129  << "Only the first time-step will be written";
130  }
131  writer->SetStream(this->GetOutputStream());
132  }
133  else
134  {
135  writer->SetFileName(fileName.c_str());
136  }
137 
138  if (writer->Write() == 0 || writer->GetErrorCode() != 0)
139  {
140  mitkThrow() << "Error during surface writing"
141  << (writer->GetErrorCode() ?
142  std::string(": ") + vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()) :
143  std::string());
144  }
145 
146  if (this->GetOutputStream())
147  break;
148  }
149  }
150 
151  SurfaceVtkXmlIO *SurfaceVtkXmlIO::IOClone() const { return new SurfaceVtkXmlIO(*this); }
152 }
std::vector< BaseData::Pointer > Read() override
Reads a path or stream and creates a list of BaseData objects.
Class for storing surfaces (vtkPolyData).
Definition: mitkSurface.h:28
virtual TimeStepType CountTimeSteps() const =0
Returns the number of time steps.
The IOMimeTypes class.
ConfidenceLevel GetReaderConfidenceLevel() const override
std::istream * GetInputStream() const override
Get the input stream.
DataCollection - Class to facilitate loading/accessing structured data.
vtkSmartPointer< vtkPolyData > GetPolyData(unsigned int t, std::string &fileName)
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:61
#define MITK_WARN
Definition: mitkLogMacros.h:19
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:45
std::pair< us::ServiceRegistration< IFileReader >, us::ServiceRegistration< IFileWriter > > RegisterService(us::ModuleContext *context=us::GetModuleContext())
void Write() override
Write the base data to the specified location or output stream.
#define mitkThrow()
const BaseData * GetInput() const override
Get the input data set via SetInput().
std::ostream * GetOutputStream() const override
Get the output stream.
std::string GetInputLocation() const override
Get the current input location.
ConfidenceLevel GetReaderConfidenceLevel() const override
static Pointer New()