]> Creatis software - gdcm.git/blobdiff - vtk/vtkgdcmSerieViewer.cxx
Fix mistypings
[gdcm.git] / vtk / vtkgdcmSerieViewer.cxx
index 322dae31c87759eea291204fbc38464c762d4855..f081e02bf76433b72dd9fa739cc383a5dcd59d67 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: vtkgdcmSerieViewer.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/07/30 18:37:48 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2007/06/21 14:47:16 $
+  Version:   $Revision: 1.18 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
      PURPOSE.  See the above copyright notices for more information.
                                                                                 
 =========================================================================*/
-// This example illustrates how the vtkGdcmReader vtk class can be
-// used in order to:
-//  * produce a simple (vtk based) Dicom image STACK VIEWER.
-//  * dump the stack considered as a volume in a vtkStructuredPoints
-//    vtk file: the vtk gdcm wrappers can be seen as a simple way to convert
-//    a stack of Dicom images into a native vtk volume.
-//
+// This example illustrates how the vtkGdcmReader vtk class can 
+// use the result of GDCM_NAME_SPACE::SerieHelper constructor and check
+// the various Setters :
+//     SerieHelper::SetOrderToReverse, 
+//     SerieHelper::SetUserLessThanFunction
+//     SerieHelper::SetLoadMode
+//     vtkGdcmReader::SetUserFunction
+//     vtkGdcmReader::SetCoherentFileList
 // Usage:
 //  * the Directory name that contains the Dicom images constituting the stack 
-//    should be given as command line argument,
+//    should be given as command line argument (keyword : dirname=),
 //  * you can navigate through the stack by hitting any character key,
 //  * the produced vtk file is named "foo.vtk" (in the invocation directory).
 // 
 #include "gdcmDocument.h"  // for NO_SHADOWSEQ
 #include "gdcmSerieHelper.h"
 #include "gdcmDebug.h"
+#include "gdcmDataEntry.h"
+
 #include "gdcmArgMgr.h" // for Argument Manager functions
+#include <string.h>     // for strcmp
 #ifndef vtkFloatingPointType
 #define vtkFloatingPointType float
 #endif
 
-void userSuppliedMirrorFunction (uint8_t *im, gdcm::File *f);
-void userSuppliedTopDownFunction(uint8_t *im, gdcm::File *f);
+void userSuppliedMirrorFunction (uint8_t *im, GDCM_NAME_SPACE::File *f);
+void userSuppliedTopDownFunction(uint8_t *im, GDCM_NAME_SPACE::File *f);
+bool userSuppliedLessThanFunction(GDCM_NAME_SPACE::File *f1, GDCM_NAME_SPACE::File *f2);
+bool userSuppliedLessThanFunction2(GDCM_NAME_SPACE::File *f1, GDCM_NAME_SPACE::File *f2);
+
+int orderNb;
+uint16_t *elemsToOrderOn;
 
 //----------------------------------------------------------------------------
 // Callback for the interaction
@@ -91,23 +100,34 @@ int main(int argc, char *argv[])
 {
    START_USAGE(usage)
    " \n vtkgdcmSerieViewer : \n",
-   " Display a Serie within a Directory                                       ",
+   " Display a 'Serie' (same Serie UID) within a Directory                    ",
    " You can navigate through the stack by hitting any character key.         ",
-   " usage: vtkgdcmSerieViewer filein=fileName [noshadowseq][noshadow][noseq] ",
+   " usage: vtkgdcmSerieViewer dirname=sourcedirectory                        ",
+   "                           [noshadowseq][noshadow][noseq]                 ",
    "                           [reverse] [{[mirror]|[topdown]|[rotate]}]      ",
-   "                           [check][debug]                                 ",
+   "                           [order=] [check][debug]                        ",
+   "      sourcedirectory : name of the directory holding the images          ",
+   "                        if it holds more than one serie,                  ",
+   "                        only the first one id displayed.                  ",
    "      noshadowseq: user doesn't want to load Private Sequences            ",
    "      noshadow   : user doesn't want to load Private groups (odd number)  ",
    "      noseq      : user doesn't want to load Sequences                    ",
+   "      reverse    : user wants to sort the images reverse order            ",
    "      mirror     : user wants to 'mirror' the images | just some simple   ",
    "      topdown    : user wants to 'topdown' the images| examples of user   ",
-   "      rotate     : user wants NOT YET MADE           | supplied functions ",
+   "      rotate     : NOT YET MADE (useless?)           | supplied functions ",
+   "      check      : user wants to force more coherence checking            ",
+   "      order=     : group1-elem1,group2-elem2,... (in hexa, no space)      ",
+   "                   if we want to use them as a sort criterium             ",
+   "                   Right now : ValEntries only -just an example-          ",
+   "        or                                                                ",
+   "      order=     : order=name if we want to sort on file name (why not ?) ",
    "      debug      : user wants to run the program in 'debug mode'          ",
    FINISH_USAGE
 
 
    // Initialize Arguments Manager   
-   gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv);
+   GDCM_NAME_SPACE::ArgMgr *am= new GDCM_NAME_SPACE::ArgMgr(argc, argv);
   
    if (argc == 1 || am->ArgMgrDefined("usage") )
    {
@@ -118,35 +138,45 @@ int main(int argc, char *argv[])
 
    char *dirName = am->ArgMgrWantString("dirname",usage);
 
-   int loadMode = 0x00000000;
+   int loadMode = GDCM_NAME_SPACE::LD_ALL;
    if ( am->ArgMgrDefined("noshadowseq") )
-      loadMode |= NO_SHADOWSEQ;
+      loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ;
    else 
    {
       if ( am->ArgMgrDefined("noshadow") )
-         loadMode |= NO_SHADOW;
+         loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW;
       if ( am->ArgMgrDefined("noseq") )
-         loadMode |= NO_SEQ;
+         loadMode |= GDCM_NAME_SPACE::LD_NOSEQ;
    }
 
-   bool reverse = am->ArgMgrDefined("reverse");
-
-   bool mirror  = am->ArgMgrDefined("mirror");
-   bool topdown = am->ArgMgrDefined("topdown");
-   bool rotate  = am->ArgMgrDefined("rotate");
+   int reverse = am->ArgMgrDefined("reverse");
 
-  bool check   = am->ArgMgrDefined("check");
+   int mirror  = am->ArgMgrDefined("mirror");
+   int topdown = am->ArgMgrDefined("topdown");
+   int rotate  = am->ArgMgrDefined("rotate");
 
-   if ( (int)mirror + (int)topdown + (int)rotate > 1)
+   if ( mirror && topdown )
    {
-      std::cout << "mirror *OR* topDown *OR* rotate !"
+      std::cout << "mirror *OR* topDown !"
                 << std::endl;
       delete am;
       return 0;
    }
+   if ( rotate )
+   {
+      std::cout << "'rotate' undealt with -> ignored !"
+                << std::endl;
+   }
+
+   int check   = am->ArgMgrDefined("check");
+  
+   // This is so ugly, a cstring is NOT a char * (god damit!)
+   bool bname = ( strcmp(am->ArgMgrGetString("order", "not found"),"name")==0 );
+   if (bname)
+      elemsToOrderOn = am->ArgMgrGetXInt16Enum("order", &orderNb);
 
    if (am->ArgMgrDefined("debug"))
-      gdcm::Debug::DebugOn();
+      GDCM_NAME_SPACE::Debug::DebugOn();
 
    /* if unused Param we give up */
    if ( am->ArgMgrPrintUnusedLabels() )
@@ -160,9 +190,7 @@ int main(int argc, char *argv[])
 
    // ----------------------- End Arguments Manager ----------------------
   
-   // ------------ to check Coherent File List as a parameter
-
-   gdcm::SerieHelper *sh = new gdcm::SerieHelper();
+   GDCM_NAME_SPACE::SerieHelper *sh = GDCM_NAME_SPACE::SerieHelper::New();
    sh->SetLoadMode(loadMode);
    if (reverse)
       sh->SetSortOrderToReverse();
@@ -171,13 +199,19 @@ int main(int argc, char *argv[])
    // Just to see
 
    int nbFiles;
-   // For all the Coherent Files lists of the gdcm::Serie
-   gdcm::FileList *l = sh->GetFirstCoherentFileList();
+   // For all the 'Single Serie UID' FileSets of the GDCM_NAME_SPACE::Serie
+   GDCM_NAME_SPACE::FileList *l = sh->GetFirstSingleSerieUIDFileSet();
    if (l == 0 )
    {
-      std::cout << "Oops! No CoherentFileList found ?!?" << std::endl;
+      std::cout << "Oops! No 'Single Serie UID' FileSet found ?!?" << std::endl;
       return 0;
    }
+
+   if (bname)
+     sh->SetUserLessThanFunction(userSuppliedLessThanFunction2);
+   else if (orderNb != 0)
+      sh->SetUserLessThanFunction(userSuppliedLessThanFunction);
+
    while (l)
    { 
       nbFiles = l->size() ;
@@ -189,9 +223,10 @@ int main(int argc, char *argv[])
       }
       else
       {
-         std::cout << "Oops! Empty CoherentFileList found ?!?" << std::endl;
+         std::cout << "Oops! Empty 'Single Serie UID' FileSet found ?!?"
+                   << std::endl;
       }
-      l = sh->GetNextCoherentFileList();
+      l = sh->GetNextSingleSerieUIDFileSet();
    }
 
    if (check)
@@ -199,7 +234,7 @@ int main(int argc, char *argv[])
       if ( !sh->IsCoherent(l) ) // just be sure (?)
       {
          std::cout << "Files are not coherent. Stop everything " << std::endl;
-         delete sh;
+         sh->Delete();
          return 0;
       }
    }
@@ -303,6 +338,7 @@ int main(int argc, char *argv[])
    }                                    \
    if (nx%2 != 0)                       \
    {                                    \
+      i = nx / 2;                       \
       for (j=0;j<ny;j++)                \
       {                                 \
         imj = (ty *)im  +j*nx;          \
@@ -312,7 +348,7 @@ int main(int argc, char *argv[])
       }                                 \
    }
 
-void userSuppliedMirrorFunction(uint8_t *im, gdcm::File *f)
+void userSuppliedMirrorFunction(uint8_t *im, GDCM_NAME_SPACE::File *f)
 {
    if (f->GetZSize() != 1)
    {
@@ -367,7 +403,7 @@ void userSuppliedMirrorFunction(uint8_t *im, gdcm::File *f)
       }                                 \
    }
 
-void userSuppliedTopDownFunction(uint8_t *im, gdcm::File *f)
+void userSuppliedTopDownFunction(uint8_t *im, GDCM_NAME_SPACE::File *f)
 {
    if (f->GetZSize() != 1)
    {
@@ -399,6 +435,68 @@ void userSuppliedTopDownFunction(uint8_t *im, gdcm::File *f)
    return;
 }
 
+// --------------------------------------------------------
+// This is just a *very* simple example of user supplied 'LessThan' function
+// It's *not* part of gdcm.
+//
+// Note : orderNb and elemsToOrderOn are here global variables.
+// Within a 'normal' function they would't be any orderNb and elemsToOrderOn var
+// User *knows* on what field(s) he wants to compare; 
+// He just writes a decent function.
+// Here, we want to get info from the command line Argument Manager.
+//
+// Warning : it's up to 'vtkgdcmSerieViewer' user to find a suitable data set !
+// --------------------------------------------------------
 
 
+bool userSuppliedLessThanFunction(GDCM_NAME_SPACE::File *f1, GDCM_NAME_SPACE::File *f2)
+{
+   // for *this* user supplied function, I supposed only ValEntries are checked.
+// 
+   std::string s1, s2;
+   GDCM_NAME_SPACE::DataEntry *e1,*e2;
+   for (int ri=0; ri<orderNb; ri++)
+   {
+      std::cout << std::hex << elemsToOrderOn[2*ri] << "|" 
+                            << elemsToOrderOn[2*ri+1]
+                            << std::endl;
+      e1= f1->GetDataEntry( elemsToOrderOn[2*ri],
+                 elemsToOrderOn[2*ri+1]);
+
+      e2= f2->GetDataEntry( elemsToOrderOn[2*ri],
+                                 elemsToOrderOn[2*ri+1]);
+      if(!e2 || !e2)
+      {
+         std::cout << std::hex << elemsToOrderOn[2*ri] << "|"
+                              << elemsToOrderOn[2*ri+1]
+                              << " not found" << std::endl;
+         continue;
+      }
+      s1 = e1->GetString();      
+      s2 = e2->GetString();
+      std::cout << "[" << s1 << "] vs [" << s2 << "]" << std::endl;
+      if ( s1 < s2 ) 
+         return true;
+      else if (s1 == s2 )
+         continue;
+      else 
+         return false;
+   }
+   return false; // all fields equal
+}
 
+// --------------------------------------------------------
+// This is just an other *very* simple example of user supplied 'LessThan'
+// function
+// It's *not* part of gdcm.
+//
+// Warning : it's up to 'vtkgdcmSerieViewer' user to find a suitable data set !
+// --------------------------------------------------------
+
+bool userSuppliedLessThanFunction2(GDCM_NAME_SPACE::File *f1, GDCM_NAME_SPACE::File *f2)
+{
+   std::cout << "[" << f1->GetFileName() << "] vs [" 
+                    << f2->GetFileName() << "]" << std::endl;
+   return f1->GetFileName() < f2->GetFileName();
+}