BlockScopeWxApp
creaImageIOGimmickReaderDialog
+ # Viewer
+ creaImageIOWxViewer
+
)
<<std::endl);
// Start the threads ...
mReader.Start();
+
}
//======================================================================
}
//Dimention validation
- //Compatibility with maximum
+ //Compatibility with maximum and minimum
if(valid)
{
}
}
+
+
+ //======================================================================
+
+ //======================================================================
+ 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
GimmickView(Gimmick*, int number_of_threads = 0 );
/// Virtual destructor
virtual ~GimmickView();
-
-
/// Initializes the view :
/// Creates the TreeViews for all the TreeHandler of the Controller
///
/// 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)
///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;}
/// 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
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
/// 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; }
//Gimmick
mGimmick=gimmick;
+ mViewer=new WxViewer(this, wxID_ANY, wxT("Gimmick! Viewer"),wxDefaultPosition, wxDefaultSize );
+
mSelectionMaxDimension= max_dim;
mSelectionMinDimension= min_dim;
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
#ifdef USE_WXWIDGETS
#include <creaImageIOGimmickView.h>
+#include <creaImageIOWxViewer.h>
#include <creaWx.h>
#include <wx/splitter.h>
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
/// 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;
int mSelectionMaxDimension;
///The selection's minimum dimension
int mSelectionMinDimension;
+ ///Image previewer
+ WxViewer* mViewer;
+ ///Currently Displayed Node
+ tree::Node* mCurImageItemToShow;
wxString mCurrentDirectory;
#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
}
+///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
sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW ,0);
mColumnSelected=1;
+ mLastSelected=0;
mDirection=true;
UpdateLevel(1);
{
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);
+ }
}
}
}
//=====================================================================
- ///
+ /// Updates a level of the view (adds or removes children, proganizes, etc.)
void WxTreeView::UpdateLevel( int level )
{
GimmickDebugMessage(1,
}
//=====================================================================
- ///
+ /// Recursive method called upon by UpdateLevel to refresh all windows
void WxTreeView::RecursiveUpdateLevel( int level )
{
GimmickDebugMessage(2,
wxListItem info;
info.m_itemId = event.m_itemIndex;
-
+ mLastSelected=event.m_itemIndex;
// retrieve the level
wxObject* obj = event.GetEventObject();
{
//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]);
+
+ }
+ }
}
//================================================================
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)
{
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 );
///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;
--- /dev/null
+
+#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
+
--- /dev/null
+#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