Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkFiberBundleVtkReader.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 
18 #include <itkMetaDataObject.h>
19 #include <vtkPolyData.h>
20 #include <vtkDataReader.h>
21 #include <vtkPolyDataReader.h>
22 #include <vtkMatrix4x4.h>
23 #include <vtkPolyLine.h>
24 #include <vtkCellArray.h>
25 #include <vtkDataArray.h>
26 #include <vtkFloatArray.h>
27 #include <vtkCellData.h>
28 #include <vtkPointData.h>
29 #include <itksys/SystemTools.hxx>
30 #include <tinyxml.h>
31 #include <vtkCleanPolyData.h>
32 #include <mitkTrackvis.h>
33 #include <mitkCustomMimeType.h>
34 #include <vtkXMLPolyDataReader.h>
35 #include <vtkXMLDataReader.h>
37 
38 
40  : mitk::AbstractFileReader( mitk::DiffusionIOMimeTypes::FIBERBUNDLE_VTK_MIMETYPE_NAME(), "VTK Fiber Bundle Reader" )
41 {
42  m_ServiceReg = this->RegisterService();
43 }
44 
46  :mitk::AbstractFileReader(other)
47 {
48 }
49 
51 {
52  return new FiberBundleVtkReader(*this);
53 }
54 
55 
56 std::vector<itk::SmartPointer<mitk::BaseData> > mitk::FiberBundleVtkReader::Read()
57 {
58 
59  std::vector<itk::SmartPointer<mitk::BaseData> > result;
60 
61  const std::string& locale = "C";
62  const std::string& currLocale = setlocale( LC_ALL, NULL );
63  setlocale(LC_ALL, locale.c_str());
64 
65  std::string filename = this->GetInputLocation();
66 
67  std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename);
68  ext = itksys::SystemTools::LowerCase(ext);
69 
70  try
71  {
72  MITK_INFO << "Trying to load fiber file as VTK format.";
73  vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();
74  reader->SetFileName( this->GetInputLocation().c_str() );
75 
76  if (reader->IsFilePolyData())
77  {
78  reader->Update();
79 
80  if ( reader->GetOutput() != NULL )
81  {
82  vtkSmartPointer<vtkPolyData> fiberPolyData = reader->GetOutput();
83  FiberBundle::Pointer fiberBundle = FiberBundle::New(fiberPolyData);
84 
85  vtkSmartPointer<vtkFloatArray> weights = vtkFloatArray::SafeDownCast(fiberPolyData->GetCellData()->GetArray("FIBER_WEIGHTS"));
86  if (weights!=NULL)
87  {
88  float weight=0;
89  for (int i=0; i<weights->GetSize(); i++)
90  if (!mitk::Equal(weights->GetValue(i),weight,0.00001))
91  {
92  MITK_INFO << "Weight: " << weights->GetValue(i);
93  weight = weights->GetValue(i);
94  }
95  fiberBundle->SetFiberWeights(weights);
96  }
97 
98  vtkSmartPointer<vtkUnsignedCharArray> fiberColors = vtkUnsignedCharArray::SafeDownCast(fiberPolyData->GetPointData()->GetArray("FIBER_COLORS"));
99  if (fiberColors!=NULL)
100  fiberBundle->SetFiberColors(fiberColors);
101 
102  result.push_back(fiberBundle.GetPointer());
103  return result;
104  }
105  }
106  else
107  MITK_INFO << "File is not VTK format.";
108  }
109  catch(...)
110  {
111  throw;
112  }
113 
114  try
115  {
116  MITK_INFO << "Trying to load fiber file as VTP format.";
117  vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
118  reader->SetFileName( this->GetInputLocation().c_str() );
119 
120  if ( reader->CanReadFile(this->GetInputLocation().c_str()) )
121  {
122  reader->Update();
123 
124  if ( reader->GetOutput() != NULL )
125  {
126  vtkSmartPointer<vtkPolyData> fiberPolyData = reader->GetOutput();
127  FiberBundle::Pointer fiberBundle = FiberBundle::New(fiberPolyData);
128 
129  vtkSmartPointer<vtkFloatArray> weights = vtkFloatArray::SafeDownCast(fiberPolyData->GetCellData()->GetArray("FIBER_WEIGHTS"));
130 
131  if (weights!=NULL)
132  {
133 // float weight=0;
134 // for (int i=0; i<weights->GetSize(); i++)
135 // if (!mitk::Equal(weights->GetValue(i),weight,0.00001))
136 // {
137 // MITK_INFO << "Weight: " << weights->GetValue(i);
138 // weight = weights->GetValue(i);
139 // }
140  fiberBundle->SetFiberWeights(weights);
141  }
142 
143  vtkSmartPointer<vtkUnsignedCharArray> fiberColors = vtkUnsignedCharArray::SafeDownCast(fiberPolyData->GetPointData()->GetArray("FIBER_COLORS"));
144  if (fiberColors!=NULL)
145  fiberBundle->SetFiberColors(fiberColors);
146 
147  result.push_back(fiberBundle.GetPointer());
148  return result;
149  }
150  }
151  else
152  MITK_INFO << "File is not VTP format.";
153  }
154  catch(...)
155  {
156  throw;
157  }
158 
159  try
160  {
161  MITK_INFO << "Trying to load fiber file as deprecated XML format.";
162  vtkSmartPointer<vtkPolyData> fiberPolyData = vtkSmartPointer<vtkPolyData>::New();
163  vtkSmartPointer<vtkCellArray> cellArray = vtkSmartPointer<vtkCellArray>::New();
164  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
165  TiXmlDocument doc( this->GetInputLocation().c_str() );
166  if(doc.LoadFile())
167  {
168  TiXmlHandle hDoc(&doc);
169  TiXmlElement* pElem;
170  TiXmlHandle hRoot(0);
171  pElem = hDoc.FirstChildElement().Element();
172  // save this for later
173  hRoot = TiXmlHandle(pElem);
174  pElem = hRoot.FirstChildElement("geometry").Element();
175  // read geometry
177  // read origin
178  mitk::Point3D origin;
179  double temp = 0;
180  pElem->Attribute("origin_x", &temp);
181  origin[0] = temp;
182  pElem->Attribute("origin_y", &temp);
183  origin[1] = temp;
184  pElem->Attribute("origin_z", &temp);
185  origin[2] = temp;
186  geometry->SetOrigin(origin);
187  // read spacing
188  ScalarType spacing[3];
189  pElem->Attribute("spacing_x", &temp);
190  spacing[0] = temp;
191  pElem->Attribute("spacing_y", &temp);
192  spacing[1] = temp;
193  pElem->Attribute("spacing_z", &temp);
194  spacing[2] = temp;
195  geometry->SetSpacing(spacing);
196  // read transform
197  vtkMatrix4x4* m = vtkMatrix4x4::New();
198  pElem->Attribute("xx", &temp);
199  m->SetElement(0,0,temp);
200  pElem->Attribute("xy", &temp);
201  m->SetElement(1,0,temp);
202  pElem->Attribute("xz", &temp);
203  m->SetElement(2,0,temp);
204  pElem->Attribute("yx", &temp);
205  m->SetElement(0,1,temp);
206  pElem->Attribute("yy", &temp);
207  m->SetElement(1,1,temp);
208  pElem->Attribute("yz", &temp);
209  m->SetElement(2,1,temp);
210  pElem->Attribute("zx", &temp);
211  m->SetElement(0,2,temp);
212  pElem->Attribute("zy", &temp);
213  m->SetElement(1,2,temp);
214  pElem->Attribute("zz", &temp);
215  m->SetElement(2,2,temp);
216  m->SetElement(0,3,origin[0]);
217  m->SetElement(1,3,origin[1]);
218  m->SetElement(2,3,origin[2]);
219  m->SetElement(3,3,1);
220  geometry->SetIndexToWorldTransformByVtkMatrix(m);
221  // read bounds
222  float bounds[] = {0, 0, 0, 0, 0, 0};
223  pElem->Attribute("size_x", &temp);
224  bounds[1] = temp;
225  pElem->Attribute("size_y", &temp);
226  bounds[3] = temp;
227  pElem->Attribute("size_z", &temp);
228  bounds[5] = temp;
229  geometry->SetFloatBounds(bounds);
230  geometry->SetImageGeometry(true);
231  pElem = hRoot.FirstChildElement("fiber_bundle").FirstChild().Element();
232  for( ; pElem ; pElem=pElem->NextSiblingElement())
233  {
234  TiXmlElement* pElem2 = pElem->FirstChildElement();
235  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
236  for( ; pElem2; pElem2=pElem2->NextSiblingElement())
237  {
238  Point3D point;
239  pElem2->Attribute("pos_x", &temp);
240  point[0] = temp;
241  pElem2->Attribute("pos_y", &temp);
242  point[1] = temp;
243  pElem2->Attribute("pos_z", &temp);
244  point[2] = temp;
245  geometry->IndexToWorld(point, point);
246  vtkIdType id = points->InsertNextPoint(point.GetDataPointer());
247  container->GetPointIds()->InsertNextId(id);
248  }
249  cellArray->InsertNextCell(container);
250  }
251  fiberPolyData->SetPoints(points);
252  fiberPolyData->SetLines(cellArray);
253  vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New();
254  cleaner->SetInputData(fiberPolyData);
255  cleaner->Update();
256  fiberPolyData = cleaner->GetOutput();
257  FiberBundle::Pointer image = FiberBundle::New(fiberPolyData);
258  result.push_back(image.GetPointer());
259  return result;
260  }
261  else
262  {
263  MITK_INFO << "File is not deprectaed XML format.";
264  }
265 
266  setlocale(LC_ALL, currLocale.c_str());
267  MITK_INFO << "Fiber bundle read";
268  }
269  catch(...)
270  {
271  throw;
272  }
273 
274  throw "Selected file is no vtk readable fiber format (binary or ascii vtk or vtp file).";
275 
276  return result;
277 }
#define MITK_INFO
Definition: mitkLogMacros.h:22
double ScalarType
DataCollection - Class to facilitate loading/accessing structured data.
static Pointer New()
us::ServiceRegistration< IFileReader > RegisterService(us::ModuleContext *context=us::GetModuleContext())
static const std::string filename
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
Base class for creating mitk::BaseData objects from files or streams.
virtual FiberBundleVtkReader * Clone() const override
virtual std::vector< itk::SmartPointer< BaseData > > Read() override
Reads a path or stream and creates a list of BaseData objects.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.