mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #2875 from pypeclub/bugfix/OP-2813_AE-rendering-for-single-frame-doesnt-work-in-DL
AfterEffects: Fix rendering for single frame in DL
This commit is contained in:
commit
1ae7536e9d
6 changed files with 209 additions and 17 deletions
|
|
@ -101,7 +101,7 @@ class LoadClip(plugin.NukeLoader):
|
|||
last += self.handle_end
|
||||
|
||||
if not is_sequence:
|
||||
duration = last - first + 1
|
||||
duration = last - first
|
||||
first = 1
|
||||
last = first + duration
|
||||
elif "#" not in file:
|
||||
|
|
@ -216,7 +216,7 @@ class LoadClip(plugin.NukeLoader):
|
|||
last += self.handle_end
|
||||
|
||||
if not is_sequence:
|
||||
duration = last - first + 1
|
||||
duration = last - first
|
||||
first = 1
|
||||
last = first + duration
|
||||
elif "#" not in file:
|
||||
|
|
|
|||
|
|
@ -10,14 +10,20 @@ def collect_frames(files):
|
|||
"""
|
||||
Returns dict of source path and its frame, if from sequence
|
||||
|
||||
Uses clique as most precise solution
|
||||
Uses clique as most precise solution, used when anatomy template that
|
||||
created files is not known.
|
||||
|
||||
Assumption is that frames are separated by '.', negative frames are not
|
||||
allowed.
|
||||
|
||||
Args:
|
||||
files(list): list of source paths
|
||||
files(list) or (set with single value): list of source paths
|
||||
Returns:
|
||||
(dict): {'/asset/subset_v001.0001.png': '0001', ....}
|
||||
"""
|
||||
collections, remainder = clique.assemble(files, minimum_items=1)
|
||||
patterns = [clique.PATTERNS["frames"]]
|
||||
collections, remainder = clique.assemble(files, minimum_items=1,
|
||||
patterns=patterns)
|
||||
|
||||
sources_and_frames = {}
|
||||
if collections:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import pyblish.api
|
|||
from avalon import api
|
||||
|
||||
from openpype.lib import env_value_to_bool
|
||||
from openpype.lib.delivery import collect_frames
|
||||
from openpype_modules.deadline import abstract_submit_deadline
|
||||
from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo
|
||||
|
||||
|
|
@ -102,24 +103,18 @@ class AfterEffectsSubmitDeadline(
|
|||
|
||||
def get_plugin_info(self):
|
||||
deadline_plugin_info = DeadlinePluginInfo()
|
||||
context = self._instance.context
|
||||
script_path = context.data["currentFile"]
|
||||
|
||||
render_path = self._instance.data["expectedFiles"][0]
|
||||
|
||||
if len(self._instance.data["expectedFiles"]) > 1:
|
||||
file_name, frame = list(collect_frames([render_path]).items())[0]
|
||||
if frame:
|
||||
# replace frame ('000001') with Deadline's required '[#######]'
|
||||
# expects filename in format project_asset_subset_version.FRAME.ext
|
||||
render_dir = os.path.dirname(render_path)
|
||||
file_name = os.path.basename(render_path)
|
||||
arr = file_name.split('.')
|
||||
assert len(arr) == 3, \
|
||||
"Unable to parse frames from {}".format(file_name)
|
||||
hashed = '[{}]'.format(len(arr[1]) * "#")
|
||||
|
||||
render_path = os.path.join(render_dir,
|
||||
'{}.{}.{}'.format(arr[0], hashed,
|
||||
arr[2]))
|
||||
hashed = '[{}]'.format(len(frame) * "#")
|
||||
file_name = file_name.replace(frame, hashed)
|
||||
render_path = os.path.join(render_dir, file_name)
|
||||
|
||||
deadline_plugin_info.Comp = self._instance.data["comp_name"]
|
||||
deadline_plugin_info.Version = self._instance.data["app_version"]
|
||||
|
|
|
|||
|
|
@ -606,7 +606,18 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
"fps": instance.get("fps"),
|
||||
"tags": ["review"]
|
||||
})
|
||||
self._solve_families(instance, True)
|
||||
self._solve_families(instance, True)
|
||||
|
||||
already_there = False
|
||||
for repre in instance.get("representations", []):
|
||||
# might be added explicitly before by publish_on_farm
|
||||
already_there = repre.get("files") == rep["files"]
|
||||
if already_there:
|
||||
self.log.debug("repre {} already_there".format(repre))
|
||||
break
|
||||
|
||||
if not already_there:
|
||||
representations.append(rep)
|
||||
|
||||
return representations
|
||||
|
||||
|
|
|
|||
|
|
@ -21,3 +21,27 @@ Specific location could be provided to this command as an argument, either as ab
|
|||
(eg. `python ${OPENPYPE_ROOT}/start.py start.py runtests ../tests/integration`) will trigger only tests in `integration` folder.
|
||||
|
||||
See `${OPENPYPE_ROOT}/cli.py:runtests` for other arguments.
|
||||
|
||||
Run in IDE:
|
||||
-----------
|
||||
If you prefer to run/debug single file directly in IDE of your choice, you might encounter issues with imports.
|
||||
It would manifest like `KeyError: 'OPENPYPE_DATABASE_NAME'`. That means you are importing module that depends on OP to be running, eg. all expected variables are set.
|
||||
|
||||
In some cases your tests might be so localized, that you don't care about all env vars to be set properly.
|
||||
In that case you might add this dummy configuration BEFORE any imports in your test file
|
||||
```
|
||||
import os
|
||||
os.environ["AVALON_MONGO"] = "mongodb://localhost:27017"
|
||||
os.environ["OPENPYPE_MONGO"] = "mongodb://localhost:27017"
|
||||
os.environ["AVALON_DB"] = "avalon"
|
||||
os.environ["OPENPYPE_DATABASE_NAME"] = "openpype"
|
||||
os.environ["AVALON_TIMEOUT"] = '3000'
|
||||
os.environ["OPENPYPE_DEBUG"] = "3"
|
||||
os.environ["AVALON_CONFIG"] = "pype"
|
||||
os.environ["AVALON_ASSET"] = "Asset"
|
||||
os.environ["AVALON_PROJECT"] = "test_project"
|
||||
```
|
||||
(AVALON_ASSET and AVALON_PROJECT values should exist in your environment)
|
||||
|
||||
This might be enough to run your test file separately. Do not commit this skeleton though.
|
||||
Use only when you know what you are doing!
|
||||
156
tests/unit/openpype/lib/test_delivery.py
Normal file
156
tests/unit/openpype/lib/test_delivery.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Test suite for delivery functions."""
|
||||
from openpype.lib.delivery import collect_frames
|
||||
|
||||
|
||||
def test_collect_frames_multi_sequence():
|
||||
files = ["Asset_renderCompositingMain_v001.0000.png",
|
||||
"Asset_renderCompositingMain_v001.0001.png",
|
||||
"Asset_renderCompositingMain_v001.0002.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset_renderCompositingMain_v001.0000.png": "0000",
|
||||
"Asset_renderCompositingMain_v001.0001.png": "0001",
|
||||
"Asset_renderCompositingMain_v001.0002.png": "0002"
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_multi_sequence_different_format():
|
||||
files = ["Asset.v001.renderCompositingMain.0000.png",
|
||||
"Asset.v001.renderCompositingMain.0001.png",
|
||||
"Asset.v001.renderCompositingMain.0002.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset.v001.renderCompositingMain.0000.png": "0000",
|
||||
"Asset.v001.renderCompositingMain.0001.png": "0001",
|
||||
"Asset.v001.renderCompositingMain.0002.png": "0002"
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence():
|
||||
files = ["Asset_renderCompositingMain_v001.0000.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset_renderCompositingMain_v001.0000.png": "0000"
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_negative():
|
||||
files = ["Asset_renderCompositingMain_v001.-0000.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset_renderCompositingMain_v001.-0000.png": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_shot():
|
||||
files = ["testing_sh010_workfileCompositing_v001.aep"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"testing_sh010_workfileCompositing_v001.aep": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_numbers():
|
||||
files = ["PRJ_204_430_0005_renderLayoutMain_v001.0001.exr"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"PRJ_204_430_0005_renderLayoutMain_v001.0001.exr": "0001"
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_shot_with_frame():
|
||||
files = ["testing_sh010_workfileCompositing_000_v001.aep"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"testing_sh010_workfileCompositing_000_v001.aep": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_full_path():
|
||||
files = ['C:/test_project/assets/locations/Town/work/compositing\\renders\\aftereffects\\test_project_TestAsset_compositing_v001\\TestAsset_renderCompositingMain_v001.mov'] # noqa: E501
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
'C:/test_project/assets/locations/Town/work/compositing\\renders\\aftereffects\\test_project_TestAsset_compositing_v001\\TestAsset_renderCompositingMain_v001.mov': None # noqa: E501
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_different_format():
|
||||
files = ["Asset.v001.renderCompositingMain_0000.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset.v001.renderCompositingMain_0000.png": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_withhout_version():
|
||||
files = ["pngv001.renderCompositingMain_0000.png"]
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"pngv001.renderCompositingMain_0000.png": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_sequence_as_dict():
|
||||
files = {"Asset_renderCompositingMain_v001.0000.png"}
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset_renderCompositingMain_v001.0000.png": "0000"
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
|
||||
def test_collect_frames_single_file():
|
||||
files = {"Asset_renderCompositingMain_v001.png"}
|
||||
ret = collect_frames(files)
|
||||
|
||||
expected = {
|
||||
"Asset_renderCompositingMain_v001.png": None
|
||||
}
|
||||
|
||||
print(ret)
|
||||
assert ret == expected, "Not matching"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue