SMILX  1.01
milxQtDiffusionTensorImage.cpp
1 /*=========================================================================
2  The Software is copyright (c) Commonwealth Scientific and Industrial Research Organisation (CSIRO)
3  ABN 41 687 119 230.
4  All rights reserved.
5 
6  Licensed under the CSIRO BSD 3-Clause License
7  You may not use this file except in compliance with the License.
8  You may obtain a copy of the License in the file LICENSE.md or at
9 
10  https://stash.csiro.au/projects/SMILI/repos/smili/browse/license.txt
11 
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 =========================================================================*/
18 #include "milxQtDiffusionTensorImage.h"
19 
20 #include <vtkSphereSource.h>
21 #include <vtkMath.h>
22 #include <vtkFloatArray.h>
23 #include <vtkPolyDataNormals.h>
24 #include <vtkAppendPolyData.h>
25 
26 #include "vtkDiffusionTensorGlyphFilter.h"
27 
28 typedef vtkDiffusionTensorGlyphFilter::VectorImageType::SpacingType SpacingType;
29 
30 void CalcGlyph(void *arg)
31 {
33 
34  if(!glyphFilter)
35  {
36  std::cerr << "vtkDiffusionTensorGlyphFilter is not valid!" << std::endl;
37  }
38 
40  std::vector<vectorImageType::IndexType> indices = glyphFilter->GetTensorImageIndices();
41  vtkDiffusionTensorGlyphFilter::VectorImageType::Pointer image = glyphFilter->GetTensorImage();
42  const vectorImageType::PixelType normVector = glyphFilter->GetNormaliseVector();
43 
45  vectorImageType::IndexType index = indices[glyphFilter->GetPointId()];
47  const vectorImageType::PixelType harmonicsVector = image->GetPixel(index);
48 
49 // SpacingType spacing = glyphFilter->GetTensorImage()->GetSpacing();
50  double radiusScaling = 2.5;
51 
52  double pointCoords[3];
53  glyphFilter->GetPoint(pointCoords);
54 
55  typedef double projectionType;
56 
57 // std::cout << "Calling CalcGlyph for point "
58 // << glyphFilter->GetPointId() << std::endl;
59 // std::cout << "Point coords are: "
60 // << pointCoords[0] << " "
61 // << pointCoords[1] << " "
62 // << pointCoords[2] << std::endl;
63 
64  vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
65  sphereSource->SetThetaResolution( glyphFilter->GetResolution() );
66  sphereSource->SetPhiResolution( glyphFilter->GetResolution() );
67  sphereSource->SetRadius( 1.0 );
68  sphereSource->Update();
69  vtkSmartPointer<vtkPolyData> glyph = sphereSource->GetOutput();
70 
71  vtkSmartPointer<vtkFloatArray> projections = vtkSmartPointer<vtkFloatArray>::New();
72  projections->SetNumberOfComponents(3);
73  projections->SetNumberOfTuples(glyph->GetNumberOfPoints());
74  projections->SetName("Fibre Projections");
75  projections->FillComponent(0, 0.0);
76  projections->FillComponent(1, 0.0);
77  projections->FillComponent(2, 0.0);
78 
80  double m_x = pointCoords[0], m_y = pointCoords[1], m_z = pointCoords[2];
81  for(vtkIdType i = 0; i < glyph->GetNumberOfPoints(); i ++)
82  {
83  double point_sphere[3];
84  glyph->GetPoint(i, point_sphere);
85  const double x_s = point_sphere[0];
86  const double y_s = point_sphere[1];
87  const double z_s = point_sphere[2];
88 
90  std::vector<double> sHarmonicCoefficients;
91  for(size_t j = 0; j < harmonicsVector.GetSize(); j ++)
92  sHarmonicCoefficients.push_back(harmonicsVector[j]/normVector[j]);
93 
95  const int n_coefs = sHarmonicCoefficients.size();
96  const int l_max = vtkDiffusionTensorGlyphFilter::LforN( n_coefs );
97  double amplitude = vtkDiffusionTensorGlyphFilter::computeAmplitude( sHarmonicCoefficients, x_s, y_s, z_s, l_max );
98 // cout << "Amplitude: " << amplitude << ", ";
99 
100  if(amplitude < 0)
101  amplitude = 0;
102 
104  double x_g = x_s * amplitude * radiusScaling;
105  double y_g = y_s * amplitude * radiusScaling;
106  double z_g = z_s * amplitude * radiusScaling;
107 
108  glyph->GetPoints()->SetPoint(i, x_g, y_g, z_g);
109 
111  for(size_t j = 0; j < 3; j ++)
112  {
113  projectionType axis[3] = {0.0, 0.0, 0.0};
114  coordinate currentProjection(projections->GetTuple3(i)), position(glyph->GetPoint(i)); //coordinate is vnl_vector_fixed
115 
116  axis[j] = 1.0;
117  projectionType projection = vtkMath::Dot(axis, position.data_block()); //project to axis being done,
118  currentProjection[j] = projection; //projection in each direction
119 
120  projections->SetTuple3(i, static_cast<float>(currentProjection[0])
121  , static_cast<float>(currentProjection[1])
122  , static_cast<float>(currentProjection[2]));
123  }
124 
126  x_g += m_x;
127  y_g += m_y;
128  z_g += m_z;
129  glyph->GetPoints()->SetPoint(i, x_g, y_g, z_g);
130 
131  qApp->processEvents(); //keep UI responsive
132  }
133 
135  vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
136  scalars->SetNumberOfComponents(3);
137  scalars->SetNumberOfTuples(glyph->GetNumberOfPoints());
138  scalars->SetName("Colours");
139  scalars->FillComponent(0, 0);
140  scalars->FillComponent(1, 0);
141  scalars->FillComponent(2, 0);
142  for(vtkIdType i = 0; i < glyph->GetNumberOfPoints(); i ++)
143  {
144  coordinate currentProjection(projections->GetTuple3(i));
145  coordinate currentProjSquared = element_product(currentProjection, currentProjection);
146  projectionType maxProjection = currentProjSquared.max_value();
147  currentProjSquared /= maxProjection;
148 
149  unsigned char colourOfPoint[3] = {0, 0, 0};
150  colourOfPoint[0] = static_cast<unsigned char>( currentProjSquared[0]*255.0 );
151  colourOfPoint[1] = static_cast<unsigned char>( currentProjSquared[1]*255.0 );
152  colourOfPoint[2] = static_cast<unsigned char>( currentProjSquared[2]*255.0 );
153 
154  scalars->SetTupleValue(i, colourOfPoint);
155 
156  qApp->processEvents(); //keep UI responsive
157  }
158  // cout << endl;
159  glyph->GetPointData()->SetScalars(scalars);
160  glyph->Modified();
161 
162  vtkSmartPointer< vtkPolyDataNormals > normals = vtkSmartPointer< vtkPolyDataNormals >::New();
163  #if VTK_MAJOR_VERSION <= 5
164  normals->SetInput(glyph);
165  #else
166  normals->SetInputData(glyph);
167  #endif
168  normals->ComputePointNormalsOn();
169  normals->SplittingOff();
170  normals->ComputeCellNormalsOff();
171  normals->Update();
172 
173 #if VTK_MAJOR_VERSION <= 5
174  glyphFilter->SetSource(normals->GetOutput());
175 #else
176  glyphFilter->SetSourceConnection(normals->GetOutputPort());
177 #endif
178 }
179 
180 milxQtDiffusionTensorImage::milxQtDiffusionTensorImage(QWidget *theParent) : milxQtImage(theParent)
181 {
182  milxQtWindow::prefix = "DTI Img: ";
183 
184  createActions();
185 
186  createConnections();
187 }
188 
189 milxQtDiffusionTensorImage::~milxQtDiffusionTensorImage()
190 {
191  //dtor
192 }
193 
194 void milxQtDiffusionTensorImage::diffusionGlyphs(size_t subsampleFactor, size_t resolution)
195 {
196  if(ITK_VERSION_MAJOR < 4 || VTK_MAJOR_VERSION < 6)
197  {
198  printError("You are not using ITK 4 or above OR VTK 6 or above. Ignoring.");
199  return;
200  }
201 
202  printDebug("Computing Diffusion Glyphs");
203 
204  bool ok1 = false, ok2 = false;
205  if(subsampleFactor == 0)
206  {
207  subsampleFactor = QInputDialog::getInt(this, tr("Please Provide the sub-sample factor of the data"),
208  tr("Sub-sample Factor:"), 1, 1, 1000, 1, &ok1);
209  resolution = QInputDialog::getInt(this, tr("Please Provide the resolution of the glyphs"),
210  tr("Resolution:"), 16, 4, 256, 1, &ok2);
211  if(!ok1 || !ok2)
212  return;
213  }
214 
215  int extent[6];
216  milxQtImage::viewer->GetImageActor()->GetDisplayExtent(extent);
217 
218  if(flipped)
219  {
220  int actualExtent[6];
221  milxQtImage::imageData->GetExtent(actualExtent);
222 
223  if(extent[3]-extent[2] == 0) //flip y extent
224  {
225  extent[2] = actualExtent[3]-extent[2];
226  extent[3] = actualExtent[3]-extent[3];
227  }
228  }
229 
230  emit working(-1);
232  vectorImageType::Pointer sliceVector = milx::Image<vectorImageType>::ExtractSlice<vectorImageType>(milxQtImage::imageVector, extent);
233 
234  //Which dimension is sliced?
235  vectorImageType::SizeType imageSize = sliceVector->GetLargestPossibleRegion().GetSize();
236  size_t sliceDimension = 0;
237  for(size_t j = 0; j < vectorImageType::ImageDimension; j ++)
238  {
239  if(imageSize[j] == 1)
240  sliceDimension = j;
241  }
242 
244  vectorImageType::SizeType sliceSubsampleSizes;
245  sliceSubsampleSizes.Fill(subsampleFactor);
246  sliceSubsampleSizes[sliceDimension] = 1;
247 
249  const size_t components = milxQtImage::imageVector->GetNumberOfComponentsPerPixel();
250  vectorImageType::Pointer imgSubSampled = milx::Image<vectorImageType>::SubsampleImage(sliceVector, sliceSubsampleSizes);
251  cout << "Slice Information: " << endl;
253 
255  printDebug("Setting up seed points for glyphs using the current slice");
256  vtkSmartPointer<vtkPoints> slicePoints = vtkSmartPointer<vtkPoints>::New();
257  typedef itk::Point<double, 3> InputImagePointType;
258  itk::ImageRegionConstIteratorWithIndex<vectorImageType> imageIterator(imgSubSampled, imgSubSampled->GetLargestPossibleRegion());
259 
261  std::vector<vectorImageType::IndexType> indices;
262 
264  InputImagePointType point;
265  vectorImageType::PixelType maxVector(components);
266  maxVector.Fill(0.0);
267  while(!imageIterator.IsAtEnd())
268  {
269  double position[3];
270 
271  imgSubSampled->TransformIndexToPhysicalPoint(imageIterator.GetIndex(), point);
272 
273  position[0] = point[0];
274  position[1] = point[1];
275  position[2] = point[2];
276 
277  slicePoints->InsertNextPoint(position);
278  indices.push_back(imageIterator.GetIndex());
279 
280  vectorImageType::PixelType pixelVector = imageIterator.Get();
281  for(size_t j = 0; j < pixelVector.GetSize(); j ++)
282  {
283  if(maxVector[j] < pixelVector[j])
284  maxVector[j] = pixelVector[j];
285  }
286 
287  ++imageIterator;
288  }
289  cout << "Max Vector found: " << maxVector << endl;
290  cout << "ID Type Size: " << sizeof(vtkIdType) << endl;
291  cout << "Integer Type Size: " << sizeof(unsigned) << endl;
292 
293 // double magNormVector = maxVector.GetNorm();
294 // double magNormVector = maxVector[0];
295 // for(size_t j = 0; j < maxVector.GetSize(); j ++)
296 // maxVector[j] /= magNormVector;
297 // cout << "Max Vector normalised: " << maxVector << endl;
298 
299  vtkSmartPointer<vtkPolyData> slice = vtkSmartPointer<vtkPolyData>::New();
300  slice->SetPoints(slicePoints);
301 
303  vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
304  sphereSource->SetThetaResolution( resolution );
305  sphereSource->SetPhiResolution( resolution );
306  sphereSource->SetRadius( 1.0 );
307  sphereSource->Update();
308  vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
309  scalars->SetNumberOfComponents(3);
310  scalars->SetNumberOfTuples(sphereSource->GetOutput()->GetNumberOfPoints());
311  scalars->SetName("Dummy Colours");
312  scalars->FillComponent(0, 0);
313  scalars->FillComponent(1, 0);
314  scalars->FillComponent(2, 0);
315  sphereSource->GetOutput()->GetPointData()->SetScalars(scalars); //dummy allocation to get uchar array type into output of glyph filter.
316  vtkSmartPointer< vtkPolyDataNormals > normals = vtkSmartPointer< vtkPolyDataNormals >::New();
317  #if VTK_MAJOR_VERSION <= 5
318  normals->SetInput(sphereSource->GetOutput());
319  #else
320  normals->SetInputData(sphereSource->GetOutput());
321  #endif
322  normals->ComputePointNormalsOn();
323  normals->SplittingOff();
324  normals->ComputeCellNormalsOff();
325  normals->Update();
326 
327  vtkSmartPointer<vtkDiffusionTensorGlyphFilter> diffusionTensorGlyphs = vtkSmartPointer<vtkDiffusionTensorGlyphFilter>::New();
328  #if VTK_MAJOR_VERSION <= 5
329  diffusionTensorGlyphs->SetInput(slice);
330  diffusionTensorGlyphs->SetSource(normals->GetOutput());
331  #else
332  diffusionTensorGlyphs->SetInputData(slice);
333  diffusionTensorGlyphs->SetSourceData(normals->GetOutput());
334  #endif
335  diffusionTensorGlyphs->SetTensorImage(sliceVector);
336  diffusionTensorGlyphs->SetTensorImageIndices(indices);
337  diffusionTensorGlyphs->SetNormaliseVector(maxVector);
338  diffusionTensorGlyphs->SetResolution(resolution);
339  diffusionTensorGlyphs->SetGlyphMethod(CalcGlyph, diffusionTensorGlyphs);
340  linkProgressEventOf(diffusionTensorGlyphs);
341  printDebug("Creating Glyphs");
342  diffusionTensorGlyphs->SetColorModeToColorBySource();
343  diffusionTensorGlyphs->Update();
344 
345  QPointer<milxQtModel> model = new milxQtModel;
346  model->setName("Diffusion Glyphs");
347  model->SetInput(diffusionTensorGlyphs->GetOutput());
348  model->generateModel();
349  model->ImmediateModeRenderingOn(); //for large datasets
350 
351  emit done(-1);
352  emit resultAvailable(model);
353 }
354 
355 void milxQtDiffusionTensorImage::diffusionGlyphs2(size_t subsampleFactor, size_t resolution)
356 {
357  if(ITK_VERSION_MAJOR < 4)
358  {
359  printError("You are not using ITK 4 or above. Ignoring.");
360  return;
361  }
362 
363  printDebug("Computing Diffusion Glyphs via Brute Force");
364 
365  bool ok1 = false, ok2 = false;
366  if(subsampleFactor == 0)
367  {
368  subsampleFactor = QInputDialog::getInt(this, tr("Please Provide the sub-sample factor of the data"),
369  tr("Sub-sample Factor:"), 1, 1, 1000, 1, &ok1);
370  resolution = QInputDialog::getInt(this, tr("Please Provide the resolution of the glyphs"),
371  tr("Resolution:"), 16, 4, 256, 1, &ok2);
372  if(!ok1 || !ok2)
373  return;
374  }
375 
376  int extent[6];
377  milxQtImage::viewer->GetImageActor()->GetDisplayExtent(extent);
378 
379  if(flipped)
380  {
381  int actualExtent[6];
382  milxQtImage::imageData->GetExtent(actualExtent);
383 
384  if(extent[3]-extent[2] == 0) //flip y extent
385  {
386  extent[2] = actualExtent[3]-extent[2];
387  extent[3] = actualExtent[3]-extent[3];
388  }
389  }
390 
391  emit working(-1);
393  vectorImageType::Pointer sliceVector = milx::Image<vectorImageType>::ExtractSlice<vectorImageType>(milxQtImage::imageVector, extent);
394 
395  //Which dimension is sliced?
396  vectorImageType::SizeType imageSize = sliceVector->GetLargestPossibleRegion().GetSize();
397  size_t sliceDimension = 0;
398  for(size_t j = 0; j < vectorImageType::ImageDimension; j ++)
399  {
400  if(imageSize[j] == 1)
401  sliceDimension = j;
402  }
403 
405  vectorImageType::SizeType sliceSubsampleSizes;
406  sliceSubsampleSizes.Fill(subsampleFactor);
407  sliceSubsampleSizes[sliceDimension] = 1;
408 
410  const size_t components = milxQtImage::imageVector->GetNumberOfComponentsPerPixel();
411  vectorImageType::Pointer imgSubSampled = milx::Image<vectorImageType>::SubsampleImage(sliceVector, sliceSubsampleSizes);
412  cout << "Slice Information: " << endl;
414  typedef float projectionType;
415 
417  printDebug("Setting up seed points for glyphs using the current slice");
418  typedef itk::Point<double, 3> InputImagePointType;
419  itk::ImageRegionConstIteratorWithIndex<vectorImageType> imageIterator(imgSubSampled, imgSubSampled->GetLargestPossibleRegion());
420 
421  vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
422  sphereSource->SetThetaResolution( resolution );
423  sphereSource->SetPhiResolution( resolution );
424  sphereSource->SetRadius( 1.0 );
425  sphereSource->Update();
426  sphereSource->GetOutput()->GetPointData()->RemoveArray("Normals");
427 
429  vtkSmartPointer<vtkAppendPolyData> appendedPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
430  InputImagePointType point;
431  const double radiusScaling = 2.5;
432 // vectorImageType::PixelType maxVector(components);
433 // maxVector.Fill(0.0);
434  while(!imageIterator.IsAtEnd())
435  {
436  imgSubSampled->TransformIndexToPhysicalPoint(imageIterator.GetIndex(), point);
437 
438  const vectorImageType::PixelType harmonicsVector = imageIterator.Get();
439 
440 // vectorImageType::PixelType pixelVector = imageIterator.Get();
441 // for(size_t j = 0; j < pixelVector.GetSize(); j ++)
442 // {
443 // if(maxVector[j] < pixelVector[j])
444 // maxVector[j] = pixelVector[j];
445 // }
446 
447  vtkSmartPointer<vtkPolyData> glyph = vtkSmartPointer<vtkPolyData>::New();
448  glyph->DeepCopy(sphereSource->GetOutput());
449 
450  vtkSmartPointer<vtkFloatArray> projections = vtkSmartPointer<vtkFloatArray>::New();
451  projections->SetNumberOfComponents(3);
452  projections->SetNumberOfTuples(glyph->GetNumberOfPoints());
453  projections->SetName("Fibre Projections");
454  projections->FillComponent(0, 0.0);
455  projections->FillComponent(1, 0.0);
456  projections->FillComponent(2, 0.0);
457 
459  double m_x = point[0], m_y = point[1], m_z = point[2];
460  for(vtkIdType i = 0; i < glyph->GetNumberOfPoints(); i ++)
461  {
462  double point_sphere[3];
463  glyph->GetPoint(i, point_sphere);
464  const double x_s = point_sphere[0];
465  const double y_s = point_sphere[1];
466  const double z_s = point_sphere[2];
467 
469  std::vector<double> sHarmonicCoefficients;
470  for(size_t j = 0; j < harmonicsVector.GetSize(); j ++)
471  sHarmonicCoefficients.push_back(harmonicsVector[j]);
472 
474  const int n_coefs = sHarmonicCoefficients.size();
475  const int l_max = vtkDiffusionTensorGlyphFilter::LforN( n_coefs );
476  double amplitude = vtkDiffusionTensorGlyphFilter::computeAmplitude( sHarmonicCoefficients, x_s, y_s, z_s, l_max );
477  // cout << "Amplitude: " << amplitude << ", ";
478 
479  if(amplitude < 0)
480  amplitude = 0;
481 
483  double x_g = x_s * amplitude * radiusScaling;
484  double y_g = y_s * amplitude * radiusScaling;
485  double z_g = z_s * amplitude * radiusScaling;
486 
487  glyph->GetPoints()->SetPoint(i, x_g, y_g, z_g);
488 
490  for(size_t j = 0; j < 3; j ++)
491  {
492  projectionType axis[3] = {0.0, 0.0, 0.0};
493  const projectionType position[3] = {glyph->GetPoint(i)[0], glyph->GetPoint(i)[1], glyph->GetPoint(i)[2]};
494  projectionType currentProjection[3] = {projections->GetTuple3(i)[0], projections->GetTuple3(i)[1], projections->GetTuple3(i)[2]}; //coordinate is vnl_vector_fixed
495 
496  axis[j] = 1.0;
497  const projectionType projection = vtkMath::Dot(axis, position); //project to axis being done,
498  currentProjection[j] = projection; //projection in each direction
499 
500  projections->SetTuple3(i, currentProjection[0], currentProjection[1], currentProjection[2]);
501  }
502 
504  x_g += m_x;
505  y_g += m_y;
506  z_g += m_z;
507  glyph->GetPoints()->SetPoint(i, x_g, y_g, z_g);
508 
509  qApp->processEvents(); //keep UI responsive
510  }
511 
513  vtkSmartPointer<vtkUnsignedCharArray> scalars = vtkSmartPointer<vtkUnsignedCharArray>::New();
514  scalars->SetNumberOfComponents(3);
515  scalars->SetNumberOfTuples(glyph->GetNumberOfPoints());
516  scalars->SetName("Colours");
517  scalars->FillComponent(0, 0);
518  scalars->FillComponent(1, 0);
519  scalars->FillComponent(2, 0);
520 
521  for(vtkIdType i = 0; i < glyph->GetNumberOfPoints(); i ++)
522  {
523  coordinate currentProjection(projections->GetTuple3(i));
524  coordinate currentProjSquared = element_product(currentProjection, currentProjection);
525  projectionType maxProjection = currentProjSquared.max_value();
526  currentProjSquared /= maxProjection;
527 
528  unsigned char colourOfPoint[3] = {0, 0, 0};
529  colourOfPoint[0] = static_cast<unsigned char>( currentProjSquared[0]*255.0 );
530  colourOfPoint[1] = static_cast<unsigned char>( currentProjSquared[1]*255.0 );
531  colourOfPoint[2] = static_cast<unsigned char>( currentProjSquared[2]*255.0 );
532 
533  scalars->SetTupleValue(i, colourOfPoint);
534 
535  qApp->processEvents(); //keep UI responsive
536  }
537  // cout << endl;
538  glyph->GetPointData()->SetScalars(scalars);
539 
540  #if VTK_MAJOR_VERSION <= 5
541  appendedPolyData->AddInput(glyph); //append to model
542  #else
543  appendedPolyData->AddInputData(glyph); //append to model
544  #endif
545 
546  ++imageIterator;
547  }
548  cout << "Updating Polydata" << endl;
549  appendedPolyData->Update();
550 
551  QPointer<milxQtModel> model = new milxQtModel;
552  model->SetInput(appendedPolyData->GetOutput());
553  model->setName("Diffusion Glyphs");
554  model->generateModel();
555  model->ImmediateModeRenderingOn(); //for large datasets
556 
557  emit done(-1);
558  emit resultAvailable(model);
559 }
560 
561 void milxQtDiffusionTensorImage::createActions()
562 {
563  diffusionAct = new QAction(this);
564  diffusionAct->setText(QApplication::translate("Model", "Diffusion Glyphs for Slice", 0, QApplication::UnicodeUTF8));
565  diffusionAct->setShortcut(tr("Shift+Alt+d"));
566  diffusion2Act = new QAction(this);
567  diffusion2Act->setText(QApplication::translate("Model", "Diffusion Glyphs for Slice Brute Force", 0, QApplication::UnicodeUTF8));
568  diffusion2Act->setShortcut(tr("Ctrl+Shift+d"));
569 }
570 
571 void milxQtDiffusionTensorImage::createConnections()
572 {
573  //Operations
574  connect(diffusionAct, SIGNAL(triggered()), this, SLOT(diffusionGlyphs()));
575  connect(diffusion2Act, SIGNAL(triggered()), this, SLOT(diffusionGlyphs2()));
576 
577  //milxQtImage::createConnections();
578 }
579 
580 void milxQtDiffusionTensorImage::contextMenuEvent(QContextMenuEvent *currentEvent)
581 {
582  contextMenu = milxQtImage::basicContextMenu();
583 
584  contextMenu->addSeparator()->setText(tr("Diffusion Tensor"));
585  contextMenu->addAction(diffusionAct);
586  contextMenu->addAction(diffusion2Act);
587  contextMenu->addSeparator()->setText(tr("Extensions"));
588  foreach(QAction *currAct, extActionsToAdd)
589  {
590  contextMenu->addAction(currAct);
591  }
592  contextMenu->addSeparator();
594  contextMenu->addMenu(milxQtRenderWindow::contourMenu);
595  contextMenu->addMenu(milxQtRenderWindow::windowPropertiesMenu);
596  contextMenu->addAction(milxQtRenderWindow::refreshAct);
597  contextMenu->addAction(milxQtRenderWindow::resetAct);
598 
599  contextMenu->exec(currentEvent->globalPos());
600 }
vtkSmartPointer< vtkImageData > imageData
Points to the current VTK Image Data, Smart Pointer.
Definition: milxQtImage.h:1410
QMenu * basicContextMenu()
Return the basic context menu with the milxQtImage class ordering. This is for the benefit of derived...
void setName(const QString filename)
Set the name of the data.
vtkSmartPointer< vtkImageViewer3 > viewer
VTK Viewer handler, Smart Pointer.
Definition: milxQtImage.h:1409
This class represents the MILX Qt Image Display object using VTK.
Definition: milxQtImage.h:118
void done(int value)
Send signal that computation is done. Value carries the progress,.
void SetInput(vtkSmartPointer< vtkPolyData > mesh)
Assigns the mesh provided to the class, preparing for display. Call generateModel() and then show() t...
void resultAvailable(milxQtRenderWindow *)
Send signal that Resultant render window is available for showing.
QString prefix
Prefix of the data.
Definition: milxQtWindow.h:242
This class represents the MILX Qt Model/Mesh Display object using VTK.
Definition: milxQtModel.h:115
void working(int value)
Send signal that computation is in progress. Value carries the progress,.
QAction * refreshAct
Action for refreshing the display.
Represents an image (i.e. an regular rectangular array with scalar values) and their common operation...
Definition: milxImage.h:174
QMenu * contourMenu
Contour Menu.
QAction * resetAct
Action for refreshing the display.
void diffusionGlyphs(size_t subsampleFactor=0, size_t resolution=16)
static void Information(itk::SmartPointer< TImage > img)
Prints the information of the image to standard output.
Definition: milxImage.h:2067
vectorImageType::Pointer imageVector
Up to date vector image data.
Definition: milxQtImage.h:1403
QMenu * windowPropertiesMenu
Context Menu.
static itk::SmartPointer< TImage > SubsampleImage(itk::SmartPointer< TImage > img, typename TImage::SizeType factors)
Subsamples or shrinks the current image using the factors provided.
Definition: milxImage.h:1459
void diffusionGlyphs2(size_t subsampleFactor=0, size_t resolution=16)