]> Creatis software - creaImageIO.git/commitdiff
Viewer with movie done.
authorcaballero <caballero>
Fri, 6 Mar 2009 14:18:59 +0000 (14:18 +0000)
committercaballero <caballero>
Fri, 6 Mar 2009 14:18:59 +0000 (14:18 +0000)
src2/CMakeLists.txt
src2/creaImageIOGimmickView.cpp
src2/creaImageIOGimmickView.h
src2/creaImageIOTreeView.h
src2/creaImageIOWxGimmickView.cpp
src2/creaImageIOWxGimmickView.h
src2/creaImageIOWxTreeView.cpp
src2/creaImageIOWxTreeView.h
src2/creaImageIOWxViewer.cpp [new file with mode: 0644]
src2/creaImageIOWxViewer.h [new file with mode: 0644]

index e8e9aaea75530e418679d078bca0649af69f06f3..1ce13d9f87580a3818bfd2bd7eb48a37b4b79716 100644 (file)
@@ -48,6 +48,9 @@ SET( SRCS
   BlockScopeWxApp
   creaImageIOGimmickReaderDialog
 
+  #  Viewer
+  creaImageIOWxViewer
+
 
 )
 
index 49297e9be755c074c127bafa89adf24931ddb479..6084c7d7ff3d097ba932bbdbc78803fdbc6860fb 100644 (file)
@@ -13,6 +13,7 @@ namespace creaImageIO
                        <<std::endl);
        // Start the threads ...
     mReader.Start();
+
   }
   //======================================================================
 
@@ -111,7 +112,7 @@ namespace creaImageIO
                }
 
                //Dimention validation
-               //Compatibility with maximum 
+               //Compatibility with maximum and minimum
                        if(valid)
                        {       
                                
@@ -263,6 +264,28 @@ namespace creaImageIO
       }
        
   }
+
+
+  //======================================================================
+
+  //======================================================================
+  void GimmickView::
+  OnMultiThreadImageReaderEvent(const std::string& filename,
+                               MultiThreadImageReaderUser::EventType e,
+                               vtkImageData* image)
+  {
+    if (filename.size()==0)
+      {
+       mImageEventQueue.push_back(ImageEventType(image));
+       return;
+      }
+         std::map<std::string,tree::Node*>::iterator i;
+    i = mImageFileNameToNode.find(filename);
+    if (i!=mImageFileNameToNode.end())
+      {
+               mImageEventQueue.push_back(ImageEventType(i->second,image));
+      }
+  }
          
   
 } // EO namespace creaImageIO
index 62dc2d12ee8df2328fecbf6aa964a306c01dc0b9..9aa507231597bc5a8460ac71274ab939e23e1291 100644 (file)
@@ -35,8 +35,6 @@ namespace creaImageIO
       GimmickView(Gimmick*, int number_of_threads = 0 );
       /// Virtual destructor
       virtual ~GimmickView();
-
-
       /// Initializes the view : 
       /// Creates the TreeViews for all the TreeHandler of the Controller
       /// 
@@ -55,6 +53,9 @@ namespace creaImageIO
       /// Finalize 
       virtual void Finalize();
 
+         //Returns the maximal priority
+         int GetMaximalPriority(){return mReader.GetMaximalPriority();}
+
          ///Returns the selected Images and validates to see if they comply with the given parameter(<4D)
          vtkImageData* GetSelectedImage(int dim);
       ///Adds the selected Images to the given vector and validates to see if they comply with the given parameter (4D)
@@ -69,6 +70,21 @@ namespace creaImageIO
 
          ///Reads the vector of nodes, builds images in the dimension required and returns them in the supplied vector.
          void ReadImagesNotThreaded(std::vector<vtkImageData*>& s,std::vector<tree::Node*> im, int dim);
+         ///Requests the reading of an image
+         void RequestReading(tree::Node* n, int prio){mReader.Request(this,n->GetAttribute("FullFileName"),prio);}
+         ///Adds an entry to the filename to node map
+         void AddEntryToMap(tree::Node* node){mImageFileNameToNode[node->GetAttribute("FullFileName")] = node;}
+         ///Returns true if the ImageEventQueue is empty
+         bool IsQueueEmpty(){return mImageEventQueue.empty();}
+         ///Clears the queue
+         void ClearQueue(){mImageEventQueue.clear();}
+         ///Returns the next in line EventType's image
+         vtkImageData* GetNextImageQueued(){return mImageEventQueue.front().image;}
+         ///Returns the next in line EventType's node
+         tree::Node* GetNextNodeQueued(){return mImageEventQueue.front().node;}
+         ///Unqueus the next in line EventType
+         void UnqueueNext(){mImageEventQueue.pop_front();}
+  
 
          ///Obtains the message of the state
          std::string GetMessage(){return mMess;}
@@ -85,6 +101,10 @@ namespace creaImageIO
       /// Updates the TreeView of given name from level l to bottom
       /// (calls the virtual method TreeView::UpdateLevel(l))
       virtual void UpdateTreeViewLevel(const std::string&, int l);
+         // Multi-thread image reader callback
+         void OnMultiThreadImageReaderEvent(const std::string& filename,
+                                      MultiThreadImageReaderUser::EventType t,
+                                      vtkImageData* image);
 
     private:
       /// Controller which manages the interaction with the model
@@ -95,7 +115,23 @@ namespace creaImageIO
          std::string mMess;
          /// Multi-thread image reader
          MultiThreadImageReader mReader;
-         
+         /// Map of images' names to nodes
+         std::map<std::string,tree::Node*> mImageFileNameToNode;
+         /// type of image event
+         /// If the image pointer is non null then the image is available (loaded)
+      /// else it has been unloaded
+      struct ImageEventType
+      {
+                 ImageEventType( tree::Node* no,  vtkImageData* im )
+         : node(no), image(im) {}
+        ImageEventType(vtkImageData* im )
+         : image(im) {}
+        tree::Node* node;
+        vtkImageData* image;
+      };
+      // queue of image event 
+      typedef std::deque<ImageEventType> ImageEventQueueType;
+      ImageEventQueueType mImageEventQueue;
       
     };
     // EO class GimmickView
index 44347895312047f211d715fd381dc7419715c722..a8071405a05a35c87b57ce2d50186b245075269d 100644 (file)
@@ -44,6 +44,9 @@ namespace creaImageIO
          /// Gets the user selected data from the level passed as a parameter
       virtual std::vector<tree::Node*> GetSelected(int level){ GimmickError("INTERNAL ERROR : TreeView::GetSelected not overloaded"); }
 
+         /// Gets the next nodes on the list, be it up(true) or down(false).
+      virtual void GetNodes(std::vector<tree::Node*>& nodes, bool direction){ GimmickError("INTERNAL ERROR : TreeView::GetNodes not overloaded"); }
+
     protected:
       TreeHandler* GetTreeHandler() { return mTreeHandler; }
         
index 5e851a398639fdffe765dd053ec163539d45e1f9..a21617c744a831daa3727994dcbd2338e9e60a93 100644 (file)
@@ -98,7 +98,9 @@ namespace creaImageIO
 
        //Gimmick
        mGimmick=gimmick;
+       mViewer=new WxViewer(this, wxID_ANY, wxT("Gimmick! Viewer"),wxDefaultPosition, wxDefaultSize );
 
+       
        mSelectionMaxDimension= max_dim;
        mSelectionMinDimension= min_dim;
 
@@ -359,12 +361,132 @@ namespace creaImageIO
        std::vector<tree::Node*> sel=* (std::vector<tree::Node*> *) s;
        bool valid=ValidateSelected(sel,mSelectionMinDimension,mSelectionMaxDimension );
        mText->SetLabel(_T("Status: ")+GetMessage());
+       if(valid)
+       {
+               ReadImageThreaded(sel);
+       }
+       else
+       {
+               mViewer->Hide();
+       }
        return valid;
     
    }
-  //=================================================
 
-   //=================================================
+  //==================================================
+
+  //==================================================
+  ///Reads Images (Threaded)
+  void WxGimmickView::ReadImageThreaded(std::vector<tree::Node*> sel)
+  {    
+       int maxprio = GetMaximalPriority();
+       int prio = maxprio + 2000;
+
+       //First load the selected images
+       mCurImageItemToShow = sel.front();
+       std::vector<tree::Node*>::iterator selected;
+       for(selected=sel.begin();selected!=sel.end();++selected)
+       {
+               GimmickDebugMessage(5,
+                               "Requesting image from selected "
+                               <<(*selected)->GetAttribute("FullFileName")
+                               <<std::endl);
+               RequestReading(*selected,prio);
+               AddEntryToMap(*selected);
+               prio--;
+       }
+       
+       //Going up
+       prio = maxprio + 1000;
+       std::vector<tree::Node*> up;
+       GetTreeViewMap()["Local database"]->GetNodes(up,true);
+       std::vector<tree::Node*>::iterator iterUp;
+       for(iterUp=up.begin();iterUp!=up.end();++iterUp)
+       {
+               GimmickDebugMessage(5,
+                               "Requesting image from neighbors up "
+                               <<(*iterUp)->GetAttribute("FullFileName")
+                               <<std::endl);
+               RequestReading(*iterUp,prio);
+               AddEntryToMap(*iterUp);
+               prio--;
+       }
+
+       //Going down
+       prio = maxprio + 999;
+       std::vector<tree::Node*> down;
+       GetTreeViewMap()["Local database"]->GetNodes(down,false);
+       std::vector<tree::Node*>::iterator iterDown;
+       for(iterDown=down.begin();iterDown!=down.end();++iterDown)
+       {
+               GimmickDebugMessage(5,
+                               "Requesting image from neighbors down "
+                               <<(*iterDown)->GetAttribute("FullFileName")
+                               <<std::endl);
+               RequestReading(*iterDown,prio);
+               AddEntryToMap(*iterDown);
+               prio--;
+       }       
+  }
+
+  //==================================================
+
+  //==================================================
+  /// Processes the queue of image events 
+  void WxGimmickView::ProcessImageEvents()
+  {
+       int level=GetTreeViewMap()["Local database"]->GetNumberOfLevels();
+       std::vector<tree::Node*> sel=GetTreeViewMap()["Local database"]->GetSelected(level+1);
+         GimmickDebugMessage(5,
+                               "Processing Images. Lock Started"
+                               <<std::endl);
+    MultiThreadImageReaderEventLock();
+
+       mViewer->ClearImages();
+    while (!IsQueueEmpty())
+      {
+               vtkImageData* image=GetNextImageQueued();
+               tree::Node* node=GetNextNodeQueued();
+               if( image!=0 ) 
+               {
+                       bool found=false;
+                       std::vector<tree::Node*>::iterator i;
+                       for(i=sel.begin();i!=sel.end()&&!found;++i)
+                       {
+                               if((*i)==node)
+                               {
+                                       mViewer->AddImage(image);
+                                       found=true;
+                               }
+                       }
+                       UnqueueNext();
+               }
+         }
+         if(!(mViewer->ImagesEmpty()))
+         {
+               mViewer->ShowImages();
+               mViewer->Show();
+         }
+    ClearQueue();
+       
+
+    MultiThreadImageReaderEventUnlock();
+       GimmickDebugMessage(5,
+                               "Processing Images. Lock Ended"
+                               <<std::endl);
+  }
+  //==================================================
+
+  //==================================================
+   void  WxGimmickView::OnInternalIdle()
+  {
+    ProcessImageEvents();
+  }
+  
+  //=================================================
+  //=================================================
   void WxGimmickView::OnRemove(wxCommandEvent& event)
   {
        //TODO Select current tree handler       
index a156b164fdf3d91fced2062258cadb466ab3f119..c462e8443b0d2616291c38fd4014f60d03c76924 100644 (file)
@@ -4,6 +4,7 @@
 #ifdef USE_WXWIDGETS
 
 #include <creaImageIOGimmickView.h>
+#include <creaImageIOWxViewer.h>
 #include <creaWx.h>
 
 #include <wx/splitter.h>
@@ -47,6 +48,9 @@ namespace creaImageIO
          void GetSelectedImages(std::vector<vtkImageData*>& s, int dim);
          /// Validates the selected images
          bool ValidateSelection(void *);
+         ///Sends a request to read the currently selected node and the ones that surround it.
+         void ReadImageThreaded(std::vector<tree::Node*> sel);
+
 
     protected:
       /// Creates the tool bar
@@ -89,6 +93,12 @@ namespace creaImageIO
 
       /// AddProgress Gimmick callback
       void OnAddProgress( Gimmick::AddProgress& );
+         /// Processes the queue of image events 
+         /// Called in OnInternalIdle();
+      /// (locks the MultiThreadImageReaderEvent mutex)
+      void ProcessImageEvents();
+      /// Called upon to refresh the viewer once there are no actions to be done
+      void OnInternalIdle();
      
       /// Progress dialog
       wxProgressDialog* mProgressDialog;
@@ -96,6 +106,10 @@ namespace creaImageIO
          int mSelectionMaxDimension;
          ///The selection's minimum dimension
          int mSelectionMinDimension;
+         ///Image previewer
+         WxViewer* mViewer;
+         ///Currently Displayed Node
+         tree::Node* mCurImageItemToShow;
 
 
       wxString mCurrentDirectory;
index 1f3ccfeb1ff109fa35ba57ee90497ccb41cabd92..72b58fc97ca980af62eb4e18150d3d63549e98dd 100644 (file)
@@ -1,16 +1,11 @@
 #include <creaImageIOWxTreeView.h>
 #include <creaImageIOSystem.h>
 #include <wx/splitter.h>
+///Comparing function for ordering algorithm. Takes parameters as strings.
 int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
 {      
        std::string s1((char*)((long*)item1)[1]);
        std::string s2((char*)((long*)item2)[1]);
-        GimmickMessage(1,
-               " Check: STRING 1: " 
-                       <<s1
-                       <<" STRING 2: "
-                       <<s2
-                       <<std::endl);
        if(sortData==1)
        {
                // inverse the order
@@ -34,16 +29,11 @@ int wxCALLBACK CompareFunctionStrings(long item1, long item2, long sortData)
        
 }
 
+///Comparing function for ordering algorithm. Takes parameters as ints.
 int wxCALLBACK CompareFunctionInts(long item1, long item2, long sortData)
 {      
        int val1=atoi((char*)((long*)item1)[1]);
        int val2=atoi((char*)((long*)item2)[1]);
-        GimmickMessage(1,
-               " Check: STRING 1: " 
-                       <<val1
-                       <<" STRING 2: "
-                       <<val2
-                       <<std::endl);
        if(sortData==1)
        {
                // inverse the order
@@ -157,6 +147,7 @@ namespace creaImageIO
  
       sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW  ,0);
        mColumnSelected=1;
+       mLastSelected=0;
        mDirection=true;
     UpdateLevel(1);
 
@@ -204,7 +195,16 @@ namespace creaImageIO
              {
                long adr = GetCtrl(l-1)->GetItemData(i);
                tree::Node* n = ((ItemData*)adr)->node;
-               sel.push_back(n);
+                       if(mLastSelected==i)
+                       {
+                               std::vector<tree::Node*>::iterator it;
+                               it = sel.begin();
+                               it = sel.insert ( it , n );
+                       }
+                       else
+                       {
+                               sel.push_back(n);
+                       }
              }
          }     
       }
@@ -248,7 +248,7 @@ namespace creaImageIO
 
  
   //=====================================================================
-  /// 
+  /// Updates a level of the view (adds or removes children, proganizes, etc.)
   void WxTreeView::UpdateLevel( int level )
   {
     GimmickDebugMessage(1,
@@ -270,7 +270,7 @@ namespace creaImageIO
   }
   //=====================================================================
   
-  /// 
+  /// Recursive method called upon by UpdateLevel to refresh all windows
   void WxTreeView::RecursiveUpdateLevel( int level )
   {
          GimmickDebugMessage(2,
@@ -387,7 +387,7 @@ namespace creaImageIO
 
     wxListItem info;
     info.m_itemId = event.m_itemIndex;
-    
+    mLastSelected=event.m_itemIndex;
 
     // retrieve the level
     wxObject* obj = event.GetEventObject();   
@@ -410,93 +410,94 @@ namespace creaImageIO
   {      
        //Obtain the column name and the level that needs to be organized
        mColumnSelected=event.m_col;
-    GimmickMessage(1,
-                       " Column " <<event.m_col
+    GimmickDebugMessage(1,
+               " Column selected: " <<event.m_col
                        <<std::endl);
 
-       
-    wxObject* ctrl = event.GetEventObject(); 
-       unsigned int level = 0;
-    for (level = 0; level<mLevelList.size(); ++level)
-      {
-       if ( GetCtrl(level) == ctrl ) break;
-      }
-         UpdateLevel(level+1);
-         wxBusyCursor busy;
-         int l = level - 1;
-
-         //Sets the data for the items to be sorted
-       std::string att;
-       unsigned int ty=0;
-       int n = GetCtrl(level)->GetItemCount();
-       for (int i = 0; i < n; i++)
-         {
+       if(mColumnSelected!=0)
+       {
+               wxObject* ctrl = event.GetEventObject(); 
+               unsigned int level = 0;
+               for (level = 0; level<mLevelList.size(); ++level)
+               {
+               if ( GetCtrl(level) == ctrl ) break;
+               }
+               UpdateLevel(level+1);
+               wxBusyCursor busy;
+        
+               int l = level - 1;
+
+               //Sets the data for the items to be sorted
+               std::string att;
+               unsigned int ty=0;
+               int n = GetCtrl(level)->GetItemCount();
+               for (int i = 0; i < n; i++)
+               {
+                         
+                       //Gets current item data
+                       long adr = GetCtrl(level)->GetItemData(i);
+                       //Extracts the node and the type of attribute
+                       tree::Node* nod = ((ItemData*)adr)->node;
+                       if(i==0)
+                       {
+                               (*nod).GetAttributeDescriptor(mLevelList[level].key[mColumnSelected-1]).DecodeType(ty);
+                       }
+                       //Obtains the organizing attribute
+                       att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected-1]);
+                       
+                       char* d= new char [att.size()+1];
+                       strcpy (d, att.c_str());
+
+                       //Creates array
+                       long* lp= new long[2];
+                       lp[0]=adr;
+                       lp[1]=(long)d;
+                        
+                       //Sets it as the data
+                       GetCtrl(level)->SetItemData(i,(long)lp);
+               }       
                  
-           //Gets current item data
-               long adr = GetCtrl(level)->GetItemData(i);
-               //Extracts the node and the type of attribute
-               tree::Node* nod = ((ItemData*)adr)->node;
-               if(i==0)
-                 {
-                       (*nod).GetAttributeDescriptor(mLevelList[level].key[mColumnSelected-1]).DecodeType(ty);
-                 }
-               //Obtains the organizing attribute
-               att=(*nod).GetAttribute(mLevelList[level].key[mColumnSelected-1]);
-               
-               char* d= new char [att.size()+1];
-               strcpy (d, att.c_str());
-
-               //Creates array
-               long* lp= new long[2];
-               lp[0]=adr;
-               lp[1]=(long)d;
-                
-               //Sets it as the data
-               GetCtrl(level)->SetItemData(i,(long)lp);
-         }     
-         
-         //int ty=GetAttributeDescriptor(mLevelList[level].key[mColumnSelected-1]).GetType();
-         if(mDirection)
-         {
-                 if(ty==1)
-                 {
-                         GetCtrl(level)->SortItems(CompareFunctionInts, 0);
-                 }
-                 else
-                 {
-                         GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
-                 }
-               
-               mDirection=false;
-         }
-         else
-         {
-                if(ty==1)
-                 {
-                         GetCtrl(level)->SortItems(CompareFunctionInts, 1);
-                 }
-                 else
-                 {
-                         GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
-                 }
-                 mDirection=true;
-         }
+               if(mDirection)
+               {
+                       if(ty==1)
+                       {
+                               GetCtrl(level)->SortItems(CompareFunctionInts, 0);
+                       }
+                       else
+                       {
+                               GetCtrl(level)->SortItems(CompareFunctionStrings, 0);
+                       }
+                       
+                       mDirection=false;
+               }
+               else
+               {
+                       if(ty==1)
+                       {
+                               GetCtrl(level)->SortItems(CompareFunctionInts, 1);
+                       }
+                       else
+                       {
+                               GetCtrl(level)->SortItems(CompareFunctionStrings, 1);
+                       }
+                       mDirection=true;
+               }
 
-       //Resets original data
-               
-       long it = -1;
-       for ( ;; )
-    {
-        it = GetCtrl(level)->GetNextItem(it,
-                                     wxLIST_NEXT_ALL);
-        if ( it == -1 )
-            break;
-                 //Gets current item data, extracts the node and resets it
-               long item = GetCtrl(level)->GetItemData(it);
-               GetCtrl(level)->SetItemData(it,((long*)item)[0]);
-               
-         }
+               //Resets original data
+                       
+               long it = -1;
+               for ( ;; )
+               {
+                       it = GetCtrl(level)->GetNextItem(it,
+                                                                               wxLIST_NEXT_ALL);
+                       if ( it == -1 )
+                               break;
+                       //Gets current item data, extracts the node and resets it
+                       long item = GetCtrl(level)->GetItemData(it);
+                       GetCtrl(level)->SetItemData(it,((long*)item)[0]);
+                       
+               }
+       }
        
    }
   //================================================================
@@ -510,6 +511,42 @@ namespace creaImageIO
                event.SetClientData(&sel);
                GetEventHandler()->ProcessEvent( event );
   }
+
+   //================================================================
+  void WxTreeView::GetNodes(std::vector<tree::Node*>& nodes, bool direction)
+  {
+       long item = mLastSelected;
+       int level=mLevelList.size()-1;
+       //Gets current item data
+       long adr = GetCtrl(level)->GetItemData(item);
+       //Extracts the node
+       tree::Node* nod = ((ItemData*)adr)->node;
+    for ( ;; )
+    {
+               if(direction)
+               {
+                       item = GetCtrl(level)->GetNextItem(item,
+                                     wxLIST_NEXT_ABOVE);
+               }
+               else
+               {
+                       item = GetCtrl(level)->GetNextItem(item,
+                                     wxLIST_NEXT_BELOW);
+               }
+        if ( item == -1 )
+               {
+            break;
+               }
+               if(GetCtrl(level)->GetItemState(item, wxLIST_STATE_SELECTED)==0)
+               {
+                       adr = GetCtrl(level)->GetItemData(item);
+                       nod = ((ItemData*)adr)->node;
+                       nodes.push_back(nod);
+               }
+    }
+
+  }
+
   //================================================================
   void WxTreeView::GetSelectedAsString(std::vector<std::string>&s)
   {
index 6b93641d8456bc87980c67aade95695624616abb..7401e90bd8a8c94aacb280c1301009850dcce59c 100644 (file)
@@ -66,6 +66,8 @@ namespace creaImageIO
       void ValidateSelectedImages();   
          ///Gets selected filenames
          void GetSelectedAsString(std::vector<std::string>&s);
+           /// Gets the next nodes on the list, be it up(true) or down(false).
+      void GetNodes(std::vector<tree::Node*>& nodes, bool direction);
       /// Updates the view of a level given the selected items of upper level
       /// Recursive method
       virtual void RecursiveUpdateLevel( int );
@@ -76,6 +78,8 @@ namespace creaImageIO
          ///Boolean that defines the direction of the organization
          ///True is ascending order and false is descending
          bool mDirection;
+         ///The last selected item on the list
+         long mLastSelected;
        
          
 
diff --git a/src2/creaImageIOWxViewer.cpp b/src2/creaImageIOWxViewer.cpp
new file mode 100644 (file)
index 0000000..f8ae7b9
--- /dev/null
@@ -0,0 +1,370 @@
+
+#include <creaImageIOWxViewer.h>
+#include <creaImageIOSystem.h>
+#include <fstream>
+#include <vtkCamera.h>
+#include <vtkRenderer.h>
+#include <vtkImageData.h>
+
+#include <creaMessageManager.h>
+#include <stdio.h>
+#include <time.h>
+
+
+using namespace crea;
+
+namespace creaImageIO
+{
+
+  //=====================================================================
+
+  //=====================================================================
+  class ThreadedMovie: public wxThread
+  {
+  public:
+    ThreadedMovie(std::vector<vtkImageData*> m, vtkImageViewer2* v, crea::creawxVTKRenderWindowInteractor* i, WxViewer* parent) :
+      mImagesToPlay(m), mViewer(v), mInteractor(i), mParent(parent)
+    {}
+
+    void* Entry();
+    void SetImagesToPlay(std::vector<vtkImageData*> im);
+    void ShowImage(vtkImageData* v);
+       void StartIterator();
+    void  OnExit();
+
+  private:
+         std::vector<vtkImageData*> mImagesToPlay;
+         vtkImageViewer2* mViewer;
+         /// Associated wxvtk interactor
+       crea::creawxVTKRenderWindowInteractor  *mInteractor;
+       std::vector<vtkImageData*>::iterator i;
+       WxViewer* mParent;
+  
+    int mx1,mx2,my1,my2,mz1,mz2;
+    double mspx,mspy,mspz;
+  };
+
+
+       // CTor
+  WxViewer::WxViewer(wxWindow *parent, 
+                                              wxWindowID id,
+                                              wxString title,
+                                              const wxPoint& pos,
+                                              const wxSize& size)
+ :   wxFrame( parent, 
+                 id, 
+                 title,
+                 pos,
+                 size, 
+                 wxCAPTION)
+  {
+    GimmickDebugMessage(1,"WxViewer::WxViewer"
+                       <<std::endl);
+    wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
+
+       
+        // previewer
+       
+       mInteractor = new crea::creawxVTKRenderWindowInteractor(this,-1);
+    mInteractor->UseCaptureMouseOn();  
+    mViewer    = vtkImageViewer2::New();
+    mViewer->SetupInteractor ( mInteractor );
+
+       mMovie=new ThreadedMovie(images, mViewer, mInteractor, this);
+       
+    topsizer-> Add( mInteractor ,1,wxGROW  ,0);
+    SetSizer( topsizer );     
+    Layout(); 
+  }
+
+  /// Destructor
+  WxViewer::~WxViewer()
+  {
+    GimmickDebugMessage(1,"WxViewer::~WxViewer"
+                       <<std::endl);
+  }
+
+
+  void WxViewer::ShowImage(vtkImageData* im)
+  {
+       mViewer->SetInput(im);
+       mViewer->SetSlice( 0 );
+
+       int x1,x2,y1,y2,z1,z2;
+       double spx,spy,spz;
+    im->Update();
+    
+    im->GetSpacing(spx,spy,spz);
+    im->GetExtent (x1,x2,y1,y2,z1,z2);
+    /*
+    std::cout << "-----------------------------"<<std::endl;
+      std::cout << x1 << "-"<<x2<<std::endl; 
+      std::cout << y1 << "-"<<y2<<std::endl; 
+      std::cout << z1 << "-"<<z2<<std::endl; 
+      std::cout << spx << "-"<<spy<<"-"<<spz<<std::endl; 
+    */
+   
+    if ((x1!=mx1) ||
+       (x2!=mx2) ||
+       (y1!=my1) ||
+       (y2!=my2) ||
+       (z1!=mz1) ||
+       (z2!=mz2) ||
+       (spx!=mspx) ||
+       (spy!=mspy) ||
+       (spz!=mspz) 
+       )
+      {
+       mx1 = x1;
+       mx2 = x2;
+       my1 = y1;
+       my2 = y2;
+       mz1 = z1;
+       mz2 = z2;
+       mspx = spx;
+       mspy = spy;
+       mspz = spz;
+       
+       double *range = im->GetScalarRange();
+        mViewer->SetColorWindow(range[1] - range[0]);
+        mViewer->SetColorLevel(0.5 * (range[1] + range[0]));
+
+        mViewer->GetRenderer()->ResetCamera();
+       double bounds[6];
+
+
+        mViewer->GetRenderer()->ComputeVisiblePropBounds(bounds);
+
+        /*
+       std::cout <<"bounds : "<<bounds[0]<<","
+<<bounds[1]<<","
+<<bounds[2]<<","
+<<bounds[3]<<","
+<<bounds[4]<<","
+                 <<bounds[5]<<std::endl;
+        */
+         
+        mViewer->GetRenderer()->ResetCameraClippingRange(bounds);
+       /*
+       vtkCamera *camera = mViewer->GetRenderer()->GetActiveCamera();
+       
+       camera->SetViewUp ( spx*0, -spy*1, spz*0);
+       camera->SetPosition( spx*(x1+x2)/2, spy*(y1+y2)/2, spz*10000000); 
+       camera->SetFocalPoint   ( spx*(x1+x2)/2 , spy*(y1+y2)/2 , spz*0); 
+       
+       camera->ComputeViewPlaneNormal();
+       camera->SetParallelScale(  spx*(x2-x1)/2.0 );
+       
+       camera->Roll ( 180 );
+       */
+         
+      }
+    
+    
+       
+  } 
+
+  //================================================================
+  
+  //================================================================
+
+  void WxViewer::AddImage(vtkImageData* im)
+  {
+         images.push_back(im);
+  }
+
+  //================================================================
+   
+  //================================================================
+  
+  void WxViewer::ShowImages()
+  {
+         if(!(mMovie->IsAlive()))
+         {
+               mMovie->SetImagesToPlay(images);
+               mMovie->StartIterator();
+               mMovie->Create();
+               mMovie->Run(); 
+         }
+         else
+         {
+                 if(!images.empty())
+                 {
+                       mMovie->Pause();
+                       mMovie->SetImagesToPlay(images);
+                       mMovie->StartIterator();
+                       mMovie->Resume();
+                 }
+                 else
+                 {
+                       GimmickMessage(1,"I'm empty!!!!! "<<std::endl);
+                 }
+         }
+         
+         
+  }
+
+   //================================================================
+  
+  //================================================================
+
+  void WxViewer::ClearImages()
+  {
+         images.clear();
+  }
+
+   //================================================================
+  
+  //================================================================
+
+  bool WxViewer::ImagesEmpty()
+  {
+         return images.empty();
+  }
+  //================================================================
+  //  BEGIN_EVENT_TABLE(WxGimmickFrame, wxDialog)
+  //    END_EVENT_TABLE()
+  //================================================================
+
+//========================================================================
+//========================================================================
+//========================================================================
+//========================================================================
+//========================================================================
+//========================================================================
+//========================================================================
+//========================================================================
+
+  void*  ThreadedMovie::Entry()
+  {
+         
+                       
+       while(true)
+       {               
+                       clock_t endwait;
+                               for(i=mImagesToPlay.begin();i!=mImagesToPlay.end();++i)
+                               {
+                                       if(i!=mImagesToPlay.end())
+                                       {
+                                               ShowImage(*i);
+                                               mParent->Refresh();
+                                               endwait = clock () + 0.2 * CLOCKS_PER_SEC ;
+                                               while (clock() < endwait) {}
+                                       }
+                                       
+                               }
+                                       
+       }
+       return 0;
+  }
+
+  //=====================================================================
+
+  //=====================================================================
+  void ThreadedMovie::OnExit()
+  {
+    GimmickMessage(1,"Hello WORLD IM OUT!!!!!!!! "<<std::endl);
+  }
+
+   //=====================================================================
+
+  //=====================================================================
+  void ThreadedMovie::SetImagesToPlay(std::vector<vtkImageData*> im)
+  {
+               mImagesToPlay=im;
+  }
+
+    //=====================================================================
+
+  //=====================================================================
+  void ThreadedMovie::StartIterator()
+  {
+               i=mImagesToPlay.begin();
+  }
+                       
+  //=====================================================================
+
+  //=====================================================================
+  void  ThreadedMovie::ShowImage(vtkImageData* im)
+  {
+       mViewer->SetInput(im);
+       mViewer->SetSlice( 0 );
+
+       int x1,x2,y1,y2,z1,z2;
+       double spx,spy,spz;
+
+    im->Update();
+    
+    im->GetSpacing(spx,spy,spz);
+    im->GetExtent (x1,x2,y1,y2,z1,z2);
+    /*
+    std::cout << "-----------------------------"<<std::endl;
+      std::cout << x1 << "-"<<x2<<std::endl; 
+      std::cout << y1 << "-"<<y2<<std::endl; 
+      std::cout << z1 << "-"<<z2<<std::endl; 
+      std::cout << spx << "-"<<spy<<"-"<<spz<<std::endl; 
+    */
+   
+    if ((x1!=mx1) ||
+       (x2!=mx2) ||
+       (y1!=my1) ||
+       (y2!=my2) ||
+       (z1!=mz1) ||
+       (z2!=mz2) ||
+       (spx!=mspx) ||
+       (spy!=mspy) ||
+       (spz!=mspz) 
+       )
+      {
+       mx1 = x1;
+       mx2 = x2;
+       my1 = y1;
+       my2 = y2;
+       mz1 = z1;
+       mz2 = z2;
+       mspx = spx;
+       mspy = spy;
+       mspz = spz;
+       
+       double *range = im->GetScalarRange();
+        mViewer->SetColorWindow(range[1] - range[0]);
+        mViewer->SetColorLevel(0.5 * (range[1] + range[0]));
+
+        mViewer->GetRenderer()->ResetCamera();
+       double bounds[6];
+
+
+        mViewer->GetRenderer()->ComputeVisiblePropBounds(bounds);
+
+        /*
+       std::cout <<"bounds : "<<bounds[0]<<","
+<<bounds[1]<<","
+<<bounds[2]<<","
+<<bounds[3]<<","
+<<bounds[4]<<","
+                 <<bounds[5]<<std::endl;
+        */
+         
+        mViewer->GetRenderer()->ResetCameraClippingRange(bounds);
+       /*
+       vtkCamera *camera = mViewer->GetRenderer()->GetActiveCamera();
+       
+       camera->SetViewUp ( spx*0, -spy*1, spz*0);
+       camera->SetPosition( spx*(x1+x2)/2, spy*(y1+y2)/2, spz*10000000); 
+       camera->SetFocalPoint   ( spx*(x1+x2)/2 , spy*(y1+y2)/2 , spz*0); 
+       
+       camera->ComputeViewPlaneNormal();
+       camera->SetParallelScale(  spx*(x2-x1)/2.0 );
+       
+       camera->Roll ( 180 );
+       */
+         
+      }
+    
+    //mInteractor->Render();
+  }
+
+} // EO namespace creaImageIO
+
diff --git a/src2/creaImageIOWxViewer.h b/src2/creaImageIOWxViewer.h
new file mode 100644 (file)
index 0000000..9323e3d
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef __creaImageIOWxViewer_h_INCLUDED__
+#define __creaImageIOWxViewer_h_INCLUDED__
+
+#ifdef USE_WXWIDGETS
+
+// wx
+#include <creaWx.h>
+#include <wx/image.h>
+#include <wx/imaglist.h>
+#include <wx/splitter.h>
+
+#include <creaImageIOSystem.h>
+
+// For image preview 
+// vtk and wxvtk classes
+#include "creawxVTKRenderWindowInteractor.h"
+#include "vtkImageViewer2.h"
+
+namespace creaImageIO
+{
+
+  class WxViewer : public wxFrame
+  {
+
+         public:
+                 friend class ThreadedMovie;
+    /// Ctor 
+    WxViewer();
+    WxViewer(wxWindow *parent, 
+                  const wxWindowID id,
+                  wxString title,
+                  const wxPoint& pos, 
+                  const wxSize& size);
+    /// Dtor
+    virtual ~WxViewer();
+       ///Shows the image in the vector as a movie
+       void ShowImages();
+       ///Shows the image passed as parameter
+       void ShowImage(vtkImageData* im);
+       ///Adds an image to the selection
+       void AddImage(vtkImageData* im);
+       ///Clears the selection of images
+       void ClearImages();
+       ///Returns true if the image vector is empty
+       bool ImagesEmpty();
+
+  private:
+       /// Previewer
+    vtkImageViewer2* mViewer;
+    /// Associated wxvtk interactor
+       crea::creawxVTKRenderWindowInteractor  *mInteractor;
+  
+    int mx1,mx2,my1,my2,mz1,mz2;
+    double mspx,mspy,mspz;
+
+       /// The vector of images to show
+       std::vector<vtkImageData*> images;
+       ///The threaded movie
+       ThreadedMovie* mMovie;
+
+  };
+
+}
+
+#endif // USE_WIDGETS
+// EOF
+#endif  
\ No newline at end of file