This repository has been archived by the owner on Sep 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 129
/
extract_playblast.py
180 lines (144 loc) · 6.38 KB
/
extract_playblast.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import os
import glob
import contextlib
import clique
import capture
from openpype.hosts.maya.api import lib
import openpype.api
from maya import cmds
import pymel.core as pm
class ExtractPlayblast(openpype.api.Extractor):
"""Extract viewport playblast.
Takes review camera and creates review Quicktime video based on viewport
capture.
"""
label = "Extract Playblast"
hosts = ["maya"]
families = ["review"]
optional = True
capture_preset = {}
def process(self, instance):
self.log.info("Extracting capture..")
# get scene fps
fps = instance.data.get("fps") or instance.context.data.get("fps")
# if start and end frames cannot be determined, get them
# from Maya timeline
start = instance.data.get("frameStartFtrack")
end = instance.data.get("frameEndFtrack")
if start is None:
start = cmds.playbackOptions(query=True, animationStartTime=True)
if end is None:
end = cmds.playbackOptions(query=True, animationEndTime=True)
self.log.info("start: {}, end: {}".format(start, end))
# get cameras
camera = instance.data['review_camera']
override_viewport_options = (
self.capture_preset['Viewport Options']
['override_viewport_options']
)
preset = lib.load_capture_preset(data=self.capture_preset)
# Grab capture presets from the project settings
capture_presets = self.capture_preset
# Set resolution variables from capture presets
width_preset = capture_presets["Resolution"]["width"]
height_preset = capture_presets["Resolution"]["height"]
# Set resolution variables from asset values
asset_data = instance.data["assetEntity"]["data"]
asset_width = asset_data.get("resolutionWidth")
asset_height = asset_data.get("resolutionHeight")
review_instance_width = instance.data.get("review_width")
review_instance_height = instance.data.get("review_height")
preset['camera'] = camera
# Tests if project resolution is set,
# if it is a value other than zero, that value is
# used, if not then the asset resolution is
# used
if review_instance_width and review_instance_height:
preset['width'] = review_instance_width
preset['height'] = review_instance_height
elif width_preset and height_preset:
preset['width'] = width_preset
preset['height'] = height_preset
elif asset_width and asset_height:
preset['width'] = asset_width
preset['height'] = asset_height
preset['start_frame'] = start
preset['end_frame'] = end
camera_option = preset.get("camera_option", {})
camera_option["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)
# Override transparency if requested.
transparency = instance.data.get("transparency", 0)
if transparency != 0:
preset["viewport2_options"]["transparencyAlgorithm"] = transparency
# Isolate view is requested by having objects in the set besides a
# camera.
if preset.pop("isolate_view", False) and instance.data.get("isolate"):
preset["isolate"] = instance.data["setMembers"]
# Show/Hide image planes on request.
image_plane = instance.data.get("imagePlane", True)
if "viewport_options" in preset:
preset["viewport_options"]["imagePlane"] = image_plane
else:
preset["viewport_options"] = {"imagePlane": image_plane}
with lib.maintained_time():
filename = preset.get("filename", "%TEMP%")
# Force viewer to False in call to capture because we have our own
# viewer opening call to allow a signal to trigger between
# playblast and viewer
preset['viewer'] = False
self.log.info('using viewport preset: {}'.format(preset))
# Update preset with current panel setting
# if override_viewport_options is turned off
if not override_viewport_options:
panel_preset = capture.parse_active_view()
preset.update(panel_preset)
path = capture.capture(**preset)
self.log.debug("playblast path {}".format(path))
collected_files = os.listdir(stagingdir)
collections, remainder = clique.assemble(collected_files,
minimum_items=1)
self.log.debug("filename {}".format(filename))
frame_collection = None
for collection in collections:
filebase = collection.format('{head}').rstrip(".")
self.log.debug("collection head {}".format(filebase))
if filebase in filename:
frame_collection = collection
self.log.info(
"we found collection of interest {}".format(
str(frame_collection)))
if "representations" not in instance.data:
instance.data["representations"] = []
tags = ["review"]
if not instance.data.get("keepImages"):
tags.append("delete")
# Add camera node name to representation data
camera_node_name = pm.ls(camera)[0].getTransform().name()
collected_files = list(frame_collection)
# single frame file shouldn't be in list, only as a string
if len(collected_files) == 1:
collected_files = collected_files[0]
representation = {
'name': 'png',
'ext': 'png',
'files': collected_files,
"stagingDir": stagingdir,
"frameStart": start,
"frameEnd": end,
'fps': fps,
'preview': True,
'tags': tags,
'camera_name': camera_node_name
}
instance.data["representations"].append(representation)