X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkgdcmSerieViewer.cxx;h=f081e02bf76433b72dd9fa739cc383a5dcd59d67;hb=fb1db702e2e94adb9c04387604dbe635726db898;hp=322dae31c87759eea291204fbc38464c762d4855;hpb=cb3a8e38ad6e95fad9c79b889bbe6ce972709b47;p=gdcm.git diff --git a/vtk/vtkgdcmSerieViewer.cxx b/vtk/vtkgdcmSerieViewer.cxx index 322dae31..f081e02b 100644 --- a/vtk/vtkgdcmSerieViewer.cxx +++ b/vtk/vtkgdcmSerieViewer.cxx @@ -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 @@ -15,16 +15,17 @@ 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). // @@ -42,13 +43,21 @@ #include "gdcmDocument.h" // for NO_SHADOWSEQ #include "gdcmSerieHelper.h" #include "gdcmDebug.h" +#include "gdcmDataEntry.h" + #include "gdcmArgMgr.h" // for Argument Manager functions +#include // 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;jGetZSize() != 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; riGetDataEntry( 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(); +}