Example #1
0
    def __init__(self, parent, overlayList, displayCtx, frame):
        """Create a ``Scene3dPanel``.

        :arg parent:      A :mod:`wx` parent object.
        :arg overlayList: A :class:`.OverlayList` instance.
        :arg displayCtx:  A :class:`.DisplayContext` instance.
        :arg frame:       The :class:`.FSLeyesFrame` instance.
        """

        sceneOpts = scene3dopts.Scene3DOpts(self)

        canvaspanel.CanvasPanel.__init__(self,
                                         parent,
                                         overlayList,
                                         displayCtx,
                                         frame,
                                         sceneOpts)


        # In 3D, the displaySpace must always be
        # set to world, regardless of the parent
        # DC value. This can be overridden manually
        # however (e.g. through the python shell)
        displayCtx.detachDisplaySpace()
        displayCtx.defaultDisplaySpace = 'world'
        displayCtx.displaySpace        = 'world'

        contentPanel = self.contentPanel

        self.__canvas = scene3dcanvas.WXGLScene3DCanvas(contentPanel,
                                                        overlayList,
                                                        displayCtx)

        opts = self.__canvas.opts

        opts.bindProps('pos',          displayCtx, 'location')
        opts.bindProps('showCursor',   sceneOpts)
        opts.bindProps('cursorColour', sceneOpts)
        opts.bindProps('bgColour',     sceneOpts)
        opts.bindProps('showLegend',   sceneOpts)
        opts.bindProps('legendColour', sceneOpts, 'fgColour')
        opts.bindProps('occlusion',    sceneOpts)
        opts.bindProps('light',        sceneOpts)
        opts.bindProps('lightPos',     sceneOpts)
        opts.bindProps('zoom',         sceneOpts)
        opts.bindProps('offset',       sceneOpts)
        opts.bindProps('rotation',     sceneOpts)
        opts.bindProps('highDpi',      sceneOpts)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.__canvas, flag=wx.EXPAND, proportion=1)
        contentPanel.SetSizer(sizer)

        self.centrePanelLayout()
        self.initProfile()
        self.syncLocation = True
Example #2
0
def makeDisplayContext(namespace):
    """Creates :class:`.OverlayList`, :class:`.DisplayContext``, and
    :class:`.SceneOpts` instances which represent the scene to be rendered,
    as described by the arguments in the given ``namespace`` object.
    """

    # Create an overlay list and display context.
    # The DisplayContext, Display and DisplayOpts
    # classes are designed to be created in a
    # parent-child hierarchy. So we need to create
    # a 'dummy' master display context to make
    # things work properly.
    overlayList = fsloverlay.OverlayList()
    masterDisplayCtx = displaycontext.DisplayContext(overlayList)
    childDisplayCtx = displaycontext.DisplayContext(overlayList,
                                                    parent=masterDisplayCtx)

    # We have to artificially create a ref to the
    # master display context, otherwise it may get
    # gc'd arbitrarily. The parent reference in the
    # child creation above is ultimately stored as
    # a weakref, so we need to create a real one.
    childDisplayCtx.masterDisplayCtx = masterDisplayCtx

    # The handleOverlayArgs function uses the
    # fsleyes.overlay.loadOverlays function,
    # which will call these functions as it
    # goes through the list of overlay to be
    # loaded.
    def load(ovl):
        log.info('Loading overlay {} ...'.format(ovl))

    def error(ovl, error):
        log.info('Error loading overlay {}: '.format(ovl, error))

    # Load the overlays specified on the command
    # line, and configure their display properties
    parseargs.applyOverlayArgs(namespace,
                               overlayList,
                               masterDisplayCtx,
                               loadFunc=load,
                               errorFunc=error)

    # Create a SceneOpts instance describing
    # the scene to be rendered. The parseargs
    # module assumes that GL canvases have
    # already been created, so we use mock
    # objects to trick it. The options applied
    # to these mock objects are applied to the
    # real canvases later on, in the render
    # function below.
    if namespace.scene == 'ortho':
        sceneOpts = orthoopts.OrthoOpts(MockCanvasPanel(3))
    elif namespace.scene == 'lightbox':
        sceneOpts = lightboxopts.LightBoxOpts(MockCanvasPanel(1))
    elif namespace.scene == '3d':
        sceneOpts = scene3dopts.Scene3DOpts(MockCanvasPanel(1))

    # 3D views default to
    # world display space
    if namespace.scene == '3d':
        childDisplayCtx.displaySpace = 'world'

    parseargs.applySceneArgs(namespace, overlayList, childDisplayCtx,
                             sceneOpts)

    # Centre the location. The DisplayContext
    # will typically centre its location on
    # initialisation, but this may not work
    # if any overlay arguments change the bounds
    # of an overlay (e.g. mesh reference image)
    if namespace.worldLoc is None and namespace.voxelLoc is None:
        b = childDisplayCtx.bounds
        childDisplayCtx.location = [
            b.xlo + 0.5 * b.xlen, b.ylo + 0.5 * b.ylen, b.zlo + 0.5 * b.zlen
        ]

    # This has to be applied after applySceneArgs,
    # in case the user used the '-std'/'-std1mm'
    # options.
    if namespace.selectedOverlay is not None:
        masterDisplayCtx.selectedOverlay = namespace.selectedOverlay

    if len(overlayList) == 0:
        raise RuntimeError('At least one overlay must be specified')

    return overlayList, childDisplayCtx, sceneOpts