Merge branch 'enhancement/blender_new_publisher' of https://github.com/BigRoy/OpenPype into enhancement/blender_new_publisher

This commit is contained in:
Roy Nieterau 2023-11-15 16:41:04 +01:00
commit 6fd39049a3
33 changed files with 84 additions and 69 deletions

View file

@ -35,6 +35,7 @@ body:
label: Version
description: What version are you running? Look to OpenPype Tray
options:
- 3.17.6-nightly.3
- 3.17.6-nightly.2
- 3.17.6-nightly.1
- 3.17.5
@ -134,7 +135,6 @@ body:
- 3.15.2-nightly.2
- 3.15.2-nightly.1
- 3.15.1
- 3.15.1-nightly.6
validations:
required: true
- type: dropdown

View file

@ -62,19 +62,6 @@ SHAPE_ATTRS = {"castsShadows",
"doubleSided",
"opposite"}
RENDER_ATTRS = {"vray": {
"node": "vraySettings",
"prefix": "fileNamePrefix",
"padding": "fileNamePadding",
"ext": "imageFormatStr"
},
"default": {
"node": "defaultRenderGlobals",
"prefix": "imageFilePrefix",
"padding": "extensionPadding"
}
}
DEFAULT_MATRIX = [1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,

View file

@ -33,6 +33,14 @@ class RenderSettings(object):
def get_image_prefix_attr(cls, renderer):
return cls._image_prefix_nodes[renderer]
@staticmethod
def get_padding_attr(renderer):
"""Return attribute for renderer that defines frame padding amount"""
if renderer == "vray":
return "vraySettings.fileNamePadding"
else:
return "defaultRenderGlobals.extensionPadding"
def __init__(self, project_settings=None):
if not project_settings:
project_settings = get_project_settings(

View file

@ -12,6 +12,7 @@ from openpype.pipeline.publish import (
PublishValidationError,
)
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api.lib_rendersettings import RenderSettings
def convert_to_int_or_float(string_value):
@ -129,13 +130,13 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
layer = instance.data['renderlayer']
cameras = instance.data.get("cameras", [])
# Get the node attributes for current renderer
attrs = lib.RENDER_ATTRS.get(renderer, lib.RENDER_ATTRS['default'])
# Prefix attribute can return None when a value was never set
prefix = lib.get_attr_in_layer(cls.ImagePrefixes[renderer],
layer=layer) or ""
padding = lib.get_attr_in_layer("{node}.{padding}".format(**attrs),
layer=layer)
padding = lib.get_attr_in_layer(
attr=RenderSettings.get_padding_attr(renderer),
layer=layer
)
anim_override = lib.get_attr_in_layer("defaultRenderGlobals.animation",
layer=layer)
@ -372,8 +373,6 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
lib.set_attribute(data["attribute"], data["values"][0], node)
with lib.renderlayer(layer_node):
default = lib.RENDER_ATTRS['default']
render_attrs = lib.RENDER_ATTRS.get(renderer, default)
# Repair animation must be enabled
cmds.setAttr("defaultRenderGlobals.animation", True)
@ -391,15 +390,13 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin):
default_prefix = default_prefix.replace(variant, "")
if renderer != "renderman":
node = render_attrs["node"]
prefix_attr = render_attrs["prefix"]
prefix_attr = RenderSettings.get_image_prefix_attr(renderer)
fname_prefix = default_prefix
cmds.setAttr("{}.{}".format(node, prefix_attr),
fname_prefix, type="string")
# Repair padding
padding_attr = render_attrs["padding"]
padding_attr = RenderSettings.get_padding_attr(renderer)
cmds.setAttr("{}.{}".format(node, padding_attr),
cls.DEFAULT_PADDING)
else:

View file

@ -701,6 +701,8 @@ or updating already created. Publishing will create OTIO file.
# parent time properties
"trackStartFrame": track_start_frame,
"timelineOffset": timeline_offset,
"isEditorial": True,
# creator_attributes
"creator_attributes": creator_attributes
}

View file

@ -27,6 +27,12 @@ class CollectSequenceFrameData(
if not self.is_active(instance.data):
return
# editorial would fail since they might not be in database yet
is_editorial = instance.data.get("isEditorial")
if is_editorial:
self.log.debug("Instance is Editorial. Skipping.")
return
frame_data = self.get_frame_data_from_repre_sequence(instance)
if not frame_data:

View file

@ -30,12 +30,17 @@ class ValidateFrameRange(OptionalPyblishPluginMixin,
if not self.is_active(instance.data):
return
# editorial would fail since they might not be in database yet
is_editorial = instance.data.get("isEditorial")
if is_editorial:
self.log.debug("Instance is Editorial. Skipping.")
return
if (self.skip_timelines_check and
any(re.search(pattern, instance.data["task"])
for pattern in self.skip_timelines_check)):
self.log.info("Skipping for {} task".format(instance.data["task"]))
asset_doc = instance.data["assetEntity"]
asset_data = asset_doc["data"]
frame_start = asset_data["frameStart"]
frame_end = asset_data["frameEnd"]

View file

@ -190,7 +190,7 @@ class LoadImage(plugin.Loader):
if pop_idx is None:
self.log.warning(
"Didn't found container in workfile containers. {}".format(
"Didn't find container in workfile containers. {}".format(
container
)
)

View file

@ -85,7 +85,7 @@ class AyonDeadlinePlugin(DeadlinePlugin):
}
for env, val in environment.items():
self.SetProcessEnvironmentVariable(env, val)
self.SetEnvironmentVariable(env, val)
exe_list = self.GetConfigEntry("AyonExecutable")
# clean '\ ' for MacOS pasting
@ -101,11 +101,11 @@ class AyonDeadlinePlugin(DeadlinePlugin):
if exe == "":
self.FailRender(
"Ayon executable was not found " +
"in the semicolon separated list " +
"\"" + ";".join(exe_list) + "\". " +
"The path to the render executable can be configured " +
"from the Plugin Configuration in the Deadline Monitor.")
"Ayon executable was not found in the semicolon separated "
"list: \"{}\". The path to the render executable can be "
"configured from the Plugin Configuration in the Deadline "
"Monitor.".format(exe_list)
)
return exe
def RenderArgument(self):

View file

@ -495,7 +495,10 @@ def inject_ayon_environment(deadlinePlugin):
"AYON_BUNDLE_NAME": ayon_bundle_name,
}
for env, val in environment.items():
# Add the env var for the Render Plugin that is about to render
deadlinePlugin.SetEnvironmentVariable(env, val)
# Add the env var for current calls to `DeadlinePlugin.RunProcess`
deadlinePlugin.SetProcessEnvironmentVariable(env, val)
args_str = subprocess.list2cmdline(args)
print(">>> Executing: {} {}".format(exe, args_str))

View file

@ -66,7 +66,7 @@ class TransferHierarchicalValues(ServerAction):
"items": [{
"type": "label",
"value": (
"Didn't found custom attributes"
"Didn't find custom attributes"
" that can be transferred."
)
}]

View file

@ -257,7 +257,7 @@ class NextTaskUpdate(BaseEvent):
new_task_name = mapping.get(old_status_name)
if not new_task_name:
self.log.debug(
"Didn't found mapping for status \"{}\".".format(
"Didn't find mapping for status \"{}\".".format(
task_status["name"]
)
)

View file

@ -387,7 +387,7 @@ class SyncToAvalonEvent(BaseEvent):
if not data:
# TODO logging
self.log.warning(
"Didn't found entity by key/value \"{}\" / \"{}\"".format(
"Didn't find entity by key/value \"{}\" / \"{}\"".format(
key, value
)
)

View file

@ -51,7 +51,7 @@ class ComponentOpen(BaseAction):
else:
return {
'success': False,
'message': "Didn't found file: " + fpath
'message': "Didn't find file: " + fpath
}
return {

View file

@ -169,7 +169,7 @@ class DeleteAssetSubset(BaseAction):
return {
"success": True,
"message": (
"Didn't found entities in avalon."
"Didn't find entities in avalon."
" You can use Ftrack's Delete button for the selection."
)
}

View file

@ -61,7 +61,7 @@ class Delivery(BaseAction):
return {
"success": False,
"message": (
"Didn't found project \"{}\" in avalon."
"Didn't find project \"{}\" in avalon."
).format(project_name)
}

View file

@ -29,7 +29,7 @@ class JobKiller(BaseAction):
if not jobs:
return {
"success": True,
"message": "Didn't found any running jobs"
"message": "Didn't find any running jobs"
}
# Collect user ids from jobs

View file

@ -10,6 +10,7 @@ from maya import cmds
import pyblish.api
from openpype.lib import requests_post
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api.lib_rendersettings import RenderSettings
from openpype.pipeline import legacy_io
from openpype.settings import get_system_settings
@ -68,10 +69,8 @@ def get_renderer_variables(renderlayer=None):
"""
renderer = lib.get_renderer(renderlayer or lib.get_current_renderlayer())
render_attrs = lib.RENDER_ATTRS.get(renderer, lib.RENDER_ATTRS["default"])
padding = cmds.getAttr("{}.{}".format(render_attrs["node"],
render_attrs["padding"]))
padding = cmds.getAttr(RenderSettings.get_padding_attr(renderer))
filename_0 = cmds.renderSettings(fullPath=True, firstImageName=True)[0]

View file

@ -58,21 +58,21 @@ class ExplicitCleanUp(pyblish.api.ContextPlugin):
# Store failed paths with exception
failed = []
# Store removed filepaths for logging
succeded_files = set()
succeeded_files = set()
# Remove file by file
for filepath in filepaths:
try:
os.remove(filepath)
succeded_files.add(filepath)
succeeded_files.add(filepath)
except Exception as exc:
failed.append((filepath, exc))
if succeded_files:
if succeeded_files:
self.log.info(
"Removed files:\n{}".format("\n".join(succeded_files))
"Removed files:\n{}".format("\n".join(sorted(succeeded_files)))
)
# Delete folders with it's content
# Delete folders with its content
succeeded = set()
for dirpath in dirpaths:
# Check if directory still exists
@ -87,17 +87,21 @@ class ExplicitCleanUp(pyblish.api.ContextPlugin):
if succeeded:
self.log.info(
"Removed directories:\n{}".format("\n".join(succeeded))
"Removed directories:\n{}".format(
"\n".join(sorted(succeeded))
)
)
# Prepare lines for report of failed removements
# Prepare lines for report of failed removals
lines = []
for filepath, exc in failed:
lines.append("{}: {}".format(filepath, str(exc)))
if lines:
self.log.warning(
"Failed to remove filepaths:\n{}".format("\n".join(lines))
"Failed to remove filepaths:\n{}".format(
"\n".join(sorted(lines))
)
)
def _remove_empty_dirs(self, empty_dirpaths):
@ -134,8 +138,8 @@ class ExplicitCleanUp(pyblish.api.ContextPlugin):
if to_skip_dirpaths:
self.log.debug(
"Skipped directories because contain files:\n{}".format(
"\n".join(to_skip_dirpaths)
"Skipped directories because they contain files:\n{}".format(
"\n".join(sorted(to_skip_dirpaths))
)
)
@ -147,6 +151,6 @@ class ExplicitCleanUp(pyblish.api.ContextPlugin):
if to_delete_dirpaths:
self.log.debug(
"Deleted empty directories:\n{}".format(
"\n".join(to_delete_dirpaths)
"\n".join(sorted(to_delete_dirpaths))
)
)

View file

@ -54,6 +54,8 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin):
staging_dir = data_object.get("stagingDir")
if staging_dir:
data_object["stagingDir"] = anatomy.fill_root(staging_dir)
self.log.debug("Filling stagingDir with root to: %s",
data_object["stagingDir"])
def _process_path(self, data, anatomy):
"""Process data of a single JSON publish metadata file.
@ -108,7 +110,6 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin):
instance = self._context.create_instance(
instance_data.get("subset")
)
self.log.debug("Filling stagingDir...")
self._fill_staging_dir(instance_data, anatomy)
instance.data.update(instance_data)
@ -161,7 +162,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin):
anatomy.project_name
))
self.log.debug("anatomy: {}".format(anatomy.roots))
self.log.debug("Anatomy roots: {}".format(anatomy.roots))
try:
session_is_set = False
for path in paths:

View file

@ -68,6 +68,12 @@ class CollectResourcesPath(pyblish.api.InstancePlugin):
]
def process(self, instance):
# editorial would fail since they might not be in database yet
is_editorial = instance.data.get("isEditorial")
if is_editorial:
self.log.debug("Instance is Editorial. Skipping.")
return
anatomy = instance.context.data["anatomy"]
template_data = copy.deepcopy(instance.data["anatomyData"])

View file

@ -171,8 +171,6 @@ class ExtractBurnin(publish.Extractor):
).format(host_name, family, task_name, task_type, subset))
return
self.log.debug("profile: {}".format(profile))
# Pre-filter burnin definitions by instance families
burnin_defs = self.filter_burnins_defs(profile, instance)
if not burnin_defs:
@ -450,7 +448,7 @@ class ExtractBurnin(publish.Extractor):
filling burnin strings. `temp_data` are for repre pre-process
preparation.
"""
self.log.debug("Prepring basic data for burnins")
self.log.debug("Preparing basic data for burnins")
context = instance.context
version = instance.data.get("version")

View file

@ -326,7 +326,6 @@ class ExtractOIIOTranscode(publish.Extractor):
" | Task type \"{}\" | Subset \"{}\" "
).format(host_name, family, task_name, task_type, subset))
self.log.debug("profile: {}".format(profile))
return profile
def _repre_is_valid(self, repre):

View file

@ -143,7 +143,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
custom_tags = repre.get("custom_tags")
if "review" not in tags:
self.log.debug((
"Repre: {} - Didn't found \"review\" in tags. Skipping"
"Repre: {} - Didn't find \"review\" in tags. Skipping"
).format(repre_name))
continue

View file

@ -200,7 +200,7 @@ class IntegrateThumbnails(pyblish.api.ContextPlugin):
if thumb_repre_doc is None:
self.log.debug(
"There is not representation with name \"thumbnail\""
"There is no representation with name \"thumbnail\""
)
return None

View file

@ -137,7 +137,7 @@ class IntegrateThumbnailsAYON(pyblish.api.ContextPlugin):
if thumb_repre_doc is None:
self.log.debug(
"There is not representation with name \"thumbnail\""
"There is no representation with name \"thumbnail\""
)
return None

View file

@ -352,7 +352,7 @@ class DictConditionalEntity(ItemEntity):
break
if result_key is None:
raise ValueError("Didn't found child {}".format(child_obj))
raise ValueError("Didn't find child {}".format(child_obj))
return "/".join([self.path, result_key])

View file

@ -232,7 +232,7 @@ class DictImmutableKeysEntity(ItemEntity):
break
if result_key is None:
raise ValueError("Didn't found child {}".format(child_obj))
raise ValueError("Didn't find child {}".format(child_obj))
return "/".join([self.path, result_key])

View file

@ -284,7 +284,7 @@ class DictMutableKeysEntity(EndpointEntity):
break
if result_key is None:
raise ValueError("Didn't found child {}".format(child_obj))
raise ValueError("Didn't find child {}".format(child_obj))
return "/".join([self.path, result_key])

View file

@ -295,7 +295,7 @@ class ListStrictEntity(ItemEntity):
break
if result_idx is None:
raise ValueError("Didn't found child {}".format(child_obj))
raise ValueError("Didn't find child {}".format(child_obj))
return "/".join([self.path, str(result_idx)])

View file

@ -258,7 +258,7 @@ class ListEntity(EndpointEntity):
break
if result_idx is None:
raise ValueError("Didn't found child {}".format(child_obj))
raise ValueError("Didn't find child {}".format(child_obj))
return "/".join([self.path, str(result_idx)])

View file

@ -270,7 +270,7 @@ class RootEntity(BaseItemEntity):
for key, _child_entity in self.non_gui_children.items():
if _child_entity is child_entity:
return key
raise ValueError("Didn't found child {}".format(child_entity))
raise ValueError("Didn't find child {}".format(child_entity))
@property
def value(self):

View file

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