#include #include #include "boost/filesystem.hpp" namespace fs = boost::filesystem; namespace creaImageIO { ///Class used to represent the actual state of the image selected and to perform comparisons on its values class ImageExtent { public: ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t) { sscanf(x.c_str(),"%d",&mExtent[0]); sscanf(y.c_str(),"%d",&mExtent[1]); sscanf(z.c_str(),"%d",&mExtent[2]); sscanf(t.c_str(),"%d",&mExtent[3]); if(x==""){mExtent[0]=1;} if(y==""){mExtent[1]=1;} if(z==""){mExtent[2]=1;} if(t==""){mExtent[3]=1;} if (mExtent[3]>1) mDim=4; else if (mExtent[2]>1) mDim=3; else if (mExtent[1]>1) mDim=2; else if (mExtent[0]>1) mDim=1; else mDim=0; } ///Clears the extent void Clear() { mExtent[0] = mExtent[1] = mExtent[2] = mExtent[3] = 1; } ///Returns true if the two extents are compatible bool IsCompatible( const ImageExtent& ); ///Adds the extent passed as a parameter to the current extent void Add ( const ImageExtent& ); ///Returns the ieth position of the extent int Get(int i) { return mExtent[i]; } ///Returns the dimension of the current image void SetDimension(int dim) { mDim=dim; } ///Returns the dimension of the current image int GetDimension() { return mDim; } private: int mExtent[4]; int mDim; }; //====================================================================== //====================================================================== // CTor GimmickView::GimmickView(Gimmick* gimmick, int threads) : mGimmick(gimmick), mReader(threads) { GimmickDebugMessage(1,"GimmickView::GimmickView" <GetTreeHandlerMap().begin(); i!= mGimmick->GetTreeHandlerMap().end(); ++i) { this->CreateTreeView(i->second); } } /// Create a tree view with a given name void GimmickView::CreateSingleTreeView(std::string &i_name) { this->CreateTreeView(mGimmick->GetTreeHandlerMap()[i_name]); } //====================================================================== //====================================================================== /// Updates the TreeView of given name from level l to bottom /// (calls the virtual method TreeView::Update()) void GimmickView::UpdateTreeViewLevel(const std::string& t, int l) { TreeViewMapType::iterator i; i = GetTreeViewMap().find(t); if ( i == GetTreeViewMap().end() ) { GimmickError("INTERNAL ERROR : GimmickView::UpdateTreeView : '" <second->UpdateLevel(l); } //====================================================================== /// Clears the status and begins a new selection process void GimmickView::ResetExtent() { if(mImageExtent!=0) { mImageExtent=0; } valid=true; } //====================================================================== //====================================================================== bool ImageExtent::IsCompatible(const ImageExtent& ie) { bool compatible=true; ImageExtent * extent= (ImageExtent*)&ie; if((*extent).Get(0)!=Get(0) || (*extent).Get(1)!=Get(1)) { compatible=false; } return compatible; } //====================================================================== //====================================================================== void ImageExtent::Add(const ImageExtent& ie) { ImageExtent * extent= (ImageExtent*)&ie; mExtent[2]+=(*extent).Get(2); if(mExtent[2]>1) { SetDimension(3); } } //====================================================================== ///Validates the dimension compliance of the images with the maximum and ///minimum given, and between their sizes bool GimmickView::ValidateSelected (tree::Node* sel, int min_dim, int max_dim) { GimmickDebugMessage(2,"Validating selected"<Get(min_dim-1)<2)||(mImageExtent->Get(max_dim)>1)) { valid=false; } else { std::stringstream out; out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected"; mMessage = out.str(); mImageExtent->SetDimension(2); valid=true; } } else { if(mImageExtent->IsCompatible(*ie)) { if(mImageExtent->GetDimension()==max_dim && mImageExtent->Get(max_dim)>2) { std::stringstream out; out<<"Cannot add this image to selection : would result in a "<GetDimension()+1<<"D image!"; mMessage=out.str(); valid=false; } else if(max_dim<3) { std::stringstream out; out<<"Selecting "<GetDimension()<<"D images is not allowed !"; mMessage=out.str(); valid=false; } else if(min_dim==3 && (ie->Get(2)+mImageExtent->Get(2))<2) { std::stringstream out; out << "Cannot build the selection as it would result in a "; out << mImageExtent->GetDimension(); out << "D image, and the minimum is "; out << min_dim; out << "D!"; mMessage=out.str(); valid=false; } else { mImageExtent->Add(*ie); std::stringstream out; out << mImageExtent->GetDimension() << "D image " << mImageExtent->Get(0) << "x"<< mImageExtent->Get(1) << "x"<< mImageExtent->Get(2) <<" selected"; mMessage = out.str(); } } else { mMessage="The selected images are not compatible."; valid=false; } } } modifyValidationSignal(valid); SetMessage(mMessage); return valid; } //====================================================================== void GimmickView::modifyValidationSignal(bool ivalid) { mValidationSignal(ivalid); } //====================================================================== ///Reads Images (Non Threaded) void GimmickView::ReadImagesNotThreaded(std::vector& s,std::vector im, int dimension) { // Create the output data if (im.size()==1) { // Only one image : give it vtkImageData* out = vtkImageData::New(); GimmickDebugMessage(3, "State Check: Full Filename: " <ShallowCopy(mReader.GetImage(im.front())); s.push_back( out ); } else if (im.size()>1) { vtkImageData* first = mReader.GetImage( im.front()); if (dimension==2) { // n2D to 3D vtkImageData* out = vtkImageData::New(); out->CopyStructure(first); out->SetScalarType(first->GetScalarType()); int ext[6]; first->GetExtent(ext); ext[5] = im.size(); out->SetExtent(ext); // LG : TODO : Z Spacing ? out->AllocateScalars(); //first->Print(std::cout); // out->Print(std::cout); int dim[3]; first->GetDimensions(dim); unsigned long imsize = ( (unsigned long)first->GetScalarPointer(0,1,0) - (unsigned long)first->GetScalarPointer(0,0,0)) *dim[1]; int slice = 0; std::vector::iterator it; for (it=im.begin(); it!=im.end(); ++it) { //std::cout << "copying slice "<GetScalarPointer(0,0,0); void* dst = out->GetScalarPointer(0,0,slice); // std::cout << "src="<GetAttribute("FullFileName"),prio); } //====================================================================== //====================================================================== void GimmickView:: OnMultiThreadImageReaderEvent(const std::string& filename, MultiThreadImageReaderUser::EventType e, vtkImageData* image) { GimmickDebugMessage(7, "MultiThreadImageReader event : "<second); ie.image = image; ie.pointerHolder->Set(ie.image); //mImageEventMap.erase(i); } } else if (e==Error) { std::string mess="ERROR: MultiThreadImageReader: Cannot read image in file "; mess+=filename; mess+="\n"; GimmickMessage(1,mess); ImageEventTypeMap::iterator i; i = mImageEventMap.find(filename); if (i!=mImageEventMap.end()) { ImageEventType ie(i->second); ie.image = image; ie.pointerHolder->Set(GetDefaultImage()); //mImageEventMap.erase(i); } } else if (e==ImageUnloaded) { std::string mess="Unloaded image in file "; mess+=filename; mess+="\n"; GimmickMessage(1,mess); ImageEventTypeMap::iterator i; i = mImageEventMap.find(filename); if (i!=mImageEventMap.end()) { ImageEventType ie(i->second); ie.image = image; ie.pointerHolder->Set(GetDefaultImage()); //mImageEventMap.erase(i); } } } //==================================================================== //==================================================================== void GimmickView::ConnectValidationObserver(ValidationCallbackType callback) { mValidationSignal.connect(callback); } } // EO namespace creaImageIO