Exemple #1
0
    def refreshImageTexture(self):
        """Makes sure that the :class:`.ImageTexture`, used to store the
        :class:`.Image` data, is up to date.
        """

        opts = self.opts
        texName = '{}_{}'.format(type(self).__name__, id(self.image))
        unsynced = (opts.getParent() is None
                    or not opts.isSyncedToParent('volume'))

        if unsynced:
            texName = '{}_unsync_{}'.format(texName, id(opts))

        if self.imageTexture is not None:
            if self.imageTexture.name == texName:
                return

            self.imageTexture.deregister(self.name)
            glresources.delete(self.imageTexture.name)

        if opts.interpolation == 'none': interp = gl.GL_NEAREST
        else: interp = gl.GL_LINEAR

        self.imageTexture = glresources.get(texName,
                                            textures.ImageTexture,
                                            texName,
                                            self.image,
                                            interp=interp,
                                            volume=opts.index()[3:],
                                            notify=False)

        self.imageTexture.register(self.name, self.__imageTextureChanged)
    def refreshAuxTexture(self, which, **kwargs):
        """Create/re-create an auxillary :class:`.ImageTexture`.

        The previous ``ImageTexture`` (if one exists) is destroyed.  If no
        :class:`.Image` of type ``which`` is currently registered, a small
        dummy ``Image`` and ``ImageTexture`` is created.

        :arg which: Name of the auxillary image

        All other arguments are passed through to the
        :class:`.ImageTexture.__init__` method.
        """

        self.__destroyAuxTexture(which)

        image = self.__auximages[which]
        opts = self.__auxopts[which]
        tex = self.__auxtextures[which]

        if image is None:
            textureData = np.zeros((3, 3, 3), dtype=np.uint8)
            textureData[:] = 255
            image = fslimage.Image(textureData)
            norm = None
        else:
            norm = image.dataRange

        # by default we use a name which
        # is not coupled to the aux opts
        # instance, as the texture may be
        # sharable.
        texName = '{}_{}_{}_{}'.format(
            type(self).__name__, id(self.image), id(image), which)

        # check to see whether the aux
        # opts object is unsynced from
        # its parent - if so, we have to
        # create a dedicated texture
        if opts is not None:
            unsynced = (opts.getParent() is None
                        or not opts.isSyncedToParent('volume'))
            if unsynced:
                texName = '{}_unsync_{}'.format(texName, id(opts))

        if opts is not None: volume = opts.index()[3:]
        else: volume = 0

        tex = glresources.get(texName,
                              textures.ImageTexture,
                              texName,
                              image,
                              normaliseRange=norm,
                              volume=volume,
                              notify=False,
                              **kwargs)

        self.__auxtextures[which] = tex
Exemple #3
0
    def __init__(self,
                 annot,
                 selection,
                 displayToVoxMat,
                 voxToDisplayMat,
                 voxToTexMat,
                 offsets=None,
                 *args,
                 **kwargs):
        """Create a ``VoxelSelection`` annotation.

        :arg annot:           The :class:`Annotations` object that owns this
                              ``VoxelSelection``.

        :arg selection:       A :class:`.Selection` instance which defines
                              the voxels to be highlighted.

        :arg displayToVoxMat: A transformation matrix which transforms from
                              display space coordinates into voxel space
                              coordinates.

        :arg voxToDisplayMat: A transformation matrix which transforms from
                              voxel coordinates into display space
                              coordinates.

        :arg voxToTexMat:     Transformation matrix which transforms from
                              voxel coordinates to equivalent texture
                              coordinates.

        :arg offsets:         If ``None`` (the default), the ``selection``
                              must have the same shape as the image data
                              being annotated. Alternately, you may set
                              ``offsets`` to a sequence of three values,
                              which are used as offsets for the xyz voxel
                              values. This is to allow for a sub-space of
                              the full image space to be annotated.

        All other arguments are passed through to the
        :meth:`AnnotationObject.__init__` method.
        """

        AnnotationObject.__init__(self, annot, *args, **kwargs)

        if offsets is None:
            offsets = [0, 0, 0]

        self.selection = selection
        self.displayToVoxMat = displayToVoxMat
        self.voxToDisplayMat = voxToDisplayMat
        self.voxToTexMat = voxToTexMat
        self.offsets = offsets

        texName = '{}_{}'.format(type(self).__name__, id(selection))

        self.texture = glresources.get(texName, textures.SelectionTexture,
                                       texName, selection)
Exemple #4
0
    def __init__(self,
                 annot,
                 selection,
                 opts,
                 offsets=None,
                 *args,
                 **kwargs):
        """Create a ``VoxelSelection`` annotation.

        :arg annot:     The :class:`Annotations` object that owns this
                        ``VoxelSelection``.

        :arg selection: A :class:`.selection.Selection` instance which defines
                        the voxels to be highlighted.

        :arg opts:      A :class:`.NiftiOpts` instance which is used
                        for its voxel-to-display transformation matrices.

        :arg offsets:   If ``None`` (the default), the ``selection`` must have
                        the same shape as the image data being
                        annotated. Alternately, you may set ``offsets`` to a
                        sequence of three values, which are used as offsets
                        for the xyz voxel values. This is to allow for a
                        sub-space of the full image space to be annotated.

        All other arguments are passed through to the
        :meth:`AnnotationObject.__init__` method.
        """

        AnnotationObject.__init__(self, annot, *args, **kwargs)

        if offsets is None:
            offsets = [0, 0, 0]

        self.__selection = selection
        self.__opts      = opts
        self.__offsets   = offsets

        texName = '{}_{}'.format(type(self).__name__, id(selection))

        ndims = texdata.numTextureDims(selection.shape)

        if ndims == 2: ttype = textures.SelectionTexture2D
        else:          ttype = textures.SelectionTexture3D

        self.__texture = glresources.get(
            texName,
            ttype,
            texName,
            selection)
Exemple #5
0
def updateVertices(self):
    """Creates/refreshes the :class:`.GLLineVertices` instance which is used to
    generate line vertices and texture coordinates. If the ``GLLineVertices``
    instance exists and is up to date (see the
    :meth:`.GLLineVertices.calculateHash` method), this function does nothing.
    """

    if self.lineVertices is None:
        self.lineVertices = glresources.get(self._vertexResourceName,
                                            gllinevector.GLLineVertices, self)

    if hash(self.lineVertices) != self.lineVertices.calculateHash(self):

        log.debug('Re-generating line vertices '
                  'for {}'.format(self.vectorImage))

        self.lineVertices.refresh(self)
        glresources.set(self._vertexResourceName,
                        self.lineVertices,
                        overwrite=True)
Exemple #6
0
    def refreshImageTexture(self):
        """(Re-)creates an :class:`.ImageTexture` or :class:`.ImageTexture2D`
        to store the image data.
        """

        texName = '{}_{}'.format(type(self).__name__, id(self.image))
        nvals = self.overlay.nvals

        if self.opts.interpolation == 'none': interp = gl.GL_NEAREST
        else: interp = gl.GL_LINEAR

        if nvals == 1:
            nvals = self.overlay.shape[-1]

        self.imageTexture = glresources.get(texName,
                                            textures.createImageTexture,
                                            texName,
                                            self.overlay,
                                            nvals=nvals,
                                            interp=interp,
                                            notify=False)

        self.imageTexture.register(self.name, self.__imageTextureChanged)
Exemple #7
0
    def __init__(self, image, overlayList, displayCtx, canvas, threedee):
        """Create a ``GLTensor``. Prepares the eigenvalue and eigenvector
        textures, and calls the :func:`.gl21.gltensor_funcs.init` function.

        :arg image:       A :class:`.DTIFitTensor` or compatible :class:`.Image`
                          overlay.

        :arg overlayList: The :class:`.OverlayList`

        :arg displayCtx:  The :class:`.DisplayContext` managing the scene.

        :arg canvas:      The canvas doing the drawing.

        :arg threedee:    2D or 3D rendering.
        """

        prefilter = np.abs

        def prefilterRange(dmin, dmax):
            return max((0, dmin)), max((abs(dmin), abs(dmax)))

        # The overlay must either be a DTIFitTensor
        if isinstance(image, dtifit.DTIFitTensor):

            v1 = image.V1()
            v2 = image.V2()
            v3 = image.V3()
            l1 = image.L1()
            l2 = image.L2()
            l3 = image.L3()

        # Or an Image with 6 volumes containing
        # the unique tensor matrix elements
        else:
            decomp = dtifit.decomposeTensorMatrix(image.nibImage.get_data())
            v1 = fslimage.Image(decomp[0])
            v2 = fslimage.Image(decomp[1])
            v3 = fslimage.Image(decomp[2])
            l1 = fslimage.Image(decomp[3])
            l2 = fslimage.Image(decomp[4])
            l3 = fslimage.Image(decomp[5])

        self.v1 = v1
        self.v2 = v2
        self.v3 = v3
        self.l1 = l1
        self.l2 = l2
        self.l3 = l3

        # Create a texture for each eigenvalue/
        # vector, and add each of them as suitably
        # named attributes on this GLTensor
        # instance.

        def vPrefilter(d):
            return d.transpose((3, 0, 1, 2))

        names = ['v1', 'v2', 'v3', 'l1', 'l2', 'l3']
        imgs = [v1, v2, v3, l1, l2, l3]

        for name, img in zip(names, imgs):
            texName = '{}_{}_{}'.format(type(self).__name__, name, id(img))

            if name[0] == 'v':
                texPrefilter = vPrefilter
                nvals = 3
            else:
                texPrefilter = None
                nvals = 1

            tex = glresources.get(texName,
                                  textures.ImageTexture,
                                  texName,
                                  img,
                                  nvals=nvals,
                                  normaliseRange=img.dataRange,
                                  prefilter=texPrefilter)

            setattr(self, '{}Texture'.format(name), tex)

        glvector.GLVector.__init__(
            self,
            image,
            overlayList,
            displayCtx,
            canvas,
            threedee,
            prefilter=prefilter,
            prefilterRange=prefilterRange,
            vectorImage=v1,
            init=lambda: fslgl.gltensor_funcs.init(self))