SMILX  1.01
milxQtDICOMPlugin.h
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 #ifndef MILXQTDICOMPLUGIN_H
19 #define MILXQTDICOMPLUGIN_H
20 
21 #include <QThread>
22 #include <QMenu>
23 #include <QDockWidget>
24 //ITK
25 #include <itkImageSeriesReader.h>
26 #include <itkGDCMImageIO.h>
27 #include <itkGDCMSeriesFileNames.h>
28 #include <itkPolygonSpatialObject.h>
29 #include <itkGroupSpatialObject.h>
30 #include <itkSpatialObjectToImageFilter.h>
31 #if (ITK_VERSION_MAJOR > 3) //Review only members
32  #include <gdcmTypes.h>
33  #include <gdcmAttribute.h>
34  #include <gdcmReader.h>
35 #endif // (ITK_VERSION_MAJOR > 3)
36 //VTK
37 #include <vtkPolyDataCollection.h>
38 //milxSMILI
39 #include "milxFile.h"
40 //milxQt
41 #include "milxQtAliases.h"
42 #include "milxQtPluginInterface.h"
43 #include "milxQtImage.h"
44 #include "milxQtMain.h"
45 #include "milxQtManager.h"
46 
55 {
56  Q_OBJECT
57 
58 public:
59  typedef itk::GDCMImageIO ImageIOType;
60  typedef itk::MetaDataDictionary DictionaryType;
61  typedef itk::MetaDataObject< std::string > MetaDataStringType;
62 
67  milxQtDICOMPlugin(QObject *theParent = 0);
68  virtual ~milxQtDICOMPlugin();
69 
74  virtual QString name();
75 
80  inline virtual bool hasOpenSupport()
81  { return false; }
86  virtual QString openFileSupport();
91  virtual QStringList openExtensions();
96  inline virtual bool hasSaveSupport()
97  { return false; }
102  virtual QString saveFileSupport();
107  virtual QStringList saveExtensions();
108 
113  inline virtual bool hasCollectionSupport()
114  { return false; }
119  virtual void SetInputCollection(vtkPolyDataCollection* collection, QStringList &filenames);
120 
125  virtual void open(QString filename);
130  virtual void save(QString filename);
131 
141  virtual milxQtModel* modelResult();
146  virtual milxQtImage* imageResult();
151  virtual QDockWidget* dockWidget();
152 
157  inline virtual Qt::DockWidgetArea dockDefaultArea()
158  { return Qt::LeftDockWidgetArea; }
159 
164  virtual bool isPluginWindow(QWidget *window);
165 
166 #if (ITK_VERSION_MAJOR > 3) //Review only members
167 
175  template<class TImage>
176  static bool ExportDICOM_RT(const std::string directoryPath, const std::string rsFileName, const std::string outPath, typename itk::SmartPointer<TImage> &data, std::string &seriesName, const bool reorient = true);
177 #endif // (ITK_VERSION_MAJOR > 3)
178 
179 public slots:
184  virtual void loadExtension();
192  virtual void update() {}
197  virtual void preStartTasks() {}
202  virtual void postStartTasks() {}
203 
208  void viewTags();
213  void openSeries();
218  void openStructureSet();
219 
227  void convert();
228  void anonymize();
229 
230  void showRSFileDialog();
231  void showInputFileDialog();
232  void showRTInputFileDialog();
233  void showOutputFileDialog();
234  void showRTOutputFileDialog();
235  void showInputFileDialogAnonymize();
236  void showOutputFileDialogAnonymize();
237 
242  void affectValues();
243 
255  bool anonymizeDicomImage(const std::string &input, const QString &subject_output_folder, const QString &rel_dir, unsigned int index_subject, unsigned int index_dicom, bool &isFirst);
256 
266  void makeFilename(const QString &path, ImageIOType::Pointer gdcmImageIO, unsigned int index, std::string &filename, unsigned int index_subject);
267 
274  void removeForbiddenChar(std::string &str, char* charsToRemove);
275 
276  void writeLog(QString &filename, std::string &output);
277 
285  void getTagValue(ImageIOType::Pointer gdcmImageIO, const std::string &tag, std::string & tag_value);
286 
287 protected:
288  QPointer<milxQtMain> MainWindow;
289 
290  QMenu* menuDICOM;
291  //----SSM---- (hierarchical deletion)
292  QAction* actionOpenSeries;
293  QAction* actionTags;
295  QAction* actionConvert;
296  QAction* actionAnonymize;
297 
298  //FAI variables for wizard
299  QWizard wizard;
300  QWizard wizardRT;
301  QWizard wizardAnonymize;
302  QString inputDirectoryname;
303  QLineEdit *txtInputName;
304  QString outputDirectoryname;
305  QLineEdit *txtOutputName;
306  QString inputRTDirectoryname;
307  QLineEdit *txtRTInputName;
308  QString outputRTDirectoryname;
309  QLineEdit *txtRTOutputName;
310  QString rsFilename;
311  QLineEdit *txtRSName;
312  QString inputAnonymizeDirectoryname;
313  QLineEdit *txtInputAnonymizeName;
314  QString outputAnonymizeDirectoryname;
315  QLineEdit *txtOutputAnonymizeName;
316 
317  QString outputPrefix;
318  QLineEdit *txtOutputPrefix;
319 
320  int outputInitID;
321  QLineEdit *txtOutputInitID;
322 
323  QCheckBox *checkboxPreserveFolderArc;
324  QCheckBox *checkboxPatientName;
325  QCheckBox *checkboxPatientID;
326  QCheckBox *checkboxSeriesDate;
327  QCheckBox *checkboxSeriesTime;
328  QCheckBox *checkboxStudyID;
329  QCheckBox *checkboxStudyDesc;
330  QCheckBox *checkboxSeriesNumber;
331  QCheckBox *checkboxSequenceName;
332  QCheckBox *checkboxProtocolName;
333  QCheckBox *checkboxSeriesDescription;
334 
335  QCheckBox *anonPatientInfo;
336  QCheckBox *anonPhysician;
337  QCheckBox *anonOperator;
338  QCheckBox *anonScanDate;
339 
340  //data
341  milxQtImage *image; //main window owner
342  QPointer<milxQtManager> manager;
343  QPointer<QDockWidget> dock;
344  bool valid;
345 
346  void createActions();
347  void createMenu();
348  void createWizard();
349  void createRTWizard();
350  void createConnections();
351  void createWizardAnonymise();
352 
353  //remove empty spaces from contour names
354  static inline void trim (std::string &str)
355  {
356  std::string temp;
357  for (unsigned int i = 0; i < str.length(); i++)
358  if (str[i] != ' ') temp += str[i];
359  str = temp;
360  }
361  //reset image of nD
362  template<class TImage>
363  static void resetImage(typename itk::SmartPointer<TImage> imageSlice);
364  //merge 2D in 3D image
365  template<class TImage, class TSliceType>
366  static void mergeImages(typename itk::SmartPointer<TSliceType> tempSlice, typename itk::SmartPointer<TImage> finalImage, int iRequiredSlice);
367 
368 private:
369 
370 };
371 
373 {
374  Q_OBJECT
375  Q_INTERFACES(milxQtPluginFactory)
376 
377 public:
378  milxQtPluginInterface* newPlugin(QObject *theParent = 0)
379  { return new milxQtDICOMPlugin(theParent); }
380 };
381 
382 #if (ITK_VERSION_MAJOR > 3) //Review only members
383 template<class TImage>
384 bool milxQtDICOMPlugin::ExportDICOM_RT(const std::string directoryPath, const std::string rsFileName, const std::string outPath, typename itk::SmartPointer<TImage> &data, std::string &seriesName, const bool reorient)
385 {
386  typedef itk::ImageSeriesReader<TImage> ReaderType;
387  typedef itk::GDCMImageIO ImageIOType;
388 
389  const std::vector<std::string> filenames = milx::File::GetDICOMSeriesFilenames(directoryPath, seriesName);
390 
391  ImageIOType::Pointer gdcmIO = ImageIOType::New();
392  typename ReaderType::Pointer reader = ReaderType::New();
393  reader->SetImageIO( gdcmIO );
394  reader->SetFileNames( filenames );
395  reader->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates);
396  try
397  {
398  reader->Update();
399  }
400  catch (itk::ExceptionObject &excp)
401  {
402  std::cerr << "File Exception caught while reading series!" << std::endl;
403  std::cerr << excp << std::endl;
404  return false;
405  }
406 
408  typedef itk::MetaDataObject< std::string > MetaDataStringType;
409  std::string series_type_id("0008|103e");
410  itk::MetaDataDictionary & dic = gdcmIO->GetMetaDataDictionary();
411  itk::MetaDataDictionary::ConstIterator series_type_itr = dic.Find(series_type_id);
412 
413  std::string caseId = "0010|0020";
414  itk::MetaDataDictionary::ConstIterator case_itr = dic.Find( caseId );
415 
416  std::string echoNumber = "0018|0086";
417  itk::MetaDataDictionary::ConstIterator echoNumber_itr = dic.Find( echoNumber );
418 
419  MetaDataStringType::ConstPointer entryValue= dynamic_cast<const MetaDataStringType *>(series_type_itr->second.GetPointer());
420  if(entryValue)
421  {
422  seriesName = entryValue->GetMetaDataObjectValue();
423  std::cout << "Series: " << entryValue->GetMetaDataObjectValue() << std::endl;
424  }
425  MetaDataStringType::ConstPointer entryValue2= dynamic_cast<const MetaDataStringType *>(case_itr->second.GetPointer());
426  if(entryValue2)
427  std::cout << "Case: " << entryValue2->GetMetaDataObjectValue() << std::endl;
428  MetaDataStringType::ConstPointer entryValue3;
429  if(dic.HasKey(echoNumber))
430  {
431  entryValue3 = dynamic_cast<const MetaDataStringType *>(echoNumber_itr->second.GetPointer());
432  std::cout << "Echo Number: " << entryValue3->GetMetaDataObjectValue() << std::endl;
433  }
434 
435  data = reader->GetOutput();
436  qApp->processEvents();
437 
438  //Begin J. Dowling Code
439  typedef itk::Image< typename TImage::PixelType, 2 > ImageSliceType;
440  typename ImageSliceType::Pointer temp2Dimage = ImageSliceType::New();
441 
442  gdcm::Reader RTreader;
443  RTreader.SetFileName( rsFileName.c_str() );
444  if( !RTreader.Read() )
445  {
446  std::cout << "Problem reading file: " << rsFileName << std::endl;
447  return 0;
448  }
449 
450  resetImage<TImage>(data);
451 
452  //we need to create a temporary 2D slice as well...
453  typename TImage::RegionType inputRegion = data->GetLargestPossibleRegion();
454  typedef itk::ExtractImageFilter< TImage, ImageSliceType> FilterType;
455  typename FilterType::Pointer filter = FilterType::New();
456  typename TImage::SizeType size = inputRegion.GetSize();
457  size[2] = 0;
458  typename TImage::IndexType start = inputRegion.GetIndex();
459  start[2] =0;
460  typename TImage::RegionType desiredRegion;
461  desiredRegion.SetSize( size );
462  desiredRegion.SetIndex( start );
463  filter->SetDirectionCollapseToIdentity(); //22.02.2013
464  filter->SetExtractionRegion( desiredRegion );
465  filter->SetInput( data );
466  filter->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates);
467  filter->Update();
468  temp2Dimage = filter->GetOutput();
469 
470 // const gdcm::FileMetaInformation &h = RTreader.GetFile().GetHeader();
471  const gdcm::DataSet& ds = RTreader.GetFile().GetDataSet();
472  std::cout << "Parsing: " << rsFileName << std::endl;
473 
474  gdcm::MediaStorage ms;
475  ms.SetFromFile( RTreader.GetFile() );
476  std::cout << "media storage: " << ms << std::endl;
477 
478  // (3006,0020) SQ (Sequence with explicit length #=4) # 370, 1 StructureSetROISequence
479  gdcm::Tag tssroisq(0x3006,0x0020);
480  if( !ds.FindDataElement( tssroisq ) )
481  {
482  std::cout << "Problem locating 0x3006,0x0020 - Is this a valid RT Struct file?" << std::endl;
483  return 0;
484  }
485  gdcm::Tag troicsq(0x3006,0x0039);
486  if( !ds.FindDataElement( troicsq ) )
487  {
488  std::cout << "Problem locating 0x3006,0x0039 - Is this a valid RT Struct file?" << std::endl;
489  return 0;
490  }
491 
492  const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq );
493 
494  gdcm::SmartPointer<gdcm::SequenceOfItems> sqi = roicsq.GetValueAsSQ();
495  if( !sqi || !sqi->GetNumberOfItems() )
496  {
497  return 0;
498  }
499  const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq );
500  gdcm::SmartPointer<gdcm::SequenceOfItems> ssqi = ssroisq.GetValueAsSQ();
501  if( !ssqi || !ssqi->GetNumberOfItems() )
502  {
503  return 0;
504  }
505 
506  std::cout << "Number of structures found:" << sqi->GetNumberOfItems() << std::endl;
507 
508  //loop through structures
509  for(unsigned int pd = 0; pd < sqi->GetNumberOfItems(); ++pd)
510  {
511  const gdcm::Item & item = sqi->GetItem(pd+1); // Item start at #1
512  gdcm::Attribute<0x3006,0x0084> roinumber;
513  const gdcm::DataSet& nestedds = item.GetNestedDataSet();
514  roinumber.SetFromDataElement( nestedds.GetDataElement( roinumber.GetTag() ) );
515 
516  qApp->processEvents();
517 
518  // find structure_set_roi_sequence corresponding to roi_contour_sequence (by comparing id numbers)
519  unsigned int spd = 0;
520  gdcm::Item & sitem = ssqi->GetItem(spd+1);
521  gdcm::DataSet& snestedds = sitem.GetNestedDataSet();
522 
523  gdcm::Attribute<0x3006,0x0022> sroinumber;
524 
525  do
526  {
527  sitem = ssqi->GetItem(spd+1);
528  snestedds = sitem.GetNestedDataSet();
529 
530  sroinumber.SetFromDataElement( snestedds.GetDataElement( sroinumber.GetTag() ) );
531 
532  spd++;
533 
534  } while ( sroinumber.GetValue() != roinumber.GetValue() );
535 
536  gdcm::Tag stcsq(0x3006,0x0026);
537  if( !snestedds.FindDataElement( stcsq ) )
538  {
539  std::cout<<"Did not find sttsq data el " << stcsq << " continuing..." << std::endl;
540  continue; //return 0;
541  }
542  const gdcm::DataElement &sde = snestedds.GetDataElement( stcsq );
543 
544  //(3006,002a) IS [255\192\96] # 10,3 ROI Display Color
545  gdcm::Tag troidc(0x3006,0x002a);
546  gdcm::Attribute<0x3006,0x002a> color = {};
547  if( nestedds.FindDataElement( troidc) )
548  {
549  const gdcm::DataElement &decolor = nestedds.GetDataElement( troidc );
550  color.SetFromDataElement( decolor );
551  }
552  //(3006,0040) SQ (Sequence with explicit length #=8) # 4326, 1 ContourSequence
553  gdcm::Tag tcsq(0x3006,0x0040);
554  if( !nestedds.FindDataElement( tcsq ) )
555  {
556  continue;
557  }
558  const gdcm::DataElement& csq = nestedds.GetDataElement( tcsq );
559 
560  gdcm::SmartPointer<gdcm::SequenceOfItems> sqi2 = csq.GetValueAsSQ();
561  if( !sqi2 || !sqi2->GetNumberOfItems() )
562  {
563  std::cout << "csq: " << csq << std::endl;
564  std::cout << "sqi2: " << *sqi2 << std::endl;
565  std::cout<<"Did not find sqi2 or no. items == 0 " << sqi2->GetNumberOfItems() << " continuing..." << std::endl;
566  continue;
567  }
568  unsigned int nitems = sqi2->GetNumberOfItems();
569  std::cout << "Structure " << pd << ". Number of regions: " << nitems << std::endl;
570  std::string str_currentOrgan(sde.GetByteValue()->GetPointer(), sde.GetByteValue()->GetLength());
571 
572  //trim to remove spaces in organ name which can cause problems in scripts eg. "CBCT01__BULK BONE .nii" . Might need to have this as parameter?
573  trim (str_currentOrgan);
574  std::cout << pd << ". Structure name: " << str_currentOrgan << std::endl;
575 
576  //now loop through each item for this structure (eg one prostate region on a single slice is an item)
577  typename TImage::PointType point;
578  typename TImage::IndexType pixelIndex;
579  typedef itk::PolygonSpatialObject<2> PolygonType;
580  typedef itk::SpatialObjectPoint<2> PolygonPointType;
581  PolygonType::PointListType pointList ;
582  PolygonPointType p;
583  PolygonType::Pointer polygon = PolygonType::New();;
584  typedef itk::GroupSpatialObject<2> GroupType;
585  typedef itk::SpatialObjectToImageFilter<GroupType, ImageSliceType> SpatialObjectToImageFilterType;
586  GroupType::Pointer group = GroupType::New();
587  typename SpatialObjectToImageFilterType::Pointer imageFilter =SpatialObjectToImageFilterType::New();
588  int iPointsOutsideBoundary = 0;
589  int iCurrentSlice = 0;
590  for(unsigned int i = 0; i < nitems; ++i)
591  {
592  const gdcm::Item & item2 = sqi2->GetItem(i+1); // Item start at #1
593 
594  const gdcm::DataSet& nestedds2 = item2.GetNestedDataSet();
595  // (3006,0050) DS [43.57636\65.52504\-10.0\46.043102\62.564945\-10.0\49.126537\60.714... # 398,48 ContourData
596  gdcm::Tag tcontourdata(0x3006,0x0050);
597  const gdcm::DataElement & contourdata = nestedds2.GetDataElement( tcontourdata );
598 
599  qApp->processEvents();
600 
601  //const gdcm::ByteValue *bv = contourdata.GetByteValue();
602  gdcm::Attribute<0x3006,0x0050> at;
603  at.SetFromDataElement( contourdata );
604  const double* pts = at.GetValues();
605  unsigned int npts = at.GetNumberOfValues() / 3;
606 
607  for(unsigned int j = 0; j < npts * 3; j+=3)
608  {
609  point[0] = pts[j+0];
610  point[1] = pts[j+1];
611  point[2] = pts[j+2];
612 
613  //transform points to image co-ordinates
614  if (!(data->TransformPhysicalPointToIndex( point, pixelIndex )))
615  {
616  //Are there points outside the image boundary. This may occur with automatically segmented objects such as benches or external body outlines?
617  iPointsOutsideBoundary++;
618  }
619 
620  p.SetPosition(pixelIndex[0] ,pixelIndex[1],pixelIndex[2]);
621 
622  p.SetRed(1);
623  p.SetBlue(1);
624  p.SetGreen(1);
625  pointList.push_back(p);
626  }
627 
628  // we have the points for a contour in a single slice. We need to join these up and insert into the slice as polygon.
629  iCurrentSlice = pixelIndex[2];
630 
631  //Insert Region
632  std::cout << "Inserting region with " << pointList.size() << " points into slice: " << iCurrentSlice << std::endl;
633  //reset 2D image
634  resetImage<ImageSliceType>(temp2Dimage);
635 
636  //need to create a 2D slice here, put the polygon on it, and insert it back into the 3D volume...
637  group->AddSpatialObject(polygon); //add a new polygon group
638 
639  try
640  {
641  polygon->SetPoints(pointList); //so copy them to a polygon object
642  imageFilter->SetInput(group);
643  imageFilter->SetSize(temp2Dimage->GetLargestPossibleRegion().GetSize());
644  imageFilter->AddObserver(itk::ProgressEvent(), milx::ProgressUpdates);
645  imageFilter->Update();
646  temp2Dimage=imageFilter->GetOutput();
647  }
648  catch( itk::ExceptionObject & err )
649  {
650  std::cerr << "Problem setting polygon->SetPoints for this region (non-planar)" << std::endl;
651  std::cerr << err << std::endl;
652  }
653 
654  //merge new polygon from temp image into the contour image
655  mergeImages<TImage>(temp2Dimage, data, iCurrentSlice);
656 
657  //remove the polygon and clean up pointlist
658  group->RemoveSpatialObject(polygon);
659  pointList.clear();
660  }
661 
662  if (iPointsOutsideBoundary > 0)
663  {
664  std::cout << " --" << iPointsOutsideBoundary << " contour points detected outside image boundary. Please check the output volume. " ;
665  iPointsOutsideBoundary=0;
666  }
667 
668  //filename
669  std::string strNewVolume = outPath + "/";
670  strNewVolume += str_currentOrgan;
671  strNewVolume += ".nii.gz";
672 
673  //write img
674  milx::File::WriteImageUsingITK<TImage>(strNewVolume, data);
675 
676  resetImage<TImage>(data); //reset the temporary volume ready for next structure (if any)
677  }
678  //End J. Dowling Code
679 
680  return true;
681 }
682 #endif // (ITK_VERSION_MAJOR > 3)
683 
684 template<class TImage>
685 void milxQtDICOMPlugin::resetImage(typename itk::SmartPointer<TImage> imageSlice)
686 {
687  itk::ImageRegionIterator<TImage> imageIt(imageSlice, imageSlice->GetLargestPossibleRegion()) ;
688  imageIt.GoToBegin();
689  while(!imageIt.IsAtEnd())
690  {
691  imageIt.Set(0);
692  ++imageIt;
693  }
694 }
695 
696 template<class TImage, class TSliceType>
697 void milxQtDICOMPlugin::mergeImages(typename itk::SmartPointer<TSliceType> tempSlice, typename itk::SmartPointer<TImage> finalImage, int iRequiredSlice )
698 {
699  typename TImage::PixelType pixelValue =0;
700  typename TImage::IndexType pixelIndex;
701  typename TSliceType::IndexType sliceIndex;
702  int iX = finalImage->GetLargestPossibleRegion().GetSize()[0];
703  int iY = finalImage->GetLargestPossibleRegion().GetSize()[1];
704 
705 
706  if (iRequiredSlice>0)
707  {
708  for (int i=0;i<iX;i++)
709  for (int j=0;j<iY;j++)
710  {
711  pixelIndex[0] = i;
712  pixelIndex[1] = j;
713  sliceIndex[0] =i;
714  sliceIndex[1] = j;
715 
716  pixelValue = tempSlice->GetPixel(sliceIndex);
717  pixelIndex[2] = iRequiredSlice;
718 
719  //Disable hole filling (if required please uncomment the next line (and comment the following line)).
720  //if (pixelValue != 0) finalImage->SetPixel(pixelIndex, pixelValue );
721  finalImage->SetPixel(pixelIndex, finalImage->GetPixel(pixelIndex) ^ (pixelValue != 0));
722  qApp->processEvents();
723  }
724  }
725 }
726 
727 #endif // MILXQTDICOMPLUGIN_H
728 
virtual void postStartTasks()
Tasks to complete after running or starting the thread. [Implement this].
QPointer< milxQtManager > manager
Manager widget.
virtual bool hasCollectionSupport()
Does the plugin support collections (PolyData collection etc.). [Implement this in your plugin]...
QAction * actionOpenSeries
open series action
QPointer< QDockWidget > dock
Dock widget.
virtual QDockWidget * dockWidget()=0
Return the dock widget (if one is provided by plugin). [Implement this in your plugin].
virtual QString saveFileSupport()=0
Get the file support string for saving (extension wildcard list). [Implement this in your plugin]...
virtual milxQtImage * imageResult()=0
Get the image result. The result can then be displayed in milxQtMain etc.[Implement this in your plug...
virtual void preStartTasks()
Tasks to complete before running or starting the thread. [Implement this].
The interface for the DICOM plugin for milxQt.
This file defines all the defines, aliases and frequently used functions and variables.
This class represents the MILX Qt Render Window Display object using QVTK.
virtual QStringList saveExtensions()=0
Get a list of supported file format extensions. [Implement this in your plugin].
static std::vector< std::string > GetDICOMSeriesFilenames(const std::string directoryPath, const std::string seriesName, bool recursive=false)
Returns the filenames for a given UID/Series name for a given directory.
Definition: milxFile.cxx:151
This class represents the MILX Qt Image Display object using VTK.
Definition: milxQtImage.h:118
virtual QStringList openExtensions()=0
Get a list of supported file format extensions. [Implement this in your plugin].
virtual void update()
Update the plugin. [Implement this in your plugin].
virtual void loadExtension()=0
Load the extension. [Implement this in your plugin].
QAction * actionTags
open series action
virtual QString name()=0
Get the Name of the plugin. [Implement this in your plugin].
This class represents the MILX Qt Model/Mesh Display object using VTK.
Definition: milxQtModel.h:115
virtual Qt::DockWidgetArea dockDefaultArea()
Return the default dock widget area (if one is provided by plugin). [Implement this in your plugin]...
virtual void SetInputCollection(vtkPolyDataCollection *collection, QStringList &filenames)=0
Pass a collection to internal plugin class. [Implement this in your plugin].
virtual bool hasOpenSupport()
Does the plugin support opening files? [Implement this in your plugin].
The interface for any plugins that can be made for milxQtMain.
QAction * actionAnonymize
Anonymize action.
virtual bool isPluginWindow(QWidget *window)=0
Is the window provided a plugin generated window? In this case a milxQtShapeModel window...
virtual milxQtModel * modelResult()=0
Get the model result. The result can then be displayed in milxQtMain etc. [Implement this in your plu...
QMenu * menuDICOM
DICOM menu.
virtual milxQtRenderWindow * genericResult()=0
Get the generic result, which is a milxQtRenderWindow. The result can then be displayed in milxQtMain...
virtual QString openFileSupport()=0
Get the file support string for opening (extension wildcard list). [Implement this in your plugin]...
virtual void open(QString filename)=0
Open the file using the plugin. [Implement this in your plugin].
#define MILXQT_PLUGIN_EXPORT
Define Windows Plugin DLL importing.
QAction * actionConvertStructure
convert RT action
QAction * actionConvert
convert action
virtual void save(QString filename)=0
Save the result as a file using the plugin. [Implement this in your plugin].
virtual bool hasSaveSupport()
Does the plugin support opening files? [Implement this in your plugin].