Skip to content
Snippets Groups Projects
Commit 72017208 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

1. Tweaks to clip-image logic - linkLow/link/HighRange properties were

   being slightly mis-managed..
2. The first CanvasPanel has syncOverlayOrder set to true.
parent f38315e2
No related branches found
No related tags found
No related merge requests found
......@@ -533,6 +533,7 @@ properties = TypeDict({
'VolumeOpts.displayRange' : 'Display range',
'VolumeOpts.clippingRange' : 'Clipping range',
'VolumeOpts.clipImage' : 'Clip by',
'VolumeOpts.linkLowRanges' : 'Link low display/clipping ranges',
'VolumeOpts.linkHighRanges' : 'Link high display/clipping ranges',
'VolumeOpts.cmap' : 'Colour map',
......
......@@ -307,8 +307,12 @@ _DISPLAY_PROPS = td.TypeDict({
props.Widget('cmap'),
props.Widget('invert'),
props.Widget('invertClipping'),
props.Widget('linkLowRanges'),
props.Widget('linkHighRanges'),
props.Widget('linkLowRanges',
dependencies=['clipImage'],
enabledWhen=lambda vo, ci: ci is None),
props.Widget('linkHighRanges',
dependencies=['clipImage'],
enabledWhen=lambda vo, ci: ci is None),
props.Widget('displayRange',
showLimits=False,
slider=True,
......
......@@ -622,6 +622,14 @@ class VolumeOpts(Nifti1Opts):
self .addListener('displayRange',
self.name,
self.__displayRangeChanged)
# In fact, the interaction between many of the
# VolumeOpts properties really screws with
# the parent-child sync relationship, so I'm
# just completely avoiding it by only registering
# listeners on child instances. See note above
# about why this will probably break future
# usage.
self .addListener('useNegativeCmap',
self.name,
self.__useNegativeCmapChanged)
......@@ -739,6 +747,12 @@ class VolumeOpts(Nifti1Opts):
dataMin = opts.dataMin
dataMax = opts.dataMax
# If the clipping range is based on another
# image, it makes no sense to link the low/
# high display/clipping ranges, as they are
# probably different. So if a clip image is
# selected, we disable the link range
# properties.
if self.propertyIsEnabled('linkLowRanges'):
self.disableListener('linkLowRanges', self.name)
......@@ -749,9 +763,11 @@ class VolumeOpts(Nifti1Opts):
self.__linkLowRangesChanged()
self.__linkHighRangesChanged()
self.disableProperty('linkLowRanges')
self.disableProperty('linkHighRanges')
self.enableListener('linkLowRanges', self.name)
self.enableListener('linkHighRanges', self.name)
# Keep range values 0.01% apart.
dMinDistance = abs(dataMax - dataMin) / 10000.0
......
......@@ -215,9 +215,13 @@ class FSLEyesFrame(wx.Frame):
# CanvasPanels are unsynced; other
# ViewPanels (e.g. TimeSeriesPanel) remain
# synced by default.
if panelId > 1 and issubclass(panelCls, views.CanvasPanel):
if panelId == 1:
childDC.syncToParent('overlayOrder')
childDC.syncOverlayDisplay = True
elif issubclass(panelCls, views.CanvasPanel):
childDC.syncOverlayDisplay = False
panel = panelCls(
self,
self.__overlayList,
......
......@@ -159,6 +159,13 @@ class GLVolume(globject.GLImageObject):
# Create an image texture, clip texture, and a colour map texture
self.texName = '{}_{}'.format(type(self).__name__, id(self.image))
# References to the clip image and
# associated DisplayOpts instance,
# if it is set.
self.clipImage = None
self.clipOpts = None
# Refs to all of the texture objects.
self.imageTexture = None
self.clipTexture = None
self.colourTexture = textures.ColourMapTexture(self.texName)
......@@ -186,12 +193,13 @@ class GLVolume(globject.GLImageObject):
self.colourTexture .destroy()
self.negColourTexture.destroy()
self.imageTexture = None
self.clipTexture = None
self.colourTexture = None
self.negColourTexture = None
self.deregisterClipImage()
self.removeDisplayListeners()
fslgl.glvolume_funcs .destroy(self)
......@@ -241,11 +249,16 @@ class GLVolume(globject.GLImageObject):
self.imageTexture.set(volume=volume,
interp=interp,
resolution=resolution)
if self.clipTexture is not None:
self.clipTexture.set(interp=interp, resolution=resolution)
fslgl.glvolume_funcs.updateShaderState(self)
self.onUpdate()
def clipUpdate(*a):
self.deregisterClipImage()
self.registerClipImage()
self.refreshClipTexture()
fslgl.glvolume_funcs.updateShaderState(self)
self.onUpdate()
......@@ -358,14 +371,57 @@ class GLVolume(globject.GLImageObject):
self.image,
interp=interp)
def registerClipImage(self):
"""Called whenever the :attr:`.VolumeOpts.clipImage` property changes.
Adds property listeners to the :class:`.Nifti1Opts` instance
associated with the new clip image, if necessary.
"""
clipImage = self.displayOpts.clipImage
if clipImage is None:
return
clipOpts = self.displayOpts.displayCtx.getOpts(clipImage)
self.clipImage = clipImage
self.clipOpts = clipOpts
def updateClipTexture(*a):
self.clipTexture.set(volume=clipOpts.volume)
self.onUpdate()
clipOpts.addListener('volume',
self.name,
updateClipTexture,
weak=False)
def deregisterClipImage(self):
"""Called whenever the :attr:`.VolumeOpts.clipImage` property changes.
Removes property listeners from the :class:`.Nifti1Opts` instance
associated with the old clip image, if necessary.
"""
if self.clipImage is None:
return
self.clipOpts.removeListener('volume', self.name)
self.clipImage = None
self.clipOpts = None
def refreshClipTexture(self):
"""Refreshes the :class:`.ImageTexture` used to store the
"""Re-creates the :class:`.ImageTexture` used to store the
:attr:`.VolumeOpts.clipImage`.
"""
clipImage = self.clipImage
opts = self.displayOpts
clipImage = opts.clipImage
texName = '{}_{}'.format(type(self).__name__, id(clipImage))
clipOpts = self.clipOpts
texName = '{}_clip_{}'.format(type(self).__name__, id(clipImage))
if self.clipTexture is not None:
glresources.delete(self.clipTexture.getTextureName())
......@@ -373,16 +429,18 @@ class GLVolume(globject.GLImageObject):
if clipImage is None:
return
if opts.interpolation == 'none': interp = gl.GL_NEAREST
else: interp = gl.GL_LINEAR
else: interp = gl.GL_LINEAR
self.clipTexture = glresources.get(
texName,
textures.ImageTexture,
texName,
clipImage,
interp=interp)
interp=interp,
resolution=opts.resolution,
volume=clipOpts.volume)
def refreshColourTextures(self):
......
......@@ -53,7 +53,9 @@ class ImageTexture(texture.Texture):
nvals=1,
normalise=False,
prefilter=None,
interp=gl.GL_NEAREST):
interp=gl.GL_NEAREST,
resolution=None,
volume=None):
"""Create an ``ImageTexture``. A listener is added to the
:attr:`.Image.data` property, so that the texture data can be
refreshed whenever the image data changes - see the
......@@ -108,8 +110,8 @@ class ImageTexture(texture.Texture):
self.__imageDataChanged(False)
self.set(interp=interp,
prefilter=prefilter,
resolution=None,
volume=None,
resolution=resolution,
volume=volume,
normalise=normalise)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment