Beispiel #1
0
    def canvasToWorld(self, xpos, ypos):
        """Transform the given x/y canvas coordinates into the display
        coordinate system.
        """

        b = self.__displayCtx.bounds
        width, height = self.GetSize()

        # The first step is to invert the mouse
        # coordinates w.r.t. the viewport.
        #
        # The canvas x axis corresponds to
        # (-xhalf, xhalf), and the canvas y
        # corresponds to (-yhalf, yhalf) -
        # see routines.show3D.
        xlen, ylen = glroutines.adjust(b.xlen, b.ylen, width, height)
        xhalf = 0.5 * xlen
        yhalf = 0.5 * ylen

        # Pixels to viewport coordinates
        xpos = xlen * (xpos / float(width)) - xhalf
        ypos = ylen * (ypos / float(height)) - yhalf

        # The second step is to transform from
        # viewport coords into model-view coords.
        # This is easy - transform by the inverse
        # MV matrix.
        #
        # z=-1 because the camera is offset by 1
        # on the depth axis (see __setViewport).
        pos = np.array([xpos, ypos, -1])
        xform = transform.invert(self.__viewMat)
        pos = transform.transform(pos, xform)

        return pos
Beispiel #2
0
    def __drawLegend(self):
        """Draws a legend in the bottom left corner of the screen, showing
        anatomical orientation.
        """

        copts = self.opts
        b = self.__displayCtx.bounds
        w, h = self.GetSize()
        xlen, ylen = glroutines.adjust(b.xlen, b.ylen, w, h)

        # A line for each axis
        vertices = np.zeros((6, 3), dtype=np.float32)
        vertices[0, :] = [-1, 0, 0]
        vertices[1, :] = [1, 0, 0]
        vertices[2, :] = [0, -1, 0]
        vertices[3, :] = [0, 1, 0]
        vertices[4, :] = [0, 0, -1]
        vertices[5, :] = [0, 0, 1]

        # Each axis line is scaled to
        # 60 pixels, and the legend is
        # offset from the bottom-left
        # corner by twice this amount.
        scale = [xlen * 30.0 / w] * 3
        offset = [
            -0.5 * xlen + 2.0 * scale[0], -0.5 * ylen + 2.0 * scale[1], 0
        ]

        # Apply the current camera
        # angle and rotation settings
        # to the legend vertices. Offset
        # anatomical labels off each
        # axis line by a small amount.
        rotation = transform.decompose(self.__viewMat)[2]
        xform = transform.compose(scale, offset, rotation)
        labelPoses = transform.transform(vertices * 1.2, xform)
        vertices = transform.transform(vertices, xform)

        # Draw the legend lines
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glColor3f(*copts.cursorColour[:3])
        gl.glLineWidth(2)
        gl.glBegin(gl.GL_LINES)
        gl.glVertex3f(*vertices[0])
        gl.glVertex3f(*vertices[1])
        gl.glVertex3f(*vertices[2])
        gl.glVertex3f(*vertices[3])
        gl.glVertex3f(*vertices[4])
        gl.glVertex3f(*vertices[5])
        gl.glEnd()

        # Figure out the anatomical
        # labels for each axis.
        overlay = self.__displayCtx.getSelectedOverlay()
        dopts = self.__displayCtx.getOpts(overlay)
        labels = dopts.getLabels()[0]

        # getLabels returns (xlo, ylo, zlo, xhi, yhi, zhi) -
        # - rearrange them to (xlo, xhi, ylo, yhi, zlo, zhi)
        labels = [
            labels[0], labels[3], labels[1], labels[4], labels[2], labels[5]
        ]

        canvas = np.array([w, h])
        view = np.array([xlen, ylen])

        # Draw each label
        for i in range(6):

            # Calculate pixel x/y
            # location for this label
            xx, xy = canvas * (labelPoses[i, :2] + 0.5 * view) / view

            # Calculate the size of the label
            # in pixels, so we can centre the
            # label
            tw, th = glroutines.text2D(labels[i], (xx, xy),
                                       10, (w, h),
                                       calcSize=True)

            # Draw the text
            xx -= 0.5 * tw
            xy -= 0.5 * th
            gl.glColor3f(*copts.legendColour[:3])
            glroutines.text2D(labels[i], (xx, xy), 10, (w, h))
Beispiel #3
0
    def __genViewMatrix(self, w, h):
        """Generate and return a transformation matrix to be used as the
        model-view matrix. This includes applying the current :attr:`zoom`,
        :attr:`rotation` and :attr:`offset` settings, and configuring
        the camera. This method is called by :meth:`__setViewport`.

        :arg w: Canvas width in pixels
        :arg h: Canvas height in pixels
        """

        opts = self.opts
        b = self.__displayCtx.bounds
        centre = [
            b.xlo + 0.5 * b.xlen, b.ylo + 0.5 * b.ylen, b.zlo + 0.5 * b.zlen
        ]

        # The MV matrix comprises (in this order):
        #
        #    - A rotation (the rotation property)
        #
        #    - Camera configuration. With no rotation, the
        #      camera will be looking towards the positive
        #      Y axis (i.e. +y is forwards), and oriented
        #      towards the positive Z axis (i.e. +z is up)
        #
        #    - A translation (the offset property)
        #    - A scaling (the zoom property)

        # Scaling and rotation matrices. Rotation
        # is always around the centre of the
        # displaycontext bounds (the bounding
        # box which contains all loaded overlays).
        scale = opts.zoom / 100.0
        scale = transform.scaleOffsetXform([scale] * 3, 0)
        rotate = transform.rotMatToAffine(opts.rotation, centre)

        # The offset property is defined in x/y
        # pixels, normalised to [-1, 1]. We need
        # to convert them into viewport space,
        # where the horizontal axis maps to
        # (-xhalf, xhalf), and the vertical axis
        # maps to (-yhalf, yhalf). See
        # gl.routines.ortho.
        offset = np.array(opts.offset[:] + [0])
        xlen, ylen = glroutines.adjust(b.xlen, b.ylen, w, h)
        offset[0] = xlen * offset[0] / 2
        offset[1] = ylen * offset[1] / 2
        offset = transform.scaleOffsetXform(1, offset)

        # And finally the camera.
        eye = list(centre)
        eye[1] += 1
        up = [0, 0, 1]
        camera = glroutines.lookAt(eye, centre, up)

        # Order is very important!
        xform = transform.concat(offset, scale, camera, rotate)
        np.array(xform, dtype=np.float32)

        self.__viewOffset = offset
        self.__viewScale = scale
        self.__viewRotate = rotate
        self.__viewCamera = camera
        self.__viewMat = xform
Beispiel #4
0
    def __drawLegend(self):
        """Draws a legend in the bottom left corner of the screen, showing
        anatomical orientation.
        """

        copts = self.opts
        b = self.__displayCtx.bounds
        w, h = self.GetSize()
        xlen, ylen = glroutines.adjust(b.xlen, b.ylen, w, h)

        # A line for each axis
        vertices = np.zeros((6, 3), dtype=np.float32)
        vertices[0, :] = [-1, 0, 0]
        vertices[1, :] = [1, 0, 0]
        vertices[2, :] = [0, -1, 0]
        vertices[3, :] = [0, 1, 0]
        vertices[4, :] = [0, 0, -1]
        vertices[5, :] = [0, 0, 1]

        # Each axis line is scaled to
        # 60 pixels, and the legend is
        # offset from the bottom-left
        # corner by twice this amount.
        scale = [xlen * 30.0 / w] * 3
        offset = [
            -0.5 * xlen + 2.0 * scale[0], -0.5 * ylen + 2.0 * scale[1], 0
        ]

        # Apply the current camera
        # angle and rotation settings
        # to the legend vertices. Offset
        # anatomical labels off each
        # axis line by a small amount.
        rotation = affine.decompose(self.__viewMat)[2]
        xform = affine.compose(scale, offset, rotation)
        labelPoses = affine.transform(vertices * 1.2, xform)
        vertices = affine.transform(vertices, xform)

        # Draw the legend lines
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glColor3f(*copts.cursorColour[:3])
        gl.glLineWidth(2)
        gl.glBegin(gl.GL_LINES)
        gl.glVertex3f(*vertices[0])
        gl.glVertex3f(*vertices[1])
        gl.glVertex3f(*vertices[2])
        gl.glVertex3f(*vertices[3])
        gl.glVertex3f(*vertices[4])
        gl.glVertex3f(*vertices[5])
        gl.glEnd()

        canvas = np.array([w, h])
        view = np.array([xlen, ylen])

        # Draw each label
        for i, label in enumerate(self.__legendLabels):

            # Calculate pixel x/y
            # location for this label
            xx, xy = canvas * (labelPoses[i, :2] + 0.5 * view) / view

            label.xpix = xx
            label.ypix = xy

            label.draw(w, h)