adding basic capture playblast

This commit is contained in:
Milan Kolar 2018-11-30 01:24:18 +01:00
parent 45eb1a858e
commit 16f74efb53
4 changed files with 325 additions and 0 deletions

View file

@ -2032,3 +2032,103 @@ def bake_to_world_space(nodes,
shape=shape)
return world_space_nodes
def load_capture_preset(path):
import capture_gui
import capture
path = path
preset = capture_gui.lib.load_json(path)
print preset
options = dict()
# CODEC
id = 'Codec'
for key in preset[id]:
options[str(key)]= preset[id][key]
# GENERIC
id = 'Generic'
for key in preset[id]:
if key.startswith('isolate'):
pass
# options['isolate'] = preset[id][key]
else:
options[str(key)] = preset[id][key]
# RESOLUTION
id = 'Resolution'
options['height'] = preset[id]['height']
options['width'] = preset[id]['width']
# DISPLAY OPTIONS
id = 'Display Options'
disp_options = {}
for key in preset['Display Options']:
if key.startswith('background'):
disp_options[key] = preset['Display Options'][key]
else:
disp_options['displayGradient'] = True
options['display_options'] = disp_options
# VIEWPORT OPTIONS
temp_options = {}
id = 'Renderer'
for key in preset[id]:
temp_options[str(key)] = preset[id][key]
temp_options2 = {}
id = 'Viewport Options'
light_options = { 0: "default",
1: 'all',
2: 'selected',
3: 'flat',
4: 'nolights'}
for key in preset[id]:
if key == 'high_quality':
temp_options2['multiSampleEnable'] = True
temp_options2['multiSampleCount'] = 4
temp_options2['textureMaxResolution'] = 512
temp_options2['enableTextureMaxRes'] = True
if key == 'alphaCut' :
temp_options2['transparencyAlgorithm'] = 5
temp_options2['transparencyQuality'] = 1
if key == 'headsUpDisplay' :
temp_options['headsUpDisplay'] = True
if key == 'displayLights':
temp_options[str(key)] = light_options[preset[id][key]]
else:
temp_options[str(key)] = preset[id][key]
for key in ['override_viewport_options', 'high_quality', 'alphaCut']:
temp_options.pop(key, None)
options['viewport_options'] = temp_options
options['viewport2_options'] = temp_options2
# use active sound track
scene = capture.parse_active_scene()
options['sound'] = scene['sound']
cam_options = dict()
cam_options['overscan'] = 1.0
cam_options['displayFieldChart'] = False
cam_options['displayFilmGate'] = False
cam_options['displayFilmOrigin'] = False
cam_options['displayFilmPivot'] = False
cam_options['displayGateMask'] = False
cam_options['displayResolution'] = False
cam_options['displaySafeAction'] = False
cam_options['displaySafeTitle'] = False
# options['display_options'] = temp_options
return options

View file

@ -0,0 +1,23 @@
from collections import OrderedDict
import avalon.maya
from pype.maya import lib
class CreateReview(avalon.maya.Creator):
"""Single baked camera"""
name = "reviewDefault"
label = "Review"
family = "review"
icon = "video-camera"
def __init__(self, *args, **kwargs):
super(CreateReview, self).__init__(*args, **kwargs)
# get basic animation data : start / end / handles / steps
data = OrderedDict(**self.data)
animation_data = lib.collect_animation_data()
for key, value in animation_data.items():
data[key] = value
self.data = data

View file

@ -0,0 +1,17 @@
from maya import cmds
import pyblish.api
class CollectReviewData(pyblish.api.InstancePlugin):
"""Collect Review data
"""
order = pyblish.api.CollectorOrder + 0.499
label = 'Collect Review Data'
families = ["review"]
def process(self, instance):
# make ftrack publishable
instance.data["families"] = ['ftrack']

View file

@ -0,0 +1,185 @@
import os
import contextlib
import time
import capture_gui
import pype.maya.lib as lib
import pype.api
from maya import cmds
import pymel.core as pm
import avalon.maya
# import maya_utils as mu
# from tweakHUD import master
# from tweakHUD import draft_hud as dHUD
# from tweakHUD import ftrackStrings as fStrings
#
# def soundOffsetFunc(oSF, SF, H):
# tmOff = (oSF - H) - SF
# return tmOff
class ExtractQuicktime(pype.api.Extractor):
"""Extract a Camera as Alembic.
The cameras gets baked to world space by default. Only when the instance's
`bakeToWorldSpace` is set to False it will include its full hierarchy.
"""
label = "Quicktime (Alembic)"
hosts = ["maya"]
families = ["review"]
def process(self, instance):
self.log.info("Extracting capture..")
start = instance.data["startFrame"]
end = instance.data["endFrame"]
self.log.info("start: {}, end: {}".format(start, end))
handles = instance.data.get("handles", 0)
if handles:
start -= handles
end += handles
# get cameras
members = instance.data['setMembers']
cameras = cmds.ls(members, leaf=True, shapes=True, long=True,
dag=True, type="camera")
# validate required settings
assert len(cameras) == 1, "Not a single camera found in extraction"
camera = cameras[0]
# project_code = ftrack_data['Project']['code']
# task_type = ftrack_data['Task']['type']
#
# # load Preset
# studio_repos = os.path.abspath(os.environ.get('studio_repos'))
# shot_preset_path = os.path.join(studio_repos, 'maya',
# 'capture_gui_presets',
# (project_code + '_' + task_type + '_' + asset + '.json'))
#
# task_preset_path = os.path.join(studio_repos, 'maya',
# 'capture_gui_presets',
# (project_code + '_' + task_type + '.json'))
#
# project_preset_path = os.path.join(studio_repos, 'maya',
# 'capture_gui_presets',
# (project_code + '.json'))
#
# default_preset_path = os.path.join(studio_repos, 'maya',
# 'capture_gui_presets',
# 'default.json')
#
# if os.path.isfile(shot_preset_path):
# preset_to_use = shot_preset_path
# elif os.path.isfile(task_preset_path):
# preset_to_use = task_preset_path
# elif os.path.isfile(project_preset_path):
# preset_to_use = project_preset_path
# else:
# preset_to_use = default_preset_path
capture_preset = ""
try:
preset = lib.load_capture_preset(capture_preset)
except:
preset = {}
self.log.info('using viewport preset: {}'.format(capture_preset))
#preset["off_screen"] = False
preset['camera'] = camera
preset['format'] = "image"
# preset['compression'] = "qt"
preset['quality'] = 50
preset['compression'] = "jpg"
preset['start_frame'] = 1
preset['end_frame'] = 25
preset['camera_options'] = {
"displayGateMask": False,
"displayResolution": False,
"displayFilmGate": False,
"displayFieldChart": False,
"displaySafeAction": False,
"displaySafeTitle": False,
"displayFilmPivot": False,
"displayFilmOrigin": False,
"overscan": 1.0,
"depthOfField": cmds.getAttr("{0}.depthOfField".format(camera)),
}
stagingdir = self.staging_dir(instance)
filename = "{0}".format(instance.name)
path = os.path.join(stagingdir, filename)
self.log.info("Outputting images to %s" % path)
preset['filename'] = path
preset['overwrite'] = True
# pm.refresh(f=True)
#
# refreshFrameInt = int(pm.playbackOptions(q=True, minTime=True))
# pm.currentTime(refreshFrameInt - 1, edit=True)
# pm.currentTime(refreshFrameInt, edit=True)
with maintained_time():
playblast = capture_gui.lib.capture_scene(preset)
if "files" not in instance.data:
instance.data["files"] = list()
instance.data["files"].append(playblast)
# self.log.info("Calculating HUD data overlay")
# movieFullPth = path + ".mov"
# fls = [os.path.join(dir_path, f).replace("\\","/") for f in os.listdir( dir_path ) if f.endswith(preset['compression'])]
#self.log.info(" these %s" % fls[0])
# ftrackStrings = fStrings.annotationData()
# nData = ftrackStrings.niceData
# nData['version'] = instance.context.data('version')
# fFrame = int(pm.playbackOptions( q = True, minTime = True))
# eFrame = int(pm.playbackOptions( q = True, maxTime = True))
# nData['frame'] = [(str("{0:05d}".format(f))) for f in range(fFrame, eFrame + 1)]
# soundOfst = int(float(nData['oFStart'])) - int(float(nData['handle'])) - fFrame
# soundFile = mu.giveMePublishedAudio()
# self.log.info("SOUND offset %s" % str(soundOfst))
# self.log.info("SOUND source video to %s" % str(soundFile))
# ann = dHUD.draftAnnotate()
# if soundFile:
# ann.addAnotation(seqFls = fls, outputMoviePth = movieFullPth, annotateDataArr = nData, soundFile = soundFile, soundOffset = soundOfst)
# else:
# ann.addAnotation(seqFls = fls, outputMoviePth = movieFullPth, annotateDataArr = nData)
# for f in fls:
# os.remove(f)
# playblast = (ann.expPth).replace("\\","/")
instance.data["outputPath_qt"] = playblast
self.log.info("Outputting video to %s" % playblast)
@contextlib.contextmanager
def maintained_time():
ct = cmds.currentTime(query=True)
try:
yield
finally:
cmds.currentTime(ct, edit=True)