Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkFiberBundle.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 
18 #define _USE_MATH_DEFINES
19 #include "mitkFiberBundle.h"
20 
21 #include <mitkPlanarCircle.h>
22 #include <mitkPlanarPolygon.h>
25 #include <mitkPixelTypeMultiplex.h>
26 
27 #include <vtkPointData.h>
28 #include <vtkDataArray.h>
29 #include <vtkUnsignedCharArray.h>
30 #include <vtkPolyLine.h>
31 #include <vtkCellArray.h>
32 #include <vtkCellData.h>
33 #include <vtkIdFilter.h>
34 #include <vtkClipPolyData.h>
35 #include <vtkPlane.h>
36 #include <vtkDoubleArray.h>
37 #include <vtkKochanekSpline.h>
38 #include <vtkParametricFunctionSource.h>
39 #include <vtkParametricSpline.h>
40 #include <vtkPolygon.h>
41 #include <vtkCleanPolyData.h>
42 #include <cmath>
43 #include <boost/progress.hpp>
44 #include <vtkTransformPolyDataFilter.h>
45 #include <mitkTransferFunction.h>
46 #include <vtkLookupTable.h>
47 #include <mitkLookupTable.h>
48 
49 const char* mitk::FiberBundle::FIBER_ID_ARRAY = "Fiber_IDs";
50 
51 using namespace std;
52 
53 mitk::FiberBundle::FiberBundle( vtkPolyData* fiberPolyData )
54  : m_NumFibers(0)
55  , m_FiberSampling(0)
56 {
57  m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New();
58  m_FiberWeights->SetName("FIBER_WEIGHTS");
59 
60  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
61  if (fiberPolyData != nullptr)
62  {
63  m_FiberPolyData = fiberPolyData;
65  }
66 
67  this->UpdateFiberGeometry();
68  this->GenerateFiberIds();
69 }
70 
72 {
73 
74 }
75 
77 {
78  mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(m_FiberPolyData);
79  newFib->SetFiberColors(this->m_FiberColors);
80  newFib->SetFiberWeights(this->m_FiberWeights);
81  return newFib;
82 }
83 
84 vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GeneratePolyDataByIds(std::vector<long> fiberIds)
85 {
86  vtkSmartPointer<vtkPolyData> newFiberPolyData = vtkSmartPointer<vtkPolyData>::New();
87  vtkSmartPointer<vtkCellArray> newLineSet = vtkSmartPointer<vtkCellArray>::New();
88  vtkSmartPointer<vtkPoints> newPointSet = vtkSmartPointer<vtkPoints>::New();
89 
90  auto finIt = fiberIds.begin();
91  while ( finIt != fiberIds.end() )
92  {
93  if (*finIt < 0 || *finIt>GetNumFibers()){
94  MITK_INFO << "FiberID can not be negative or >NumFibers!!! check id Extraction!" << *finIt;
95  break;
96  }
97 
98  vtkSmartPointer<vtkCell> fiber = m_FiberIdDataSet->GetCell(*finIt);//->DeepCopy(fiber);
99  vtkSmartPointer<vtkPoints> fibPoints = fiber->GetPoints();
100  vtkSmartPointer<vtkPolyLine> newFiber = vtkSmartPointer<vtkPolyLine>::New();
101  newFiber->GetPointIds()->SetNumberOfIds( fibPoints->GetNumberOfPoints() );
102 
103  for(int i=0; i<fibPoints->GetNumberOfPoints(); i++)
104  {
105  newFiber->GetPointIds()->SetId(i, newPointSet->GetNumberOfPoints());
106  newPointSet->InsertNextPoint(fibPoints->GetPoint(i)[0], fibPoints->GetPoint(i)[1], fibPoints->GetPoint(i)[2]);
107  }
108 
109  newLineSet->InsertNextCell(newFiber);
110  ++finIt;
111  }
112 
113  newFiberPolyData->SetPoints(newPointSet);
114  newFiberPolyData->SetLines(newLineSet);
115  return newFiberPolyData;
116 }
117 
118 // merge two fiber bundles
120 {
121  if (fib==nullptr)
122  {
123  MITK_WARN << "trying to call AddBundle with NULL argument";
124  return nullptr;
125  }
126  MITK_INFO << "Adding fibers";
127 
128  vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
129  vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
130  vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
131 
132  // add current fiber bundle
133  vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
134  weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers());
135 
136  unsigned int counter = 0;
137  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
138  {
139  vtkCell* cell = m_FiberPolyData->GetCell(i);
140  int numPoints = cell->GetNumberOfPoints();
141  vtkPoints* points = cell->GetPoints();
142 
143  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
144  for (int j=0; j<numPoints; j++)
145  {
146  double p[3];
147  points->GetPoint(j, p);
148 
149  vtkIdType id = vNewPoints->InsertNextPoint(p);
150  container->GetPointIds()->InsertNextId(id);
151  }
152  weights->InsertValue(counter, this->GetFiberWeight(i));
153  vNewLines->InsertNextCell(container);
154  counter++;
155  }
156 
157  // add new fiber bundle
158  for (int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++)
159  {
160  vtkCell* cell = fib->GetFiberPolyData()->GetCell(i);
161  int numPoints = cell->GetNumberOfPoints();
162  vtkPoints* points = cell->GetPoints();
163 
164  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
165  for (int j=0; j<numPoints; j++)
166  {
167  double p[3];
168  points->GetPoint(j, p);
169 
170  vtkIdType id = vNewPoints->InsertNextPoint(p);
171  container->GetPointIds()->InsertNextId(id);
172  }
173  weights->InsertValue(counter, fib->GetFiberWeight(i));
174  vNewLines->InsertNextCell(container);
175  counter++;
176  }
177 
178  // initialize polydata
179  vNewPolyData->SetPoints(vNewPoints);
180  vNewPolyData->SetLines(vNewLines);
181 
182  // initialize fiber bundle
183  mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData);
184  newFib->SetFiberWeights(weights);
185  return newFib;
186 }
187 
188 // subtract two fiber bundles
190 {
191  MITK_INFO << "Subtracting fibers";
192 
193  vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
194  vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
195  vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
196 
197  // iterate over current fibers
198  boost::progress_display disp(m_NumFibers);
199  for( int i=0; i<m_NumFibers; i++ )
200  {
201  ++disp;
202  vtkCell* cell = m_FiberPolyData->GetCell(i);
203  int numPoints = cell->GetNumberOfPoints();
204  vtkPoints* points = cell->GetPoints();
205 
206  if (points==nullptr || numPoints<=0)
207  continue;
208 
209  int numFibers2 = fib->GetNumFibers();
210  bool contained = false;
211  for( int i2=0; i2<numFibers2; i2++ )
212  {
213  vtkCell* cell2 = fib->GetFiberPolyData()->GetCell(i2);
214  int numPoints2 = cell2->GetNumberOfPoints();
215  vtkPoints* points2 = cell2->GetPoints();
216 
217  if (points2==nullptr)// || numPoints2<=0)
218  continue;
219 
220  // check endpoints
221  if (numPoints2==numPoints)
222  {
223  itk::Point<float, 3> point_start = GetItkPoint(points->GetPoint(0));
224  itk::Point<float, 3> point_end = GetItkPoint(points->GetPoint(numPoints-1));
225  itk::Point<float, 3> point2_start = GetItkPoint(points2->GetPoint(0));
226  itk::Point<float, 3> point2_end = GetItkPoint(points2->GetPoint(numPoints2-1));
227 
228  if ((point_start.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps) ||
229  (point_start.SquaredEuclideanDistanceTo(point2_end)<=mitk::eps && point_end.SquaredEuclideanDistanceTo(point2_start)<=mitk::eps))
230  {
231  // further checking ???
232  contained = true;
233  break;
234  }
235  }
236  }
237 
238  // add to result because fiber is not subtracted
239  if (!contained)
240  {
241  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
242  for( int j=0; j<numPoints; j++)
243  {
244  vtkIdType id = vNewPoints->InsertNextPoint(points->GetPoint(j));
245  container->GetPointIds()->InsertNextId(id);
246  }
247  vNewLines->InsertNextCell(container);
248  }
249  }
250  if(vNewLines->GetNumberOfCells()==0)
251  return nullptr;
252  // initialize polydata
253  vNewPolyData->SetPoints(vNewPoints);
254  vNewPolyData->SetLines(vNewLines);
255 
256  // initialize fiber bundle
257  return mitk::FiberBundle::New(vNewPolyData);
258 }
259 
260 itk::Point<float, 3> mitk::FiberBundle::GetItkPoint(double point[3])
261 {
262  itk::Point<float, 3> itkPoint;
263  itkPoint[0] = point[0];
264  itkPoint[1] = point[1];
265  itkPoint[2] = point[2];
266  return itkPoint;
267 }
268 
269 /*
270  * set polydata (additional flag to recompute fiber geometry, default = true)
271  */
272 void mitk::FiberBundle::SetFiberPolyData(vtkSmartPointer<vtkPolyData> fiberPD, bool updateGeometry)
273 {
274  if (fiberPD == nullptr)
275  this->m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
276  else
277  {
278  m_FiberPolyData->DeepCopy(fiberPD);
279  ColorFibersByOrientation();
280  }
281 
282  m_NumFibers = m_FiberPolyData->GetNumberOfLines();
283 
284  if (updateGeometry)
285  UpdateFiberGeometry();
286  GenerateFiberIds();
287 }
288 
289 /*
290  * return vtkPolyData
291  */
292 vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GetFiberPolyData() const
293 {
294  return m_FiberPolyData;
295 }
296 
298 {
299  //===== FOR WRITING A TEST ========================
300  // colorT size == tupelComponents * tupelElements
301  // compare color results
302  // to cover this code 100% also polydata needed, where colorarray already exists
303  // + one fiber with exactly 1 point
304  // + one fiber with 0 points
305  //=================================================
306 
307  vtkPoints* extrPoints = nullptr;
308  extrPoints = m_FiberPolyData->GetPoints();
309  int numOfPoints = 0;
310  if (extrPoints!=nullptr)
311  numOfPoints = extrPoints->GetNumberOfPoints();
312 
313  //colors and alpha value for each single point, RGBA = 4 components
314  unsigned char rgba[4] = {0,0,0,0};
315  int componentSize = 4;
317  m_FiberColors->Allocate(numOfPoints * componentSize);
318  m_FiberColors->SetNumberOfComponents(componentSize);
319  m_FiberColors->SetName("FIBER_COLORS");
320 
321  int numOfFibers = m_FiberPolyData->GetNumberOfLines();
322  if (numOfFibers < 1)
323  return;
324 
325  /* extract single fibers of fiberBundle */
326  vtkCellArray* fiberList = m_FiberPolyData->GetLines();
327  fiberList->InitTraversal();
328  for (int fi=0; fi<numOfFibers; ++fi) {
329 
330  vtkIdType* idList; // contains the point id's of the line
331  vtkIdType pointsPerFiber; // number of points for current line
332  fiberList->GetNextCell(pointsPerFiber, idList);
333 
334  /* single fiber checkpoints: is number of points valid */
335  if (pointsPerFiber > 1)
336  {
337  /* operate on points of single fiber */
338  for (int i=0; i <pointsPerFiber; ++i)
339  {
340  /* process all points except starting and endpoint for calculating color value take current point, previous point and next point */
341  if (i<pointsPerFiber-1 && i > 0)
342  {
343  /* The color value of the current point is influenced by the previous point and next point. */
344  vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
345  vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]);
346  vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]);
347 
348  vnl_vector_fixed< double, 3 > diff1;
349  diff1 = currentPntvtk - nextPntvtk;
350 
351  vnl_vector_fixed< double, 3 > diff2;
352  diff2 = currentPntvtk - prevPntvtk;
353 
354  vnl_vector_fixed< double, 3 > diff;
355  diff = (diff1 - diff2) / 2.0;
356  diff.normalize();
357 
358  rgba[0] = (unsigned char) (255.0 * std::fabs(diff[0]));
359  rgba[1] = (unsigned char) (255.0 * std::fabs(diff[1]));
360  rgba[2] = (unsigned char) (255.0 * std::fabs(diff[2]));
361  rgba[3] = (unsigned char) (255.0);
362  }
363  else if (i==0)
364  {
365  /* First point has no previous point, therefore only diff1 is taken */
366 
367  vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
368  vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]);
369 
370  vnl_vector_fixed< double, 3 > diff1;
371  diff1 = currentPntvtk - nextPntvtk;
372  diff1.normalize();
373 
374  rgba[0] = (unsigned char) (255.0 * std::fabs(diff1[0]));
375  rgba[1] = (unsigned char) (255.0 * std::fabs(diff1[1]));
376  rgba[2] = (unsigned char) (255.0 * std::fabs(diff1[2]));
377  rgba[3] = (unsigned char) (255.0);
378  }
379  else if (i==pointsPerFiber-1)
380  {
381  /* Last point has no next point, therefore only diff2 is taken */
382  vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
383  vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]);
384 
385  vnl_vector_fixed< double, 3 > diff2;
386  diff2 = currentPntvtk - prevPntvtk;
387  diff2.normalize();
388 
389  rgba[0] = (unsigned char) (255.0 * std::fabs(diff2[0]));
390  rgba[1] = (unsigned char) (255.0 * std::fabs(diff2[1]));
391  rgba[2] = (unsigned char) (255.0 * std::fabs(diff2[2]));
392  rgba[3] = (unsigned char) (255.0);
393  }
394  m_FiberColors->InsertTupleValue(idList[i], rgba);
395  }
396  }
397  else if (pointsPerFiber == 1)
398  {
399  /* a single point does not define a fiber (use vertex mechanisms instead */
400  continue;
401  }
402  else
403  {
404  MITK_DEBUG << "Fiber with 0 points detected... please check your tractography algorithm!" ;
405  continue;
406  }
407  }
408  m_UpdateTime3D.Modified();
409  m_UpdateTime2D.Modified();
410 }
411 
412 void mitk::FiberBundle::ColorFibersByCurvature(bool minMaxNorm)
413 {
414  double window = 5;
415 
416  //colors and alpha value for each single point, RGBA = 4 components
417  unsigned char rgba[4] = {0,0,0,0};
418  int componentSize = 4;
420  m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * componentSize);
421  m_FiberColors->SetNumberOfComponents(componentSize);
422  m_FiberColors->SetName("FIBER_COLORS");
423 
425  vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
426  lookupTable->SetTableRange(0.0, 0.8);
427  lookupTable->Build();
428  mitkLookup->SetVtkLookupTable(lookupTable);
429  mitkLookup->SetType(mitk::LookupTable::JET);
430 
431  vector< double > values;
432  double min = 1;
433  double max = 0;
434  MITK_INFO << "Coloring fibers by curvature";
435  boost::progress_display disp(m_FiberPolyData->GetNumberOfCells());
436  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
437  {
438  ++disp;
439  vtkCell* cell = m_FiberPolyData->GetCell(i);
440  int numPoints = cell->GetNumberOfPoints();
441  vtkPoints* points = cell->GetPoints();
442 
443  // calculate curvatures
444  for (int j=0; j<numPoints; j++)
445  {
446  double dist = 0;
447  int c = j;
448  std::vector< vnl_vector_fixed< float, 3 > > vectors;
449  vnl_vector_fixed< float, 3 > meanV; meanV.fill(0.0);
450  while(dist<window/2 && c>1)
451  {
452  double p1[3];
453  points->GetPoint(c-1, p1);
454  double p2[3];
455  points->GetPoint(c, p2);
456 
457  vnl_vector_fixed< float, 3 > v;
458  v[0] = p2[0]-p1[0];
459  v[1] = p2[1]-p1[1];
460  v[2] = p2[2]-p1[2];
461  dist += v.magnitude();
462  v.normalize();
463  vectors.push_back(v);
464  if (c==j)
465  meanV += v;
466  c--;
467  }
468  c = j;
469  dist = 0;
470  while(dist<window/2 && c<numPoints-1)
471  {
472  double p1[3];
473  points->GetPoint(c, p1);
474  double p2[3];
475  points->GetPoint(c+1, p2);
476 
477  vnl_vector_fixed< float, 3 > v;
478  v[0] = p2[0]-p1[0];
479  v[1] = p2[1]-p1[1];
480  v[2] = p2[2]-p1[2];
481  dist += v.magnitude();
482  v.normalize();
483  vectors.push_back(v);
484  if (c==j)
485  meanV += v;
486  c++;
487  }
488  meanV.normalize();
489 
490  double dev = 0;
491  for (unsigned int c=0; c<vectors.size(); c++)
492  {
493  double angle = dot_product(meanV, vectors.at(c));
494  if (angle>1.0)
495  angle = 1.0;
496  if (angle<-1.0)
497  angle = -1.0;
498  dev += acos(angle)*180/M_PI;
499  }
500  if (vectors.size()>0)
501  dev /= vectors.size();
502 
503  dev = 1.0-dev/180.0;
504  values.push_back(dev);
505  if (dev<min)
506  min = dev;
507  if (dev>max)
508  max = dev;
509  }
510  }
511  unsigned int count = 0;
512  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
513  {
514  vtkCell* cell = m_FiberPolyData->GetCell(i);
515  int numPoints = cell->GetNumberOfPoints();
516  for (int j=0; j<numPoints; j++)
517  {
518  double color[3];
519  double dev = values.at(count);
520  if (minMaxNorm)
521  dev = (dev-min)/(max-min);
522  // double dev = values.at(count)*values.at(count);
523  lookupTable->GetColor(dev, color);
524 
525  rgba[0] = (unsigned char) (255.0 * color[0]);
526  rgba[1] = (unsigned char) (255.0 * color[1]);
527  rgba[2] = (unsigned char) (255.0 * color[2]);
528  rgba[3] = (unsigned char) (255.0);
529  m_FiberColors->InsertTupleValue(cell->GetPointId(j), rgba);
530  count++;
531  }
532  }
533  m_UpdateTime3D.Modified();
534  m_UpdateTime2D.Modified();
535 }
536 
537 void mitk::FiberBundle::SetFiberOpacity(vtkDoubleArray* FAValArray)
538 {
539  for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++)
540  {
541  double faValue = FAValArray->GetValue(i);
542  faValue = faValue * 255.0;
543  m_FiberColors->SetComponent(i,3, (unsigned char) faValue );
544  }
545  m_UpdateTime3D.Modified();
546  m_UpdateTime2D.Modified();
547 }
548 
550 {
551  for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++)
552  m_FiberColors->SetComponent(i,3, 255.0 );
553  m_UpdateTime3D.Modified();
554  m_UpdateTime2D.Modified();
555 }
556 
558 {
559  mitkPixelTypeMultiplex2( ColorFibersByScalarMap, FAimage->GetPixelType(), FAimage, opacity );
560  m_UpdateTime3D.Modified();
561  m_UpdateTime2D.Modified();
562 }
563 
564 template <typename TPixel>
566 {
568  m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
569  m_FiberColors->SetNumberOfComponents(4);
570  m_FiberColors->SetName("FIBER_COLORS");
571 
572  mitk::ImagePixelReadAccessor<TPixel,3> readimage(image, image->GetVolumeData(0));
573 
574  unsigned char rgba[4] = {0,0,0,0};
575  vtkPoints* pointSet = m_FiberPolyData->GetPoints();
576 
578  vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
579  lookupTable->SetTableRange(0.0, 0.8);
580  lookupTable->Build();
581  mitkLookup->SetVtkLookupTable(lookupTable);
582  mitkLookup->SetType(mitk::LookupTable::JET);
583 
584  for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
585  {
586  Point3D px;
587  px[0] = pointSet->GetPoint(i)[0];
588  px[1] = pointSet->GetPoint(i)[1];
589  px[2] = pointSet->GetPoint(i)[2];
590  double pixelValue = readimage.GetPixelByWorldCoordinates(px);
591 
592  double color[3];
593  lookupTable->GetColor(1-pixelValue, color);
594 
595  rgba[0] = (unsigned char) (255.0 * color[0]);
596  rgba[1] = (unsigned char) (255.0 * color[1]);
597  rgba[2] = (unsigned char) (255.0 * color[2]);
598  if (opacity)
599  rgba[3] = (unsigned char) (255.0 * pixelValue);
600  else
601  rgba[3] = (unsigned char) (255.0);
602  m_FiberColors->InsertTupleValue(i, rgba);
603  }
604  m_UpdateTime3D.Modified();
605  m_UpdateTime2D.Modified();
606 }
607 
608 void mitk::FiberBundle::SetFiberColors(float r, float g, float b, float alpha)
609 {
611  m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
612  m_FiberColors->SetNumberOfComponents(4);
613  m_FiberColors->SetName("FIBER_COLORS");
614 
615  unsigned char rgba[4] = {0,0,0,0};
616  for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
617  {
618  rgba[0] = (unsigned char) r;
619  rgba[1] = (unsigned char) g;
620  rgba[2] = (unsigned char) b;
621  rgba[3] = (unsigned char) alpha;
622  m_FiberColors->InsertTupleValue(i, rgba);
623  }
624  m_UpdateTime3D.Modified();
625  m_UpdateTime2D.Modified();
626 }
627 
629 {
630  if (m_FiberPolyData == nullptr)
631  return;
632 
633  vtkSmartPointer<vtkIdFilter> idFiberFilter = vtkSmartPointer<vtkIdFilter>::New();
634  idFiberFilter->SetInputData(m_FiberPolyData);
635  idFiberFilter->CellIdsOn();
636  // idFiberFilter->PointIdsOn(); // point id's are not needed
637  idFiberFilter->SetIdsArrayName(FIBER_ID_ARRAY);
638  idFiberFilter->FieldDataOn();
639  idFiberFilter->Update();
640 
641  m_FiberIdDataSet = idFiberFilter->GetOutput();
642 
643 }
644 
646 {
647  vtkSmartPointer<vtkPolyData> polyData = m_FiberPolyData;
648  if (anyPoint)
649  {
650  float minSpacing = 1;
651  if(mask->GetSpacing()[0]<mask->GetSpacing()[1] && mask->GetSpacing()[0]<mask->GetSpacing()[2])
652  minSpacing = mask->GetSpacing()[0];
653  else if (mask->GetSpacing()[1] < mask->GetSpacing()[2])
654  minSpacing = mask->GetSpacing()[1];
655  else
656  minSpacing = mask->GetSpacing()[2];
657 
658  mitk::FiberBundle::Pointer fibCopy = this->GetDeepCopy();
659  fibCopy->ResampleSpline(minSpacing/5);
660  polyData = fibCopy->GetFiberPolyData();
661  }
662  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
663  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
664 
665  MITK_INFO << "Extracting fibers";
666  boost::progress_display disp(m_NumFibers);
667  for (int i=0; i<m_NumFibers; i++)
668  {
669  ++disp;
670 
671  vtkCell* cell = polyData->GetCell(i);
672  int numPoints = cell->GetNumberOfPoints();
673  vtkPoints* points = cell->GetPoints();
674 
675  vtkCell* cellOriginal = m_FiberPolyData->GetCell(i);
676  int numPointsOriginal = cellOriginal->GetNumberOfPoints();
677  vtkPoints* pointsOriginal = cellOriginal->GetPoints();
678 
679  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
680 
681  if (numPoints>1 && numPointsOriginal)
682  {
683  if (anyPoint)
684  {
685  if (!invert)
686  {
687  for (int j=0; j<numPoints; j++)
688  {
689  double* p = points->GetPoint(j);
690 
691  itk::Point<float, 3> itkP;
692  itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
693  itk::Index<3> idx;
694  mask->TransformPhysicalPointToIndex(itkP, idx);
695 
696  if ( mask->GetPixel(idx)>0 && mask->GetLargestPossibleRegion().IsInside(idx) )
697  {
698  for (int k=0; k<numPointsOriginal; k++)
699  {
700  double* p = pointsOriginal->GetPoint(k);
701  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
702  container->GetPointIds()->InsertNextId(id);
703  }
704  break;
705  }
706  }
707  }
708  else
709  {
710  bool includeFiber = true;
711  for (int j=0; j<numPoints; j++)
712  {
713  double* p = points->GetPoint(j);
714 
715  itk::Point<float, 3> itkP;
716  itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
717  itk::Index<3> idx;
718  mask->TransformPhysicalPointToIndex(itkP, idx);
719 
720  if ( mask->GetPixel(idx)>0 && mask->GetLargestPossibleRegion().IsInside(idx) )
721  {
722  includeFiber = false;
723  break;
724  }
725  }
726  if (includeFiber)
727  {
728 
729  for (int k=0; k<numPointsOriginal; k++)
730  {
731  double* p = pointsOriginal->GetPoint(k);
732  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
733  container->GetPointIds()->InsertNextId(id);
734  }
735  }
736  }
737  }
738  else
739  {
740  double* start = pointsOriginal->GetPoint(0);
741  itk::Point<float, 3> itkStart;
742  itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2];
743  itk::Index<3> idxStart;
744  mask->TransformPhysicalPointToIndex(itkStart, idxStart);
745 
746  double* end = pointsOriginal->GetPoint(numPointsOriginal-1);
747  itk::Point<float, 3> itkEnd;
748  itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2];
749  itk::Index<3> idxEnd;
750  mask->TransformPhysicalPointToIndex(itkEnd, idxEnd);
751 
752  if (invert)
753  {
754  if (bothEnds)
755  {
756  if ( !mask->GetPixel(idxStart)>0 && !mask->GetPixel(idxEnd)>0 )
757  {
758  for (int j=0; j<numPointsOriginal; j++)
759  {
760  double* p = pointsOriginal->GetPoint(j);
761  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
762  container->GetPointIds()->InsertNextId(id);
763  }
764  }
765  }
766  else if ( !mask->GetPixel(idxStart)>0 || !mask->GetPixel(idxEnd)>0 )
767  {
768  for (int j=0; j<numPointsOriginal; j++)
769  {
770  double* p = pointsOriginal->GetPoint(j);
771  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
772  container->GetPointIds()->InsertNextId(id);
773  }
774  }
775  }
776  else
777  {
778  if (bothEnds)
779  {
780  if ( mask->GetPixel(idxStart)>0 && mask->GetPixel(idxEnd)>0 && mask->GetLargestPossibleRegion().IsInside(idxStart) && mask->GetLargestPossibleRegion().IsInside(idxEnd) )
781  {
782  for (int j=0; j<numPointsOriginal; j++)
783  {
784  double* p = pointsOriginal->GetPoint(j);
785  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
786  container->GetPointIds()->InsertNextId(id);
787  }
788  }
789  }
790  else if ( (mask->GetPixel(idxStart)>0 && mask->GetLargestPossibleRegion().IsInside(idxStart)) || (mask->GetPixel(idxEnd)>0 && mask->GetLargestPossibleRegion().IsInside(idxEnd)) )
791  {
792  for (int j=0; j<numPointsOriginal; j++)
793  {
794  double* p = pointsOriginal->GetPoint(j);
795  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
796  container->GetPointIds()->InsertNextId(id);
797  }
798  }
799  }
800  }
801  }
802 
803  vtkNewCells->InsertNextCell(container);
804  }
805 
806  if (vtkNewCells->GetNumberOfCells()<=0)
807  return nullptr;
808 
809  vtkSmartPointer<vtkPolyData> newPolyData = vtkSmartPointer<vtkPolyData>::New();
810  newPolyData->SetPoints(vtkNewPoints);
811  newPolyData->SetLines(vtkNewCells);
812  return mitk::FiberBundle::New(newPolyData);
813 }
814 
816 {
817  float minSpacing = 1;
818  if(mask->GetSpacing()[0]<mask->GetSpacing()[1] && mask->GetSpacing()[0]<mask->GetSpacing()[2])
819  minSpacing = mask->GetSpacing()[0];
820  else if (mask->GetSpacing()[1] < mask->GetSpacing()[2])
821  minSpacing = mask->GetSpacing()[1];
822  else
823  minSpacing = mask->GetSpacing()[2];
824 
825  mitk::FiberBundle::Pointer fibCopy = this->GetDeepCopy();
826  fibCopy->ResampleSpline(minSpacing/10);
827  vtkSmartPointer<vtkPolyData> polyData =fibCopy->GetFiberPolyData();
828 
829  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
830  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
831 
832  MITK_INFO << "Cutting fibers";
833  boost::progress_display disp(m_NumFibers);
834  for (int i=0; i<m_NumFibers; i++)
835  {
836  ++disp;
837 
838  vtkCell* cell = polyData->GetCell(i);
839  int numPoints = cell->GetNumberOfPoints();
840  vtkPoints* points = cell->GetPoints();
841 
842  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
843  if (numPoints>1)
844  {
845  int newNumPoints = 0;
846  for (int j=0; j<numPoints; j++)
847  {
848  double* p = points->GetPoint(j);
849 
850  itk::Point<float, 3> itkP;
851  itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
852  itk::Index<3> idx;
853  mask->TransformPhysicalPointToIndex(itkP, idx);
854 
855  if ( mask->GetPixel(idx)>0 && mask->GetLargestPossibleRegion().IsInside(idx) && !invert )
856  {
857  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
858  container->GetPointIds()->InsertNextId(id);
859  newNumPoints++;
860  }
861  else if ( (mask->GetPixel(idx)<=0 || !mask->GetLargestPossibleRegion().IsInside(idx)) && invert )
862  {
863  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
864  container->GetPointIds()->InsertNextId(id);
865  newNumPoints++;
866  }
867  else if (newNumPoints>0)
868  {
869  vtkNewCells->InsertNextCell(container);
870 
871  newNumPoints = 0;
872  container = vtkSmartPointer<vtkPolyLine>::New();
873  }
874  }
875 
876  if (newNumPoints>0)
877  vtkNewCells->InsertNextCell(container);
878  }
879 
880  }
881 
882  if (vtkNewCells->GetNumberOfCells()<=0)
883  return nullptr;
884 
885  vtkSmartPointer<vtkPolyData> newPolyData = vtkSmartPointer<vtkPolyData>::New();
886  newPolyData->SetPoints(vtkNewPoints);
887  newPolyData->SetLines(vtkNewCells);
889  newFib->Compress(0.1);
890  return newFib;
891 }
892 
894 {
895  if (roi==nullptr || !(dynamic_cast<PlanarFigure*>(roi->GetData()) || dynamic_cast<PlanarFigureComposite*>(roi->GetData())) )
896  return nullptr;
897 
898  std::vector<long> tmp = ExtractFiberIdSubset(roi, storage);
899 
900  if (tmp.size()<=0)
901  return mitk::FiberBundle::New();
902  vtkSmartPointer<vtkPolyData> pTmp = GeneratePolyDataByIds(tmp);
903  return mitk::FiberBundle::New(pTmp);
904 }
905 
907 {
908  std::vector<long> result;
909  if (roi==nullptr || roi->GetData()==nullptr)
910  return result;
911 
913  if (!pfc.IsNull()) // handle composite
914  {
916  if (children->size()==0)
917  return result;
918 
919  switch (pfc->getOperationType())
920  {
921  case 0: // AND
922  {
923  MITK_INFO << "AND";
924  result = this->ExtractFiberIdSubset(children->ElementAt(0), storage);
925  std::vector<long>::iterator it;
926  for (unsigned int i=1; i<children->Size(); ++i)
927  {
928  std::vector<long> inRoi = this->ExtractFiberIdSubset(children->ElementAt(i), storage);
929 
930  std::vector<long> rest(std::min(result.size(),inRoi.size()));
931  it = std::set_intersection(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() );
932  rest.resize( it - rest.begin() );
933  result = rest;
934  }
935  break;
936  }
937  case 1: // OR
938  {
939  MITK_INFO << "OR";
940  result = ExtractFiberIdSubset(children->ElementAt(0), storage);
941  std::vector<long>::iterator it;
942  for (unsigned int i=1; i<children->Size(); ++i)
943  {
944  it = result.end();
945  std::vector<long> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage);
946  result.insert(it, inRoi.begin(), inRoi.end());
947  }
948 
949  // remove duplicates
950  sort(result.begin(), result.end());
951  it = unique(result.begin(), result.end());
952  result.resize( it - result.begin() );
953  break;
954  }
955  case 2: // NOT
956  {
957  MITK_INFO << "NOT";
958  for(long i=0; i<this->GetNumFibers(); i++)
959  result.push_back(i);
960 
961  std::vector<long>::iterator it;
962  for (long i=0; i<children->Size(); ++i)
963  {
964  std::vector<long> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage);
965 
966  std::vector<long> rest(result.size()-inRoi.size());
967  it = std::set_difference(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() );
968  rest.resize( it - rest.begin() );
969  result = rest;
970  }
971  break;
972  }
973  }
974  }
975  else if ( dynamic_cast<mitk::PlanarFigure*>(roi->GetData()) ) // actual extraction
976  {
977  if ( dynamic_cast<mitk::PlanarPolygon*>(roi->GetData()) )
978  {
979  mitk::PlanarFigure::Pointer planarPoly = dynamic_cast<mitk::PlanarFigure*>(roi->GetData());
980 
981  //create vtkPolygon using controlpoints from planarFigure polygon
982  vtkSmartPointer<vtkPolygon> polygonVtk = vtkSmartPointer<vtkPolygon>::New();
983  for (unsigned int i=0; i<planarPoly->GetNumberOfControlPoints(); ++i)
984  {
985  itk::Point<double,3> p = planarPoly->GetWorldControlPoint(i);
986  vtkIdType id = polygonVtk->GetPoints()->InsertNextPoint(p[0], p[1], p[2] );
987  polygonVtk->GetPointIds()->InsertNextId(id);
988  }
989 
990  MITK_INFO << "Extracting with polygon";
991  boost::progress_display disp(m_NumFibers);
992  for (int i=0; i<m_NumFibers; i++)
993  {
994  ++disp ;
995  vtkCell* cell = m_FiberPolyData->GetCell(i);
996  int numPoints = cell->GetNumberOfPoints();
997  vtkPoints* points = cell->GetPoints();
998 
999  for (int j=0; j<numPoints-1; j++)
1000  {
1001  // Inputs
1002  double p1[3] = {0,0,0};
1003  points->GetPoint(j, p1);
1004  double p2[3] = {0,0,0};
1005  points->GetPoint(j+1, p2);
1006  double tolerance = 0.001;
1007 
1008  // Outputs
1009  double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2))
1010  double x[3] = {0,0,0}; // The coordinate of the intersection
1011  double pcoords[3] = {0,0,0};
1012  int subId = 0;
1013 
1014  int iD = polygonVtk->IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId);
1015  if (iD!=0)
1016  {
1017  result.push_back(i);
1018  break;
1019  }
1020  }
1021  }
1022  }
1023  else if ( dynamic_cast<mitk::PlanarCircle*>(roi->GetData()) )
1024  {
1025  mitk::PlanarFigure::Pointer planarFigure = dynamic_cast<mitk::PlanarFigure*>(roi->GetData());
1026  Vector3D planeNormal = planarFigure->GetPlaneGeometry()->GetNormal();
1027  planeNormal.Normalize();
1028 
1029  //calculate circle radius
1030  mitk::Point3D V1w = planarFigure->GetWorldControlPoint(0); //centerPoint
1031  mitk::Point3D V2w = planarFigure->GetWorldControlPoint(1); //radiusPoint
1032 
1033  double radius = V1w.EuclideanDistanceTo(V2w);
1034  radius *= radius;
1035 
1036  MITK_INFO << "Extracting with circle";
1037  boost::progress_display disp(m_NumFibers);
1038  for (int i=0; i<m_NumFibers; i++)
1039  {
1040  ++disp ;
1041  vtkCell* cell = m_FiberPolyData->GetCell(i);
1042  int numPoints = cell->GetNumberOfPoints();
1043  vtkPoints* points = cell->GetPoints();
1044 
1045  for (int j=0; j<numPoints-1; j++)
1046  {
1047  // Inputs
1048  double p1[3] = {0,0,0};
1049  points->GetPoint(j, p1);
1050  double p2[3] = {0,0,0};
1051  points->GetPoint(j+1, p2);
1052 
1053  // Outputs
1054  double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2))
1055  double x[3] = {0,0,0}; // The coordinate of the intersection
1056 
1057  int iD = vtkPlane::IntersectWithLine(p1,p2,planeNormal.GetDataPointer(),V1w.GetDataPointer(),t,x);
1058 
1059  if (iD!=0)
1060  {
1061  double dist = (x[0]-V1w[0])*(x[0]-V1w[0])+(x[1]-V1w[1])*(x[1]-V1w[1])+(x[2]-V1w[2])*(x[2]-V1w[2]);
1062  if( dist <= radius)
1063  {
1064  result.push_back(i);
1065  break;
1066  }
1067  }
1068  }
1069  }
1070  }
1071  return result;
1072  }
1073 
1074  return result;
1075 }
1076 
1078 {
1079  vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New();
1080  cleaner->SetInputData(m_FiberPolyData);
1081  cleaner->PointMergingOff();
1082  cleaner->Update();
1083  m_FiberPolyData = cleaner->GetOutput();
1084 
1085  m_FiberLengths.clear();
1086  m_MeanFiberLength = 0;
1087  m_MedianFiberLength = 0;
1088  m_LengthStDev = 0;
1089  m_NumFibers = m_FiberPolyData->GetNumberOfCells();
1090 
1091  if (m_FiberColors==nullptr || m_FiberColors->GetNumberOfTuples()!=m_FiberPolyData->GetNumberOfPoints())
1092  this->ColorFibersByOrientation();
1093 
1094  if (m_FiberWeights->GetSize()!=m_NumFibers)
1095  {
1096  m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New();
1097  m_FiberWeights->SetName("FIBER_WEIGHTS");
1098  m_FiberWeights->SetNumberOfValues(m_NumFibers);
1099  this->SetFiberWeights(1);
1100  }
1101 
1102  if (m_NumFibers<=0) // no fibers present; apply default geometry
1103  {
1104  m_MinFiberLength = 0;
1105  m_MaxFiberLength = 0;
1107  geometry->SetImageGeometry(false);
1108  float b[] = {0, 1, 0, 1, 0, 1};
1109  geometry->SetFloatBounds(b);
1110  SetGeometry(geometry);
1111  return;
1112  }
1113  double b[6];
1114  m_FiberPolyData->GetBounds(b);
1115 
1116  // calculate statistics
1117  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
1118  {
1119  vtkCell* cell = m_FiberPolyData->GetCell(i);
1120  int p = cell->GetNumberOfPoints();
1121  vtkPoints* points = cell->GetPoints();
1122  float length = 0;
1123  for (int j=0; j<p-1; j++)
1124  {
1125  double p1[3];
1126  points->GetPoint(j, p1);
1127  double p2[3];
1128  points->GetPoint(j+1, p2);
1129 
1130  float dist = std::sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
1131  length += dist;
1132  }
1133  m_FiberLengths.push_back(length);
1134  m_MeanFiberLength += length;
1135  if (i==0)
1136  {
1137  m_MinFiberLength = length;
1138  m_MaxFiberLength = length;
1139  }
1140  else
1141  {
1142  if (length<m_MinFiberLength)
1143  m_MinFiberLength = length;
1144  if (length>m_MaxFiberLength)
1145  m_MaxFiberLength = length;
1146  }
1147  }
1148  m_MeanFiberLength /= m_NumFibers;
1149 
1150  std::vector< float > sortedLengths = m_FiberLengths;
1151  std::sort(sortedLengths.begin(), sortedLengths.end());
1152  for (int i=0; i<m_NumFibers; i++)
1153  m_LengthStDev += (m_MeanFiberLength-sortedLengths.at(i))*(m_MeanFiberLength-sortedLengths.at(i));
1154  if (m_NumFibers>1)
1155  m_LengthStDev /= (m_NumFibers-1);
1156  else
1157  m_LengthStDev = 0;
1158  m_LengthStDev = std::sqrt(m_LengthStDev);
1159  m_MedianFiberLength = sortedLengths.at(m_NumFibers/2);
1160 
1162  geometry->SetFloatBounds(b);
1163  this->SetGeometry(geometry);
1164 
1165  m_UpdateTime3D.Modified();
1166  m_UpdateTime2D.Modified();
1167 }
1168 
1169 float mitk::FiberBundle::GetFiberWeight(unsigned int fiber)
1170 {
1171  return m_FiberWeights->GetValue(fiber);
1172 }
1173 
1175 {
1176  for (int i=0; i<m_FiberWeights->GetSize(); i++)
1177  m_FiberWeights->SetValue(i, newWeight);
1178 }
1179 
1180 void mitk::FiberBundle::SetFiberWeights(vtkSmartPointer<vtkFloatArray> weights)
1181 {
1182  if (m_NumFibers!=weights->GetSize())
1183  {
1184  MITK_INFO << "Weights array not equal to number of fibers!";
1185  return;
1186  }
1187 
1188  for (int i=0; i<weights->GetSize(); i++)
1189  m_FiberWeights->SetValue(i, weights->GetValue(i));
1190 
1191  m_FiberWeights->SetName("FIBER_WEIGHTS");
1192 }
1193 
1194 void mitk::FiberBundle::SetFiberWeight(unsigned int fiber, float weight)
1195 {
1196  m_FiberWeights->SetValue(fiber, weight);
1197 }
1198 
1199 void mitk::FiberBundle::SetFiberColors(vtkSmartPointer<vtkUnsignedCharArray> fiberColors)
1200 {
1201  for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
1202  {
1203  unsigned char source[4] = {0,0,0,0};
1204  fiberColors->GetTupleValue(i, source);
1205 
1206  unsigned char target[4] = {0,0,0,0};
1207  target[0] = source[0];
1208  target[1] = source[1];
1209  target[2] = source[2];
1210  target[3] = source[3];
1211  m_FiberColors->InsertTupleValue(i, target);
1212  }
1213  m_UpdateTime3D.Modified();
1214  m_UpdateTime2D.Modified();
1215 }
1216 
1217 itk::Matrix< double, 3, 3 > mitk::FiberBundle::TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz)
1218 {
1219  rx = rx*M_PI/180;
1220  ry = ry*M_PI/180;
1221  rz = rz*M_PI/180;
1222 
1223  itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
1224  rotX[1][1] = cos(rx);
1225  rotX[2][2] = rotX[1][1];
1226  rotX[1][2] = -sin(rx);
1227  rotX[2][1] = -rotX[1][2];
1228 
1229  itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
1230  rotY[0][0] = cos(ry);
1231  rotY[2][2] = rotY[0][0];
1232  rotY[0][2] = sin(ry);
1233  rotY[2][0] = -rotY[0][2];
1234 
1235  itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
1236  rotZ[0][0] = cos(rz);
1237  rotZ[1][1] = rotZ[0][0];
1238  rotZ[0][1] = -sin(rz);
1239  rotZ[1][0] = -rotZ[0][1];
1240 
1241  itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
1242 
1243  m = rot*m;
1244 
1245  return m;
1246 }
1247 
1248 itk::Point<float, 3> mitk::FiberBundle::TransformPoint(vnl_vector_fixed< double, 3 > point, double rx, double ry, double rz, double tx, double ty, double tz)
1249 {
1250  rx = rx*M_PI/180;
1251  ry = ry*M_PI/180;
1252  rz = rz*M_PI/180;
1253 
1254  vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity();
1255  rotX[1][1] = cos(rx);
1256  rotX[2][2] = rotX[1][1];
1257  rotX[1][2] = -sin(rx);
1258  rotX[2][1] = -rotX[1][2];
1259 
1260  vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity();
1261  rotY[0][0] = cos(ry);
1262  rotY[2][2] = rotY[0][0];
1263  rotY[0][2] = sin(ry);
1264  rotY[2][0] = -rotY[0][2];
1265 
1266  vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity();
1267  rotZ[0][0] = cos(rz);
1268  rotZ[1][1] = rotZ[0][0];
1269  rotZ[0][1] = -sin(rz);
1270  rotZ[1][0] = -rotZ[0][1];
1271 
1272  vnl_matrix_fixed< double, 3, 3 > rot = rotZ*rotY*rotX;
1273 
1274  mitk::BaseGeometry::Pointer geom = this->GetGeometry();
1275  mitk::Point3D center = geom->GetCenter();
1276 
1277  point[0] -= center[0];
1278  point[1] -= center[1];
1279  point[2] -= center[2];
1280  point = rot*point;
1281  point[0] += center[0]+tx;
1282  point[1] += center[1]+ty;
1283  point[2] += center[2]+tz;
1284  itk::Point<float, 3> out; out[0] = point[0]; out[1] = point[1]; out[2] = point[2];
1285  return out;
1286 }
1287 
1288 void mitk::FiberBundle::TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz)
1289 {
1290  rx = rx*M_PI/180;
1291  ry = ry*M_PI/180;
1292  rz = rz*M_PI/180;
1293 
1294  vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity();
1295  rotX[1][1] = cos(rx);
1296  rotX[2][2] = rotX[1][1];
1297  rotX[1][2] = -sin(rx);
1298  rotX[2][1] = -rotX[1][2];
1299 
1300  vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity();
1301  rotY[0][0] = cos(ry);
1302  rotY[2][2] = rotY[0][0];
1303  rotY[0][2] = sin(ry);
1304  rotY[2][0] = -rotY[0][2];
1305 
1306  vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity();
1307  rotZ[0][0] = cos(rz);
1308  rotZ[1][1] = rotZ[0][0];
1309  rotZ[0][1] = -sin(rz);
1310  rotZ[1][0] = -rotZ[0][1];
1311 
1312  vnl_matrix_fixed< double, 3, 3 > rot = rotZ*rotY*rotX;
1313 
1314  mitk::BaseGeometry::Pointer geom = this->GetGeometry();
1315  mitk::Point3D center = geom->GetCenter();
1316 
1317  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1318  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1319 
1320  for (int i=0; i<m_NumFibers; i++)
1321  {
1322  vtkCell* cell = m_FiberPolyData->GetCell(i);
1323  int numPoints = cell->GetNumberOfPoints();
1324  vtkPoints* points = cell->GetPoints();
1325 
1326  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1327  for (int j=0; j<numPoints; j++)
1328  {
1329  double* p = points->GetPoint(j);
1330  vnl_vector_fixed< double, 3 > dir;
1331  dir[0] = p[0]-center[0];
1332  dir[1] = p[1]-center[1];
1333  dir[2] = p[2]-center[2];
1334  dir = rot*dir;
1335  dir[0] += center[0]+tx;
1336  dir[1] += center[1]+ty;
1337  dir[2] += center[2]+tz;
1338  vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block());
1339  container->GetPointIds()->InsertNextId(id);
1340  }
1341  vtkNewCells->InsertNextCell(container);
1342  }
1343 
1344  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1345  m_FiberPolyData->SetPoints(vtkNewPoints);
1346  m_FiberPolyData->SetLines(vtkNewCells);
1347  this->SetFiberPolyData(m_FiberPolyData, true);
1348 }
1349 
1350 void mitk::FiberBundle::RotateAroundAxis(double x, double y, double z)
1351 {
1352  x = x*M_PI/180;
1353  y = y*M_PI/180;
1354  z = z*M_PI/180;
1355 
1356  vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity();
1357  rotX[1][1] = cos(x);
1358  rotX[2][2] = rotX[1][1];
1359  rotX[1][2] = -sin(x);
1360  rotX[2][1] = -rotX[1][2];
1361 
1362  vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity();
1363  rotY[0][0] = cos(y);
1364  rotY[2][2] = rotY[0][0];
1365  rotY[0][2] = sin(y);
1366  rotY[2][0] = -rotY[0][2];
1367 
1368  vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity();
1369  rotZ[0][0] = cos(z);
1370  rotZ[1][1] = rotZ[0][0];
1371  rotZ[0][1] = -sin(z);
1372  rotZ[1][0] = -rotZ[0][1];
1373 
1374  mitk::BaseGeometry::Pointer geom = this->GetGeometry();
1375  mitk::Point3D center = geom->GetCenter();
1376 
1377  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1378  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1379 
1380  for (int i=0; i<m_NumFibers; i++)
1381  {
1382  vtkCell* cell = m_FiberPolyData->GetCell(i);
1383  int numPoints = cell->GetNumberOfPoints();
1384  vtkPoints* points = cell->GetPoints();
1385 
1386  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1387  for (int j=0; j<numPoints; j++)
1388  {
1389  double* p = points->GetPoint(j);
1390  vnl_vector_fixed< double, 3 > dir;
1391  dir[0] = p[0]-center[0];
1392  dir[1] = p[1]-center[1];
1393  dir[2] = p[2]-center[2];
1394  dir = rotZ*rotY*rotX*dir;
1395  dir[0] += center[0];
1396  dir[1] += center[1];
1397  dir[2] += center[2];
1398  vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block());
1399  container->GetPointIds()->InsertNextId(id);
1400  }
1401  vtkNewCells->InsertNextCell(container);
1402  }
1403 
1404  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1405  m_FiberPolyData->SetPoints(vtkNewPoints);
1406  m_FiberPolyData->SetLines(vtkNewCells);
1407  this->SetFiberPolyData(m_FiberPolyData, true);
1408 }
1409 
1410 void mitk::FiberBundle::ScaleFibers(double x, double y, double z, bool subtractCenter)
1411 {
1412  MITK_INFO << "Scaling fibers";
1413  boost::progress_display disp(m_NumFibers);
1414 
1415  mitk::BaseGeometry* geom = this->GetGeometry();
1416  mitk::Point3D c = geom->GetCenter();
1417 
1418  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1419  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1420 
1421  for (int i=0; i<m_NumFibers; i++)
1422  {
1423  ++disp ;
1424  vtkCell* cell = m_FiberPolyData->GetCell(i);
1425  int numPoints = cell->GetNumberOfPoints();
1426  vtkPoints* points = cell->GetPoints();
1427 
1428  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1429  for (int j=0; j<numPoints; j++)
1430  {
1431  double* p = points->GetPoint(j);
1432  if (subtractCenter)
1433  {
1434  p[0] -= c[0]; p[1] -= c[1]; p[2] -= c[2];
1435  }
1436  p[0] *= x;
1437  p[1] *= y;
1438  p[2] *= z;
1439  if (subtractCenter)
1440  {
1441  p[0] += c[0]; p[1] += c[1]; p[2] += c[2];
1442  }
1443  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
1444  container->GetPointIds()->InsertNextId(id);
1445  }
1446  vtkNewCells->InsertNextCell(container);
1447  }
1448 
1449  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1450  m_FiberPolyData->SetPoints(vtkNewPoints);
1451  m_FiberPolyData->SetLines(vtkNewCells);
1452  this->SetFiberPolyData(m_FiberPolyData, true);
1453 }
1454 
1455 void mitk::FiberBundle::TranslateFibers(double x, double y, double z)
1456 {
1457  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1458  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1459 
1460  for (int i=0; i<m_NumFibers; i++)
1461  {
1462  vtkCell* cell = m_FiberPolyData->GetCell(i);
1463  int numPoints = cell->GetNumberOfPoints();
1464  vtkPoints* points = cell->GetPoints();
1465 
1466  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1467  for (int j=0; j<numPoints; j++)
1468  {
1469  double* p = points->GetPoint(j);
1470  p[0] += x;
1471  p[1] += y;
1472  p[2] += z;
1473  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
1474  container->GetPointIds()->InsertNextId(id);
1475  }
1476  vtkNewCells->InsertNextCell(container);
1477  }
1478 
1479  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1480  m_FiberPolyData->SetPoints(vtkNewPoints);
1481  m_FiberPolyData->SetLines(vtkNewCells);
1482  this->SetFiberPolyData(m_FiberPolyData, true);
1483 }
1484 
1485 void mitk::FiberBundle::MirrorFibers(unsigned int axis)
1486 {
1487  if (axis>2)
1488  return;
1489 
1490  MITK_INFO << "Mirroring fibers";
1491  boost::progress_display disp(m_NumFibers);
1492 
1493  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1494  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1495 
1496  for (int i=0; i<m_NumFibers; i++)
1497  {
1498  ++disp;
1499  vtkCell* cell = m_FiberPolyData->GetCell(i);
1500  int numPoints = cell->GetNumberOfPoints();
1501  vtkPoints* points = cell->GetPoints();
1502 
1503  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1504  for (int j=0; j<numPoints; j++)
1505  {
1506  double* p = points->GetPoint(j);
1507  p[axis] = -p[axis];
1508  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
1509  container->GetPointIds()->InsertNextId(id);
1510  }
1511  vtkNewCells->InsertNextCell(container);
1512  }
1513 
1514  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1515  m_FiberPolyData->SetPoints(vtkNewPoints);
1516  m_FiberPolyData->SetLines(vtkNewCells);
1517  this->SetFiberPolyData(m_FiberPolyData, true);
1518 }
1519 
1520 void mitk::FiberBundle::RemoveDir(vnl_vector_fixed<double,3> dir, double threshold)
1521 {
1522  dir.normalize();
1523  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1524  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1525 
1526  boost::progress_display disp(m_FiberPolyData->GetNumberOfCells());
1527  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
1528  {
1529  ++disp ;
1530  vtkCell* cell = m_FiberPolyData->GetCell(i);
1531  int numPoints = cell->GetNumberOfPoints();
1532  vtkPoints* points = cell->GetPoints();
1533 
1534  // calculate curvatures
1535  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1536  bool discard = false;
1537  for (int j=0; j<numPoints-1; j++)
1538  {
1539  double p1[3];
1540  points->GetPoint(j, p1);
1541  double p2[3];
1542  points->GetPoint(j+1, p2);
1543 
1544  vnl_vector_fixed< double, 3 > v1;
1545  v1[0] = p2[0]-p1[0];
1546  v1[1] = p2[1]-p1[1];
1547  v1[2] = p2[2]-p1[2];
1548  if (v1.magnitude()>0.001)
1549  {
1550  v1.normalize();
1551 
1552  if (fabs(dot_product(v1,dir))>threshold)
1553  {
1554  discard = true;
1555  break;
1556  }
1557  }
1558  }
1559  if (!discard)
1560  {
1561  for (int j=0; j<numPoints; j++)
1562  {
1563  double p1[3];
1564  points->GetPoint(j, p1);
1565 
1566  vtkIdType id = vtkNewPoints->InsertNextPoint(p1);
1567  container->GetPointIds()->InsertNextId(id);
1568  }
1569  vtkNewCells->InsertNextCell(container);
1570  }
1571  }
1572 
1573  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1574  m_FiberPolyData->SetPoints(vtkNewPoints);
1575  m_FiberPolyData->SetLines(vtkNewCells);
1576 
1577  this->SetFiberPolyData(m_FiberPolyData, true);
1578 
1579  // UpdateColorCoding();
1580  // UpdateFiberGeometry();
1581 }
1582 
1583 bool mitk::FiberBundle::ApplyCurvatureThreshold(float minRadius, bool deleteFibers)
1584 {
1585  if (minRadius<0)
1586  return true;
1587 
1588  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1589  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1590 
1591  MITK_INFO << "Applying curvature threshold";
1592  boost::progress_display disp(m_FiberPolyData->GetNumberOfCells());
1593  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
1594  {
1595  ++disp ;
1596  vtkCell* cell = m_FiberPolyData->GetCell(i);
1597  int numPoints = cell->GetNumberOfPoints();
1598  vtkPoints* points = cell->GetPoints();
1599 
1600  // calculate curvatures
1601  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1602  for (int j=0; j<numPoints-2; j++)
1603  {
1604  double p1[3];
1605  points->GetPoint(j, p1);
1606  double p2[3];
1607  points->GetPoint(j+1, p2);
1608  double p3[3];
1609  points->GetPoint(j+2, p3);
1610 
1611  vnl_vector_fixed< float, 3 > v1, v2, v3;
1612 
1613  v1[0] = p2[0]-p1[0];
1614  v1[1] = p2[1]-p1[1];
1615  v1[2] = p2[2]-p1[2];
1616 
1617  v2[0] = p3[0]-p2[0];
1618  v2[1] = p3[1]-p2[1];
1619  v2[2] = p3[2]-p2[2];
1620 
1621  v3[0] = p1[0]-p3[0];
1622  v3[1] = p1[1]-p3[1];
1623  v3[2] = p1[2]-p3[2];
1624 
1625  float a = v1.magnitude();
1626  float b = v2.magnitude();
1627  float c = v3.magnitude();
1628  float r = a*b*c/std::sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a-b+c)); // radius of triangle via Heron's formula (area of triangle)
1629 
1630  vtkIdType id = vtkNewPoints->InsertNextPoint(p1);
1631  container->GetPointIds()->InsertNextId(id);
1632 
1633  if (deleteFibers && r<minRadius)
1634  break;
1635 
1636  if (r<minRadius)
1637  {
1638  j += 2;
1639  vtkNewCells->InsertNextCell(container);
1640  container = vtkSmartPointer<vtkPolyLine>::New();
1641  }
1642  else if (j==numPoints-3)
1643  {
1644  id = vtkNewPoints->InsertNextPoint(p2);
1645  container->GetPointIds()->InsertNextId(id);
1646  id = vtkNewPoints->InsertNextPoint(p3);
1647  container->GetPointIds()->InsertNextId(id);
1648  vtkNewCells->InsertNextCell(container);
1649  }
1650  }
1651  }
1652 
1653  if (vtkNewCells->GetNumberOfCells()<=0)
1654  return false;
1655 
1656  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1657  m_FiberPolyData->SetPoints(vtkNewPoints);
1658  m_FiberPolyData->SetLines(vtkNewCells);
1659  this->SetFiberPolyData(m_FiberPolyData, true);
1660  return true;
1661 }
1662 
1664 {
1665  MITK_INFO << "Removing short fibers";
1666  if (lengthInMM<=0 || lengthInMM<m_MinFiberLength)
1667  {
1668  MITK_INFO << "No fibers shorter than " << lengthInMM << " mm found!";
1669  return true;
1670  }
1671 
1672  if (lengthInMM>m_MaxFiberLength) // can't remove all fibers
1673  {
1674  MITK_WARN << "Process aborted. No fibers would be left!";
1675  return false;
1676  }
1677 
1678  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1679  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1680  float min = m_MaxFiberLength;
1681 
1682  boost::progress_display disp(m_NumFibers);
1683  for (int i=0; i<m_NumFibers; i++)
1684  {
1685  ++disp;
1686  vtkCell* cell = m_FiberPolyData->GetCell(i);
1687  int numPoints = cell->GetNumberOfPoints();
1688  vtkPoints* points = cell->GetPoints();
1689 
1690  if (m_FiberLengths.at(i)>=lengthInMM)
1691  {
1692  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1693  for (int j=0; j<numPoints; j++)
1694  {
1695  double* p = points->GetPoint(j);
1696  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
1697  container->GetPointIds()->InsertNextId(id);
1698  }
1699  vtkNewCells->InsertNextCell(container);
1700  if (m_FiberLengths.at(i)<min)
1701  min = m_FiberLengths.at(i);
1702  }
1703  }
1704 
1705  if (vtkNewCells->GetNumberOfCells()<=0)
1706  return false;
1707 
1708  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1709  m_FiberPolyData->SetPoints(vtkNewPoints);
1710  m_FiberPolyData->SetLines(vtkNewCells);
1711  this->SetFiberPolyData(m_FiberPolyData, true);
1712  return true;
1713 }
1714 
1716 {
1717  if (lengthInMM<=0 || lengthInMM>m_MaxFiberLength)
1718  return true;
1719 
1720  if (lengthInMM<m_MinFiberLength) // can't remove all fibers
1721  return false;
1722 
1723  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1724  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1725 
1726  MITK_INFO << "Removing long fibers";
1727  boost::progress_display disp(m_NumFibers);
1728  for (int i=0; i<m_NumFibers; i++)
1729  {
1730  ++disp;
1731  vtkCell* cell = m_FiberPolyData->GetCell(i);
1732  int numPoints = cell->GetNumberOfPoints();
1733  vtkPoints* points = cell->GetPoints();
1734 
1735  if (m_FiberLengths.at(i)<=lengthInMM)
1736  {
1737  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1738  for (int j=0; j<numPoints; j++)
1739  {
1740  double* p = points->GetPoint(j);
1741  vtkIdType id = vtkNewPoints->InsertNextPoint(p);
1742  container->GetPointIds()->InsertNextId(id);
1743  }
1744  vtkNewCells->InsertNextCell(container);
1745  }
1746  }
1747 
1748  if (vtkNewCells->GetNumberOfCells()<=0)
1749  return false;
1750 
1751  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1752  m_FiberPolyData->SetPoints(vtkNewPoints);
1753  m_FiberPolyData->SetLines(vtkNewCells);
1754  this->SetFiberPolyData(m_FiberPolyData, true);
1755  return true;
1756 }
1757 
1758 void mitk::FiberBundle::ResampleSpline(float pointDistance, double tension, double continuity, double bias )
1759 {
1760  if (pointDistance<=0)
1761  return;
1762 
1763  vtkSmartPointer<vtkPoints> vtkSmoothPoints = vtkSmartPointer<vtkPoints>::New(); //in smoothpoints the interpolated points representing a fiber are stored.
1764 
1765  //in vtkcells all polylines are stored, actually all id's of them are stored
1766  vtkSmartPointer<vtkCellArray> vtkSmoothCells = vtkSmartPointer<vtkCellArray>::New(); //cellcontainer for smoothed lines
1767  vtkIdType pointHelperCnt = 0;
1768 
1769  MITK_INFO << "Smoothing fibers";
1770  boost::progress_display disp(m_NumFibers);
1771  for (int i=0; i<m_NumFibers; i++)
1772  {
1773  ++disp;
1774  vtkCell* cell = m_FiberPolyData->GetCell(i);
1775  int numPoints = cell->GetNumberOfPoints();
1776  vtkPoints* points = cell->GetPoints();
1777 
1778  vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
1779  for (int j=0; j<numPoints; j++)
1780  newPoints->InsertNextPoint(points->GetPoint(j));
1781 
1782  float length = m_FiberLengths.at(i);
1783  int sampling = std::ceil(length/pointDistance);
1784 
1785  vtkSmartPointer<vtkKochanekSpline> xSpline = vtkSmartPointer<vtkKochanekSpline>::New();
1786  vtkSmartPointer<vtkKochanekSpline> ySpline = vtkSmartPointer<vtkKochanekSpline>::New();
1787  vtkSmartPointer<vtkKochanekSpline> zSpline = vtkSmartPointer<vtkKochanekSpline>::New();
1788  xSpline->SetDefaultBias(bias); xSpline->SetDefaultTension(tension); xSpline->SetDefaultContinuity(continuity);
1789  ySpline->SetDefaultBias(bias); ySpline->SetDefaultTension(tension); ySpline->SetDefaultContinuity(continuity);
1790  zSpline->SetDefaultBias(bias); zSpline->SetDefaultTension(tension); zSpline->SetDefaultContinuity(continuity);
1791 
1792  vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
1793  spline->SetXSpline(xSpline);
1794  spline->SetYSpline(ySpline);
1795  spline->SetZSpline(zSpline);
1796  spline->SetPoints(newPoints);
1797 
1798  vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
1799  functionSource->SetParametricFunction(spline);
1800  functionSource->SetUResolution(sampling);
1801  functionSource->SetVResolution(sampling);
1802  functionSource->SetWResolution(sampling);
1803  functionSource->Update();
1804 
1805  vtkPolyData* outputFunction = functionSource->GetOutput();
1806  vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber
1807 
1808  vtkSmartPointer<vtkPolyLine> smoothLine = vtkSmartPointer<vtkPolyLine>::New();
1809  smoothLine->GetPointIds()->SetNumberOfIds(tmpSmoothPnts->GetNumberOfPoints());
1810 
1811  for (int j=0; j<smoothLine->GetNumberOfPoints(); j++)
1812  {
1813  smoothLine->GetPointIds()->SetId(j, j+pointHelperCnt);
1814  vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(j));
1815  }
1816  vtkSmoothCells->InsertNextCell(smoothLine);
1817  pointHelperCnt += tmpSmoothPnts->GetNumberOfPoints();
1818  }
1819 
1820  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1821  m_FiberPolyData->SetPoints(vtkSmoothPoints);
1822  m_FiberPolyData->SetLines(vtkSmoothCells);
1823  this->SetFiberPolyData(m_FiberPolyData, true);
1824  m_FiberSampling = 10/pointDistance;
1825 }
1826 
1827 void mitk::FiberBundle::ResampleSpline(float pointDistance)
1828 {
1829  ResampleSpline(pointDistance, 0, 0, 0 );
1830 }
1831 
1833 {
1834  unsigned long points = 0;
1835  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
1836  {
1837  vtkCell* cell = m_FiberPolyData->GetCell(i);
1838  points += cell->GetNumberOfPoints();
1839  }
1840  return points;
1841 }
1842 
1844 {
1845  vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
1846  vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
1847 
1848  MITK_INFO << "Compressing fibers";
1849  unsigned long numRemovedPoints = 0;
1850  boost::progress_display disp(m_FiberPolyData->GetNumberOfCells());
1851 
1852  for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
1853  {
1854  ++disp;
1855  vtkCell* cell = m_FiberPolyData->GetCell(i);
1856  int numPoints = cell->GetNumberOfPoints();
1857  vtkPoints* points = cell->GetPoints();
1858 
1859  // calculate curvatures
1860  std::vector< int > removedPoints; removedPoints.resize(numPoints, 0);
1861  removedPoints[0]=-1; removedPoints[numPoints-1]=-1;
1862 
1863  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
1864 
1865  bool pointFound = true;
1866  while (pointFound)
1867  {
1868  pointFound = false;
1869  double minError = error;
1870  int removeIndex = -1;
1871 
1872  for (int j=0; j<numPoints; j++)
1873  {
1874  if (removedPoints[j]==0)
1875  {
1876  double cand[3];
1877  points->GetPoint(j, cand);
1878  vnl_vector_fixed< double, 3 > candV;
1879  candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2];
1880 
1881  int validP = -1;
1882  vnl_vector_fixed< double, 3 > pred;
1883  for (int k=j-1; k>=0; k--)
1884  if (removedPoints[k]<=0)
1885  {
1886  double ref[3];
1887  points->GetPoint(k, ref);
1888  pred[0]=ref[0]; pred[1]=ref[1]; pred[2]=ref[2];
1889  validP = k;
1890  break;
1891  }
1892  int validS = -1;
1893  vnl_vector_fixed< double, 3 > succ;
1894  for (int k=j+1; k<numPoints; k++)
1895  if (removedPoints[k]<=0)
1896  {
1897  double ref[3];
1898  points->GetPoint(k, ref);
1899  succ[0]=ref[0]; succ[1]=ref[1]; succ[2]=ref[2];
1900  validS = k;
1901  break;
1902  }
1903 
1904  if (validP>=0 && validS>=0)
1905  {
1906  double a = (candV-pred).magnitude();
1907  double b = (candV-succ).magnitude();
1908  double c = (pred-succ).magnitude();
1909  double s=0.5*(a+b+c);
1910  double hc=(2.0/c)*sqrt(fabs(s*(s-a)*(s-b)*(s-c)));
1911 
1912  if (hc<minError)
1913  {
1914  removeIndex = j;
1915  minError = hc;
1916  pointFound = true;
1917  }
1918  }
1919  }
1920  }
1921 
1922  if (pointFound)
1923  {
1924  removedPoints[removeIndex] = 1;
1925  numRemovedPoints++;
1926  }
1927  }
1928 
1929  for (int j=0; j<numPoints; j++)
1930  {
1931  if (removedPoints[j]<=0)
1932  {
1933  double cand[3];
1934  points->GetPoint(j, cand);
1935  vtkIdType id = vtkNewPoints->InsertNextPoint(cand);
1936  container->GetPointIds()->InsertNextId(id);
1937  }
1938  }
1939 
1940  vtkNewCells->InsertNextCell(container);
1941  }
1942 
1943  if (vtkNewCells->GetNumberOfCells()>0)
1944  {
1945  MITK_INFO << "Removed points: " << numRemovedPoints;
1946  m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
1947  m_FiberPolyData->SetPoints(vtkNewPoints);
1948  m_FiberPolyData->SetLines(vtkNewCells);
1949  this->SetFiberPolyData(m_FiberPolyData, true);
1950  }
1951 }
1952 
1953 // reapply selected colorcoding in case polydata structure has changed
1955 {
1956  if (fib==nullptr)
1957  {
1958  MITK_INFO << "Reference bundle is NULL!";
1959  return false;
1960  }
1961 
1962  if (m_NumFibers!=fib->GetNumFibers())
1963  {
1964  MITK_INFO << "Unequal number of fibers!";
1965  MITK_INFO << m_NumFibers << " vs. " << fib->GetNumFibers();
1966  return false;
1967  }
1968 
1969  for (int i=0; i<m_NumFibers; i++)
1970  {
1971  vtkCell* cell = m_FiberPolyData->GetCell(i);
1972  int numPoints = cell->GetNumberOfPoints();
1973  vtkPoints* points = cell->GetPoints();
1974 
1975  vtkCell* cell2 = fib->GetFiberPolyData()->GetCell(i);
1976  int numPoints2 = cell2->GetNumberOfPoints();
1977  vtkPoints* points2 = cell2->GetPoints();
1978 
1979  if (numPoints2!=numPoints)
1980  {
1981  MITK_INFO << "Unequal number of points in fiber " << i << "!";
1982  MITK_INFO << numPoints2 << " vs. " << numPoints;
1983  return false;
1984  }
1985 
1986  for (int j=0; j<numPoints; j++)
1987  {
1988  double* p1 = points->GetPoint(j);
1989  double* p2 = points2->GetPoint(j);
1990  if (fabs(p1[0]-p2[0])>eps || fabs(p1[1]-p2[1])>eps || fabs(p1[2]-p2[2])>eps)
1991  {
1992  MITK_INFO << "Unequal points in fiber " << i << " at position " << j << "!";
1993  MITK_INFO << "p1: " << p1[0] << ", " << p1[1] << ", " << p1[2];
1994  MITK_INFO << "p2: " << p2[0] << ", " << p2[1] << ", " << p2[2];
1995  return false;
1996  }
1997  }
1998  }
1999 
2000  return true;
2001 }
2002 
2003 /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */
2005 {
2006 
2007 }
2009 {
2010 
2011 }
2013 {
2014  return false;
2015 }
2017 {
2018  return true;
2019 }
2020 void mitk::FiberBundle::SetRequestedRegion(const itk::DataObject* )
2021 {
2022 
2023 }
FiberBundle::Pointer SubtractBundle(FiberBundle *fib)
bool RemoveLongFibers(float lengthInMM)
void ResampleSpline(float pointDistance=1)
Data management class that handles 'was created by' relations.
Gives locked and index-based read access for a particular image part. The class provides several set-...
static const char * FIBER_ID_ARRAY
void ScaleFibers(double x, double y, double z, bool subtractCenter=true)
void SetFiberOpacity(vtkDoubleArray *FAValArray)
#define MITK_INFO
Definition: mitkLogMacros.h:22
virtual void SetRequestedRegion(const itk::DataObject *) override
Set the requested region from this data object to match the requested region of the data object passe...
virtual void SetRequestedRegionToLargestPossibleRegion() override
Set the RequestedRegion to the LargestPossibleRegion.
itk::Matrix< double, 3, 3 > TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz)
virtual void UpdateOutputInformation() override
virtual SetOfObjects::ConstPointer GetDerivations(const mitk::DataNode *node, const NodePredicateBase *condition=nullptr, bool onlyDirectDerivations=true) const =0
returns a set of derived objects for a given node.
void SetFiberWeights(float newWeight)
void RemoveDir(vnl_vector_fixed< double, 3 > dir, double threshold)
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
STL namespace.
itk::Point< float, 3 > GetItkPoint(double point[3])
bool RemoveShortFibers(float lengthInMM)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
#define mitkPixelTypeMultiplex2(function, ptype, param1, param2)
static Pointer New()
float GetFiberWeight(unsigned int fiber)
void SetFiberWeight(unsigned int fiber, float weight)
itk::Image< unsigned char, 3 > ItkUcharImgType
void TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz)
void RotateAroundAxis(double x, double y, double z)
itk::SmartPointer< const Self > ConstPointer
FiberBundle::Pointer AddBundle(FiberBundle *fib)
FiberBundle(vtkPolyData *fiberPolyData=nullptr)
bool ApplyCurvatureThreshold(float minRadius, bool deleteFibers)
mitk::FiberBundle::Pointer GetDeepCopy()
#define MITK_WARN
Definition: mitkLogMacros.h:23
itk::Point< float, 3 > TransformPoint(vnl_vector_fixed< double, 3 > point, double rx, double ry, double rz, double tx, double ty, double tz)
static Pointer New()
vtkSmartPointer< vtkPolyData > GetFiberPolyData() const
Base Class for Fiber Bundles;.
static T max(T x, T y)
Definition: svm.cpp:70
Point3D GetCenter() const
Get the center of the bounding-box in mm.
virtual bool VerifyRequestedRegion() override
Verify that the RequestedRegion is within the LargestPossibleRegion.
std::vector< long > ExtractFiberIdSubset(DataNode *roi, DataStorage *storage)
unsigned long GetNumberOfPoints()
void TranslateFibers(double x, double y, double z)
static T min(T x, T y)
Definition: svm.cpp:67
FiberBundle::Pointer ExtractFiberSubset(DataNode *roi, DataStorage *storage)
Base-class for geometric planar (2D) figures, such as lines, circles, rectangles, polygons...
void ColorFibersByScalarMap(mitk::Image::Pointer, bool opacity)
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion() override
Determine whether the RequestedRegion is outside of the BufferedRegion.
void SetFiberColors(vtkSmartPointer< vtkUnsignedCharArray > fiberColors)
MITKCORE_EXPORT const ScalarType eps
void MirrorFibers(unsigned int axis)
FiberBundle::Pointer RemoveFibersOutside(ItkUcharImgType *mask, bool invert=false)
bool Equals(FiberBundle *fib, double eps=0.0001)
void Compress(float error=0.0)
virtual int GetNumFibers()
void SetFiberPolyData(vtkSmartPointer< vtkPolyData >, bool updateGeometry=true)
BaseGeometry Describes the geometry of a data object.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
vtkSmartPointer< vtkPolyData > GeneratePolyDataByIds(std::vector< long >)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.