Commit bc21685fee9a79071c8678b8792739b3e6c722b5
1 parent
2faf0f45
Exists in
master
and in
6 other branches
ADD: ProgressDialog in the loading serie
Showing
5 changed files
with
123 additions
and
16 deletions
Show diff stats
invesalius/control.py
@@ -51,8 +51,9 @@ class Controller(): | @@ -51,8 +51,9 @@ class Controller(): | ||
51 | #self.frame.Bind(reader.evt_end_load_file, self.LoadPanel) | 51 | #self.frame.Bind(reader.evt_end_load_file, self.LoadPanel) |
52 | 52 | ||
53 | def Progress(self, evt): | 53 | def Progress(self, evt): |
54 | - print evt | ||
55 | data = evt.data | 54 | data = evt.data |
55 | + if (data): | ||
56 | + message = "Loading file %d of %d"%(data[0],data[1]) | ||
56 | 57 | ||
57 | if (data): | 58 | if (data): |
58 | if not(self.progress_dialog): | 59 | if not(self.progress_dialog): |
@@ -60,7 +61,7 @@ class Controller(): | @@ -60,7 +61,7 @@ class Controller(): | ||
60 | maximum = data[1]) | 61 | maximum = data[1]) |
61 | else: | 62 | else: |
62 | print data[0] | 63 | print data[0] |
63 | - if not(self.progress_dialog.Update(data[0])): | 64 | + if not(self.progress_dialog.Update(data[0],message)): |
64 | self.progress_dialog.Close() | 65 | self.progress_dialog.Close() |
65 | self.progress_dialog = None | 66 | self.progress_dialog = None |
66 | else: | 67 | else: |
@@ -153,7 +154,7 @@ class Controller(): | @@ -153,7 +154,7 @@ class Controller(): | ||
153 | 154 | ||
154 | def OnOpenDicomGroup(self, pubsub_evt): | 155 | def OnOpenDicomGroup(self, pubsub_evt): |
155 | group = pubsub_evt.data | 156 | group = pubsub_evt.data |
156 | - imagedata, dicom = self.OpenDicomGroup(group, gui=False) | 157 | + imagedata, dicom = self.OpenDicomGroup(group, gui=True) |
157 | self.CreateDicomProject(imagedata, dicom) | 158 | self.CreateDicomProject(imagedata, dicom) |
158 | self.LoadProject() | 159 | self.LoadProject() |
159 | 160 |
invesalius/data/imagedata_utils.py
1 | import math | 1 | import math |
2 | import vtk | 2 | import vtk |
3 | import vtkgdcm | 3 | import vtkgdcm |
4 | +import wx.lib.pubsub as ps | ||
4 | 5 | ||
5 | import constants as const | 6 | import constants as const |
7 | +from data import vtk_utils | ||
8 | + | ||
6 | 9 | ||
7 | # TODO: Test cases which are originally in sagittal/coronal orientation | 10 | # TODO: Test cases which are originally in sagittal/coronal orientation |
8 | # and have gantry | 11 | # and have gantry |
@@ -27,7 +30,8 @@ def ResampleImage3D(imagedata, value): | @@ -27,7 +30,8 @@ def ResampleImage3D(imagedata, value): | ||
27 | 30 | ||
28 | return resample.GetOutput() | 31 | return resample.GetOutput() |
29 | 32 | ||
30 | -def ResampleImage2D(imagedata, xy_dimension): | 33 | +def ResampleImage2D(imagedata, xy_dimension, |
34 | + update_progress = None): | ||
31 | """ | 35 | """ |
32 | Resample vtkImageData matrix. | 36 | Resample vtkImageData matrix. |
33 | """ | 37 | """ |
@@ -56,6 +60,10 @@ def ResampleImage2D(imagedata, xy_dimension): | @@ -56,6 +60,10 @@ def ResampleImage2D(imagedata, xy_dimension): | ||
56 | resample.SetAxisMagnificationFactor(0, factor) | 60 | resample.SetAxisMagnificationFactor(0, factor) |
57 | resample.SetAxisMagnificationFactor(1, factor) | 61 | resample.SetAxisMagnificationFactor(1, factor) |
58 | resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2]) | 62 | resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2]) |
63 | + if (update_progress): | ||
64 | + message = "Generating multiplanar visualization..." | ||
65 | + resample.AddObserver("ProgressEvent", lambda obj, | ||
66 | + evt:update_progress(resample,message)) | ||
59 | resample.Update() | 67 | resample.Update() |
60 | 68 | ||
61 | 69 | ||
@@ -167,14 +175,18 @@ def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): | @@ -167,14 +175,18 @@ def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): | ||
167 | return voi.GetOutput() | 175 | return voi.GetOutput() |
168 | 176 | ||
169 | def CreateImageData(filelist, zspacing): | 177 | def CreateImageData(filelist, zspacing): |
170 | - | 178 | + message = "Generating multiplanar visualization..." |
171 | if not(const.REDUCE_IMAGEDATA_QUALITY): | 179 | if not(const.REDUCE_IMAGEDATA_QUALITY): |
180 | + update_progress= vtk_utils.ShowProgress(1) | ||
181 | + | ||
172 | array = vtk.vtkStringArray() | 182 | array = vtk.vtkStringArray() |
173 | for x in xrange(len(filelist)): | 183 | for x in xrange(len(filelist)): |
174 | array.InsertValue(x,filelist[x]) | 184 | array.InsertValue(x,filelist[x]) |
175 | - | 185 | + |
176 | reader = vtkgdcm.vtkGDCMImageReader() | 186 | reader = vtkgdcm.vtkGDCMImageReader() |
177 | reader.SetFileNames(array) | 187 | reader.SetFileNames(array) |
188 | + reader.AddObserver("ProgressEvent", lambda obj,evt: | ||
189 | + update_progress(reader,message)) | ||
178 | reader.Update() | 190 | reader.Update() |
179 | 191 | ||
180 | # The zpacing is a DicomGroup property, so we need to set it | 192 | # The zpacing is a DicomGroup property, so we need to set it |
@@ -183,6 +195,9 @@ def CreateImageData(filelist, zspacing): | @@ -183,6 +195,9 @@ def CreateImageData(filelist, zspacing): | ||
183 | spacing = imagedata.GetSpacing() | 195 | spacing = imagedata.GetSpacing() |
184 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | 196 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) |
185 | else: | 197 | else: |
198 | + update_progress= vtk_utils.ShowProgress(2*len(filelist), | ||
199 | + dialog_type = "ProgressDialog") | ||
200 | + | ||
186 | # Reformat each slice and future append them | 201 | # Reformat each slice and future append them |
187 | appender = vtk.vtkImageAppend() | 202 | appender = vtk.vtkImageAppend() |
188 | appender.SetAppendAxis(2) #Define Stack in Z | 203 | appender.SetAppendAxis(2) #Define Stack in Z |
@@ -194,13 +209,16 @@ def CreateImageData(filelist, zspacing): | @@ -194,13 +209,16 @@ def CreateImageData(filelist, zspacing): | ||
194 | # If the resolution of the matrix is too large | 209 | # If the resolution of the matrix is too large |
195 | reader = vtkgdcm.vtkGDCMImageReader() | 210 | reader = vtkgdcm.vtkGDCMImageReader() |
196 | reader.SetFileName(filelist[x]) | 211 | reader.SetFileName(filelist[x]) |
212 | + reader.AddObserver("ProgressEvent", lambda obj,evt: | ||
213 | + update_progress(reader,message)) | ||
197 | reader.Update() | 214 | reader.Update() |
198 | 215 | ||
199 | #Resample image in x,y dimension | 216 | #Resample image in x,y dimension |
200 | - slice_imagedata = ResampleImage2D(reader.GetOutput(), 256) | 217 | + slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) |
201 | 218 | ||
202 | #Stack images in Z axes | 219 | #Stack images in Z axes |
203 | appender.AddInput(slice_imagedata) | 220 | appender.AddInput(slice_imagedata) |
221 | + #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) | ||
204 | appender.Update() | 222 | appender.Update() |
205 | 223 | ||
206 | # The zpacing is a DicomGroup property, so we need to set it | 224 | # The zpacing is a DicomGroup property, so we need to set it |
@@ -210,7 +228,78 @@ def CreateImageData(filelist, zspacing): | @@ -210,7 +228,78 @@ def CreateImageData(filelist, zspacing): | ||
210 | 228 | ||
211 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | 229 | imagedata.SetSpacing(spacing[0], spacing[1], zspacing) |
212 | 230 | ||
231 | + imagedata.AddObserver("ProgressEvent", lambda obj,evt: | ||
232 | + update_progress(imagedata,message)) | ||
213 | imagedata.Update() | 233 | imagedata.Update() |
234 | + | ||
214 | return imagedata | 235 | return imagedata |
215 | 236 | ||
216 | 237 | ||
238 | +class ImageCreator: | ||
239 | + def __init__(self): | ||
240 | + ps.Publisher().sendMessage("Cancel imagedata load", self.CancelImageDataLoad) | ||
241 | + | ||
242 | + def CancelImageDataLoad(self, evt_pusub): | ||
243 | + self.running = evt_pusub.data | ||
244 | + | ||
245 | + def CreateImageData(filelist, zspacing): | ||
246 | + message = "Generating multiplanar visualization..." | ||
247 | + if not(const.REDUCE_IMAGEDATA_QUALITY): | ||
248 | + update_progress= vtk_utils.ShowProgress(1) | ||
249 | + | ||
250 | + array = vtk.vtkStringArray() | ||
251 | + for x in xrange(len(filelist)): | ||
252 | + array.InsertValue(x,filelist[x]) | ||
253 | + | ||
254 | + reader = vtkgdcm.vtkGDCMImageReader() | ||
255 | + reader.SetFileNames(array) | ||
256 | + reader.AddObserver("ProgressEvent", lambda obj,evt: | ||
257 | + update_progress(reader,message)) | ||
258 | + reader.Update() | ||
259 | + | ||
260 | + # The zpacing is a DicomGroup property, so we need to set it | ||
261 | + imagedata = vtk.vtkImageData() | ||
262 | + imagedata.DeepCopy(reader.GetOutput()) | ||
263 | + spacing = imagedata.GetSpacing() | ||
264 | + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | ||
265 | + else: | ||
266 | + update_progress= vtk_utils.ShowProgress(2*len(filelist), | ||
267 | + dialog_type = "ProgressDialog") | ||
268 | + | ||
269 | + # Reformat each slice and future append them | ||
270 | + appender = vtk.vtkImageAppend() | ||
271 | + appender.SetAppendAxis(2) #Define Stack in Z | ||
272 | + | ||
273 | + # Reformat each slice | ||
274 | + for x in xrange(len(filelist)): | ||
275 | + # TODO: We need to check this automatically according | ||
276 | + # to each computer's architecture | ||
277 | + # If the resolution of the matrix is too large | ||
278 | + reader = vtkgdcm.vtkGDCMImageReader() | ||
279 | + reader.SetFileName(filelist[x]) | ||
280 | + reader.AddObserver("ProgressEvent", lambda obj,evt: | ||
281 | + update_progress(reader,message)) | ||
282 | + reader.Update() | ||
283 | + | ||
284 | + #Resample image in x,y dimension | ||
285 | + slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) | ||
286 | + | ||
287 | + #Stack images in Z axes | ||
288 | + appender.AddInput(slice_imagedata) | ||
289 | + #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) | ||
290 | + appender.Update() | ||
291 | + | ||
292 | + # The zpacing is a DicomGroup property, so we need to set it | ||
293 | + imagedata = vtk.vtkImageData() | ||
294 | + imagedata.DeepCopy(appender.GetOutput()) | ||
295 | + spacing = imagedata.GetSpacing() | ||
296 | + | ||
297 | + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) | ||
298 | + | ||
299 | + imagedata.AddObserver("ProgressEvent", lambda obj,evt: | ||
300 | + update_progress(imagedata,message)) | ||
301 | + imagedata.Update() | ||
302 | + | ||
303 | + return imagedata | ||
304 | + | ||
305 | + |
invesalius/data/vtk_utils.py
1 | import wx.lib.pubsub as ps | 1 | import wx.lib.pubsub as ps |
2 | import vtk | 2 | import vtk |
3 | 3 | ||
4 | + | ||
4 | import constants as const | 5 | import constants as const |
6 | +from gui.dialogs import ProgressDialog | ||
5 | 7 | ||
6 | # If you are frightened by the code bellow, or think it must have been result of | 8 | # If you are frightened by the code bellow, or think it must have been result of |
7 | # an identation error, lookup at: | 9 | # an identation error, lookup at: |
@@ -13,7 +15,8 @@ import constants as const | @@ -13,7 +15,8 @@ import constants as const | ||
13 | # http://www.ibm.com/developerworks/library/l-prog2.html | 15 | # http://www.ibm.com/developerworks/library/l-prog2.html |
14 | # http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html | 16 | # http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html |
15 | 17 | ||
16 | -def ShowProgress(number_of_filters = 1): | 18 | +def ShowProgress(number_of_filters = 1, |
19 | + dialog_type="GaugeProgress"): | ||
17 | """ | 20 | """ |
18 | To use this closure, do something like this: | 21 | To use this closure, do something like this: |
19 | UpdateProgress = ShowProgress(NUM_FILTERS) | 22 | UpdateProgress = ShowProgress(NUM_FILTERS) |
@@ -21,10 +24,13 @@ def ShowProgress(number_of_filters = 1): | @@ -21,10 +24,13 @@ def ShowProgress(number_of_filters = 1): | ||
21 | """ | 24 | """ |
22 | progress = [0] | 25 | progress = [0] |
23 | last_obj_progress = [0] | 26 | last_obj_progress = [0] |
27 | + if (dialog_type == "ProgressDialog"): | ||
28 | + dlg = ProgressDialog(100) | ||
29 | + | ||
24 | 30 | ||
25 | # when the pipeline is larger than 1, we have to consider this object | 31 | # when the pipeline is larger than 1, we have to consider this object |
26 | # percentage | 32 | # percentage |
27 | - ratio = 100.0 / number_of_filters | 33 | + ratio = (100.0 / number_of_filters) |
28 | 34 | ||
29 | def UpdateProgress(obj, label=""): | 35 | def UpdateProgress(obj, label=""): |
30 | """ | 36 | """ |
@@ -46,8 +52,16 @@ def ShowProgress(number_of_filters = 1): | @@ -46,8 +52,16 @@ def ShowProgress(number_of_filters = 1): | ||
46 | progress[0] = progress[0] + ratio*difference | 52 | progress[0] = progress[0] + ratio*difference |
47 | 53 | ||
48 | # Tell GUI to update progress status value | 54 | # Tell GUI to update progress status value |
49 | - ps.Publisher().sendMessage('Update status in GUI', | ||
50 | - (progress[0], label)) | 55 | + if (dialog_type == "GaugeProgress"): |
56 | + ps.Publisher().sendMessage('Update status in GUI', | ||
57 | + (progress[0], label)) | ||
58 | + else: | ||
59 | + if (int(progress[0]) == 99): | ||
60 | + progress[0] = 100 | ||
61 | + | ||
62 | + if not(dlg.Update(progress[0],label)): | ||
63 | + dlg.Close() | ||
64 | + | ||
51 | return progress[0] | 65 | return progress[0] |
52 | 66 | ||
53 | return UpdateProgress | 67 | return UpdateProgress |
invesalius/gui/dialogs.py
@@ -78,19 +78,18 @@ class ProgressDialog(object): | @@ -78,19 +78,18 @@ class ProgressDialog(object): | ||
78 | ) | 78 | ) |
79 | 79 | ||
80 | self.dlg.Bind(wx.EVT_BUTTON, self.Cancel) | 80 | self.dlg.Bind(wx.EVT_BUTTON, self.Cancel) |
81 | - self.dlg.SetSize(wx.Size(200,150)) | 81 | + self.dlg.SetSize(wx.Size(215,150)) |
82 | 82 | ||
83 | def Cancel(self, evt): | 83 | def Cancel(self, evt): |
84 | ps.Publisher().sendMessage("Cancel DICOM load") | 84 | ps.Publisher().sendMessage("Cancel DICOM load") |
85 | 85 | ||
86 | - def Update(self, value): | ||
87 | - message = "Loading file %d of %d"%(value,self.maximum) | ||
88 | - if(value != self.maximum): | 86 | + def Update(self, value, message): |
87 | + if(int(value) != self.maximum): | ||
89 | self.dlg.Update(value,message) | 88 | self.dlg.Update(value,message) |
90 | return True | 89 | return True |
91 | else: | 90 | else: |
92 | return False | 91 | return False |
93 | - | 92 | + |
94 | def Close(self): | 93 | def Close(self): |
95 | self.dlg.Destroy() | 94 | self.dlg.Destroy() |
96 | 95 |
invesalius/gui/frame.py
@@ -308,6 +308,10 @@ class StatusBar(wx.StatusBar): | @@ -308,6 +308,10 @@ class StatusBar(wx.StatusBar): | ||
308 | value, label = pubsub_evt.data | 308 | value, label = pubsub_evt.data |
309 | self.progress_bar.UpdateValue(value) | 309 | self.progress_bar.UpdateValue(value) |
310 | self.SetStatusText(label, 0) | 310 | self.SetStatusText(label, 0) |
311 | + if (int(value) >= 99): | ||
312 | + self.SetStatusText("",0) | ||
313 | + wx.Yield() | ||
314 | + | ||
311 | 315 | ||
312 | def UpdateStatusLabel(self, pubsub_evt): | 316 | def UpdateStatusLabel(self, pubsub_evt): |
313 | label = pubsub_evt.data | 317 | label = pubsub_evt.data |