mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-27 06:12:19 +01:00
Merge branch 'develop' into feature/OP-4245Data_Exchange_Geometry
This commit is contained in:
commit
24b492dc49
14 changed files with 311 additions and 121 deletions
|
|
@ -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)
|
||||
|
|
@ -3562,3 +3574,34 @@ def get_color_management_output_transform():
|
|||
if preferences["output_transform_enabled"]:
|
||||
colorspace = preferences["output_transform"]
|
||||
return colorspace
|
||||
|
||||
|
||||
def len_flattened(components):
|
||||
"""Return the length of the list as if it was flattened.
|
||||
|
||||
Maya will return consecutive components as a single entry
|
||||
when requesting with `maya.cmds.ls` without the `flatten`
|
||||
flag. Though enabling `flatten` on a large list (e.g. millions)
|
||||
will result in a slow result. This command will return the amount
|
||||
of entries in a non-flattened list by parsing the result with
|
||||
regex.
|
||||
|
||||
Args:
|
||||
components (list): The non-flattened components.
|
||||
|
||||
Returns:
|
||||
int: The amount of entries.
|
||||
|
||||
"""
|
||||
assert isinstance(components, (list, tuple))
|
||||
n = 0
|
||||
|
||||
pattern = re.compile(r"\[(\d+):(\d+)\]")
|
||||
for c in components:
|
||||
match = pattern.search(c)
|
||||
if match:
|
||||
start, end = match.groups()
|
||||
n += int(end) - int(start) + 1
|
||||
else:
|
||||
n += 1
|
||||
return n
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
# Create the instance
|
||||
instance = context.create_instance(objset)
|
||||
instance[:] = members_hierarchy
|
||||
instance.data["objset"] = objset
|
||||
|
||||
# Store the exact members of the object set
|
||||
instance.data["setMembers"] = members
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
from openpype.pipeline.publish import (
|
||||
ValidateContentsOrder, PublishValidationError, RepairAction
|
||||
)
|
||||
from openpype.pipeline import discover_legacy_creator_plugins
|
||||
from openpype.hosts.maya.api.lib import imprint
|
||||
|
||||
|
||||
class ValidateInstanceAttributes(pyblish.api.InstancePlugin):
|
||||
"""Validate Instance Attributes.
|
||||
|
||||
New attributes can be introduced as new features come in. Old instances
|
||||
will need to be updated with these attributes for the documentation to make
|
||||
sense, and users do not have to recreate the instances.
|
||||
"""
|
||||
|
||||
order = ValidateContentsOrder
|
||||
hosts = ["maya"]
|
||||
families = ["*"]
|
||||
label = "Instance Attributes"
|
||||
plugins_by_family = {
|
||||
p.family: p for p in discover_legacy_creator_plugins()
|
||||
}
|
||||
actions = [RepairAction]
|
||||
|
||||
@classmethod
|
||||
def get_missing_attributes(self, instance):
|
||||
plugin = self.plugins_by_family[instance.data["family"]]
|
||||
subset = instance.data["subset"]
|
||||
asset = instance.data["asset"]
|
||||
objset = instance.data["objset"]
|
||||
|
||||
missing_attributes = {}
|
||||
for key, value in plugin(subset, asset).data.items():
|
||||
if not cmds.objExists("{}.{}".format(objset, key)):
|
||||
missing_attributes[key] = value
|
||||
|
||||
return missing_attributes
|
||||
|
||||
def process(self, instance):
|
||||
objset = instance.data.get("objset")
|
||||
if objset is None:
|
||||
self.log.debug(
|
||||
"Skipping {} because no objectset found.".format(instance)
|
||||
)
|
||||
return
|
||||
|
||||
missing_attributes = self.get_missing_attributes(instance)
|
||||
if missing_attributes:
|
||||
raise PublishValidationError(
|
||||
"Missing attributes on {}:\n{}".format(
|
||||
objset, missing_attributes
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
imprint(instance.data["objset"], cls.get_missing_attributes(instance))
|
||||
54
openpype/hosts/maya/plugins/publish/validate_mesh_empty.py
Normal file
54
openpype/hosts/maya/plugins/publish/validate_mesh_empty.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
import openpype.hosts.maya.api.action
|
||||
from openpype.pipeline.publish import (
|
||||
RepairAction,
|
||||
ValidateMeshOrder
|
||||
)
|
||||
|
||||
|
||||
class ValidateMeshEmpty(pyblish.api.InstancePlugin):
|
||||
"""Validate meshes have some vertices.
|
||||
|
||||
Its possible to have meshes without any vertices. To replicate
|
||||
this issue, delete all faces/polygons then all edges.
|
||||
"""
|
||||
|
||||
order = ValidateMeshOrder
|
||||
hosts = ["maya"]
|
||||
families = ["model"]
|
||||
label = "Mesh Empty"
|
||||
actions = [
|
||||
openpype.hosts.maya.api.action.SelectInvalidAction, RepairAction
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
invalid = cls.get_invalid(instance)
|
||||
for node in invalid:
|
||||
cmds.delete(node)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
invalid = []
|
||||
|
||||
meshes = cmds.ls(instance, type="mesh", long=True)
|
||||
for mesh in meshes:
|
||||
num_vertices = cmds.polyEvaluate(mesh, vertex=True)
|
||||
|
||||
if num_vertices == 0:
|
||||
cls.log.warning(
|
||||
"\"{}\" does not have any vertices.".format(mesh)
|
||||
)
|
||||
invalid.append(mesh)
|
||||
|
||||
return invalid
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError(
|
||||
"Meshes found in instance without any vertices: %s" % invalid
|
||||
)
|
||||
|
|
@ -1,39 +1,9 @@
|
|||
import re
|
||||
|
||||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
import openpype.hosts.maya.api.action
|
||||
from openpype.pipeline.publish import ValidateMeshOrder
|
||||
|
||||
|
||||
def len_flattened(components):
|
||||
"""Return the length of the list as if it was flattened.
|
||||
|
||||
Maya will return consecutive components as a single entry
|
||||
when requesting with `maya.cmds.ls` without the `flatten`
|
||||
flag. Though enabling `flatten` on a large list (e.g. millions)
|
||||
will result in a slow result. This command will return the amount
|
||||
of entries in a non-flattened list by parsing the result with
|
||||
regex.
|
||||
|
||||
Args:
|
||||
components (list): The non-flattened components.
|
||||
|
||||
Returns:
|
||||
int: The amount of entries.
|
||||
|
||||
"""
|
||||
assert isinstance(components, (list, tuple))
|
||||
n = 0
|
||||
for c in components:
|
||||
match = re.search("\[([0-9]+):([0-9]+)\]", c)
|
||||
if match:
|
||||
start, end = match.groups()
|
||||
n += int(end) - int(start) + 1
|
||||
else:
|
||||
n += 1
|
||||
return n
|
||||
from openpype.hosts.maya.api.lib import len_flattened
|
||||
|
||||
|
||||
class ValidateMeshHasUVs(pyblish.api.InstancePlugin):
|
||||
|
|
@ -57,6 +27,15 @@ class ValidateMeshHasUVs(pyblish.api.InstancePlugin):
|
|||
invalid = []
|
||||
|
||||
for node in cmds.ls(instance, type='mesh'):
|
||||
num_vertices = cmds.polyEvaluate(node, vertex=True)
|
||||
|
||||
if num_vertices == 0:
|
||||
cls.log.warning(
|
||||
"Skipping \"{}\", cause it does not have any "
|
||||
"vertices.".format(node)
|
||||
)
|
||||
continue
|
||||
|
||||
uv = cmds.polyEvaluate(node, uv=True)
|
||||
|
||||
if uv == 0:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ class ValidateMeshNonZeroEdgeLength(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
"""Return the invalid edges.
|
||||
Also see: http://help.autodesk.com/view/MAYAUL/2015/ENU/?guid=Mesh__Cleanup
|
||||
|
||||
Also see:
|
||||
|
||||
http://help.autodesk.com/view/MAYAUL/2015/ENU/?guid=Mesh__Cleanup
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -36,8 +39,21 @@ class ValidateMeshNonZeroEdgeLength(pyblish.api.InstancePlugin):
|
|||
if not meshes:
|
||||
return list()
|
||||
|
||||
valid_meshes = []
|
||||
for mesh in meshes:
|
||||
num_vertices = cmds.polyEvaluate(mesh, vertex=True)
|
||||
|
||||
if num_vertices == 0:
|
||||
cls.log.warning(
|
||||
"Skipping \"{}\", cause it does not have any "
|
||||
"vertices.".format(mesh)
|
||||
)
|
||||
continue
|
||||
|
||||
valid_meshes.append(mesh)
|
||||
|
||||
# Get all edges
|
||||
edges = ['{0}.e[*]'.format(node) for node in meshes]
|
||||
edges = ['{0}.e[*]'.format(node) for node in valid_meshes]
|
||||
|
||||
# Filter by constraint on edge length
|
||||
invalid = lib.polyConstraint(edges,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import re
|
||||
|
||||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
|
|
@ -8,37 +6,7 @@ from openpype.pipeline.publish import (
|
|||
RepairAction,
|
||||
ValidateMeshOrder,
|
||||
)
|
||||
|
||||
|
||||
def len_flattened(components):
|
||||
"""Return the length of the list as if it was flattened.
|
||||
|
||||
Maya will return consecutive components as a single entry
|
||||
when requesting with `maya.cmds.ls` without the `flatten`
|
||||
flag. Though enabling `flatten` on a large list (e.g. millions)
|
||||
will result in a slow result. This command will return the amount
|
||||
of entries in a non-flattened list by parsing the result with
|
||||
regex.
|
||||
|
||||
Args:
|
||||
components (list): The non-flattened components.
|
||||
|
||||
Returns:
|
||||
int: The amount of entries.
|
||||
|
||||
"""
|
||||
assert isinstance(components, (list, tuple))
|
||||
n = 0
|
||||
|
||||
pattern = re.compile(r"\[(\d+):(\d+)\]")
|
||||
for c in components:
|
||||
match = pattern.search(c)
|
||||
if match:
|
||||
start, end = match.groups()
|
||||
n += int(end) - int(start) + 1
|
||||
else:
|
||||
n += 1
|
||||
return n
|
||||
from openpype.hosts.maya.api.lib import len_flattened
|
||||
|
||||
|
||||
class ValidateMeshVerticesHaveEdges(pyblish.api.InstancePlugin):
|
||||
|
|
@ -87,6 +55,13 @@ class ValidateMeshVerticesHaveEdges(pyblish.api.InstancePlugin):
|
|||
for mesh in meshes:
|
||||
num_vertices = cmds.polyEvaluate(mesh, vertex=True)
|
||||
|
||||
if num_vertices == 0:
|
||||
cls.log.warning(
|
||||
"Skipping \"{}\", cause it does not have any "
|
||||
"vertices.".format(mesh)
|
||||
)
|
||||
continue
|
||||
|
||||
# Vertices from all edges
|
||||
edges = "%s.e[*]" % mesh
|
||||
vertices = cmds.polyListComponentConversion(edges, toVertex=True)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -179,6 +179,13 @@
|
|||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateReview": {
|
||||
"enabled": true,
|
||||
"defaults": [
|
||||
"Main"
|
||||
],
|
||||
"useMayaTimeline": true
|
||||
},
|
||||
"CreateAss": {
|
||||
"enabled": true,
|
||||
"defaults": [
|
||||
|
|
@ -255,12 +262,6 @@
|
|||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateReview": {
|
||||
"enabled": true,
|
||||
"defaults": [
|
||||
"Main"
|
||||
]
|
||||
},
|
||||
"CreateRig": {
|
||||
"enabled": true,
|
||||
"defaults": [
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -398,10 +423,6 @@
|
|||
"key": "CreateRenderSetup",
|
||||
"label": "Create Render Setup"
|
||||
},
|
||||
{
|
||||
"key": "CreateReview",
|
||||
"label": "Create Review"
|
||||
},
|
||||
{
|
||||
"key": "CreateRig",
|
||||
"label": "Create Rig"
|
||||
|
|
|
|||
|
|
@ -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
|
|||
|
||||

|
||||
|
||||
### 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`
|
||||
|
||||

|
||||
|
||||
- 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.
|
||||
|
||||

|
||||
|
||||
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`
|
||||
|
||||

|
||||
|
||||
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`
|
||||
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue