fix(nuke): review workflow and other fixes

This commit is contained in:
Jakub Jezek 2019-07-18 16:19:21 +02:00
parent b8886eaa50
commit 39d0391934
11 changed files with 115 additions and 90 deletions

View file

@ -343,8 +343,6 @@ def reset_frame_range_handles():
"""Set frame range to current asset"""
root = nuke.root()
fps = float(api.Session.get("AVALON_FPS", 25))
root["fps"].setValue(fps)
name = api.Session["AVALON_ASSET"]
asset = io.find_one({"name": name, "type": "asset"})
@ -356,7 +354,7 @@ def reset_frame_range_handles():
data = asset["data"]
missing_cols = []
check_cols = ["fstart", "fend", "handle_start", "handle_end"]
check_cols = ["fps", "fstart", "fend", "handle_start", "handle_end"]
for col in check_cols:
if col not in data:
@ -373,20 +371,29 @@ def reset_frame_range_handles():
handles = avalon.nuke.get_handles(asset)
handle_start, handle_end = pype.get_handle_irregular(asset)
log.info("__ handles: `{}`".format(handles))
log.info("__ handle_start: `{}`".format(handle_start))
log.info("__ handle_end: `{}`".format(handle_end))
fps = asset["data"]["fps"]
edit_in = int(asset["data"]["fstart"]) - handle_start
edit_out = int(asset["data"]["fend"]) + handle_end
root["fps"].setValue(fps)
root["first_frame"].setValue(edit_in)
root["last_frame"].setValue(edit_out)
log.info("__ handles: `{}`".format(handles))
log.info("__ handle_start: `{}`".format(handle_start))
log.info("__ handle_end: `{}`".format(handle_end))
log.info("__ edit_in: `{}`".format(edit_in))
log.info("__ edit_out: `{}`".format(edit_out))
log.info("__ fps: `{}`".format(fps))
# setting active viewers
nuke.frame(int(asset["data"]["fstart"]))
vv = nuke.activeViewer().node()
try:
vv = nuke.activeViewer().node()
except AttributeError:
log.error("No active viewer. Select any node and hit num `1`")
return
range = '{0}-{1}'.format(
int(asset["data"]["fstart"]),

View file

@ -56,6 +56,7 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin):
component_data = {
"name": "thumbnail" # Default component name is "main".
}
comp['thumbnail'] = True
elif comp.get('preview') or ("preview" in comp.get('tags', [])):
'''
Ftrack bug requirement:

View file

@ -28,15 +28,14 @@ class ExtractBurnin(pype.api.Extractor):
if instance.context.data.get('version'):
version = "v" + str(instance.context.data['version'])
burnin_data = {
prep_data = {
"username": instance.context.data['user'],
"asset": os.environ['AVALON_ASSET'],
"task": os.environ['AVALON_TASK'],
"start_frame": int(instance.data['startFrame']),
"version": version
}
self.log.debug("__ burnin_data1: {}".format(burnin_data))
self.log.debug("__ prep_data: {}".format(prep_data))
for i, repre in enumerate(instance.data["representations"]):
self.log.debug("__ i: `{}`, repre: `{}`".format(i, repre))
@ -56,7 +55,7 @@ class ExtractBurnin(pype.api.Extractor):
burnin_data = {
"input": full_movie_path.replace("\\", "/"),
"output": full_burnin_path.replace("\\", "/"),
"burnin_data": burnin_data
"burnin_data": prep_data
}
self.log.debug("__ burnin_data2: {}".format(burnin_data))
@ -76,14 +75,17 @@ class ExtractBurnin(pype.api.Extractor):
)
p.wait()
if not os.path.isfile(full_burnin_path):
self.log.error(
"Burnin file wasn't created succesfully")
raise RuntimeError("File not existing: {}".format(full_burnin_path))
except Exception as e:
raise RuntimeError("Burnin script didn't work: `{}`".format(e))
if os.path.exists(full_burnin_path):
repre_update = {
"files": movieFileBurnin,
"name": repre["name"] + name
"name": repre["name"]
}
instance.data["representations"][i].update(repre_update)
# removing the source mov file
os.remove(full_movie_path)
self.log.debug("Removed: `{}`".format(full_movie_path))

View file

@ -36,7 +36,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
representations = instance.data["representations"]
# filter out mov and img sequences
representations_new = representations.copy()
representations_new = representations[:]
for repre in representations:
if repre['ext'] in plugin_attrs["ext_filter"]:
tags = repre.get("tags", [])
@ -46,10 +46,19 @@ class ExtractReview(pyblish.api.InstancePlugin):
if "review" in tags:
staging_dir = repre["stagingDir"]
for name, profile in output_profiles.items():
self.log.debug("Profile name: {}".format(name))
ext = profile.get("ext", None)
if not ext:
ext = "mov"
self.log.warning(
"`ext` attribute not in output profile. Setting to default ext: `mov`")
self.log.debug("instance.families: {}".format(instance.data['families']))
self.log.debug("profile.families: {}".format(profile['families']))
if any(item in instance.data['families'] for item in profile['families']):
if isinstance(repre["files"], list):
# if "mov" not in repre['ext']:
# get output presets and loop them
collections, remainder = clique.assemble(
repre["files"])
@ -62,27 +71,26 @@ class ExtractReview(pyblish.api.InstancePlugin):
if filename.endswith('.'):
filename = filename[:-1]
else:
self.log.info("1: {}".format(full_input_path))
full_input_path = os.path.join(
staging_dir, repre["files"])
filename = repre["files"].split(".")[0]
mov_file = filename + "_{0}.{1}".format(name, "mov")
repr_file = filename + "_{0}.{1}".format(name, ext)
full_output_path = os.path.join(staging_dir, mov_file)
full_output_path = os.path.join(
staging_dir, repr_file)
self.log.info("input {}".format(full_input_path))
self.log.info("output {}".format(full_output_path))
repre_new = repre.copy()
self.log.debug("Profile name: {}".format(name))
new_tags = tags[:]
p_tags = profile.get('tags', [])
self.log.info("p_tags: `{}`".format(p_tags))
# add families
[instance.data["families"].append(t) for t in p_tags
[instance.data["families"].append(t)
for t in p_tags
if t not in instance.data["families"]]
# add to
[new_tags.append(t) for t in p_tags
@ -101,16 +109,22 @@ class ExtractReview(pyblish.api.InstancePlugin):
# necessary input data
# adds start arg only if image sequence
if "mov" not in repre_new['ext']:
input_args.append("-start_number {}".format(
start_frame))
input_args.append("-start_number {0} -framerate {1}".format(
start_frame, fps))
input_args.append("-i {}".format(full_input_path))
input_args.append("-framerate {}".format(fps))
output_args = []
# preset's output data
output_args.extend(profile.get('output', []))
# letter_box
# TODO: add to documentation
lb = profile.get('letter_box', None)
if lb:
output_args.append(
"-filter:v drawbox=0:0:iw:round((ih-(iw*(1/{0})))/2):t=fill:c=black,drawbox=0:ih-round((ih-(iw*(1/{0})))/2):iw:round((ih-(iw*(1/{0})))/2):t=fill:c=black".format(lb))
# output filename
output_args.append(full_output_path)
mov_args = [
@ -118,25 +132,25 @@ class ExtractReview(pyblish.api.InstancePlugin):
" ".join(input_args),
" ".join(output_args)
]
subprocess_mov = " ".join(mov_args)
subprcs_cmd = " ".join(mov_args)
# run subprocess
sub_proc = subprocess.Popen(subprocess_mov)
self.log.debug("{}".format(subprcs_cmd))
sub_proc = subprocess.Popen(subprcs_cmd)
sub_proc.wait()
if not os.path.isfile(full_output_path):
self.log.error(
raise FileExistsError(
"Quicktime wasn't created succesfully")
# create representation data
repre_new.update({
'name': name,
'ext': 'mov',
'files': mov_file,
'ext': ext,
'files': repr_file,
"tags": new_tags,
"outputName": name
})
if repre_new.get('preview'):
repre_new.pop("preview")
if repre_new.get('thumbnail'):
@ -144,12 +158,15 @@ class ExtractReview(pyblish.api.InstancePlugin):
# adding representation
representations_new.append(repre_new)
# if "delete" in tags:
# if "mov" in full_input_path:
# os.remove(full_input_path)
# self.log.debug("Removed: `{}`".format(full_input_path))
else:
continue
else:
continue
self.log.debug(
"new representations: {}".format(representations_new))
instance.data["representations"] = representations_new

View file

@ -99,18 +99,18 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
# \ /
# o __/
#
for result in context.data["results"]:
if not result["success"]:
self.log.debug(result)
exc_type, exc_value, exc_traceback = result["error_info"]
extracted_traceback = traceback.extract_tb(exc_traceback)[-1]
self.log.debug(
"Error at line {}: \"{}\"".format(
extracted_traceback[1], result["error"]
)
)
assert all(result["success"] for result in context.data["results"]), (
"Atomicity not held, aborting.")
# for result in context.data["results"]:
# if not result["success"]:
# self.log.debug(result)
# exc_type, exc_value, exc_traceback = result["error_info"]
# extracted_traceback = traceback.extract_tb(exc_traceback)[-1]
# self.log.debug(
# "Error at line {}: \"{}\"".format(
# extracted_traceback[1], result["error"]
# )
# )
# assert all(result["success"] for result in context.data["results"]), (
# "Atomicity not held, aborting.")
# Assemble
#
@ -225,17 +225,6 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
# hierarchy = os.path.sep.join(hierarchy)
hierarchy = os.path.join(*parents)
template_data = {"root": root,
"project": {"name": PROJECT,
"code": project['data']['code']},
"silo": asset['silo'],
"task": TASK,
"asset": ASSET,
"family": instance.data['family'],
"subset": subset["name"],
"version": int(version["name"]),
"hierarchy": hierarchy}
anatomy = instance.context.data['anatomy']
# Find the representations to transfer amongst the files
@ -257,6 +246,17 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
# | ||
# |_______|
#
# create template data for Anatomy
template_data = {"root": root,
"project": {"name": PROJECT,
"code": project['data']['code']},
"silo": asset['silo'],
"task": TASK,
"asset": ASSET,
"family": instance.data['family'],
"subset": subset["name"],
"version": int(version["name"]),
"hierarchy": hierarchy}
files = repre['files']
if repre.get('stagingDir'):
@ -286,7 +286,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
os.path.normpath(
anatomy_filled[template_name]["path"])
)
self.log.debug(
"test_dest_files: {}".format(str(test_dest_files)))

View file

@ -64,7 +64,7 @@ class CollectNukeInstances(pyblish.api.ContextPlugin):
"name": node.name(),
"subset": subset,
"family": avalon_knob_data["family"],
"families": [family],
"families": [avalon_knob_data["family"], family],
"avalonKnob": avalon_knob_data,
"publish": node.knob('publish').value(),
"step": 1,

View file

@ -66,19 +66,20 @@ class CollectNukeWrites(pyblish.api.InstancePlugin):
instance.data['families'].append('ftrack')
if "representations" not in instance.data:
instance.data["representations"] = list()
try:
collected_frames = os.listdir(output_dir)
representation = {
'name': ext,
'ext': ext,
'files': collected_frames,
"stagingDir": output_dir,
"anatomy_template": "render"
}
instance.data["representations"].append(representation)
try:
collected_frames = os.listdir(output_dir)
representation['files'] = collected_frames
instance.data["representations"].append(representation)
except Exception:
instance.data["representations"].append(representation)
self.log.debug("couldn't collect frames: {}".format(label))
if 'render.local' in instance.data['families']:

View file

@ -28,12 +28,6 @@ class NukeRenderLocal(pype.api.Extractor):
last_frame = instance.data.get("endFrame", None)
node_subset_name = instance.data.get("name", None)
# swap path to stageDir
temp_dir = self.staging_dir(instance).replace("\\", "/")
output_dir = instance.data.get("outputDir")
path = node['file'].value()
node['file'].setValue(path.replace(output_dir, temp_dir))
self.log.info("Starting render")
self.log.info("Start frame: {}".format(first_frame))
self.log.info("End frame: {}".format(last_frame))
@ -45,27 +39,26 @@ class NukeRenderLocal(pype.api.Extractor):
int(last_frame)
)
# swap path back to publish path
path = node['file'].value()
node['file'].setValue(path.replace(temp_dir, output_dir))
out_dir = os.path.dirname(path)
ext = node["file_type"].value()
if "representations" not in instance.data:
instance.data["representations"] = []
collected_frames = os.listdir(temp_dir)
collected_frames = os.listdir(out_dir)
repre = {
'name': ext,
'ext': ext,
'files': collected_frames,
"stagingDir": temp_dir,
"stagingDir": out_dir,
"anatomy_template": "render"
}
instance.data["representations"].append(repre)
self.log.info("Extracted instance '{0}' to: {1}".format(
instance.name,
temp_dir
out_dir
))
instance.data['family'] = 'render'

View file

@ -82,10 +82,15 @@ class ExtractReviewData(pype.api.Extractor):
temporary_nodes.append(node)
reformat_node = nuke.createNode("Reformat")
reformat_node["format"].setValue("HD_1080")
reformat_node["resize"].setValue("fit")
reformat_node["filter"].setValue("Lanczos6")
reformat_node["black_outside"].setValue(True)
ref_node = self.nodes.get("Reformat", None)
if ref_node:
for k, v in ref_node:
self.log.debug("k,v: {0}:{1}".format(k,v))
if isinstance(v, unicode):
v = str(v)
reformat_node[k].setValue(v)
reformat_node.setInput(0, previous_node)
previous_node = reformat_node
temporary_nodes.append(reformat_node)
@ -112,6 +117,7 @@ class ExtractReviewData(pype.api.Extractor):
if representation in "mov":
file = fhead + "baked.mov"
name = "baked"
path = os.path.join(stagingDir, file).replace("\\", "/")
self.log.debug("Path: {}".format(path))
instance.data["baked_colorspace_movie"] = path
@ -120,12 +126,11 @@ class ExtractReviewData(pype.api.Extractor):
write_node["raw"].setValue(1)
write_node.setInput(0, previous_node)
temporary_nodes.append(write_node)
thumbnail = False
preview = True
tags = ["review"]
tags = ["review", "delete"]
elif representation in "jpeg":
file = fhead + "jpeg"
name = "thumbnail"
path = os.path.join(stagingDir, file).replace("\\", "/")
instance.data["thumbnail"] = path
write_node["file"].setValue(path)
@ -133,8 +138,6 @@ class ExtractReviewData(pype.api.Extractor):
write_node["raw"].setValue(1)
write_node.setInput(0, previous_node)
temporary_nodes.append(write_node)
thumbnail = True
preview = False
tags = ["thumbnail"]
# retime for
@ -142,15 +145,13 @@ class ExtractReviewData(pype.api.Extractor):
last_frame = int(last_frame) / 2
repre = {
'name': representation,
'name': name,
'ext': representation,
'files': file,
"stagingDir": stagingDir,
"startFrame": first_frame,
"endFrame": last_frame,
"anatomy_template": "render",
"thumbnail": thumbnail,
"preview": preview,
"tags": tags
}
instance.data["representations"].append(repre)

View file

@ -11,9 +11,12 @@ class RepairCollectionAction(pyblish.api.Action):
icon = "wrench"
def process(self, context, plugin):
self.log.info(context[0])
files_remove = [os.path.join(context[0].data["outputDir"], f)
for f in context[0].data["files"]]
for r in context[0].data.get("representations", [])
for f in r.get("files", [])
]
self.log.info(files_remove)
for f in files_remove:
os.remove(f)
self.log.debug("removing file: {}".format(f))
@ -38,7 +41,7 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin):
if not repre.get('files'):
msg = ("no frames were collected, "
"you need to render them")
self.log.error(msg)
self.log.warning(msg)
raise ValidationException(msg)
collections, remainder = clique.assemble(repre["files"])

View file

@ -24,7 +24,7 @@ class ValidateScript(pyblish.api.InstancePlugin):
# These attributes will be checked
attributes = [
"fps", "fstart", "fend",
"resolution_width", "resolution_height", "pixel_aspect", "handle_start", "handle_end"
"resolution_width", "resolution_height", "handle_start", "handle_end"
]
# Value of these attributes can be found on parents