mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
fix(nuke): review workflow and other fixes
This commit is contained in:
parent
b8886eaa50
commit
39d0391934
11 changed files with 115 additions and 90 deletions
|
|
@ -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"]),
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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']:
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue