diff --git a/invesalius/control.py b/invesalius/control.py index a6cfa63..3bc5608 100755 --- a/invesalius/control.py +++ b/invesalius/control.py @@ -51,8 +51,9 @@ class Controller(): #self.frame.Bind(reader.evt_end_load_file, self.LoadPanel) def Progress(self, evt): - print evt data = evt.data + if (data): + message = "Loading file %d of %d"%(data[0],data[1]) if (data): if not(self.progress_dialog): @@ -60,7 +61,7 @@ class Controller(): maximum = data[1]) else: print data[0] - if not(self.progress_dialog.Update(data[0])): + if not(self.progress_dialog.Update(data[0],message)): self.progress_dialog.Close() self.progress_dialog = None else: @@ -153,7 +154,7 @@ class Controller(): def OnOpenDicomGroup(self, pubsub_evt): group = pubsub_evt.data - imagedata, dicom = self.OpenDicomGroup(group, gui=False) + imagedata, dicom = self.OpenDicomGroup(group, gui=True) self.CreateDicomProject(imagedata, dicom) self.LoadProject() diff --git a/invesalius/data/imagedata_utils.py b/invesalius/data/imagedata_utils.py index 0a3038a..4e65783 100644 --- a/invesalius/data/imagedata_utils.py +++ b/invesalius/data/imagedata_utils.py @@ -1,8 +1,11 @@ import math import vtk import vtkgdcm +import wx.lib.pubsub as ps import constants as const +from data import vtk_utils + # TODO: Test cases which are originally in sagittal/coronal orientation # and have gantry @@ -27,7 +30,8 @@ def ResampleImage3D(imagedata, value): return resample.GetOutput() -def ResampleImage2D(imagedata, xy_dimension): +def ResampleImage2D(imagedata, xy_dimension, + update_progress = None): """ Resample vtkImageData matrix. """ @@ -56,6 +60,10 @@ def ResampleImage2D(imagedata, xy_dimension): resample.SetAxisMagnificationFactor(0, factor) resample.SetAxisMagnificationFactor(1, factor) resample.SetOutputSpacing(spacing[0] * factor, spacing[1] * factor, spacing[2]) + if (update_progress): + message = "Generating multiplanar visualization..." + resample.AddObserver("ProgressEvent", lambda obj, + evt:update_progress(resample,message)) resample.Update() @@ -167,14 +175,18 @@ def ExtractVOI(imagedata,xi,xf,yi,yf,zi,zf): return voi.GetOutput() def CreateImageData(filelist, zspacing): - + message = "Generating multiplanar visualization..." if not(const.REDUCE_IMAGEDATA_QUALITY): + update_progress= vtk_utils.ShowProgress(1) + array = vtk.vtkStringArray() for x in xrange(len(filelist)): array.InsertValue(x,filelist[x]) - + reader = vtkgdcm.vtkGDCMImageReader() reader.SetFileNames(array) + reader.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(reader,message)) reader.Update() # The zpacing is a DicomGroup property, so we need to set it @@ -183,6 +195,9 @@ def CreateImageData(filelist, zspacing): spacing = imagedata.GetSpacing() imagedata.SetSpacing(spacing[0], spacing[1], zspacing) else: + update_progress= vtk_utils.ShowProgress(2*len(filelist), + dialog_type = "ProgressDialog") + # Reformat each slice and future append them appender = vtk.vtkImageAppend() appender.SetAppendAxis(2) #Define Stack in Z @@ -194,13 +209,16 @@ def CreateImageData(filelist, zspacing): # If the resolution of the matrix is too large reader = vtkgdcm.vtkGDCMImageReader() reader.SetFileName(filelist[x]) + reader.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(reader,message)) reader.Update() #Resample image in x,y dimension - slice_imagedata = ResampleImage2D(reader.GetOutput(), 256) + slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) #Stack images in Z axes appender.AddInput(slice_imagedata) + #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) appender.Update() # The zpacing is a DicomGroup property, so we need to set it @@ -210,7 +228,78 @@ def CreateImageData(filelist, zspacing): imagedata.SetSpacing(spacing[0], spacing[1], zspacing) + imagedata.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(imagedata,message)) imagedata.Update() + return imagedata +class ImageCreator: + def __init__(self): + ps.Publisher().sendMessage("Cancel imagedata load", self.CancelImageDataLoad) + + def CancelImageDataLoad(self, evt_pusub): + self.running = evt_pusub.data + + def CreateImageData(filelist, zspacing): + message = "Generating multiplanar visualization..." + if not(const.REDUCE_IMAGEDATA_QUALITY): + update_progress= vtk_utils.ShowProgress(1) + + array = vtk.vtkStringArray() + for x in xrange(len(filelist)): + array.InsertValue(x,filelist[x]) + + reader = vtkgdcm.vtkGDCMImageReader() + reader.SetFileNames(array) + reader.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(reader,message)) + reader.Update() + + # The zpacing is a DicomGroup property, so we need to set it + imagedata = vtk.vtkImageData() + imagedata.DeepCopy(reader.GetOutput()) + spacing = imagedata.GetSpacing() + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) + else: + update_progress= vtk_utils.ShowProgress(2*len(filelist), + dialog_type = "ProgressDialog") + + # Reformat each slice and future append them + appender = vtk.vtkImageAppend() + appender.SetAppendAxis(2) #Define Stack in Z + + # Reformat each slice + for x in xrange(len(filelist)): + # TODO: We need to check this automatically according + # to each computer's architecture + # If the resolution of the matrix is too large + reader = vtkgdcm.vtkGDCMImageReader() + reader.SetFileName(filelist[x]) + reader.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(reader,message)) + reader.Update() + + #Resample image in x,y dimension + slice_imagedata = ResampleImage2D(reader.GetOutput(), 256, update_progress) + + #Stack images in Z axes + appender.AddInput(slice_imagedata) + #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender)) + appender.Update() + + # The zpacing is a DicomGroup property, so we need to set it + imagedata = vtk.vtkImageData() + imagedata.DeepCopy(appender.GetOutput()) + spacing = imagedata.GetSpacing() + + imagedata.SetSpacing(spacing[0], spacing[1], zspacing) + + imagedata.AddObserver("ProgressEvent", lambda obj,evt: + update_progress(imagedata,message)) + imagedata.Update() + + return imagedata + + diff --git a/invesalius/data/vtk_utils.py b/invesalius/data/vtk_utils.py index cd66a24..2f67009 100644 --- a/invesalius/data/vtk_utils.py +++ b/invesalius/data/vtk_utils.py @@ -1,7 +1,9 @@ import wx.lib.pubsub as ps import vtk + import constants as const +from gui.dialogs import ProgressDialog # If you are frightened by the code bellow, or think it must have been result of # an identation error, lookup at: @@ -13,7 +15,8 @@ import constants as const # http://www.ibm.com/developerworks/library/l-prog2.html # http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html -def ShowProgress(number_of_filters = 1): +def ShowProgress(number_of_filters = 1, + dialog_type="GaugeProgress"): """ To use this closure, do something like this: UpdateProgress = ShowProgress(NUM_FILTERS) @@ -21,10 +24,13 @@ def ShowProgress(number_of_filters = 1): """ progress = [0] last_obj_progress = [0] + if (dialog_type == "ProgressDialog"): + dlg = ProgressDialog(100) + # when the pipeline is larger than 1, we have to consider this object # percentage - ratio = 100.0 / number_of_filters + ratio = (100.0 / number_of_filters) def UpdateProgress(obj, label=""): """ @@ -46,8 +52,16 @@ def ShowProgress(number_of_filters = 1): progress[0] = progress[0] + ratio*difference # Tell GUI to update progress status value - ps.Publisher().sendMessage('Update status in GUI', - (progress[0], label)) + if (dialog_type == "GaugeProgress"): + ps.Publisher().sendMessage('Update status in GUI', + (progress[0], label)) + else: + if (int(progress[0]) == 99): + progress[0] = 100 + + if not(dlg.Update(progress[0],label)): + dlg.Close() + return progress[0] return UpdateProgress diff --git a/invesalius/gui/dialogs.py b/invesalius/gui/dialogs.py index 4817f6e..6ab6215 100644 --- a/invesalius/gui/dialogs.py +++ b/invesalius/gui/dialogs.py @@ -78,19 +78,18 @@ class ProgressDialog(object): ) self.dlg.Bind(wx.EVT_BUTTON, self.Cancel) - self.dlg.SetSize(wx.Size(200,150)) + self.dlg.SetSize(wx.Size(215,150)) def Cancel(self, evt): ps.Publisher().sendMessage("Cancel DICOM load") - def Update(self, value): - message = "Loading file %d of %d"%(value,self.maximum) - if(value != self.maximum): + def Update(self, value, message): + if(int(value) != self.maximum): self.dlg.Update(value,message) return True else: return False - + def Close(self): self.dlg.Destroy() diff --git a/invesalius/gui/frame.py b/invesalius/gui/frame.py index 838ad69..82253cf 100755 --- a/invesalius/gui/frame.py +++ b/invesalius/gui/frame.py @@ -308,6 +308,10 @@ class StatusBar(wx.StatusBar): value, label = pubsub_evt.data self.progress_bar.UpdateValue(value) self.SetStatusText(label, 0) + if (int(value) >= 99): + self.SetStatusText("",0) + wx.Yield() + def UpdateStatusLabel(self, pubsub_evt): label = pubsub_evt.data -- libgit2 0.21.2