feat(fusion): renaming saver family to render

also changing render targeting names
This commit is contained in:
Jakub Jezek 2020-08-21 11:27:57 +02:00
parent 70f0257fd9
commit 52470b2cfc
No known key found for this signature in database
GPG key ID: C4B96E101D2A47F3
21 changed files with 79 additions and 147 deletions

View file

@ -3,10 +3,10 @@ from avalon.vendor import qtawesome
import avalon.fusion as avalon
_help = {"renderlocal": "Render the comp on your own machine and publish "
"it from that the destination folder",
"deadline": "Submit a Fusion render job to Deadline to use all other "
"computers and add a publish job"}
_help = {"local": "Render the comp on your own machine and publish "
"it from that the destination folder",
"farm": "Submit a Fusion render job to a Render farm to use all other"
" computers and add a publish job"}
class SetRenderMode(QtWidgets.QWidget):
@ -96,7 +96,7 @@ class SetRenderMode(QtWidgets.QWidget):
return self._comp.GetAttrs("COMPS_Name")
def _get_comp_rendermode(self):
return self._comp.GetData("pype.rendermode") or "renderlocal"
return self._comp.GetData("pype.rendermode") or "local"
def _set_comp_rendermode(self):
rendermode = self.mode_options.currentText()

View file

@ -4,16 +4,16 @@ import avalon.api
from avalon import fusion
class CreateTiffSaver(avalon.api.Creator):
class CreateOpenEXRSaver(avalon.api.Creator):
name = "tiffDefault"
label = "Create Tiff Saver"
name = "openexrDefault"
label = "Create OpenEXR Saver"
hosts = ["fusion"]
family = "saver"
family = "render"
def process(self):
file_format = "TiffFormat"
file_format = "OpenEXRFormat"
comp = fusion.get_current_comp()

View file

@ -4,6 +4,10 @@ import contextlib
from avalon import api
import avalon.io as io
from avalon import fusion
comp = fusion.get_current_comp()
@contextlib.contextmanager
def preserve_inputs(tool, inputs):
@ -113,7 +117,7 @@ def loader_shift(loader, frame, relative=True):
class FusionLoadSequence(api.Loader):
"""Load image sequence into Fusion"""
families = ["imagesequence"]
families = ["imagesequence", "review"]
representations = ["*"]
label = "Load sequence"
@ -134,7 +138,7 @@ class FusionLoadSequence(api.Loader):
namespace = context['asset']['name']
# Use the first file for now
path = self._get_first_image(self.fname)
path = self._get_first_image(os.path.dirname(self.fname))
# Create the Loader with the filename path set
comp = get_current_comp()

View file

@ -43,8 +43,8 @@ class CollectInstances(pyblish.api.ContextPlugin):
savers = [tool for tool in tools if tool.ID == "Saver"]
start, end = get_comp_render_range(comp)
context.data["frameStart"] = start
context.data["frameEnd"] = end
context.data["frameStart"] = int(start)
context.data["frameEnd"] = int(end)
for tool in savers:
path = tool["Clip"][comp.TIME_UNDEFINED]
@ -76,8 +76,11 @@ class CollectInstances(pyblish.api.ContextPlugin):
"outputDir": os.path.dirname(path),
"ext": ext, # todo: should be redundant
"label": label,
"families": ["saver"],
"family": "saver",
"frameStart": context.data["frameStart"],
"frameEnd": context.data["frameEnd"],
"fps": context.data["fps"],
"families": ["render", "review", "ftrack"],
"family": "render",
"active": active,
"publish": active # backwards compatibility
})

View file

@ -5,8 +5,8 @@ class CollectFusionRenderMode(pyblish.api.InstancePlugin):
"""Collect current comp's render Mode
Options:
renderlocal
deadline
local
farm
Note that this value is set for each comp separately. When you save the
comp this information will be stored in that file. If for some reason the
@ -23,22 +23,22 @@ class CollectFusionRenderMode(pyblish.api.InstancePlugin):
order = pyblish.api.CollectorOrder + 0.4
label = "Collect Render Mode"
hosts = ["fusion"]
families = ["saver"]
families = ["render"]
def process(self, instance):
"""Collect all image sequence tools"""
options = ["renderlocal", "deadline"]
options = ["local", "farm"]
comp = instance.context.data.get("currentComp")
if not comp:
raise RuntimeError("No comp previously collected, unable to "
"retrieve Fusion version.")
rendermode = comp.GetData("pype.rendermode") or "renderlocal"
rendermode = comp.GetData("pype.rendermode") or "local"
assert rendermode in options, "Must be supported render mode"
self.log.info("Render mode: {0}".format(rendermode))
# Append family
family = "saver.{0}".format(rendermode)
family = "render.{0}".format(rendermode)
instance.data["families"].append(family)

View file

@ -11,7 +11,7 @@ class FusionIncrementCurrentFile(pyblish.api.ContextPlugin):
label = "Increment current file"
order = pyblish.api.IntegratorOrder + 9.0
hosts = ["fusion"]
families = ["saver.deadline"]
families = ["render.farm"]
optional = True
def process(self, context):
@ -23,7 +23,7 @@ class FusionIncrementCurrentFile(pyblish.api.ContextPlugin):
if any(plugin.__name__ == "FusionSubmitDeadline"
for plugin in errored_plugins):
raise RuntimeError("Skipping incrementing current file because "
"submission to deadline failed.")
"submission to render farm failed.")
comp = context.data.get("currentComp")
assert comp, "Must have comp"

View file

@ -1,98 +0,0 @@
import re
import os
import json
import subprocess
import pyblish.api
from pype.action import get_errored_plugins_from_data
def _get_script():
"""Get path to the image sequence script"""
# todo: use a more elegant way to get the python script
try:
from pype.scripts import publish_filesequence
except Exception:
raise RuntimeError("Expected module 'publish_imagesequence'"
"to be available")
module_path = publish_filesequence.__file__
if module_path.endswith(".pyc"):
module_path = module_path[:-len(".pyc")] + ".py"
return module_path
class PublishImageSequence(pyblish.api.InstancePlugin):
"""Publish the generated local image sequences."""
order = pyblish.api.IntegratorOrder
label = "Publish Rendered Image Sequence(s)"
hosts = ["fusion"]
families = ["saver.renderlocal"]
def process(self, instance):
# Skip this plug-in if the ExtractImageSequence failed
errored_plugins = get_errored_plugins_from_data(instance.context)
if any(plugin.__name__ == "FusionRenderLocal" for plugin in
errored_plugins):
raise RuntimeError("Fusion local render failed, "
"publishing images skipped.")
subset = instance.data["subset"]
ext = instance.data["ext"]
# Regex to match resulting renders
regex = "^{subset}.*[0-9]+{ext}+$".format(subset=re.escape(subset),
ext=re.escape(ext))
# The instance has most of the information already stored
metadata = {
"regex": regex,
"frameStart": instance.context.data["frameStart"],
"frameEnd": instance.context.data["frameEnd"],
"families": ["imagesequence"],
}
# Write metadata and store the path in the instance
output_directory = instance.data["outputDir"]
path = os.path.join(output_directory,
"{}_metadata.json".format(subset))
with open(path, "w") as f:
json.dump(metadata, f)
assert os.path.isfile(path), ("Stored path is not a file for %s"
% instance.data["name"])
# Suppress any subprocess console
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
process = subprocess.Popen(["python", _get_script(),
"--paths", path],
bufsize=1,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
startupinfo=startupinfo)
while True:
output = process.stdout.readline()
# Break when there is no output or a return code has been given
if output == '' and process.poll() is not None:
process.stdout.close()
break
if output:
line = output.strip()
if line.startswith("ERROR"):
self.log.error(line)
else:
self.log.info(line)
if process.returncode != 0:
raise RuntimeError("Process quit with non-zero "
"return code: {}".format(process.returncode))

View file

@ -1,9 +1,11 @@
import os
import pyblish.api
import avalon.fusion as fusion
from pprint import pformat
class FusionRenderLocal(pyblish.api.InstancePlugin):
class Fusionlocal(pyblish.api.InstancePlugin):
"""Render the current Fusion composition locally.
Extract the result of savers by starting a comp render
@ -14,12 +16,10 @@ class FusionRenderLocal(pyblish.api.InstancePlugin):
order = pyblish.api.ExtractorOrder
label = "Render Local"
hosts = ["fusion"]
families = ["saver.renderlocal"]
families = ["render.local"]
def process(self, instance):
# This should be a ContextPlugin, but this is a workaround
# for a bug in pyblish to run once for a family: issue #250
context = instance.context
key = "__hasRun{}".format(self.__class__.__name__)
if context.data.get(key, False):
@ -28,15 +28,35 @@ class FusionRenderLocal(pyblish.api.InstancePlugin):
context.data[key] = True
current_comp = context.data["currentComp"]
start_frame = current_comp.GetAttrs("COMPN_RenderStart")
end_frame = current_comp.GetAttrs("COMPN_RenderEnd")
frame_start = current_comp.GetAttrs("COMPN_RenderStart")
frame_end = current_comp.GetAttrs("COMPN_RenderEnd")
path = instance.data["path"]
output_dir = instance.data["outputDir"]
ext = os.path.splitext(os.path.basename(path))[-1]
self.log.info("Starting render")
self.log.info("Start frame: {}".format(start_frame))
self.log.info("End frame: {}".format(end_frame))
self.log.info("Start frame: {}".format(frame_start))
self.log.info("End frame: {}".format(frame_end))
with fusion.comp_lock_and_undo_chunk(current_comp):
result = current_comp.Render()
if "representations" not in instance.data:
instance.data["representations"] = []
collected_frames = os.listdir(output_dir)
repre = {
'name': ext[1:],
'ext': ext[1:],
'frameStart': "%0{}d".format(len(str(frame_end))) % frame_start,
'files': collected_frames,
"stagingDir": output_dir,
"tags": ["review", "ftrackreview"]
}
instance.data["representations"].append(repre)
self.log.debug(f"_ instance.data: {pformat(instance.data)}")
if not result:
raise RuntimeError("Comp render failed")

View file

@ -7,7 +7,7 @@ class FusionSaveComp(pyblish.api.ContextPlugin):
label = "Save current file"
order = pyblish.api.ExtractorOrder - 0.49
hosts = ["fusion"]
families = ["saver"]
families = ["render"]
def process(self, context):

View file

@ -19,10 +19,9 @@ class FusionSubmitDeadline(pyblish.api.InstancePlugin):
label = "Submit to Deadline"
order = pyblish.api.IntegratorOrder
hosts = ["fusion"]
families = ["saver.deadline"]
families = ["render.farm"]
def process(self, instance):
instance.data["toBeRenderedOn"] = "deadline"
context = instance.context
key = "__hasRun{}".format(self.__class__.__name__)

View file

@ -10,7 +10,7 @@ class ValidateBackgroundDepth(pyblish.api.InstancePlugin):
label = "Validate Background Depth 32 bit"
actions = [action.RepairAction]
hosts = ["fusion"]
families = ["saver"]
families = ["render"]
optional = True
@classmethod

View file

@ -8,7 +8,7 @@ class ValidateFusionCompSaved(pyblish.api.ContextPlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Comp Saved"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
def process(self, context):

View file

@ -13,7 +13,7 @@ class ValidateCreateFolderChecked(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
actions = [action.RepairAction]
label = "Validate Create Folder Checked"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
@classmethod

View file

@ -14,7 +14,7 @@ class ValidateFilenameHasExtension(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Filename Has Extension"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
def process(self, instance):

View file

@ -10,7 +10,7 @@ class ValidateSaverHasInput(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Saver Has Input"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
@classmethod

View file

@ -6,7 +6,7 @@ class ValidateSaverPassthrough(pyblish.api.ContextPlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Saver Passthrough"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
def process(self, context):

View file

@ -6,7 +6,7 @@ class ValidateUniqueSubsets(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Unique Subsets"
families = ["saver"]
families = ["render"]
hosts = ["fusion"]
@classmethod
@ -14,7 +14,7 @@ class ValidateUniqueSubsets(pyblish.api.InstancePlugin):
context = instance.context
subset = instance.data["subset"]
for other_instance in context[:]:
for other_instance in context:
if other_instance == instance:
continue

View file

@ -86,3 +86,5 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin):
frame_end_h = frame_end + context.data["handleEnd"]
context.data["frameStartHandle"] = frame_start_h
context.data["frameEndHandle"] = frame_end_h
context.data["fps"] = data["fps"]

View file

@ -25,7 +25,8 @@ class ExtractBurnin(pype.api.Extractor):
"shell",
"nukestudio",
"premiere",
"standalonepublisher"
"standalonepublisher",
"fusion"
]
optional = True

View file

@ -29,7 +29,8 @@ class ExtractReview(pyblish.api.InstancePlugin):
"nukestudio",
"premiere",
"harmony",
"standalonepublisher"
"standalonepublisher",
"fusion"
]
# Supported extensions
@ -50,9 +51,9 @@ class ExtractReview(pyblish.api.InstancePlugin):
to_height = 1080
def process(self, instance):
# Skip review when requested.
if not instance.data.get("review"):
return
# # Skip review when requested.
# if not instance.data.get("review"):
# return
# ffmpeg doesn't support multipart exrs
if instance.data.get("multipartExr") is True:

View file

@ -526,7 +526,7 @@ def burnins_from_data(
bit_rate = burnin._streams[0].get("bit_rate")
if bit_rate:
ffmpeg_args.append("--b:v {}".format(bit_rate))
ffmpeg_args.append("-b:v {}".format(bit_rate))
pix_fmt = burnin._streams[0].get("pix_fmt")
if pix_fmt: