From fe2cd1f828461b1b83e6158b5f23f7e2802fc4d9 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauld.mccarthy@gmail.com> Date: Wed, 21 May 2014 17:02:35 +0100 Subject: [PATCH] lightboxpanel.py uses a bunch of SliceCanvas objects, and has rubbish performance. I'm about to start playing with a new idea, the LightBoxCanvas, which renders *all* slices onto a single canvas. What do you think? Why am i asking a git repository what it thinks? --- fsl/fslview/lightboxcanvas.py | 20 ++++++++++++++++ fsl/fslview/lightboxpanel.py | 44 ++++++++++++++++++++++++++--------- fsl/fslview/slicecanvas.py | 9 +++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 fsl/fslview/lightboxcanvas.py diff --git a/fsl/fslview/lightboxcanvas.py b/fsl/fslview/lightboxcanvas.py new file mode 100644 index 000000000..fd85cfb91 --- /dev/null +++ b/fsl/fslview/lightboxcanvas.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# lightboxcanvas.py - A wx.GLCanvas canvas whcih displays all slices from +# a collection of 3D images. +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# + +import fsl.fslview.slicecanvas as slicecanvas + + +class LightBoxCanvas(slicecanvas.SliceCanvas): + + # I think this will work ... + + def resize(self): + pass + + def draw(self, ev): + pass diff --git a/fsl/fslview/lightboxpanel.py b/fsl/fslview/lightboxpanel.py index 7ec54f15d..630c149c2 100644 --- a/fsl/fslview/lightboxpanel.py +++ b/fsl/fslview/lightboxpanel.py @@ -7,11 +7,12 @@ import wx -import numpy as np +import numpy as np -import fsl.props as props -import fsl.data.fslimage as fslimage -import fsl.fslview.slicecanvas as slicecanvas +import fsl.props as props +import fsl.data.fslimage as fslimage +import fsl.fslview.slicecanvas as slicecanvas +import fsl.fslview.imagelistpanel as imagelistpanel class LightBoxPanel(wx.ScrolledWindow, props.HasProperties): @@ -22,7 +23,6 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties): def __init__(self, parent, imageList): wx.ScrolledWindow.__init__(self, parent) - # wx.Panel.__init__(self, parent) if not isinstance(imageList, fslimage.ImageList): raise TypeError( @@ -32,6 +32,13 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties): self.canvases = [] self.imageList = imageList + def refresh(*a): + self._createCanvases() + + LightBoxPanel.sliceSpacing.addListener(self, 'refresh', refresh) + LightBoxPanel.sliceAxis .addListener(self, 'refresh', refresh) + + self._glContext = None self._createCanvases() @@ -40,7 +47,6 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties): if self.sizer is not None: self.sizer.Clear(True) - axis = int(self.sliceAxis) imgMin = self.imageList.minBounds[axis] imgMax = self.imageList.maxBounds[axis] @@ -50,15 +56,17 @@ class LightBoxPanel(wx.ScrolledWindow, props.HasProperties): self.sizer = wx.WrapSizer(wx.HORIZONTAL) self.canvases = [] + print '{} slices to be drawn'.format(len(slicePoss)) + for i, pos in enumerate(slicePoss): - if i == 0: ctx = None - else: ctx = self.canvases[0].context - canvas = slicecanvas.SliceCanvas(self, self.imageList, zax=axis, - context=ctx) + context=self._glContext) + + if self._glContext is None: self._glContext = canvas.context + canvas.zpos = pos canvas.SetMinSize((100, 100)) @@ -78,7 +86,21 @@ class LightBoxFrame(wx.Frame): def __init__(self, parent, imageList, title=None): wx.Frame.__init__(self, parent, title=title) - self.panel = LightBoxPanel(self, imageList) + + + + + self.mainPanel = LightBoxPanel( self, imageList) + self.propPanel = props.buildGUI(self, self.mainPanel) + self.listPanel = imagelistpanel.ImageListPanel(self, imageList) + + self.sizer = wx.BoxSizer(wx.VERTICAL) + + self.sizer.Add(self.propPanel, flag=wx.EXPAND) + self.sizer.Add(self.mainPanel, flag=wx.EXPAND, proportion=1) + self.sizer.Add(self.listPanel, flag=wx.EXPAND) + + self.SetSizer(self.sizer) self.Layout() diff --git a/fsl/fslview/slicecanvas.py b/fsl/fslview/slicecanvas.py index 84b7f8b41..9eba4a2f4 100644 --- a/fsl/fslview/slicecanvas.py +++ b/fsl/fslview/slicecanvas.py @@ -305,8 +305,17 @@ class SliceCanvas(wxgl.GLCanvas): # so we know when to refresh the canvas. for image in self.imageList: try: + + # TODO I could share GLImageData instances + # across different canvases which are + # displaying the image with the same axis + # orientation. Could store the GLImageData + # object with a geneic name, e.g. + # "GLImageData_0_1_2", where 0, 1, 2, are + # the screen x/y/z axes. glData = image.getAttribute(self.name) continue + except KeyError: pass -- GitLab