def makeDisplayContext(namespace, splash): """Creates the top-level *FSLeyes* :class:`.DisplayContext` and :class:`.OverlayList` . This function does the following: 1. Creates the :class:`.OverlayList` and the top level :class:`.DisplayContext`. 2. Loads and configures all of the overlays which were passed in on the command line. :arg namesace: Parsed command line arguments (see :func:`parseArgs`). :arg splash: The :class:`.FSLeyesSplash` frame, created in :func:`init`. :returns: a tuple containing: - the :class:`.OverlayList` - the master :class:`.DisplayContext` """ import fsleyes_widgets.utils.status as status import fsleyes.overlay as fsloverlay import fsleyes.parseargs as parseargs import fsleyes.displaycontext as displaycontext # Splash status update must be # performed on the main thread. def splashStatus(msg): wx.CallAfter(splash.SetStatus, msg) # Redirect status updates # to the splash frame status.setTarget(splashStatus) # Create the overlay list (only one of these # ever exists) and the master DisplayContext. # A new DisplayContext instance will be # created for every new view that is opened # in the FSLeyesFrame, but all child # DisplayContext instances will be linked to # this master one. overlayList = fsloverlay.OverlayList() displayCtx = displaycontext.DisplayContext(overlayList) log.debug('Created overlay list and master DisplayContext ({})'.format( id(displayCtx))) # Load the images - the splash screen status will # be updated with the currently loading overlay name. parseargs.applyMainArgs(namespace, overlayList, displayCtx) parseargs.applyOverlayArgs(namespace, overlayList, displayCtx) return overlayList, displayCtx
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.error('Error loading overlay {}: {}'.format(ovl, error)) raise error # Load the overlays specified on the command # line, and configure their display properties parseargs.applyMainArgs(namespace, overlayList, masterDisplayCtx) 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