Merge branch 'bugfix/OP-5037_Global-workfile-template-builder-Creators-failing' into feature/OP-4778_Nuke-create-first-workfile-template-switch-to-preset

This commit is contained in:
Jakub Jezek 2023-03-06 12:08:25 +01:00
commit 0993fa447d
No known key found for this signature in database
GPG key ID: 730D7C02726179A7
18 changed files with 208 additions and 87 deletions

View file

@ -4,7 +4,6 @@ import os
import sys
import platform
import uuid
import math
import re
import json
@ -2064,13 +2063,8 @@ def set_scene_resolution(width, height, pixelAspect):
cmds.setAttr("%s.pixelAspect" % control_node, pixelAspect)
def reset_frame_range():
"""Set frame range to current asset"""
fps = convert_to_maya_fps(
float(legacy_io.Session.get("AVALON_FPS", 25))
)
set_scene_fps(fps)
def get_frame_range():
"""Get the current assets frame range and handles."""
# Set frame start/end
project_name = legacy_io.active_project()
@ -2097,8 +2091,26 @@ def reset_frame_range():
if handle_end is None:
handle_end = handles
frame_start -= int(handle_start)
frame_end += int(handle_end)
return {
"frameStart": frame_start,
"frameEnd": frame_end,
"handleStart": handle_start,
"handleEnd": handle_end
}
def reset_frame_range():
"""Set frame range to current asset"""
fps = convert_to_maya_fps(
float(legacy_io.Session.get("AVALON_FPS", 25))
)
set_scene_fps(fps)
frame_range = get_frame_range()
frame_start = frame_range["frameStart"] - int(frame_range["handleStart"])
frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"])
cmds.playbackOptions(minTime=frame_start)
cmds.playbackOptions(maxTime=frame_end)

View file

@ -25,16 +25,20 @@ class CreateReview(plugin.Creator):
"depth peeling",
"alpha cut"
]
useMayaTimeline = True
def __init__(self, *args, **kwargs):
super(CreateReview, self).__init__(*args, **kwargs)
# get basic animation data : start / end / handles / steps
data = OrderedDict(**self.data)
animation_data = lib.collect_animation_data(fps=True)
for key, value in animation_data.items():
# Option for using Maya or asset frame range in settings.
frame_range = lib.get_frame_range()
if self.useMayaTimeline:
frame_range = lib.collect_animation_data(fps=True)
for key, value in frame_range.items():
data[key] = value
data["fps"] = lib.collect_animation_data(fps=True)["fps"]
data["review_width"] = self.Width
data["review_height"] = self.Height
data["isolate"] = self.isolate

View file

@ -9,6 +9,9 @@ class CreateVrayProxy(plugin.Creator):
family = "vrayproxy"
icon = "gears"
vrmesh = True
alembic = True
def __init__(self, *args, **kwargs):
super(CreateVrayProxy, self).__init__(*args, **kwargs)
@ -18,3 +21,6 @@ class CreateVrayProxy(plugin.Creator):
# Write vertex colors
self.data["vertexColors"] = False
self.data["vrmesh"] = self.vrmesh
self.data["alembic"] = self.alembic

View file

@ -9,10 +9,16 @@ class CollectVrayProxy(pyblish.api.InstancePlugin):
Add `pointcache` family for it.
"""
order = pyblish.api.CollectorOrder + 0.01
label = 'Collect Vray Proxy'
label = "Collect Vray Proxy"
families = ["vrayproxy"]
def process(self, instance):
"""Collector entry point."""
if not instance.data.get('families'):
instance.data["families"] = []
if instance.data.get("vrmesh"):
instance.data["families"].append("vrayproxy.vrmesh")
if instance.data.get("alembic"):
instance.data["families"].append("vrayproxy.alembic")

View file

@ -23,7 +23,7 @@ class ExtractAlembic(publish.Extractor):
label = "Extract Pointcache (Alembic)"
hosts = ["maya"]
families = ["pointcache", "model", "vrayproxy"]
families = ["pointcache", "model", "vrayproxy.alembic"]
targets = ["local", "remote"]
def process(self, instance):

View file

@ -16,7 +16,7 @@ class ExtractVRayProxy(publish.Extractor):
label = "VRay Proxy (.vrmesh)"
hosts = ["maya"]
families = ["vrayproxy"]
families = ["vrayproxy.vrmesh"]
def process(self, instance):

View file

@ -57,6 +57,10 @@ class ValidateFrameRange(pyblish.api.InstancePlugin):
inst_start = int(instance.data.get("frameStartHandle"))
inst_end = int(instance.data.get("frameEndHandle"))
inst_frame_start = int(instance.data.get("frameStart"))
inst_frame_end = int(instance.data.get("frameEnd"))
inst_handle_start = int(instance.data.get("handleStart"))
inst_handle_end = int(instance.data.get("handleEnd"))
# basic sanity checks
assert frame_start_handle <= frame_end_handle, (
@ -69,24 +73,37 @@ class ValidateFrameRange(pyblish.api.InstancePlugin):
if [ef for ef in self.exclude_families
if instance.data["family"] in ef]:
return
if(inst_start != frame_start_handle):
if (inst_start != frame_start_handle):
errors.append("Instance start frame [ {} ] doesn't "
"match the one set on instance [ {} ]: "
"match the one set on asset [ {} ]: "
"{}/{}/{}/{} (handle/start/end/handle)".format(
inst_start,
frame_start_handle,
handle_start, frame_start, frame_end, handle_end
))
if(inst_end != frame_end_handle):
if (inst_end != frame_end_handle):
errors.append("Instance end frame [ {} ] doesn't "
"match the one set on instance [ {} ]: "
"match the one set on asset [ {} ]: "
"{}/{}/{}/{} (handle/start/end/handle)".format(
inst_end,
frame_end_handle,
handle_start, frame_start, frame_end, handle_end
))
checks = {
"frame start": (frame_start, inst_frame_start),
"frame end": (frame_end, inst_frame_end),
"handle start": (handle_start, inst_handle_start),
"handle end": (handle_end, inst_handle_end)
}
for label, values in checks.items():
if values[0] != values[1]:
errors.append(
"{} on instance ({}) does not match with the asset "
"({}).".format(label.title(), values[1], values[0])
)
for e in errors:
self.log.error(e)

View file

@ -1,27 +1,31 @@
import pyblish.api
from openpype.pipeline import KnownPublishError
class ValidateVrayProxy(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
label = 'VRay Proxy Settings'
hosts = ['maya']
families = ['studio.vrayproxy']
label = "VRay Proxy Settings"
hosts = ["maya"]
families = ["vrayproxy"]
def process(self, instance):
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("'%s' has invalid settings for VRay Proxy "
"export!" % instance.name)
@classmethod
def get_invalid(cls, instance):
data = instance.data
if not data["setMembers"]:
cls.log.error("'%s' is empty! This is a bug" % instance.name)
raise KnownPublishError(
"'%s' is empty! This is a bug" % instance.name
)
if data["animation"]:
if data["frameEnd"] < data["frameStart"]:
cls.log.error("End frame is smaller than start frame")
raise KnownPublishError(
"End frame is smaller than start frame"
)
if not data["vrmesh"] and not data["alembic"]:
raise KnownPublishError(
"Both vrmesh and alembic are off. Needs at least one to"
" publish."
)

View file

@ -419,8 +419,13 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
assembly_job_info.Name += " - Tile Assembly Job"
assembly_job_info.Frames = 1
assembly_job_info.MachineLimit = 1
assembly_job_info.Priority = instance.data.get("tile_priority",
self.tile_priority)
assembly_job_info.Priority = instance.data.get(
"tile_priority", self.tile_priority
)
pool = instance.context.data["project_settings"]["deadline"]
pool = pool["publish"]["ProcessSubmittedJobOnFarm"]["deadline_pool"]
assembly_job_info.Pool = pool or instance.data.get("primaryPool", "")
assembly_plugin_info = {
"CleanupTiles": 1,

View file

@ -284,6 +284,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
args.append("--automatic-tests")
# Generate the payload for Deadline submission
secondary_pool = (
self.deadline_pool_secondary or instance.data.get("secondaryPool")
)
payload = {
"JobInfo": {
"Plugin": self.deadline_plugin,
@ -297,8 +300,8 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
"Priority": priority,
"Group": self.deadline_group,
"Pool": instance.data.get("primaryPool"),
"SecondaryPool": instance.data.get("secondaryPool"),
"Pool": self.deadline_pool or instance.data.get("primaryPool"),
"SecondaryPool": secondary_pool,
# ensure the outputdirectory with correct slashes
"OutputDirectory0": output_dir.replace("\\", "/")
},
@ -588,7 +591,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
self.log.debug("instances:{}".format(instances))
return instances
def _get_representations(self, instance, exp_files, additional_data):
def _get_representations(self, instance, exp_files):
"""Create representations for file sequences.
This will return representations of expected files if they are not
@ -933,20 +936,21 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
self.log.info(data.get("expectedFiles"))
additional_data = {
"renderProducts": instance.data["renderProducts"],
"colorspaceConfig": instance.data["colorspaceConfig"],
"display": instance.data["colorspaceDisplay"],
"view": instance.data["colorspaceView"],
"colorspaceTemplate": instance.data["colorspaceConfig"].replace(
str(context.data["anatomy"].roots["work"]), "{root[work]}"
)
}
if isinstance(data.get("expectedFiles")[0], dict):
# we cannot attach AOVs to other subsets as we consider every
# AOV subset of its own.
config = instance.data["colorspaceConfig"]
additional_data = {
"renderProducts": instance.data["renderProducts"],
"colorspaceConfig": instance.data["colorspaceConfig"],
"display": instance.data["colorspaceDisplay"],
"view": instance.data["colorspaceView"],
"colorspaceTemplate": config.replace(
str(context.data["anatomy"].roots["work"]), "{root[work]}"
)
}
if len(data.get("attachTo")) > 0:
assert len(data.get("expectedFiles")[0].keys()) == 1, (
"attaching multiple AOVs or renderable cameras to "

View file

@ -1711,7 +1711,7 @@ class PlaceholderCreateMixin(object):
task_name=task_name
)
except:
except: # noqa: E722
failed = True
self.create_failed(placeholder, creator_data)

View file

@ -129,11 +129,14 @@ class ExtractOIIOTranscode(publish.Extractor):
colorspace_data.get("display"))
# both could be already collected by DCC,
# but could be overwritten
# but could be overwritten when transcoding
if view:
new_repre["colorspaceData"]["view"] = view
if display:
new_repre["colorspaceData"]["display"] = display
if target_colorspace:
new_repre["colorspaceData"]["colorspace"] = \
target_colorspace
additional_command_args = (output_def["oiiotool_args"]
["additional_command_args"])

View file

@ -179,6 +179,13 @@
"Main"
]
},
"CreateReview": {
"enabled": true,
"defaults": [
"Main"
],
"useMayaTimeline": true
},
"CreateAss": {
"enabled": true,
"defaults": [
@ -199,6 +206,14 @@
"maskColor_manager": false,
"maskOperator": false
},
"CreateVrayProxy": {
"enabled": true,
"vrmesh": true,
"alembic": true,
"defaults": [
"Main"
]
},
"CreateMultiverseUsd": {
"enabled": true,
"defaults": [
@ -247,12 +262,6 @@
"Main"
]
},
"CreateReview": {
"enabled": true,
"defaults": [
"Main"
]
},
"CreateRig": {
"enabled": true,
"defaults": [
@ -268,12 +277,6 @@
"Anim"
]
},
"CreateVrayProxy": {
"enabled": true,
"defaults": [
"Main"
]
},
"CreateVRayScene": {
"enabled": true,
"defaults": [
@ -676,7 +679,7 @@
"families": [
"pointcache",
"model",
"vrayproxy"
"vrayproxy.alembic"
]
},
"ExtractObj": {

View file

@ -240,6 +240,31 @@
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "CreateReview",
"label": "Create Review",
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "list",
"key": "defaults",
"label": "Default Subsets",
"object_type": "text"
},
{
"type": "boolean",
"key": "useMayaTimeline",
"label": "Use Maya Timeline for Frame Range."
}
]
},
{
"type": "dict",
"collapsible": true,
@ -332,6 +357,36 @@
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "CreateVrayProxy",
"label": "Create VRay Proxy",
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "boolean",
"key": "vrmesh",
"label": "VrMesh"
},
{
"type": "boolean",
"key": "alembic",
"label": "Alembic"
},
{
"type": "list",
"key": "defaults",
"label": "Default Subsets",
"object_type": "text"
}
]
},
{
"type": "schema_template",
"name": "template_create_plugin",
@ -368,10 +423,6 @@
"key": "CreateRenderSetup",
"label": "Create Render Setup"
},
{
"key": "CreateReview",
"label": "Create Review"
},
{
"key": "CreateRig",
"label": "Create Rig"
@ -380,10 +431,6 @@
"key": "CreateSetDress",
"label": "Create Set Dress"
},
{
"key": "CreateVrayProxy",
"label": "Create VRay Proxy"
},
{
"key": "CreateVRayScene",
"label": "Create VRay Scene"

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring Pype version."""
__version__ = "3.15.2-nightly.2"
__version__ = "3.15.2-nightly.3"

View file

@ -68,7 +68,7 @@ function Install-Poetry() {
}
$env:POETRY_HOME="$openpype_root\.poetry"
# $env:POETRY_VERSION="1.1.15"
$env:POETRY_VERSION="1.3.2"
(Invoke-WebRequest -Uri https://install.python-poetry.org/ -UseBasicParsing).Content | & $($python) -
}

View file

@ -109,7 +109,7 @@ detect_python () {
install_poetry () {
echo -e "${BIGreen}>>>${RST} Installing Poetry ..."
export POETRY_HOME="$openpype_root/.poetry"
# export POETRY_VERSION="1.1.15"
export POETRY_VERSION="1.3.2"
command -v curl >/dev/null 2>&1 || { echo -e "${BIRed}!!!${RST}${BIYellow} Missing ${RST}${BIBlue}curl${BIYellow} command.${RST}"; return 1; }
curl -sSL https://install.python-poetry.org/ | python -
}

View file

@ -28,16 +28,16 @@ For [AWS Thinkbox Deadline](https://www.awsthinkbox.com/deadline) support you ne
OpenPype integration for Deadline consists of two parts:
- The `OpenPype` Deadline Plug-in
- A `GlobalJobPreLoad` Deadline Script (this gets triggered for each deadline job)
- A `GlobalJobPreLoad` Deadline Script (this gets triggered for each deadline job)
The `GlobalJobPreLoad` handles populating render and publish jobs with proper environment variables using settings from the `OpenPype` Deadline Plug-in.
The `OpenPype` Deadline Plug-in must be configured to point to a valid OpenPype executable location. The executable need to be installed to
The `OpenPype` Deadline Plug-in must be configured to point to a valid OpenPype executable location. The executable need to be installed to
destinations accessible by DL process. Check permissions (must be executable and accessible by Deadline process)
- Enable `Tools > Super User Mode` in Deadline Monitor
- Go to `Tools > Configure Plugins...`, find `OpenPype` in the list on the left side, find location of OpenPype
- Go to `Tools > Configure Plugins...`, find `OpenPype` in the list on the left side, find location of OpenPype
executable. It is recommended to use the `openpype_console` executable as it provides a bit more logging.
- In case of multi OS farms, provide multiple locations, each Deadline Worker goes through the list and tries to find the first accessible
@ -45,12 +45,22 @@ executable. It is recommended to use the `openpype_console` executable as it pro
![Configure plugin](assets/deadline_configure_plugin.png)
### Pools
The main pools can be configured at `project_settings/deadline/publish/CollectDeadlinePools/primary_pool`, which is applied to the rendering jobs.
The dependent publishing job's pool uses `project_settings/deadline/publish/ProcessSubmittedJobOnFarm/deadline_pool`. If nothing is specified the pool will fallback to the primary pool above.
:::note maya tile rendering
The logic for publishing job pool assignment applies to tiling jobs.
:::
## Troubleshooting
#### Publishing jobs fail directly in DCCs
- Double check that all previously described steps were finished
- Check that `deadlinewebservice` is running on DL server
- Check that `deadlinewebservice` is running on DL server
- Check that user's machine has access to deadline server on configured port
#### Jobs are failing on DL side
@ -61,40 +71,40 @@ Each publishing from OpenPype consists of 2 jobs, first one is rendering, second
- Jobs are failing with `OpenPype executable was not found` error
Check if OpenPype is installed on the Worker handling this job and ensure `OpenPype` Deadline Plug-in is properly [configured](#configuration)
Check if OpenPype is installed on the Worker handling this job and ensure `OpenPype` Deadline Plug-in is properly [configured](#configuration)
- Publishing job is failing with `ffmpeg not installed` error
OpenPype executable has to have access to `ffmpeg` executable, check OpenPype `Setting > General`
![FFmpeg setting](assets/ffmpeg_path.png)
- Both jobs finished successfully, but there is no review on Ftrack
Make sure that you correctly set published family to be send to Ftrack.
Make sure that you correctly set published family to be send to Ftrack.
![Ftrack Family](assets/ftrack/ftrack-collect-main.png)
Example: I want send to Ftrack review of rendered images from Harmony :
- `Host names`: "harmony"
- `Families`: "render"
- `Families`: "render"
- `Add Ftrack Family` to "Enabled"
Make sure that you actually configured to create review for published subset in `project_settings/ftrack/publish/CollectFtrackFamily`
![Ftrack Family](assets/deadline_review.png)
Example: I want to create review for all reviewable subsets in Harmony :
Example: I want to create review for all reviewable subsets in Harmony :
- Add "harmony" as a new key an ".*" as a value.
- Rendering jobs are stuck in 'Queued' state or failing
Make sure that your Deadline is not limiting specific jobs to be run only on specific machines. (Eg. only some machines have installed particular application.)
Check `project_settings/deadline`
![Deadline group](assets/deadline_group.png)
Example: I have separated machines with "Harmony" installed into "harmony" group on Deadline. I want rendering jobs published from Harmony to run only on those machines.