mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
feat(fusion): renaming saver family to render
also changing render targeting names
This commit is contained in:
parent
70f0257fd9
commit
52470b2cfc
21 changed files with 79 additions and 147 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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__)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ class ExtractBurnin(pype.api.Extractor):
|
|||
"shell",
|
||||
"nukestudio",
|
||||
"premiere",
|
||||
"standalonepublisher"
|
||||
"standalonepublisher",
|
||||
"fusion"
|
||||
]
|
||||
optional = True
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue