Loading .dockerignore 0 → 100644 +3 −0 Original line number Diff line number Diff line .git* .python-version Dockerfile Dockerfile 0 → 100644 +30 −0 Original line number Diff line number Diff line FROM ubuntu:16.04 RUN apt-get update RUN apt-get install -y \ cython \ locales \ python-concurrent.futures \ python-gdcm \ python-matplotlib \ python-nibabel \ python-numpy \ python-pil \ python-psutil \ python-scipy \ python-serial \ python-skimage \ python-vtk6 \ python-vtkgdcm \ python-wxgtk3.0 RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 WORKDIR /usr/local/app COPY . . RUN python setup.py build_ext --inplace app.py 100755 → 100644 +203 −38 Original line number Diff line number Diff line Loading @@ -18,31 +18,42 @@ # detalhes. #------------------------------------------------------------------------- from __future__ import print_function import multiprocessing import optparse as op import os import sys import shutil import traceback import re if sys.platform == 'win32': import _winreg else: if sys.platform != 'darwin': import wxversion #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) #wxversion.select('2.8-unicode', optionsRequired=True) wxversion.ensureMinimal('3.0') try: import winreg except ImportError: import _winreg as winreg # else: # if sys.platform != 'darwin': # import wxversion # #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) # #wxversion.select('2.8-unicode', optionsRequired=True) # # wxversion.ensureMinimal('4.0') import wx try: from wx.adv import SplashScreen except ImportError: from wx import SplashScreen #from wx.lib.pubsub import setupv1 #new wx from wx.lib.pubsub import setuparg1# as psv1 # from wx.lib.pubsub import setuparg1# as psv1 #from wx.lib.pubsub import Publisher #import wx.lib.pubsub as ps from wx.lib.pubsub import pub as Publisher #import wx.lib.agw.advancedsplash as agw #if sys.platform == 'linux2': #if sys.platform.startswith('linux'): # _SplashScreen = agw.AdvancedSplash #else: # if sys.platform != 'darwin': Loading @@ -61,9 +72,9 @@ if sys.platform == 'win32': try: USER_DIR = expand_user() except: USER_DIR = os.path.expanduser('~').decode(FS_ENCODE) USER_DIR = utils.decode(os.path.expanduser('~'), FS_ENCODE) else: USER_DIR = os.path.expanduser('~').decode(FS_ENCODE) USER_DIR = utils.decode(os.path.expanduser('~'),FS_ENCODE) USER_INV_DIR = os.path.join(USER_DIR, u'.invesalius') USER_PRESET_DIR = os.path.join(USER_INV_DIR, u'presets') Loading @@ -72,6 +83,15 @@ USER_LOG_DIR = os.path.join(USER_INV_DIR, u'logs') # ------------------------------------------------------------------ if sys.platform in ('linux2', 'linux', 'win32'): try: tmp_var = wx.GetXDisplay except AttributeError: # A workaround to make InVesalius run with wxPython4 from Ubuntu 18.04 wx.GetXDisplay = lambda: None else: del tmp_var class InVesalius(wx.App): """ Loading @@ -86,7 +106,7 @@ class InVesalius(wx.App): freeze_support() self.SetAppName("InVesalius 3") self.splash = SplashScreen() self.splash = Inv3SplashScreen() self.splash.Show() wx.CallLater(1000,self.Startup2) Loading @@ -97,7 +117,7 @@ class InVesalius(wx.App): Open drag & drop files under darwin """ path = os.path.abspath(filename) Publisher.sendMessage('Open project', path) Publisher.sendMessage('Open project', filepath=path) def Startup2(self): self.control = self.splash.control Loading @@ -108,7 +128,7 @@ class InVesalius(wx.App): # ------------------------------------------------------------------ class SplashScreen(wx.SplashScreen): class Inv3SplashScreen(SplashScreen): """ Splash screen to be shown in InVesalius initialization. """ Loading Loading @@ -175,7 +195,10 @@ class SplashScreen(wx.SplashScreen): if lang: # print "LANG", lang, _, wx.Locale(), wx.GetLocale() import locale try: locale.setlocale(locale.LC_ALL, '') except locale.Error: pass # For pt_BR, splash_pt.png should be used if (lang.startswith('pt')): icon_file = "splash_pt.png" Loading @@ -196,8 +219,12 @@ class SplashScreen(wx.SplashScreen): bmp = wx.Image(path).ConvertToBitmap() try: style = wx.adv.SPLASH_TIMEOUT | wx.adv.SPLASH_CENTRE_ON_SCREEN except AttributeError: style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN wx.SplashScreen.__init__(self, SplashScreen.__init__(self, bitmap=bmp, splashStyle=style, milliseconds=1500, Loading @@ -218,7 +245,8 @@ class SplashScreen(wx.SplashScreen): self.control = Controller(self.main) self.fc = wx.FutureCall(1, self.ShowMain) wx.FutureCall(1, parse_comand_line) options, args = parse_comand_line() wx.FutureCall(1, use_cmd_optargs, options, args) # Check for updates from threading import Thread Loading @@ -244,6 +272,24 @@ class SplashScreen(wx.SplashScreen): if self.fc.IsRunning(): self.Raise() def non_gui_startup(options, args): lang = 'en' _ = i18n.InstallLanguage(lang) from invesalius.control import Controller from invesalius.project import Project session = ses.Session() if not session.ReadSession(): session.CreateItens() session.SetLanguage(lang) session.WriteSessionFile() control = Controller(None) use_cmd_optargs(options, args) # ------------------------------------------------------------------ Loading @@ -262,49 +308,168 @@ def parse_comand_line(): action="store_true", dest="debug") parser.add_option('--no-gui', action='store_true', dest='no_gui') # -i or --import: import DICOM directory # chooses largest series parser.add_option("-i", "--import", action="store", dest="dicom_dir") parser.add_option("--import-all", action="store") parser.add_option("-s", "--save", help="Save the project after an import.") parser.add_option("-t", "--threshold", help="Define the threshold for the export (e.g. 100-780).") parser.add_option("-e", "--export", help="Export to STL.") parser.add_option("-a", "--export-to-all", help="Export to STL for all mask presets.") options, args = parser.parse_args() return options, args def use_cmd_optargs(options, args): # If debug argument... if options.debug: Publisher.subscribe(print_events, Publisher.ALL_TOPICS) session = ses.Session() session.debug = 1 # If import DICOM argument... if options.dicom_dir: import_dir = options.dicom_dir Publisher.sendMessage('Import directory', import_dir) Publisher.sendMessage('Import directory', directory=import_dir, use_gui=not options.no_gui) if options.save: Publisher.sendMessage('Save project', filepath=os.path.abspath(options.save)) exit(0) check_for_export(options) return True elif options.import_all: import invesalius.reader.dicom_reader as dcm for patient in dcm.GetDicomGroups(options.import_all): for group in patient.GetGroups(): Publisher.sendMessage('Import group', group=group, use_gui=not options.no_gui) check_for_export(options, suffix=group.title, remove_surfaces=False) Publisher.sendMessage('Remove masks', mask_indexes=(0,)) return True # Check if there is a file path somewhere in what the user wrote # In case there is, try opening as it was a inv3 else: i = len(args) while i: i -= 1 file = args[i].decode(sys.stdin.encoding) for arg in reversed(args): file = utils.decode(arg, FS_ENCODE) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', path) i = 0 Publisher.sendMessage('Open project', filepath=path) check_for_export(options) return True file = utils.decode(arg, sys.stdin.encoding) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', filepath=path) check_for_export(options) return True return False def print_events(data): def sanitize(text): text = str(text).strip().replace(' ', '_') return re.sub(r'(?u)[^-\w.]', '', text) def check_for_export(options, suffix='', remove_surfaces=False): suffix = sanitize(suffix) if options.export: if not options.threshold: print("Need option --threshold when using --export.") exit(1) threshold_range = tuple([int(n) for n in options.threshold.split(',')]) if suffix: if options.export.endswith('.stl'): path_ = '{}-{}.stl'.format(options.export[:-4], suffix) else: path_ = '{}-{}.stl'.format(options.export, suffix) else: path_ = options.export export(path_, threshold_range, remove_surface=remove_surfaces) elif options.export_to_all: # noinspection PyBroadException try: from invesalius.project import Project for threshold_name, threshold_range in Project().presets.thresh_ct.iteritems(): if isinstance(threshold_range[0], int): path_ = u'{}-{}-{}.stl'.format(options.export_to_all, suffix, threshold_name) export(path_, threshold_range, remove_surface=True) except: traceback.print_exc() finally: exit(0) def export(path_, threshold_range, remove_surface=False): import invesalius.constants as const Publisher.sendMessage('Set threshold values', threshold_range=threshold_range) surface_options = { 'method': { 'algorithm': 'Default', 'options': {}, }, 'options': { 'index': 0, 'name': '', 'quality': _('Optimal *'), 'fill': False, 'keep_largest': False, 'overwrite': False, } } Publisher.sendMessage('Create surface from index', surface_parameters=surface_options) Publisher.sendMessage('Export surface to file', filename=path_, filetype=const.FILETYPE_STL) if remove_surface: Publisher.sendMessage('Remove surfaces', surface_indexes=(0,)) def print_events(topic=Publisher.AUTO_TOPIC, **msg_data): """ Print pubsub messages """ utils.debug(data.topic) utils.debug("%s\n\tParameters: %s" % (topic, msg_data)) def main(): """ Initialize InVesalius GUI """ options, args = parse_comand_line() if options.no_gui: non_gui_startup(options, args) else: application = InVesalius(0) application.MainLoop() Loading @@ -316,10 +481,10 @@ if __name__ == '__main__': if hasattr(sys,"frozen") and sys.platform.startswith('win'): #Click in the .inv3 file support root = _winreg.HKEY_CLASSES_ROOT root = winreg.HKEY_CLASSES_ROOT key = "InVesalius 3.1\InstallationDir" hKey = _winreg.OpenKey (root, key, 0, _winreg.KEY_READ) value, type_ = _winreg.QueryValueEx (hKey, "") hKey = winreg.OpenKey (root, key, 0, winreg.KEY_READ) value, type_ = winreg.QueryValueEx (hKey, "") path = os.path.join(value,'dist') os.chdir(path) Loading docs/devel/example_singleton_pubsub.py +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ p3 = Person("Andre ") people = [p1, p2, p3] print "Everyone eats 2 pieces:" for i in xrange(2): for i in range(2): for person in people: person.EatPieceOfPizza() Loading docs/user_guide_en.pdf −468 KiB (15.1 MiB) File changed.No diff preview for this file type. View original file View changed file Loading
.dockerignore 0 → 100644 +3 −0 Original line number Diff line number Diff line .git* .python-version Dockerfile
Dockerfile 0 → 100644 +30 −0 Original line number Diff line number Diff line FROM ubuntu:16.04 RUN apt-get update RUN apt-get install -y \ cython \ locales \ python-concurrent.futures \ python-gdcm \ python-matplotlib \ python-nibabel \ python-numpy \ python-pil \ python-psutil \ python-scipy \ python-serial \ python-skimage \ python-vtk6 \ python-vtkgdcm \ python-wxgtk3.0 RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 WORKDIR /usr/local/app COPY . . RUN python setup.py build_ext --inplace
app.py 100755 → 100644 +203 −38 Original line number Diff line number Diff line Loading @@ -18,31 +18,42 @@ # detalhes. #------------------------------------------------------------------------- from __future__ import print_function import multiprocessing import optparse as op import os import sys import shutil import traceback import re if sys.platform == 'win32': import _winreg else: if sys.platform != 'darwin': import wxversion #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) #wxversion.select('2.8-unicode', optionsRequired=True) wxversion.ensureMinimal('3.0') try: import winreg except ImportError: import _winreg as winreg # else: # if sys.platform != 'darwin': # import wxversion # #wxversion.ensureMinimal('2.8-unicode', optionsRequired=True) # #wxversion.select('2.8-unicode', optionsRequired=True) # # wxversion.ensureMinimal('4.0') import wx try: from wx.adv import SplashScreen except ImportError: from wx import SplashScreen #from wx.lib.pubsub import setupv1 #new wx from wx.lib.pubsub import setuparg1# as psv1 # from wx.lib.pubsub import setuparg1# as psv1 #from wx.lib.pubsub import Publisher #import wx.lib.pubsub as ps from wx.lib.pubsub import pub as Publisher #import wx.lib.agw.advancedsplash as agw #if sys.platform == 'linux2': #if sys.platform.startswith('linux'): # _SplashScreen = agw.AdvancedSplash #else: # if sys.platform != 'darwin': Loading @@ -61,9 +72,9 @@ if sys.platform == 'win32': try: USER_DIR = expand_user() except: USER_DIR = os.path.expanduser('~').decode(FS_ENCODE) USER_DIR = utils.decode(os.path.expanduser('~'), FS_ENCODE) else: USER_DIR = os.path.expanduser('~').decode(FS_ENCODE) USER_DIR = utils.decode(os.path.expanduser('~'),FS_ENCODE) USER_INV_DIR = os.path.join(USER_DIR, u'.invesalius') USER_PRESET_DIR = os.path.join(USER_INV_DIR, u'presets') Loading @@ -72,6 +83,15 @@ USER_LOG_DIR = os.path.join(USER_INV_DIR, u'logs') # ------------------------------------------------------------------ if sys.platform in ('linux2', 'linux', 'win32'): try: tmp_var = wx.GetXDisplay except AttributeError: # A workaround to make InVesalius run with wxPython4 from Ubuntu 18.04 wx.GetXDisplay = lambda: None else: del tmp_var class InVesalius(wx.App): """ Loading @@ -86,7 +106,7 @@ class InVesalius(wx.App): freeze_support() self.SetAppName("InVesalius 3") self.splash = SplashScreen() self.splash = Inv3SplashScreen() self.splash.Show() wx.CallLater(1000,self.Startup2) Loading @@ -97,7 +117,7 @@ class InVesalius(wx.App): Open drag & drop files under darwin """ path = os.path.abspath(filename) Publisher.sendMessage('Open project', path) Publisher.sendMessage('Open project', filepath=path) def Startup2(self): self.control = self.splash.control Loading @@ -108,7 +128,7 @@ class InVesalius(wx.App): # ------------------------------------------------------------------ class SplashScreen(wx.SplashScreen): class Inv3SplashScreen(SplashScreen): """ Splash screen to be shown in InVesalius initialization. """ Loading Loading @@ -175,7 +195,10 @@ class SplashScreen(wx.SplashScreen): if lang: # print "LANG", lang, _, wx.Locale(), wx.GetLocale() import locale try: locale.setlocale(locale.LC_ALL, '') except locale.Error: pass # For pt_BR, splash_pt.png should be used if (lang.startswith('pt')): icon_file = "splash_pt.png" Loading @@ -196,8 +219,12 @@ class SplashScreen(wx.SplashScreen): bmp = wx.Image(path).ConvertToBitmap() try: style = wx.adv.SPLASH_TIMEOUT | wx.adv.SPLASH_CENTRE_ON_SCREEN except AttributeError: style = wx.SPLASH_TIMEOUT | wx.SPLASH_CENTRE_ON_SCREEN wx.SplashScreen.__init__(self, SplashScreen.__init__(self, bitmap=bmp, splashStyle=style, milliseconds=1500, Loading @@ -218,7 +245,8 @@ class SplashScreen(wx.SplashScreen): self.control = Controller(self.main) self.fc = wx.FutureCall(1, self.ShowMain) wx.FutureCall(1, parse_comand_line) options, args = parse_comand_line() wx.FutureCall(1, use_cmd_optargs, options, args) # Check for updates from threading import Thread Loading @@ -244,6 +272,24 @@ class SplashScreen(wx.SplashScreen): if self.fc.IsRunning(): self.Raise() def non_gui_startup(options, args): lang = 'en' _ = i18n.InstallLanguage(lang) from invesalius.control import Controller from invesalius.project import Project session = ses.Session() if not session.ReadSession(): session.CreateItens() session.SetLanguage(lang) session.WriteSessionFile() control = Controller(None) use_cmd_optargs(options, args) # ------------------------------------------------------------------ Loading @@ -262,49 +308,168 @@ def parse_comand_line(): action="store_true", dest="debug") parser.add_option('--no-gui', action='store_true', dest='no_gui') # -i or --import: import DICOM directory # chooses largest series parser.add_option("-i", "--import", action="store", dest="dicom_dir") parser.add_option("--import-all", action="store") parser.add_option("-s", "--save", help="Save the project after an import.") parser.add_option("-t", "--threshold", help="Define the threshold for the export (e.g. 100-780).") parser.add_option("-e", "--export", help="Export to STL.") parser.add_option("-a", "--export-to-all", help="Export to STL for all mask presets.") options, args = parser.parse_args() return options, args def use_cmd_optargs(options, args): # If debug argument... if options.debug: Publisher.subscribe(print_events, Publisher.ALL_TOPICS) session = ses.Session() session.debug = 1 # If import DICOM argument... if options.dicom_dir: import_dir = options.dicom_dir Publisher.sendMessage('Import directory', import_dir) Publisher.sendMessage('Import directory', directory=import_dir, use_gui=not options.no_gui) if options.save: Publisher.sendMessage('Save project', filepath=os.path.abspath(options.save)) exit(0) check_for_export(options) return True elif options.import_all: import invesalius.reader.dicom_reader as dcm for patient in dcm.GetDicomGroups(options.import_all): for group in patient.GetGroups(): Publisher.sendMessage('Import group', group=group, use_gui=not options.no_gui) check_for_export(options, suffix=group.title, remove_surfaces=False) Publisher.sendMessage('Remove masks', mask_indexes=(0,)) return True # Check if there is a file path somewhere in what the user wrote # In case there is, try opening as it was a inv3 else: i = len(args) while i: i -= 1 file = args[i].decode(sys.stdin.encoding) for arg in reversed(args): file = utils.decode(arg, FS_ENCODE) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', path) i = 0 Publisher.sendMessage('Open project', filepath=path) check_for_export(options) return True file = utils.decode(arg, sys.stdin.encoding) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', filepath=path) check_for_export(options) return True return False def print_events(data): def sanitize(text): text = str(text).strip().replace(' ', '_') return re.sub(r'(?u)[^-\w.]', '', text) def check_for_export(options, suffix='', remove_surfaces=False): suffix = sanitize(suffix) if options.export: if not options.threshold: print("Need option --threshold when using --export.") exit(1) threshold_range = tuple([int(n) for n in options.threshold.split(',')]) if suffix: if options.export.endswith('.stl'): path_ = '{}-{}.stl'.format(options.export[:-4], suffix) else: path_ = '{}-{}.stl'.format(options.export, suffix) else: path_ = options.export export(path_, threshold_range, remove_surface=remove_surfaces) elif options.export_to_all: # noinspection PyBroadException try: from invesalius.project import Project for threshold_name, threshold_range in Project().presets.thresh_ct.iteritems(): if isinstance(threshold_range[0], int): path_ = u'{}-{}-{}.stl'.format(options.export_to_all, suffix, threshold_name) export(path_, threshold_range, remove_surface=True) except: traceback.print_exc() finally: exit(0) def export(path_, threshold_range, remove_surface=False): import invesalius.constants as const Publisher.sendMessage('Set threshold values', threshold_range=threshold_range) surface_options = { 'method': { 'algorithm': 'Default', 'options': {}, }, 'options': { 'index': 0, 'name': '', 'quality': _('Optimal *'), 'fill': False, 'keep_largest': False, 'overwrite': False, } } Publisher.sendMessage('Create surface from index', surface_parameters=surface_options) Publisher.sendMessage('Export surface to file', filename=path_, filetype=const.FILETYPE_STL) if remove_surface: Publisher.sendMessage('Remove surfaces', surface_indexes=(0,)) def print_events(topic=Publisher.AUTO_TOPIC, **msg_data): """ Print pubsub messages """ utils.debug(data.topic) utils.debug("%s\n\tParameters: %s" % (topic, msg_data)) def main(): """ Initialize InVesalius GUI """ options, args = parse_comand_line() if options.no_gui: non_gui_startup(options, args) else: application = InVesalius(0) application.MainLoop() Loading @@ -316,10 +481,10 @@ if __name__ == '__main__': if hasattr(sys,"frozen") and sys.platform.startswith('win'): #Click in the .inv3 file support root = _winreg.HKEY_CLASSES_ROOT root = winreg.HKEY_CLASSES_ROOT key = "InVesalius 3.1\InstallationDir" hKey = _winreg.OpenKey (root, key, 0, _winreg.KEY_READ) value, type_ = _winreg.QueryValueEx (hKey, "") hKey = winreg.OpenKey (root, key, 0, winreg.KEY_READ) value, type_ = winreg.QueryValueEx (hKey, "") path = os.path.join(value,'dist') os.chdir(path) Loading
docs/devel/example_singleton_pubsub.py +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ p3 = Person("Andre ") people = [p1, p2, p3] print "Everyone eats 2 pieces:" for i in xrange(2): for i in range(2): for person in people: person.EatPieceOfPizza() Loading
docs/user_guide_en.pdf −468 KiB (15.1 MiB) File changed.No diff preview for this file type. View original file View changed file