]> Creatis software - creaImageIO.git/blob - src2/creaImageIOGimmickView.cpp
*** empty log message ***
[creaImageIO.git] / src2 / creaImageIOGimmickView.cpp
1 #include <creaImageIOGimmickView.h>
2 #include <creaImageIOSystem.h>
3
4 #include "boost/filesystem.hpp"
5
6 namespace fs = boost::filesystem;
7
8 namespace creaImageIO
9 {
10
11   //======================================================================
12   // CTor
13   GimmickView::GimmickView(Gimmick* gimmick, int threads)
14     : mGimmick(gimmick),
15           mReader(threads)
16   {
17     GimmickDebugMessage(1,"GimmickView::GimmickView"
18                         <<std::endl);
19         // Anciently started the threads ...
20     // Threads now automatically start at first image request
21     //mReader.Start();
22
23   }
24   //======================================================================
25
26   //======================================================================
27   /// Destructor
28   GimmickView::~GimmickView()
29   {
30     GimmickDebugMessage(1,"GimmickView::~GimmickView"
31                         <<std::endl);
32   }
33    //======================================================================
34  
35   //======================================================================  
36   /// Initializes the view : 
37   /// Creates the TreeViews for all the TreeHandler of the Controller
38   /// 
39   void GimmickView::Initialize()
40   {
41           row="";
42           col="";
43           plane="";
44           selectionSize=0;
45   }
46   //======================================================================
47   
48   //======================================================================
49   /// Finalize 
50   void GimmickView::Finalize()
51   {
52   }
53
54   //======================================================================
55
56   //======================================================================
57   /// Create the tree views 
58   void GimmickView::CreateTreeViews()
59   {
60     GimmickMessage(2,"Creating the tree views"<<std::endl);
61     Gimmick::TreeHandlerMapType::const_iterator i;
62     for (i = mGimmick->GetTreeHandlerMap().begin();
63          i!= mGimmick->GetTreeHandlerMap().end();
64          ++i)
65       {
66         this->CreateTreeView(i->second);
67       }
68   }
69   //======================================================================
70
71   //======================================================================
72   /// Updates the TreeView of given name from level l to bottom
73   /// (calls the virtual method TreeView::Update())
74   void GimmickView::UpdateTreeViewLevel(const std::string& t, int l)
75   {
76     TreeViewMapType::iterator i;
77     i = GetTreeViewMap().find(t);
78     if ( i == GetTreeViewMap().end() )
79       {
80         GimmickError("INTERNAL ERROR : GimmickView::UpdateTreeView : '"
81                      <<t<<"' is not in TreeViewMap");
82       }
83     i->second->UpdateLevel(l);    
84   }
85   //======================================================================
86   /// Clears the status and begins a new selection process
87   void GimmickView::ClearStatus()
88   {
89           row="";
90           col="";
91           plane="";
92           selectionSize=0;
93           valid=true;
94   }
95
96
97   class ImageExtent
98   {
99   public:
100     ImageExtent(const std::string& x, const std::string& y, const std::string& z, const std::string& t);
101
102     void Clear() { mExtent[0] = mExtent[1] = mExtent[2] = mExtent[3] = 1; }
103
104     bool IsCompatible( const ImageExtent& );
105
106     void Add ( const ImageExtent& );
107                 
108     int Get(int i) { return mExtent[i]; }
109     
110     int GetDimension() { return mDim; }
111
112   private:
113     int mExtent[4];
114     int mDim;
115   };
116
117
118   //======================================================================
119   ///Validates the dimension compliance of the images with the maximum and 
120   ///minimum given, and between their sizes
121   bool GimmickView::ValidateSelected (tree::Node* sel, int min_dim, int max_dim)
122   {
123         GimmickMessage(2,"Validating selected"<<std::endl);
124         std::string mMessage;
125         if(sel==0)
126         {
127                 mMessage="Cannot have 0 images selected!";
128                 valid=false;
129         }
130         if(valid)
131         {
132         selectionSize++;
133           /*// EED validate all
134           mValidationSignal(valid);
135           return valid;*/
136           
137         int level;
138         
139         
140         if(row.compare("")==0 || col.compare("")==0)
141         {
142                 row=(*sel).GetAttribute("D0028_0010");
143                 col=(*sel).GetAttribute("D0028_0011");
144                 plane=(*sel).GetAttribute("D0028_0012");
145                 level=(*sel).GetLevel();
146         }
147         else
148         {
149                 if(((*sel).GetAttribute("D0028_0010"))!=row ||
150                         ((*sel).GetAttribute("D0028_0011"))!=col ||
151                         ((*sel).GetAttribute("D0028_0012"))!=plane)
152                         {
153                                 mMessage="The selected images are not compatible.";
154                                 valid=false;
155                         }
156         }
157                 
158         
159         int dim = 0;
160         int rows;
161         int cols;
162         int planes;
163         
164         //Dimention validation
165         //Compatibility with maximum and minimum
166         if(valid)
167           {     
168                     sscanf(row.c_str(),"%d",&rows);
169             sscanf(col.c_str(),"%d",&cols);
170             sscanf(plane.c_str(),"%d",&planes);
171             if(row==""){rows=1;}
172             if(col==""){cols=1;}
173             if(plane==""){planes=1;}
174             
175             std::cout << cols << "x"<<rows<<"x"<<planes << std::endl;
176
177             if (planes>1) dim=3;
178             else if (cols>1) dim=2;
179             else if (rows>1) dim=1;
180             
181             if (dim == 0) 
182               {
183                 mMessage="Unknown image dimension : cannot select !";
184                 valid= false;
185               }
186             else if (dim>max_dim)
187               {
188                 mMessage="Selecting ";
189                 mMessage+=dim;
190                 mMessage+="D images is not allowed !";
191                 valid= false;
192               }
193             if ( dim == max_dim )
194               {
195                 mMessage="Cannot add this image to selection : would result in a ";
196                 mMessage+=(dim+1);
197                 mMessage+="D image!";
198                 
199                 valid= false;
200               }
201             if ( dim < min_dim )
202               {
203                 GimmickMessage(1, "State Check: Dim: "
204                                <<dim
205                                <<" Dim min:"
206                                <<min_dim
207                                <<std::endl);
208                 std::stringstream out;
209                 out << "Cannot build the selection as it would result in a ";
210                 out << dim;
211                 out << "D image, and the minimum is ";
212                 out << min_dim;
213                 out << "D!";
214                 mMessage+=out.str();
215                 valid= false;
216               }
217           }
218         
219         
220         if(valid)
221           {
222             std::stringstream out;
223             out << dim << "D image " << cols << "x"<< rows << "x"<< planes <<" selected";
224             mMessage = out.str();
225           }
226         }
227         mValidationSignal(valid);
228         SetMessage(mMessage);
229         return valid;
230   }
231
232    //======================================================================
233
234    //======================================================================
235   ///Reads Images (Non Threaded)
236   void GimmickView::ReadImagesNotThreaded(std::vector<vtkImageData*>& s,std::vector<tree::Node*> im, int dimension)
237   {
238           
239         // Create the output data
240         if (im.size()==1) 
241       {
242                   
243                 // Only one image : give it
244                 vtkImageData* out = vtkImageData::New();
245                 GimmickMessage(1, "State Check: Full Filename: "
246                                                 <<im.front()->GetAttribute("FullFileName")
247                                                 <<std::endl);
248                 out->ShallowCopy(mReader.GetImage(im.front()->GetAttribute("FullFileName")));
249                 s.push_back( out );
250       }
251           
252     else if (im.size()>1)
253       {
254         vtkImageData* first = mReader.GetImage( im.front()->GetAttribute("FullFileName"));
255         if (dimension==2) 
256           {     
257             // n2D to 3D
258             vtkImageData* out = vtkImageData::New();
259             out->CopyStructure(first);  
260             out->SetScalarType(first->GetScalarType());
261             int ext[6];
262             first->GetExtent(ext);
263             ext[5] = im.size();
264             out->SetExtent(ext);
265             // LG : TODO : Z Spacing  ?
266             
267             out->AllocateScalars();
268             
269             //first->Print(std::cout);
270             //      out->Print(std::cout);
271             
272             int dim[3];
273             first->GetDimensions(dim);
274             unsigned long imsize = 
275               ( (unsigned long)first->GetScalarPointer(0,1,0)
276                 - (unsigned long)first->GetScalarPointer(0,0,0))
277               *dim[1];
278
279             int slice = 0;
280                 std::vector<tree::Node*>::iterator it;
281             for (it=im.begin(); it!=im.end(); ++it) 
282               {
283                 //std::cout << "copying slice "<<slice <<std::endl;
284                           vtkImageData* cur = mReader.GetImage( (*it)->GetAttribute("FullFileName"));
285                 
286                 void* src = cur->GetScalarPointer(0,0,0);
287                 void* dst = out->GetScalarPointer(0,0,slice);
288                 //              std::cout << "src="<<src<<std::endl;
289                 //              std::cout << "dst="<<dst<<std::endl;
290                 //              std::cout << "siz="<<imsize<<std::endl;
291                 memcpy(dst,src,imsize);
292
293                 slice++;
294               }
295             s.push_back(out);
296           }
297         else 
298           {
299             // n3D
300                   std::vector<tree::Node*>::iterator it;
301             for (it=im.begin(); it!=im.end(); ++it) 
302               {
303                 vtkImageData* out = vtkImageData::New();
304                 out->ShallowCopy(mReader.GetImage((*it)->GetAttribute("FullFileName")));
305                 s.push_back(out);
306               }
307           }
308       }
309         
310   }
311   //======================================================================
312
313   //======================================================================
314   ///Requests the reading of an image
315   void GimmickView::RequestReading(tree::Node* n, 
316                                    int prio, int selection_index, ImagePointerHolder *p)
317   {
318         mReader.Start();
319     ImageEventType t(n,selection_index, p);
320     mImageEventMap[n->GetAttribute("FullFileName")] = t;    
321     mReader.Request(this,n->GetAttribute("FullFileName"),prio);
322   }
323   //======================================================================
324
325   //======================================================================
326   void GimmickView::
327   OnMultiThreadImageReaderEvent(const std::string& filename,
328                                 MultiThreadImageReaderUser::EventType e,
329                                 vtkImageData* image)
330   {
331     GimmickDebugMessage(7,
332                         "MultiThreadImageReader event : "<<e<<std::endl);
333         if (e==ImageLoaded)
334         {
335     if (filename.size()==0)
336       {
337                   //What to do in this case?
338                   /*
339                 GimmickDebugMessage(5,
340                                         "Pushing unknown image in queue"
341                                         <<std::endl);
342                 mImageEventQueue.push_back(ImageEventType(image));*/
343                 return;
344       }
345     ImageEventTypeMap::iterator i;
346     i = mImageEventMap.find(filename);
347     if (i!=mImageEventMap.end())
348       {
349                 GimmickDebugMessage(5,
350                                         "Putting image of file '"<<filename<<"' on pointer"
351                                         <<std::endl);
352                 ImageEventType ie(i->second);
353                 ie.image = image;
354                 ie.pointerHolder->Set(ie.image);
355                 //mImageEventMap.erase(i);
356       }
357         }
358         else if (e==Error)
359         {
360                 std::string mess="ERROR: MultiThreadImageReader: Cannot read image in file ";
361                 mess+=filename;
362                 mess+="\n";
363                 GimmickMessage(1,mess);
364                 ImageEventTypeMap::iterator i;
365                 i = mImageEventMap.find(filename);
366                 if (i!=mImageEventMap.end())
367                 {
368                 ImageEventType ie(i->second);
369                 ie.image = image;
370                 ie.pointerHolder->Set(GetDefaultImage());
371                 //mImageEventMap.erase(i);
372                 }
373         }
374
375         else if (e==ImageUnloaded)
376         {
377                 std::string mess="Unloaded image in file ";
378                 mess+=filename;
379                 mess+="\n";
380                 GimmickMessage(1,mess);
381                                 ImageEventTypeMap::iterator i;
382                 i = mImageEventMap.find(filename);
383                 if (i!=mImageEventMap.end())
384                 {
385                 ImageEventType ie(i->second);
386                 ie.image = image;
387                 ie.pointerHolder->Set(GetDefaultImage());
388                 //mImageEventMap.erase(i);
389                 }
390
391         }
392   }
393
394   //====================================================================
395
396   //====================================================================
397   void GimmickView::ConnectValidationObserver(ValidationCallbackType callback)
398   {
399     mValidationSignal.connect(callback);
400   }
401           
402   
403 } // EO namespace creaImageIO
404
405