Commit 4d99bc518a7b7d89df3c40f65ef19fc469a2c087

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent 320c4ae3
Exists in master

Give the user the option to compact or not when saving the file. When the file i…

…s not compacted the file is saved faster. Also, save the surface file only one time.

* Option to save compressed or not

* Improvements

* Saving only one time the surface

* Checking if surface file exists

* Incremented the format version to 1.1

* Showing an info dialog about user opening a inv3 file created by a newer invesalius format
invesalius/constants.py
@@ -26,6 +26,8 @@ import itertools @@ -26,6 +26,8 @@ import itertools
26 #from invesalius.project import Project 26 #from invesalius.project import Project
27 INVESALIUS_VERSION = "3.1.1" 27 INVESALIUS_VERSION = "3.1.1"
28 28
  29 +INVESALIUS_ACTUAL_FORMAT_VERSION = 1.1
  30 +
29 #--------------- 31 #---------------
30 32
31 # Measurements 33 # Measurements
invesalius/control.py
@@ -233,17 +233,19 @@ class Controller(): @@ -233,17 +233,19 @@ class Controller():
233 session = ses.Session() 233 session = ses.Session()
234 if saveas or session.temp_item: 234 if saveas or session.temp_item:
235 proj = prj.Project() 235 proj = prj.Project()
236 - filepath = dialog.ShowSaveAsProjectDialog(proj.name) 236 + filepath, compress = dialog.ShowSaveAsProjectDialog(proj.name)
237 if filepath: 237 if filepath:
238 #session.RemoveTemp() 238 #session.RemoveTemp()
239 session.OpenProject(filepath) 239 session.OpenProject(filepath)
240 else: 240 else:
241 return 241 return
242 else: 242 else:
  243 + proj = prj.Project()
  244 + compress = proj.compress
243 dirpath, filename = session.project_path 245 dirpath, filename = session.project_path
244 filepath = os.path.join(dirpath, filename) 246 filepath = os.path.join(dirpath, filename)
245 247
246 - self.SaveProject(filepath) 248 + self.SaveProject(filepath, compress)
247 249
248 250
249 def ShowDialogCloseProject(self): 251 def ShowDialogCloseProject(self):
@@ -335,7 +337,7 @@ class Controller(): @@ -335,7 +337,7 @@ class Controller():
335 path = pubsub_evt.data 337 path = pubsub_evt.data
336 self.SaveProject(path) 338 self.SaveProject(path)
337 339
338 - def SaveProject(self, path=None): 340 + def SaveProject(self, path=None, compress=False):
339 Publisher.sendMessage('Begin busy cursor') 341 Publisher.sendMessage('Begin busy cursor')
340 session = ses.Session() 342 session = ses.Session()
341 if path: 343 if path:
@@ -348,7 +350,7 @@ class Controller(): @@ -348,7 +350,7 @@ class Controller():
348 filename = filename.decode(const.FS_ENCODE) 350 filename = filename.decode(const.FS_ENCODE)
349 351
350 proj = prj.Project() 352 proj = prj.Project()
351 - prj.Project().SavePlistProject(dirpath, filename) 353 + prj.Project().SavePlistProject(dirpath, filename, compress)
352 354
353 session.SaveProject() 355 session.SaveProject()
354 Publisher.sendMessage('End busy cursor') 356 Publisher.sendMessage('End busy cursor')
invesalius/data/surface.py
@@ -74,11 +74,19 @@ class Surface(): @@ -74,11 +74,19 @@ class Surface():
74 else: 74 else:
75 self.name = name 75 self.name = name
76 76
  77 + self.filename = None
  78 +
77 def SavePlist(self, dir_temp, filelist): 79 def SavePlist(self, dir_temp, filelist):
78 - filename = u'surface_%d' % self.index  
79 - vtp_filename = filename + u'.vtp'  
80 - vtp_filepath = os.path.join(dir_temp, vtp_filename)  
81 - pu.Export(self.polydata, vtp_filepath, bin=True) 80 + if self.filename and os.path.exists(self.filename):
  81 + filename = u'surface_%d' % self.index
  82 + vtp_filename = filename + u'.vtp'
  83 + vtp_filepath = self.filename
  84 + else:
  85 + filename = u'surface_%d' % self.index
  86 + vtp_filename = filename + u'.vtp'
  87 + vtp_filepath = tempfile.mktemp()
  88 + pu.Export(self.polydata, vtp_filepath, bin=True)
  89 + self.filename = vtp_filepath
82 90
83 filelist[vtp_filepath] = vtp_filename 91 filelist[vtp_filepath] = vtp_filename
84 92
invesalius/gui/dialogs.py
@@ -221,6 +221,13 @@ class ProgressDialog(object): @@ -221,6 +221,13 @@ class ProgressDialog(object):
221 221
222 222
223 # --------- 223 # ---------
  224 +
  225 +INV_NON_COMPRESSED = 0
  226 +INV_COMPRESSED = 1
  227 +
  228 +WILDCARD_INV_SAVE = _("InVesalius project (*.inv3)|*.inv3") + "|" + \
  229 + _("InVesalius project compressed (*.inv3)|*.inv3")
  230 +
224 WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|" \ 231 WILDCARD_OPEN = "InVesalius 3 project (*.inv3)|*.inv3|" \
225 "All files (*.*)|*.*" 232 "All files (*.*)|*.*"
226 233
@@ -425,7 +432,7 @@ def ShowSaveAsProjectDialog(default_filename=None): @@ -425,7 +432,7 @@ def ShowSaveAsProjectDialog(default_filename=None):
425 _("Save project as..."), # title 432 _("Save project as..."), # title
426 "", # last used directory 433 "", # last used directory
427 default_filename, 434 default_filename,
428 - _("InVesalius project (*.inv3)|*.inv3"), 435 + WILDCARD_INV_SAVE,
429 wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) 436 wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
430 #dlg.SetFilterIndex(0) # default is VTI 437 #dlg.SetFilterIndex(0) # default is VTI
431 438
@@ -446,8 +453,9 @@ def ShowSaveAsProjectDialog(default_filename=None): @@ -446,8 +453,9 @@ def ShowSaveAsProjectDialog(default_filename=None):
446 if filename.split(".")[-1] != extension: 453 if filename.split(".")[-1] != extension:
447 filename = filename + "." + extension 454 filename = filename + "." + extension
448 455
  456 + wildcard = dlg.GetFilterIndex()
449 os.chdir(current_dir) 457 os.chdir(current_dir)
450 - return filename 458 + return filename, wildcard == INV_COMPRESSED
451 459
452 460
453 # Dialog for neuronavigation markers 461 # Dialog for neuronavigation markers
@@ -727,6 +735,15 @@ def ImportEmptyDirectory(dirpath): @@ -727,6 +735,15 @@ def ImportEmptyDirectory(dirpath):
727 dlg.Destroy() 735 dlg.Destroy()
728 736
729 737
  738 +def ImportOldFormatInvFile():
  739 + msg = _("File was created in a newer InVesalius version. Some functionalities may not work correctly.")
  740 + dlg = wx.MessageDialog(None, msg,
  741 + "InVesalius 3",
  742 + wx.ICON_INFORMATION | wx.OK)
  743 + dlg.ShowModal()
  744 + dlg.Destroy()
  745 +
  746 +
730 def ImportInvalidFiles(ftype="DICOM"): 747 def ImportInvalidFiles(ftype="DICOM"):
731 if ftype == "Bitmap": 748 if ftype == "Bitmap":
732 msg = _("There are no Bitmap, JPEG, PNG or TIFF files in the selected folder.") 749 msg = _("There are no Bitmap, JPEG, PNG or TIFF files in the selected folder.")
invesalius/project.py
@@ -71,6 +71,8 @@ class Project(object): @@ -71,6 +71,8 @@ class Project(object):
71 # TODO: Future ++ 71 # TODO: Future ++
72 self.annotation_dict = {} 72 self.annotation_dict = {}
73 73
  74 + self.compress = False
  75 +
74 # InVesalius related data 76 # InVesalius related data
75 # So we can find bugs and reproduce user-related problems 77 # So we can find bugs and reproduce user-related problems
76 self.invesalius_version = version.get_svn_revision() 78 self.invesalius_version = version.get_svn_revision()
@@ -202,17 +204,20 @@ class Project(object): @@ -202,17 +204,20 @@ class Project(object):
202 measures[str(m.index)] = item 204 measures[str(m.index)] = item
203 return measures 205 return measures
204 206
205 - def SavePlistProject(self, dir_, filename): 207 + def SavePlistProject(self, dir_, filename, compress=False):
206 dir_temp = tempfile.mkdtemp().decode(const.FS_ENCODE) 208 dir_temp = tempfile.mkdtemp().decode(const.FS_ENCODE)
207 209
  210 + self.compress = compress
  211 +
208 filename_tmp = os.path.join(dir_temp, u'matrix.dat') 212 filename_tmp = os.path.join(dir_temp, u'matrix.dat')
209 filelist = {} 213 filelist = {}
210 214
211 project = { 215 project = {
212 # Format info 216 # Format info
213 - "format_version": 1, 217 + "format_version": const.INVESALIUS_ACTUAL_FORMAT_VERSION,
214 "invesalius_version": const.INVESALIUS_VERSION, 218 "invesalius_version": const.INVESALIUS_VERSION,
215 "date": datetime.datetime.now().isoformat(), 219 "date": datetime.datetime.now().isoformat(),
  220 + "compress": self.compress,
216 221
217 # case info 222 # case info
218 "name": self.name, # patient's name 223 "name": self.name, # patient's name
@@ -267,7 +272,7 @@ class Project(object): @@ -267,7 +272,7 @@ class Project(object):
267 272
268 # Compressing and generating the .inv3 file 273 # Compressing and generating the .inv3 file
269 path = os.path.join(dir_,filename) 274 path = os.path.join(dir_,filename)
270 - Compress(dir_temp, path, filelist) 275 + Compress(dir_temp, path, filelist, compress)
271 276
272 # Removing the temp folder. 277 # Removing the temp folder.
273 shutil.rmtree(dir_temp) 278 shutil.rmtree(dir_temp)
@@ -295,6 +300,11 @@ class Project(object): @@ -295,6 +300,11 @@ class Project(object):
295 main_plist = os.path.join(dirpath ,'main.plist') 300 main_plist = os.path.join(dirpath ,'main.plist')
296 project = plistlib.readPlist(main_plist) 301 project = plistlib.readPlist(main_plist)
297 302
  303 + format_version = project["format_version"]
  304 + if format_version > const.INVESALIUS_ACTUAL_FORMAT_VERSION:
  305 + from invesalius.gui.dialogs import ImportOldFormatInvFile
  306 + ImportOldFormatInvFile()
  307 +
298 # case info 308 # case info
299 self.name = project["name"] 309 self.name = project["name"]
300 self.modality = project["modality"] 310 self.modality = project["modality"]
@@ -304,6 +314,8 @@ class Project(object): @@ -304,6 +314,8 @@ class Project(object):
304 self.threshold_range = project["scalar_range"] 314 self.threshold_range = project["scalar_range"]
305 self.spacing = project["spacing"] 315 self.spacing = project["spacing"]
306 316
  317 + self.compress = project.get("compress", True)
  318 +
307 # Opening the matrix containing the slices 319 # Opening the matrix containing the slices
308 filepath = os.path.join(dirpath, project["matrix"]["filename"]) 320 filepath = os.path.join(dirpath, project["matrix"]["filename"])
309 self.matrix_filename = filepath 321 self.matrix_filename = filepath
@@ -337,7 +349,7 @@ class Project(object): @@ -337,7 +349,7 @@ class Project(object):
337 measure.Load(measurements[index]) 349 measure.Load(measurements[index])
338 self.measurement_dict[int(index)] = measure 350 self.measurement_dict[int(index)] = measure
339 351
340 -def Compress(folder, filename, filelist): 352 +def Compress(folder, filename, filelist, compress=False):
341 tmpdir, tmpdir_ = os.path.split(folder) 353 tmpdir, tmpdir_ = os.path.split(folder)
342 current_dir = os.path.abspath(".") 354 current_dir = os.path.abspath(".")
343 temp_inv3 = tempfile.mktemp() 355 temp_inv3 = tempfile.mktemp()
@@ -348,7 +360,10 @@ def Compress(folder, filename, filelist): @@ -348,7 +360,10 @@ def Compress(folder, filename, filelist):
348 temp_inv3 = temp_inv3.decode(const.FS_ENCODE) 360 temp_inv3 = temp_inv3.decode(const.FS_ENCODE)
349 #os.chdir(tmpdir) 361 #os.chdir(tmpdir)
350 #file_list = glob.glob(os.path.join(tmpdir_,"*")) 362 #file_list = glob.glob(os.path.join(tmpdir_,"*"))
351 - tar = tarfile.open(temp_inv3, "w:gz") 363 + if compress:
  364 + tar = tarfile.open(temp_inv3, "w:gz")
  365 + else:
  366 + tar = tarfile.open(temp_inv3, "w")
352 for name in filelist: 367 for name in filelist:
353 tar.add(name, arcname=os.path.join(tmpdir_, filelist[name])) 368 tar.add(name, arcname=os.path.join(tmpdir_, filelist[name]))
354 tar.close() 369 tar.close()
@@ -361,7 +376,7 @@ def Extract(filename, folder): @@ -361,7 +376,7 @@ def Extract(filename, folder):
361 folder = win32api.GetShortPathName(folder) 376 folder = win32api.GetShortPathName(folder)
362 folder = folder.decode(const.FS_ENCODE) 377 folder = folder.decode(const.FS_ENCODE)
363 378
364 - tar = tarfile.open(filename, "r:gz") 379 + tar = tarfile.open(filename, "r")
365 idir = os.path.split(tar.getnames()[0])[0].decode('utf8') 380 idir = os.path.split(tar.getnames()[0])[0].decode('utf8')
366 os.mkdir(os.path.join(folder, idir)) 381 os.mkdir(os.path.join(folder, idir))
367 filelist = [] 382 filelist = []