Source code for capture

"""Playblasting with independent viewport, camera and display options"""

version_info = (0, 1, 0)

__author__ = "Marcus Ottosson"
__version__ = "%s.%s.%s" % version_info
__license__ = "MIT"


import sys
import contextlib


[docs]def capture(camera=None, width=None, height=None, filename=None, start_frame=None, end_frame=None, format='qt', compression='h264', off_screen=False, viewer=True, isolate=None, maintain_aspect_ratio=True, camera_options=None, viewport_options=None): """Playblast in an independent panel Arguments: camera (str, optional): Name of camera, defaults to "persp" width (int, optional): Width of output in pixels height (int, optional): Height of output in pixels filename (str, optional): Name of output file. If none is specified, no files are saved. start_frame (float, optional): Defaults to current start frame. end_frame (float, optional): Defaults to current end frame. format (str, optional): Name of format, defaults to "qt". compression (str, optional): Name of compression, defaults to "h264" off_screen (bool, optional): Whether or not to playblast off screen viewer (bool, optional): Display results in native player isolate (list): List of nodes to isolate upon capturing maintain_aspect_ratio (bool, optional): Modify height in order to maintain aspect ratio. camera_options (CameraOptions, optional): Supplied camera options, using :class:`CameraOptions` viewport_options (ViewportOptions, optional): Supplied viewport options, using :class:`ViewportOptions` Example: >>> # Launch default capture >>> capture() >>> # Launch capture with custom viewport settings >>> view_opts = ViewportOptions() >>> view_opts.grid = False >>> view_opts.polymeshes = True >>> view_opts.displayAppearance = "wireframe" >>> cam_opts = CameraOptions() >>> cam_opts.displayResolution = True >>> capture('myCamera', 800, 600, ... viewport_options=view_opts, ... camera_options=cam_opts) """ from maya import cmds camera = camera or "persp" width = width or cmds.getAttr("defaultResolution.width") height = height or cmds.getAttr("defaultResolution.height") start_frame = start_frame or cmds.playbackOptions(minTime=True, query=True) end_frame = end_frame or cmds.playbackOptions(maxTime=True, query=True) with _independent_panel( width=width, height=height, maintain_aspect_ratio=maintain_aspect_ratio) as panel: cmds.lookThru(panel, camera) cmds.setFocus(panel) assert panel in cmds.playblast(activeEditor=True) with _applied_viewport_options(viewport_options, panel): with _applied_camera_options(camera_options, panel, camera): with _isolated_nodes(isolate, panel): output = cmds.playblast( compression=compression, format=format, percent=100, quality=100, viewer=viewer, startTime=start_frame, endTime=end_frame, filename=filename, offScreen=off_screen) return output
[docs]class ViewportOptions: """Viewport options for :func:`capture`""" useDefaultMaterial = False wireframeOnShaded = False displayAppearance = 'smoothShaded' # Visibility flags nurbsCurves = False nurbsSurfaces = False polymeshes = False subdivSurfaces = False cameras = False lights = False grid = False joints = False ikHandles = False deformers = False dynamics = False fluids = False hairSystems = False follicles = False nCloths = False nParticles = False nRigids = False dynamicConstraints = False locators = False manipulators = False dimensions = False handles = False pivots = False textures = False strokes = False
[docs]class CameraOptions: """Camera settings for :func:`capture` Camera options are applied to the specified camera and then reverted once the capture is complete. """ displayGateMask = False displayResolution = False displayFilmGate = False
class DisplayOptions: """Display options for :func:`capture` Use this struct for background color, anti-alias and other display-related options. """ def _parse_options(options): """Return dictionary of properties from option-objects""" opts = dict() for attr in dir(options): if attr.startswith("__"): continue opts[attr] = getattr(options, attr) return opts @contextlib.contextmanager def _independent_panel(width, height, maintain_aspect_ratio=True): """Create capture-window context without decorations Arguments: width (int): Width of panel height (int): Height of panel maintain_aspect_ratio (bool): Modify height in order to maintain aspect ratio. Example: >>> with _independent_panel(800, 600): ... cmds.capture() """ from maya import cmds if maintain_aspect_ratio: ratio = cmds.getAttr("defaultResolution.deviceAspectRatio") height = width / ratio window = cmds.window(width=width, height=height, menuBarVisible=False, titleBar=False) cmds.paneLayout() panel = cmds.modelPanel(menuBarVisible=False) # Hide icons under panel menus bar_layout = cmds.modelPanel(panel, q=True, barLayout=True) cmds.frameLayout(bar_layout, e=True, collapse=True) cmds.showWindow(window) try: yield panel finally: # Ensure window always closes # .. note:: We hide, rather than delete as deleting # causes the focus to shift during capture of multiple # cameras immediately after one another. Altering the # visibility doesn't seem to have this effect, it does # however come at a cost to RAM of about 5 mb per capture. cmds.window(window, edit=True, visible=False) @contextlib.contextmanager def _applied_viewport_options(options, panel): """Context manager for applying `options` to `panel`""" from maya import cmds if options is not None: options = _parse_options(options) cmds.modelEditor(panel, edit=True, allObjects=False, grid=False, manipulators=False) cmds.modelEditor(panel, edit=True, **options) yield @contextlib.contextmanager def _applied_camera_options(options, panel, camera): """Context manager for applying `options` to `camera`""" from maya import cmds old_options = None if options is not None: options = _parse_options(options) old_options = dict() for opt in options: try: old_options[opt] = cmds.getAttr(camera + "." + opt) except: sys.stderr.write("Could not get camera attribute " "for capture: %s" % opt) delattr(options, opt) for opt, value in options.iteritems(): cmds.setAttr(camera + "." + opt, value) try: yield finally: if old_options: for opt, value in old_options.iteritems(): cmds.setAttr(camera + "." + opt, value) @contextlib.contextmanager def _isolated_nodes(nodes, panel): """Context manager for isolating `nodes` in `panel`""" from maya import cmds if nodes is not None: cmds.isolateSelect(panel, state=True) for obj in nodes: cmds.isolateSelect(panel, addDagObject=obj) yield