mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge branch 'develop' into enhancement/OP-4152_refactor-folder-colors
This commit is contained in:
commit
966b72c7bc
54 changed files with 428 additions and 402 deletions
|
|
@ -29,8 +29,14 @@ def main(ctx):
|
|||
|
||||
It wraps different commands together.
|
||||
"""
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
ctx.invoke(tray)
|
||||
# Print help if headless mode is used
|
||||
if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1":
|
||||
print(ctx.get_help())
|
||||
sys.exit(0)
|
||||
else:
|
||||
ctx.invoke(tray)
|
||||
|
||||
|
||||
@main.command()
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ class CreateCamera(plugin.Creator):
|
|||
subset = self.data["subset"]
|
||||
name = plugin.asset_name(asset, subset)
|
||||
|
||||
camera = bpy.data.cameras.new(subset)
|
||||
camera_obj = bpy.data.objects.new(subset, camera)
|
||||
|
||||
instances.objects.link(camera_obj)
|
||||
|
||||
asset_group = bpy.data.objects.new(name=name, object_data=None)
|
||||
asset_group.empty_display_type = 'SINGLE_ARROW'
|
||||
instances.objects.link(asset_group)
|
||||
|
|
@ -53,6 +48,11 @@ class CreateCamera(plugin.Creator):
|
|||
bpy.ops.object.parent_set(keep_transform=True)
|
||||
else:
|
||||
plugin.deselect_all()
|
||||
camera = bpy.data.cameras.new(subset)
|
||||
camera_obj = bpy.data.objects.new(subset, camera)
|
||||
|
||||
instances.objects.link(camera_obj)
|
||||
|
||||
camera_obj.select_set(True)
|
||||
asset_group.select_set(True)
|
||||
bpy.context.view_layer.objects.active = asset_group
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import contextlib
|
|||
|
||||
import hou # noqa
|
||||
|
||||
from openpype.host import HostBase, IWorkfileHost, ILoadHost, INewPublisher
|
||||
from openpype.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost
|
||||
|
||||
import pyblish.api
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create")
|
|||
INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory")
|
||||
|
||||
|
||||
class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, INewPublisher):
|
||||
class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost):
|
||||
name = "houdini"
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
|||
|
|
@ -3441,3 +3441,8 @@ def iter_visible_nodes_in_range(nodes, start, end):
|
|||
# If no more nodes to process break the frame iterations..
|
||||
if not node_dependencies:
|
||||
break
|
||||
|
||||
|
||||
def get_attribute_input(attr):
|
||||
connections = cmds.listConnections(attr, plugs=True, destination=False)
|
||||
return connections[0] if connections else None
|
||||
|
|
|
|||
|
|
@ -95,21 +95,25 @@ class RenderSettings(object):
|
|||
|
||||
if renderer == "redshift":
|
||||
self._set_redshift_settings(width, height)
|
||||
mel.eval("redshiftUpdateActiveAovList")
|
||||
|
||||
def _set_arnold_settings(self, width, height):
|
||||
"""Sets settings for Arnold."""
|
||||
from mtoa.core import createOptions # noqa
|
||||
from mtoa.aovs import AOVInterface # noqa
|
||||
createOptions()
|
||||
arnold_render_presets = self._project_settings["maya"]["RenderSettings"]["arnold_renderer"] # noqa
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
arnold_render_presets = render_settings["arnold_renderer"] # noqa
|
||||
# Force resetting settings and AOV list to avoid having to deal with
|
||||
# AOV checking logic, for now.
|
||||
# This is a work around because the standard
|
||||
# function to revert render settings does not reset AOVs list in MtoA
|
||||
# Fetch current aovs in case there's any.
|
||||
current_aovs = AOVInterface().getAOVs()
|
||||
remove_aovs = render_settings["remove_aovs"]
|
||||
if remove_aovs:
|
||||
# Remove fetched AOVs
|
||||
AOVInterface().removeAOVs(current_aovs)
|
||||
AOVInterface().removeAOVs(current_aovs)
|
||||
mel.eval("unifiedRenderGlobalsRevertToDefault")
|
||||
img_ext = arnold_render_presets["image_format"]
|
||||
img_prefix = arnold_render_presets["image_prefix"]
|
||||
|
|
@ -118,6 +122,8 @@ class RenderSettings(object):
|
|||
multi_exr = arnold_render_presets["multilayer_exr"]
|
||||
additional_options = arnold_render_presets["additional_options"]
|
||||
for aov in aovs:
|
||||
if aov in current_aovs and not remove_aovs:
|
||||
continue
|
||||
AOVInterface('defaultArnoldRenderOptions').addAOV(aov)
|
||||
|
||||
cmds.setAttr("defaultResolution.width", width)
|
||||
|
|
@ -141,12 +147,50 @@ class RenderSettings(object):
|
|||
|
||||
def _set_redshift_settings(self, width, height):
|
||||
"""Sets settings for Redshift."""
|
||||
redshift_render_presets = (
|
||||
self._project_settings
|
||||
["maya"]
|
||||
["RenderSettings"]
|
||||
["redshift_renderer"]
|
||||
)
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
redshift_render_presets = render_settings["redshift_renderer"]
|
||||
|
||||
remove_aovs = render_settings["remove_aovs"]
|
||||
all_rs_aovs = cmds.ls(type='RedshiftAOV')
|
||||
if remove_aovs:
|
||||
for aov in all_rs_aovs:
|
||||
enabled = cmds.getAttr("{}.enabled".format(aov))
|
||||
if enabled:
|
||||
cmds.delete(aov)
|
||||
|
||||
redshift_aovs = redshift_render_presets["aov_list"]
|
||||
# list all the aovs
|
||||
all_rs_aovs = cmds.ls(type='RedshiftAOV')
|
||||
for rs_aov in redshift_aovs:
|
||||
rs_layername = rs_aov
|
||||
if " " in rs_aov:
|
||||
rs_renderlayer = rs_aov.replace(" ", "")
|
||||
rs_layername = "rsAov_{}".format(rs_renderlayer)
|
||||
else:
|
||||
rs_layername = "rsAov_{}".format(rs_aov)
|
||||
if rs_layername in all_rs_aovs:
|
||||
continue
|
||||
cmds.rsCreateAov(type=rs_aov)
|
||||
# update the AOV list
|
||||
mel.eval("redshiftUpdateActiveAovList")
|
||||
|
||||
rs_p_engine = redshift_render_presets["primary_gi_engine"]
|
||||
rs_s_engine = redshift_render_presets["secondary_gi_engine"]
|
||||
|
||||
if int(rs_p_engine) or int(rs_s_engine) != 0:
|
||||
cmds.setAttr("redshiftOptions.GIEnabled", 1)
|
||||
if int(rs_p_engine) == 0:
|
||||
# reset the primary GI Engine as default
|
||||
cmds.setAttr("redshiftOptions.primaryGIEngine", 4)
|
||||
if int(rs_s_engine) == 0:
|
||||
# reset the secondary GI Engine as default
|
||||
cmds.setAttr("redshiftOptions.secondaryGIEngine", 2)
|
||||
else:
|
||||
cmds.setAttr("redshiftOptions.GIEnabled", 0)
|
||||
|
||||
cmds.setAttr("redshiftOptions.primaryGIEngine", int(rs_p_engine))
|
||||
cmds.setAttr("redshiftOptions.secondaryGIEngine", int(rs_s_engine))
|
||||
|
||||
additional_options = redshift_render_presets["additional_options"]
|
||||
ext = redshift_render_presets["image_format"]
|
||||
img_exts = ["iff", "exr", "tif", "png", "tga", "jpg"]
|
||||
|
|
@ -163,12 +207,31 @@ class RenderSettings(object):
|
|||
"""Sets important settings for Vray."""
|
||||
settings = cmds.ls(type="VRaySettingsNode")
|
||||
node = settings[0] if settings else cmds.createNode("VRaySettingsNode")
|
||||
vray_render_presets = (
|
||||
self._project_settings
|
||||
["maya"]
|
||||
["RenderSettings"]
|
||||
["vray_renderer"]
|
||||
)
|
||||
render_settings = self._project_settings["maya"]["RenderSettings"]
|
||||
vray_render_presets = render_settings["vray_renderer"]
|
||||
# vrayRenderElement
|
||||
remove_aovs = render_settings["remove_aovs"]
|
||||
all_vray_aovs = cmds.ls(type='VRayRenderElement')
|
||||
lightSelect_aovs = cmds.ls(type='VRayRenderElementSet')
|
||||
if remove_aovs:
|
||||
for aov in all_vray_aovs:
|
||||
# remove all aovs except LightSelect
|
||||
enabled = cmds.getAttr("{}.enabled".format(aov))
|
||||
if enabled:
|
||||
cmds.delete(aov)
|
||||
# remove LightSelect
|
||||
for light_aovs in lightSelect_aovs:
|
||||
light_enabled = cmds.getAttr("{}.enabled".format(light_aovs))
|
||||
if light_enabled:
|
||||
cmds.delete(lightSelect_aovs)
|
||||
|
||||
vray_aovs = vray_render_presets["aov_list"]
|
||||
for renderlayer in vray_aovs:
|
||||
renderElement = "vrayAddRenderElement {}".format(renderlayer)
|
||||
RE_name = mel.eval(renderElement)
|
||||
# if there is more than one same render element
|
||||
if RE_name.endswith("1"):
|
||||
cmds.delete(RE_name)
|
||||
# Set aov separator
|
||||
# First we need to explicitly set the UI items in Render Settings
|
||||
# because that is also what V-Ray updates to when that Render Settings
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ class ReferenceLoader(Loader):
|
|||
|
||||
# Need to save alembic settings and reapply, cause referencing resets
|
||||
# them to incoming data.
|
||||
alembic_attrs = ["speed", "offset", "cycleType"]
|
||||
alembic_attrs = ["speed", "offset", "cycleType", "time"]
|
||||
alembic_data = {}
|
||||
if representation["name"] == "abc":
|
||||
alembic_nodes = cmds.ls(
|
||||
|
|
@ -226,7 +226,12 @@ class ReferenceLoader(Loader):
|
|||
if alembic_nodes:
|
||||
for attr in alembic_attrs:
|
||||
node_attr = "{}.{}".format(alembic_nodes[0], attr)
|
||||
alembic_data[attr] = cmds.getAttr(node_attr)
|
||||
data = {
|
||||
"input": lib.get_attribute_input(node_attr),
|
||||
"value": cmds.getAttr(node_attr)
|
||||
}
|
||||
|
||||
alembic_data[attr] = data
|
||||
else:
|
||||
self.log.debug("No alembic nodes found in {}".format(members))
|
||||
|
||||
|
|
@ -263,8 +268,19 @@ class ReferenceLoader(Loader):
|
|||
"{}:*".format(namespace), type="AlembicNode"
|
||||
)
|
||||
if alembic_nodes:
|
||||
for attr, value in alembic_data.items():
|
||||
cmds.setAttr("{}.{}".format(alembic_nodes[0], attr), value)
|
||||
alembic_node = alembic_nodes[0] # assume single AlembicNode
|
||||
for attr, data in alembic_data.items():
|
||||
node_attr = "{}.{}".format(alembic_node, attr)
|
||||
input = lib.get_attribute_input(node_attr)
|
||||
if data["input"]:
|
||||
if data["input"] != input:
|
||||
cmds.connectAttr(
|
||||
data["input"], node_attr, force=True
|
||||
)
|
||||
else:
|
||||
if input:
|
||||
cmds.disconnectAttr(input, node_attr)
|
||||
cmds.setAttr(node_attr, data["value"])
|
||||
|
||||
# Fix PLN-40 for older containers created with Avalon that had the
|
||||
# `.verticesOnlySet` set to True.
|
||||
|
|
|
|||
|
|
@ -105,6 +105,11 @@ class ExtractThumbnail(publish.Extractor):
|
|||
pm.currentTime(refreshFrameInt - 1, edit=True)
|
||||
pm.currentTime(refreshFrameInt, edit=True)
|
||||
|
||||
# Override transparency if requested.
|
||||
transparency = instance.data.get("transparency", 0)
|
||||
if transparency != 0:
|
||||
preset["viewport2_options"]["transparencyAlgorithm"] = transparency
|
||||
|
||||
# Isolate view is requested by having objects in the set besides a
|
||||
# camera.
|
||||
if preset.pop("isolate_view", False) and instance.data.get("isolate"):
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import os
|
||||
import logging
|
||||
from typing import List
|
||||
import semver
|
||||
|
||||
import pyblish.api
|
||||
|
||||
|
|
@ -21,6 +22,9 @@ import unreal # noqa
|
|||
|
||||
logger = logging.getLogger("openpype.hosts.unreal")
|
||||
OPENPYPE_CONTAINERS = "OpenPypeContainers"
|
||||
UNREAL_VERSION = semver.VersionInfo(
|
||||
*os.getenv("OPENPYPE_UNREAL_VERSION").split(".")
|
||||
)
|
||||
|
||||
HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.unreal.__file__))
|
||||
PLUGINS_DIR = os.path.join(HOST_DIR, "plugins")
|
||||
|
|
@ -111,7 +115,9 @@ def ls():
|
|||
|
||||
"""
|
||||
ar = unreal.AssetRegistryHelpers.get_asset_registry()
|
||||
openpype_containers = ar.get_assets_by_class("AssetContainer", True)
|
||||
# UE 5.1 changed how class name is specified
|
||||
class_name = ["/Script/OpenPype", "AssetContainer"] if UNREAL_VERSION.major == 5 and UNREAL_VERSION.minor > 0 else "AssetContainer" # noqa
|
||||
openpype_containers = ar.get_assets_by_class(class_name, True)
|
||||
|
||||
# get_asset_by_class returns AssetData. To get all metadata we need to
|
||||
# load asset. get_tag_values() work only on metadata registered in
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ class UnrealPrelaunchHook(PreLaunchHook):
|
|||
engine_path=Path(engine_path)
|
||||
)
|
||||
|
||||
self.launch_context.env["OPENPYPE_UNREAL_VERSION"] = engine_version
|
||||
# Append project file to launch arguments
|
||||
self.launch_context.launch_args.append(
|
||||
f"\"{project_file.as_posix()}\"")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ public class OpenPype : ModuleRules
|
|||
{
|
||||
public OpenPype(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
bLegacyPublicIncludePaths = false;
|
||||
ShadowVariableWarningLevel = WarningLevel.Error;
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_0;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "AssetContainer.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "Engine.h"
|
||||
#include "Containers/UnrealString.h"
|
||||
|
|
@ -30,8 +30,8 @@ void UAssetContainer::OnAssetAdded(const FAssetData& AssetData)
|
|||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
|
||||
FString assetFName = AssetData.AssetClassPath.ToString();
|
||||
UE_LOG(LogTemp, Log, TEXT("asset name %s"), *assetFName);
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ void UAssetContainer::OnAssetRemoved(const FAssetData& AssetData)
|
|||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
FString assetFName = AssetData.AssetClassPath.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
|
@ -93,7 +93,7 @@ void UAssetContainer::OnAssetRenamed(const FAssetData& AssetData, const FString&
|
|||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
FString assetFName = AssetData.AssetClassPath.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "OpenPypePublishInstance.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "OpenPypeLib.h"
|
||||
#include "OpenPypeSettings.h"
|
||||
#include "SNotificationList.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
|
|
@ -53,7 +55,7 @@ void UOpenPypePublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
|||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.ObjectPath.ToString());
|
||||
*InAssetData.GetObjectPathString());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "Engine/AssetUserData.h"
|
||||
#include "AssetData.h"
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "AssetContainer.generated.h"
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ def get_engine_versions(env=None):
|
|||
# environment variable not set
|
||||
pass
|
||||
except OSError:
|
||||
# specified directory doesn't exists
|
||||
# specified directory doesn't exist
|
||||
pass
|
||||
except StopIteration:
|
||||
# specified directory doesn't exist
|
||||
pass
|
||||
|
||||
# if we've got something, terminate auto-detection process
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
import ast
|
||||
import unreal # noqa
|
||||
import pyblish.api
|
||||
from openpype.hosts.unreal.api.pipeline import UNREAL_VERSION
|
||||
from openpype.pipeline.publish import KnownPublishError
|
||||
|
||||
|
||||
class CollectInstances(pyblish.api.ContextPlugin):
|
||||
|
|
@ -23,8 +25,10 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
def process(self, context):
|
||||
|
||||
ar = unreal.AssetRegistryHelpers.get_asset_registry()
|
||||
instance_containers = ar.get_assets_by_class(
|
||||
"OpenPypePublishInstance", True)
|
||||
class_name = ["/Script/OpenPype",
|
||||
"AssetContainer"] if UNREAL_VERSION.major == 5 and \
|
||||
UNREAL_VERSION.minor > 0 else "OpenPypePublishInstance" # noqa
|
||||
instance_containers = ar.get_assets_by_class(class_name, True)
|
||||
|
||||
for container_data in instance_containers:
|
||||
asset = container_data.get_asset()
|
||||
|
|
@ -32,9 +36,8 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
data["objectName"] = container_data.asset_name
|
||||
# convert to strings
|
||||
data = {str(key): str(value) for (key, value) in data.items()}
|
||||
assert data.get("family"), (
|
||||
"instance has no family"
|
||||
)
|
||||
if not data.get("family"):
|
||||
raise KnownPublishError("instance has no family")
|
||||
|
||||
# content of container
|
||||
members = ast.literal_eval(data.get("members"))
|
||||
|
|
|
|||
|
|
@ -126,22 +126,16 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
"harmony": [r".*"], # for everything from AE
|
||||
"celaction": [r".*"]}
|
||||
|
||||
enviro_filter = [
|
||||
environ_job_filter = [
|
||||
"OPENPYPE_METADATA_FILE"
|
||||
]
|
||||
|
||||
environ_keys = [
|
||||
"FTRACK_API_USER",
|
||||
"FTRACK_API_KEY",
|
||||
"FTRACK_SERVER",
|
||||
"OPENPYPE_METADATA_FILE",
|
||||
"AVALON_PROJECT",
|
||||
"AVALON_ASSET",
|
||||
"AVALON_TASK",
|
||||
"AVALON_APP_NAME",
|
||||
"OPENPYPE_PUBLISH_JOB"
|
||||
|
||||
"OPENPYPE_LOG_NO_COLORS",
|
||||
"OPENPYPE_USERNAME",
|
||||
"OPENPYPE_RENDER_JOB",
|
||||
"OPENPYPE_PUBLISH_JOB",
|
||||
"OPENPYPE_MONGO",
|
||||
"OPENPYPE_VERSION"
|
||||
]
|
||||
|
||||
|
|
@ -223,29 +217,42 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
instance_version = instance.data.get("version") # take this if exists
|
||||
if instance_version != 1:
|
||||
override_version = instance_version
|
||||
output_dir = self._get_publish_folder(instance.context.data['anatomy'],
|
||||
deepcopy(
|
||||
instance.data["anatomyData"]),
|
||||
instance.data.get("asset"),
|
||||
instances[0]["subset"],
|
||||
'render',
|
||||
override_version)
|
||||
output_dir = self._get_publish_folder(
|
||||
instance.context.data['anatomy'],
|
||||
deepcopy(instance.data["anatomyData"]),
|
||||
instance.data.get("asset"),
|
||||
instances[0]["subset"],
|
||||
'render',
|
||||
override_version
|
||||
)
|
||||
|
||||
# Transfer the environment from the original job to this dependent
|
||||
# job so they use the same environment
|
||||
metadata_path, roothless_metadata_path = \
|
||||
self._create_metadata_path(instance)
|
||||
|
||||
environment = job["Props"].get("Env", {})
|
||||
environment["AVALON_PROJECT"] = legacy_io.Session["AVALON_PROJECT"]
|
||||
environment["AVALON_ASSET"] = legacy_io.Session["AVALON_ASSET"]
|
||||
environment["AVALON_TASK"] = legacy_io.Session["AVALON_TASK"]
|
||||
environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME")
|
||||
environment["OPENPYPE_VERSION"] = os.environ.get("OPENPYPE_VERSION")
|
||||
environment["OPENPYPE_LOG_NO_COLORS"] = "1"
|
||||
environment["OPENPYPE_USERNAME"] = instance.context.data["user"]
|
||||
environment["OPENPYPE_PUBLISH_JOB"] = "1"
|
||||
environment["OPENPYPE_RENDER_JOB"] = "0"
|
||||
environment = {
|
||||
"AVALON_PROJECT": legacy_io.Session["AVALON_PROJECT"],
|
||||
"AVALON_ASSET": legacy_io.Session["AVALON_ASSET"],
|
||||
"AVALON_TASK": legacy_io.Session["AVALON_TASK"],
|
||||
"OPENPYPE_USERNAME": instance.context.data["user"],
|
||||
"OPENPYPE_PUBLISH_JOB": "1",
|
||||
"OPENPYPE_RENDER_JOB": "0",
|
||||
"OPENPYPE_REMOTE_JOB": "0",
|
||||
"OPENPYPE_LOG_NO_COLORS": "1"
|
||||
}
|
||||
|
||||
# add environments from self.environ_keys
|
||||
for env_key in self.environ_keys:
|
||||
if os.getenv(env_key):
|
||||
environment[env_key] = os.environ[env_key]
|
||||
|
||||
# pass environment keys from self.environ_job_filter
|
||||
job_environ = job["Props"].get("Env", {})
|
||||
for env_j_key in self.environ_job_filter:
|
||||
if job_environ.get(env_j_key):
|
||||
environment[env_j_key] = job_environ[env_j_key]
|
||||
|
||||
# Add mongo url if it's enabled
|
||||
if instance.context.data.get("deadlinePassMongoUrl"):
|
||||
mongo_url = os.environ.get("OPENPYPE_MONGO")
|
||||
|
|
@ -309,19 +316,15 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
if instance.data.get("suspend_publish"):
|
||||
payload["JobInfo"]["InitialStatus"] = "Suspended"
|
||||
|
||||
index = 0
|
||||
for key in environment:
|
||||
if key.upper() in self.enviro_filter:
|
||||
payload["JobInfo"].update(
|
||||
{
|
||||
"EnvironmentKeyValue%d"
|
||||
% index: "{key}={value}".format(
|
||||
key=key, value=environment[key]
|
||||
)
|
||||
}
|
||||
)
|
||||
index += 1
|
||||
|
||||
for index, (key_, value_) in enumerate(environment.items()):
|
||||
payload["JobInfo"].update(
|
||||
{
|
||||
"EnvironmentKeyValue%d"
|
||||
% index: "{key}={value}".format(
|
||||
key=key_, value=value_
|
||||
)
|
||||
}
|
||||
)
|
||||
# remove secondary pool
|
||||
payload["JobInfo"].pop("SecondaryPool", None)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
import re
|
||||
import json
|
||||
import copy
|
||||
import tempfile
|
||||
|
|
@ -21,6 +20,7 @@ from openpype.lib import (
|
|||
|
||||
CREATE_NO_WINDOW
|
||||
)
|
||||
from openpype.lib.profiles_filtering import filter_profiles
|
||||
|
||||
|
||||
class ExtractBurnin(publish.Extractor):
|
||||
|
|
@ -34,6 +34,7 @@ class ExtractBurnin(publish.Extractor):
|
|||
|
||||
label = "Extract burnins"
|
||||
order = pyblish.api.ExtractorOrder + 0.03
|
||||
|
||||
families = ["review", "burnin"]
|
||||
hosts = [
|
||||
"nuke",
|
||||
|
|
@ -53,6 +54,7 @@ class ExtractBurnin(publish.Extractor):
|
|||
"flame"
|
||||
# "resolve"
|
||||
]
|
||||
|
||||
optional = True
|
||||
|
||||
positions = [
|
||||
|
|
@ -69,11 +71,15 @@ class ExtractBurnin(publish.Extractor):
|
|||
"y_offset": 5
|
||||
}
|
||||
|
||||
# Preset attributes
|
||||
# Configurable by Settings
|
||||
profiles = None
|
||||
options = None
|
||||
|
||||
def process(self, instance):
|
||||
if not self.profiles:
|
||||
self.log.warning("No profiles present for create burnin")
|
||||
return
|
||||
|
||||
# QUESTION what is this for and should we raise an exception?
|
||||
if "representations" not in instance.data:
|
||||
raise RuntimeError("Burnin needs already created mov to work on.")
|
||||
|
|
@ -137,18 +143,29 @@ class ExtractBurnin(publish.Extractor):
|
|||
return filtered_repres
|
||||
|
||||
def main_process(self, instance):
|
||||
# TODO get these data from context
|
||||
host_name = instance.context.data["hostName"]
|
||||
task_name = os.environ["AVALON_TASK"]
|
||||
family = self.main_family_from_instance(instance)
|
||||
family = instance.data["family"]
|
||||
task_data = instance.data["anatomyData"].get("task", {})
|
||||
task_name = task_data.get("name")
|
||||
task_type = task_data.get("type")
|
||||
subset = instance.data["subset"]
|
||||
|
||||
filtering_criteria = {
|
||||
"hosts": host_name,
|
||||
"families": family,
|
||||
"task_names": task_name,
|
||||
"task_types": task_type,
|
||||
"subset": subset
|
||||
}
|
||||
profile = filter_profiles(self.profiles, filtering_criteria,
|
||||
logger=self.log)
|
||||
|
||||
# Find profile most matching current host, task and instance family
|
||||
profile = self.find_matching_profile(host_name, task_name, family)
|
||||
if not profile:
|
||||
self.log.info((
|
||||
"Skipped instance. None of profiles in presets are for"
|
||||
" Host: \"{}\" | Family: \"{}\" | Task \"{}\""
|
||||
).format(host_name, family, task_name))
|
||||
" Host: \"{}\" | Families: \"{}\" | Task \"{}\""
|
||||
" | Task type \"{}\" | Subset \"{}\" "
|
||||
).format(host_name, family, task_name, task_type, subset))
|
||||
return
|
||||
|
||||
self.log.debug("profile: {}".format(profile))
|
||||
|
|
@ -158,7 +175,8 @@ class ExtractBurnin(publish.Extractor):
|
|||
if not burnin_defs:
|
||||
self.log.info((
|
||||
"Skipped instance. Burnin definitions are not set for profile"
|
||||
" Host: \"{}\" | Family: \"{}\" | Task \"{}\" | Profile \"{}\""
|
||||
" Host: \"{}\" | Families: \"{}\" | Task \"{}\""
|
||||
" | Profile \"{}\""
|
||||
).format(host_name, family, task_name, profile))
|
||||
return
|
||||
|
||||
|
|
@ -693,130 +711,6 @@ class ExtractBurnin(publish.Extractor):
|
|||
)
|
||||
})
|
||||
|
||||
def find_matching_profile(self, host_name, task_name, family):
|
||||
""" Filter profiles by Host name, Task name and main Family.
|
||||
|
||||
Filtering keys are "hosts" (list), "tasks" (list), "families" (list).
|
||||
If key is not find or is empty than it's expected to match.
|
||||
|
||||
Args:
|
||||
profiles (list): Profiles definition from presets.
|
||||
host_name (str): Current running host name.
|
||||
task_name (str): Current context task name.
|
||||
family (str): Main family of current Instance.
|
||||
|
||||
Returns:
|
||||
dict/None: Return most matching profile or None if none of profiles
|
||||
match at least one criteria.
|
||||
"""
|
||||
|
||||
matching_profiles = None
|
||||
highest_points = -1
|
||||
for profile in self.profiles or tuple():
|
||||
profile_points = 0
|
||||
profile_value = []
|
||||
|
||||
# Host filtering
|
||||
host_names = profile.get("hosts")
|
||||
match = self.validate_value_by_regexes(host_name, host_names)
|
||||
if match == -1:
|
||||
continue
|
||||
profile_points += match
|
||||
profile_value.append(bool(match))
|
||||
|
||||
# Task filtering
|
||||
task_names = profile.get("tasks")
|
||||
match = self.validate_value_by_regexes(task_name, task_names)
|
||||
if match == -1:
|
||||
continue
|
||||
profile_points += match
|
||||
profile_value.append(bool(match))
|
||||
|
||||
# Family filtering
|
||||
families = profile.get("families")
|
||||
match = self.validate_value_by_regexes(family, families)
|
||||
if match == -1:
|
||||
continue
|
||||
profile_points += match
|
||||
profile_value.append(bool(match))
|
||||
|
||||
if profile_points > highest_points:
|
||||
matching_profiles = []
|
||||
highest_points = profile_points
|
||||
|
||||
if profile_points == highest_points:
|
||||
profile["__value__"] = profile_value
|
||||
matching_profiles.append(profile)
|
||||
|
||||
if not matching_profiles:
|
||||
return
|
||||
|
||||
if len(matching_profiles) == 1:
|
||||
return matching_profiles[0]
|
||||
|
||||
return self.profile_exclusion(matching_profiles)
|
||||
|
||||
def profile_exclusion(self, matching_profiles):
|
||||
"""Find out most matching profile by host, task and family match.
|
||||
|
||||
Profiles are selectivelly filtered. Each profile should have
|
||||
"__value__" key with list of booleans. Each boolean represents
|
||||
existence of filter for specific key (host, taks, family).
|
||||
Profiles are looped in sequence. In each sequence are split into
|
||||
true_list and false_list. For next sequence loop are used profiles in
|
||||
true_list if there are any profiles else false_list is used.
|
||||
|
||||
Filtering ends when only one profile left in true_list. Or when all
|
||||
existence booleans loops passed, in that case first profile from left
|
||||
profiles is returned.
|
||||
|
||||
Args:
|
||||
matching_profiles (list): Profiles with same values.
|
||||
|
||||
Returns:
|
||||
dict: Most matching profile.
|
||||
"""
|
||||
self.log.info(
|
||||
"Search for first most matching profile in match order:"
|
||||
" Host name -> Task name -> Family."
|
||||
)
|
||||
# Filter all profiles with highest points value. First filter profiles
|
||||
# with matching host if there are any then filter profiles by task
|
||||
# name if there are any and lastly filter by family. Else use first in
|
||||
# list.
|
||||
idx = 0
|
||||
final_profile = None
|
||||
while True:
|
||||
profiles_true = []
|
||||
profiles_false = []
|
||||
for profile in matching_profiles:
|
||||
value = profile["__value__"]
|
||||
# Just use first profile when idx is greater than values.
|
||||
if not idx < len(value):
|
||||
final_profile = profile
|
||||
break
|
||||
|
||||
if value[idx]:
|
||||
profiles_true.append(profile)
|
||||
else:
|
||||
profiles_false.append(profile)
|
||||
|
||||
if final_profile is not None:
|
||||
break
|
||||
|
||||
if profiles_true:
|
||||
matching_profiles = profiles_true
|
||||
else:
|
||||
matching_profiles = profiles_false
|
||||
|
||||
if len(matching_profiles) == 1:
|
||||
final_profile = matching_profiles[0]
|
||||
break
|
||||
idx += 1
|
||||
|
||||
final_profile.pop("__value__")
|
||||
return final_profile
|
||||
|
||||
def filter_burnins_defs(self, profile, instance):
|
||||
"""Filter outputs by their values from settings.
|
||||
|
||||
|
|
@ -909,56 +803,6 @@ class ExtractBurnin(publish.Extractor):
|
|||
return True
|
||||
return False
|
||||
|
||||
def compile_list_of_regexes(self, in_list):
|
||||
"""Convert strings in entered list to compiled regex objects."""
|
||||
regexes = []
|
||||
if not in_list:
|
||||
return regexes
|
||||
|
||||
for item in in_list:
|
||||
if not item:
|
||||
continue
|
||||
|
||||
try:
|
||||
regexes.append(re.compile(item))
|
||||
except TypeError:
|
||||
self.log.warning((
|
||||
"Invalid type \"{}\" value \"{}\"."
|
||||
" Expected string based object. Skipping."
|
||||
).format(str(type(item)), str(item)))
|
||||
|
||||
return regexes
|
||||
|
||||
def validate_value_by_regexes(self, value, in_list):
|
||||
"""Validate in any regexe from list match entered value.
|
||||
|
||||
Args:
|
||||
in_list (list): List with regexes.
|
||||
value (str): String where regexes is checked.
|
||||
|
||||
Returns:
|
||||
int: Returns `0` when list is not set or is empty. Returns `1` when
|
||||
any regex match value and returns `-1` when none of regexes
|
||||
match value entered.
|
||||
"""
|
||||
if not in_list:
|
||||
return 0
|
||||
|
||||
output = -1
|
||||
regexes = self.compile_list_of_regexes(in_list)
|
||||
for regex in regexes:
|
||||
if re.match(regex, value):
|
||||
output = 1
|
||||
break
|
||||
return output
|
||||
|
||||
def main_family_from_instance(self, instance):
|
||||
"""Return main family of entered instance."""
|
||||
family = instance.data.get("family")
|
||||
if not family:
|
||||
family = instance.data["families"][0]
|
||||
return family
|
||||
|
||||
def families_from_instance(self, instance):
|
||||
"""Return all families of entered instance."""
|
||||
families = []
|
||||
|
|
|
|||
|
|
@ -209,6 +209,9 @@
|
|||
{
|
||||
"families": [],
|
||||
"hosts": [],
|
||||
"task_types": [],
|
||||
"task_names": [],
|
||||
"subsets": [],
|
||||
"burnins": {
|
||||
"burnin": {
|
||||
"TOP_LEFT": "{yy}-{mm}-{dd}",
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
"default_render_image_folder": "renders/maya",
|
||||
"enable_all_lights": true,
|
||||
"aov_separator": "underscore",
|
||||
"remove_aovs": false,
|
||||
"reset_current_frame": false,
|
||||
"arnold_renderer": {
|
||||
"image_prefix": "<Scene>/<RenderLayer>/<RenderLayer>_<RenderPass>",
|
||||
|
|
|
|||
|
|
@ -526,11 +526,28 @@
|
|||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "hosts-enum",
|
||||
"key": "hosts",
|
||||
"label": "Hosts",
|
||||
"label": "Host names",
|
||||
"type": "hosts-enum",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "task_types",
|
||||
"label": "Task types",
|
||||
"type": "task-types-enum"
|
||||
},
|
||||
{
|
||||
"key": "task_names",
|
||||
"label": "Task names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "subsets",
|
||||
"label": "Subset names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "splitter"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@
|
|||
{"dot": ". (dot)"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "remove_aovs",
|
||||
"label": "Remove existing AOVs",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"key": "reset_current_frame",
|
||||
"label": "Reset Current Frame",
|
||||
|
|
@ -204,74 +209,76 @@
|
|||
"defaults": "empty",
|
||||
"enum_items": [
|
||||
{"empty": "< empty >"},
|
||||
{"atmosphereChannel": "atmosphere"},
|
||||
{"backgroundChannel": "background"},
|
||||
{"bumpNormalsChannel": "bumpnormals"},
|
||||
{"causticsChannel": "caustics"},
|
||||
{"coatFilterChannel": "coat_filter"},
|
||||
{"coatGlossinessChannel": "coatGloss"},
|
||||
{"coatReflectionChannel": "coat_reflection"},
|
||||
{"vrayCoatChannel": "coat_specular"},
|
||||
{"CoverageChannel": "coverage"},
|
||||
{"cryptomatteChannel": "cryptomatte"},
|
||||
{"customColor": "custom_color"},
|
||||
{"drBucketChannel": "DR"},
|
||||
{"denoiserChannel": "denoiser"},
|
||||
{"diffuseChannel": "diffuse"},
|
||||
{"ExtraTexElement": "extraTex"},
|
||||
{"giChannel": "GI"},
|
||||
{"LightMixElement": "None"},
|
||||
{"lightingChannel": "lighting"},
|
||||
{"LightingAnalysisChannel": "LightingAnalysis"},
|
||||
{"materialIDChannel": "materialID"},
|
||||
{"MaterialSelectElement": "materialSelect"},
|
||||
{"matteShadowChannel": "matteShadow"},
|
||||
{"MultiMatteElement": "multimatte"},
|
||||
{"multimatteIDChannel": "multimatteID"},
|
||||
{"normalsChannel": "normals"},
|
||||
{"nodeIDChannel": "objectId"},
|
||||
{"objectSelectChannel": "objectSelect"},
|
||||
{"rawCoatFilterChannel": "raw_coat_filter"},
|
||||
{"rawCoatReflectionChannel": "raw_coat_reflection"},
|
||||
{"rawDiffuseFilterChannel": "rawDiffuseFilter"},
|
||||
{"rawGiChannel": "rawGI"},
|
||||
{"rawLightChannel": "rawLight"},
|
||||
{"rawReflectionChannel": "rawReflection"},
|
||||
{"rawReflectionFilterChannel": "rawReflectionFilter"},
|
||||
{"rawRefractionChannel": "rawRefraction"},
|
||||
{"rawRefractionFilterChannel": "rawRefractionFilter"},
|
||||
{"rawShadowChannel": "rawShadow"},
|
||||
{"rawSheenFilterChannel": "raw_sheen_filter"},
|
||||
{"rawSheenReflectionChannel": "raw_sheen_reflection"},
|
||||
{"rawTotalLightChannel": "rawTotalLight"},
|
||||
{"reflectIORChannel": "reflIOR"},
|
||||
{"reflectChannel": "reflect"},
|
||||
{"reflectionFilterChannel": "reflectionFilter"},
|
||||
{"reflectGlossinessChannel": "reflGloss"},
|
||||
{"refractChannel": "refract"},
|
||||
{"refractionFilterChannel": "refractionFilter"},
|
||||
{"refractGlossinessChannel": "refrGloss"},
|
||||
{"renderIDChannel": "renderId"},
|
||||
{"FastSSS2Channel": "SSS"},
|
||||
{"sampleRateChannel": "sampleRate"},
|
||||
{"atmosphereChannel": "atmosphereChannel"},
|
||||
{"backgroundChannel": "backgroundChannel"},
|
||||
{"bumpNormalsChannel": "bumpNormalsChannel"},
|
||||
{"causticsChannel": "causticsChannel"},
|
||||
{"coatFilterChannel": "coatFilterChannel"},
|
||||
{"coatGlossinessChannel": "coatGlossinessChannel"},
|
||||
{"coatReflectionChannel": "coatReflectionChannel"},
|
||||
{"vrayCoatChannel": "vrayCoatChannel"},
|
||||
{"CoverageChannel": "CoverageChannel"},
|
||||
{"cryptomatteChannel": "cryptomatteChannel"},
|
||||
{"customColor": "customColor"},
|
||||
{"drBucketChannel": "drBucketChannel"},
|
||||
{"denoiserChannel": "denoiserChannel"},
|
||||
{"diffuseChannel": "diffuseChannel"},
|
||||
{"ExtraTexElement": "ExtraTexElement"},
|
||||
{"giChannel": "giChannel"},
|
||||
{"LightMixElement": "LightMixElement"},
|
||||
{"LightSelectElement": "LightSelectElement"},
|
||||
{"lightingChannel": "lightingChannel"},
|
||||
{"LightingAnalysisChannel": "LightingAnalysisChannel"},
|
||||
{"materialIDChannel": "materialIDChannel"},
|
||||
{"MaterialSelectElement": "MaterialSelectElement"},
|
||||
{"matteShadowChannel": "matteShadowChannel"},
|
||||
{"metalnessChannel": "metalnessChannel"},
|
||||
{"MultiMatteElement": "MultiMatteElement"},
|
||||
{"multimatteIDChannel": "multimatteIDChannel"},
|
||||
{"noiseLevelChannel": "noiseLevelChannel"},
|
||||
{"normalsChannel": "normalsChannel"},
|
||||
{"nodeIDChannel": "nodeIDChannel"},
|
||||
{"objectSelectChannel": "objectSelectChannel"},
|
||||
{"rawCoatFilterChannel": "rawCoatFilterChannel"},
|
||||
{"rawCoatReflectionChannel": "rawCoatReflectionChannel"},
|
||||
{"rawDiffuseFilterChannel": "rawDiffuseFilterChannel"},
|
||||
{"rawGiChannel": "rawGiChannel"},
|
||||
{"rawLightChannel": "rawLightChannel"},
|
||||
{"rawReflectionChannel": "rawReflectionChannel"},
|
||||
{"rawReflectionFilterChannel": "rawReflectionFilterChannel"},
|
||||
{"rawRefractionChannel": "rawRefractionChannel"},
|
||||
{"rawRefractionFilterChannel": "rawRefractionFilterChannel"},
|
||||
{"rawShadowChannel": "rawShadowChannel"},
|
||||
{"rawSheenFilterChannel": "rawSheenFilterChannel"},
|
||||
{"rawSheenReflectionChannel": "rawSheenReflectionChannel"},
|
||||
{"rawTotalLightChannel": "rawTotalLightChannel"},
|
||||
{"reflectIORChannel": "reflectIORChannel"},
|
||||
{"reflectChannel": "reflectChannel"},
|
||||
{"reflectionFilterChannel": "reflectionFilterChannel"},
|
||||
{"reflectGlossinessChannel": "reflectGlossinessChannel"},
|
||||
{"refractChannel": "refractChannel"},
|
||||
{"refractionFilterChannel": "refractionFilterChannel"},
|
||||
{"refractGlossinessChannel": "refractGlossinessChannel"},
|
||||
{"renderIDChannel": "renderIDChannel"},
|
||||
{"FastSSS2Channel": "FastSSS2Channel"},
|
||||
{"sampleRateChannel": "sampleRateChannel"},
|
||||
{"samplerInfo": "samplerInfo"},
|
||||
{"selfIllumChannel": "selfIllum"},
|
||||
{"shadowChannel": "shadow"},
|
||||
{"sheenFilterChannel": "sheen_filter"},
|
||||
{"sheenGlossinessChannel": "sheenGloss"},
|
||||
{"sheenReflectionChannel": "sheen_reflection"},
|
||||
{"vraySheenChannel": "sheen_specular"},
|
||||
{"specularChannel": "specular"},
|
||||
{"selfIllumChannel": "selfIllumChannel"},
|
||||
{"shadowChannel": "shadowChannel"},
|
||||
{"sheenFilterChannel": "sheenFilterChannel"},
|
||||
{"sheenGlossinessChannel": "sheenGlossinessChannel"},
|
||||
{"sheenReflectionChannel": "sheenReflectionChannel"},
|
||||
{"vraySheenChannel": "vraySheenChannel"},
|
||||
{"specularChannel": "specularChannel"},
|
||||
{"Toon": "Toon"},
|
||||
{"toonLightingChannel": "toonLighting"},
|
||||
{"toonSpecularChannel": "toonSpecular"},
|
||||
{"totalLightChannel": "totalLight"},
|
||||
{"unclampedColorChannel": "unclampedColor"},
|
||||
{"VRScansPaintMaskChannel": "VRScansPaintMask"},
|
||||
{"VRScansZoneMaskChannel": "VRScansZoneMask"},
|
||||
{"velocityChannel": "velocity"},
|
||||
{"zdepthChannel": "zDepth"},
|
||||
{"LightSelectElement": "lightselect"}
|
||||
{"toonLightingChannel": "toonLightingChannel"},
|
||||
{"toonSpecularChannel": "toonSpecularChannel"},
|
||||
{"totalLightChannel": "totalLightChannel"},
|
||||
{"unclampedColorChannel": "unclampedColorChannel"},
|
||||
{"VRScansPaintMaskChannel": "VRScansPaintMaskChannel"},
|
||||
{"VRScansZoneMaskChannel": "VRScansZoneMaskChannel"},
|
||||
{"velocityChannel": "velocityChannel"},
|
||||
{"zdepthChannel": "zdepthChannel"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -310,9 +317,8 @@
|
|||
"defaults": "0",
|
||||
"enum_items": [
|
||||
{"0": "None"},
|
||||
{"1": "Photon Map"},
|
||||
{"2": "Irradiance Cache"},
|
||||
{"3": "Brute Force"}
|
||||
{"3": "Irradiance Cache"},
|
||||
{"4": "Brute Force"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -323,9 +329,8 @@
|
|||
"defaults": "0",
|
||||
"enum_items": [
|
||||
{"0": "None"},
|
||||
{"1": "Photon Map"},
|
||||
{"2": "Irradiance Cache"},
|
||||
{"3": "Brute Force"}
|
||||
{"2": "Irradiance Point Cloud"},
|
||||
{"4": "Brute Force"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -361,46 +366,46 @@
|
|||
"defaults": "empty",
|
||||
"enum_items": [
|
||||
{"empty": "< none >"},
|
||||
{"AO": "Ambient Occlusion"},
|
||||
{"Ambient Occlusion": "Ambient Occlusion"},
|
||||
{"Background": "Background"},
|
||||
{"Beauty": "Beauty"},
|
||||
{"BumpNormals": "Bump Normals"},
|
||||
{"Bump Normals": "Bump Normals"},
|
||||
{"Caustics": "Caustics"},
|
||||
{"CausticsRaw": "Caustics Raw"},
|
||||
{"Caustics Raw": "Caustics Raw"},
|
||||
{"Cryptomatte": "Cryptomatte"},
|
||||
{"Custom": "Custom"},
|
||||
{"Z": "Depth"},
|
||||
{"DiffuseFilter": "Diffuse Filter"},
|
||||
{"DiffuseLighting": "Diffuse Lighting"},
|
||||
{"DiffuseLightingRaw": "Diffuse Lighting Raw"},
|
||||
{"Depth": "Depth"},
|
||||
{"Diffuse Filter": "Diffuse Filter"},
|
||||
{"Diffuse Lighting": "Diffuse Lighting"},
|
||||
{"Diffuse Lighting Raw": "Diffuse Lighting Raw"},
|
||||
{"Emission": "Emission"},
|
||||
{"GI": "Global Illumination"},
|
||||
{"GIRaw": "Global Illumination Raw"},
|
||||
{"Global Illumination": "Global Illumination"},
|
||||
{"Global Illumination Raw": "Global Illumination Raw"},
|
||||
{"Matte": "Matte"},
|
||||
{"MotionVectors": "Ambient Occlusion"},
|
||||
{"N": "Normals"},
|
||||
{"ID": "ObjectID"},
|
||||
{"ObjectBumpNormal": "Object-Space Bump Normals"},
|
||||
{"ObjectPosition": "Object-Space Positions"},
|
||||
{"PuzzleMatte": "Puzzle Matte"},
|
||||
{"Motion Vectors": "Motion Vectors"},
|
||||
{"Normals": "Normals"},
|
||||
{"ObjectID": "ObjectID"},
|
||||
{"Object-Space Bump Normals": "Object-Space Bump Normals"},
|
||||
{"Object-Space Positions": "Object-Space Positions"},
|
||||
{"Puzzle Matte": "Puzzle Matte"},
|
||||
{"Reflections": "Reflections"},
|
||||
{"ReflectionsFilter": "Reflections Filter"},
|
||||
{"ReflectionsRaw": "Reflections Raw"},
|
||||
{"Reflections Filter": "Reflections Filter"},
|
||||
{"Reflections Raw": "Reflections Raw"},
|
||||
{"Refractions": "Refractions"},
|
||||
{"RefractionsFilter": "Refractions Filter"},
|
||||
{"RefractionsRaw": "Refractions Filter"},
|
||||
{"Refractions Filter": "Refractions Filter"},
|
||||
{"Refractions Raw": "Refractions Filter"},
|
||||
{"Shadows": "Shadows"},
|
||||
{"SpecularLighting": "Specular Lighting"},
|
||||
{"SSS": "Sub Surface Scatter"},
|
||||
{"SSSRaw": "Sub Surface Scatter Raw"},
|
||||
{"TotalDiffuseLightingRaw": "Total Diffuse Lighting Raw"},
|
||||
{"TotalTransLightingRaw": "Total Translucency Filter"},
|
||||
{"TransTint": "Translucency Filter"},
|
||||
{"TransGIRaw": "Translucency Lighting Raw"},
|
||||
{"VolumeFogEmission": "Volume Fog Emission"},
|
||||
{"VolumeFogTint": "Volume Fog Tint"},
|
||||
{"VolumeLighting": "Volume Lighting"},
|
||||
{"P": "World Position"}
|
||||
{"Sub Surface Scatter": "Sub Surface Scatter"},
|
||||
{"Sub Surface Scatter Raw": "Sub Surface Scatter Raw"},
|
||||
{"Total Diffuse Lighting Raw": "Total Diffuse Lighting Raw"},
|
||||
{"Total Translucency Filter": "Total Translucency Filter"},
|
||||
{"Translucency Filter": "Translucency Filter"},
|
||||
{"Translucency Lighting Raw": "Translucency Lighting Raw"},
|
||||
{"Volume Fog Emission": "Volume Fog Emission"},
|
||||
{"Volume Fog Tint": "Volume Fog Tint"},
|
||||
{"Volume Lighting": "Volume Lighting"},
|
||||
{"World Position": "World Position"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class DropEmpty(QtWidgets.QWidget):
|
|||
extensions_label = " or ".join(allowed_items)
|
||||
else:
|
||||
last_item = allowed_items.pop(-1)
|
||||
new_last_item = " or ".join(last_item, allowed_items.pop(-1))
|
||||
new_last_item = " or ".join([last_item, allowed_items.pop(-1)])
|
||||
allowed_items.append(new_last_item)
|
||||
extensions_label = ", ".join(allowed_items)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import sys
|
||||
from Qt import QtWidgets, QtGui
|
||||
from qtpy import QtWidgets, QtGui
|
||||
|
||||
from openpype import style
|
||||
from .lib import (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import platform
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
from .widgets import (
|
||||
Separator,
|
||||
ExpandingWidget
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
from openpype.tools.experimental_tools import (
|
||||
ExperimentalTools,
|
||||
LOCAL_EXPERIMENTAL_KEY
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import getpass
|
||||
|
||||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
from openpype.lib import is_admin_password_required
|
||||
from openpype.widgets import PasswordDialog
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import os
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
from pymongo.errors import ServerSelectionTimeoutError
|
||||
|
||||
from openpype.lib import change_openpype_mongo_url
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import platform
|
||||
import copy
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
from openpype.tools.settings.settings import ProjectListWidget
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
from openpype.settings.constants import (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
from openpype.tools.settings.settings.widgets import (
|
||||
ExpandingWidget
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtGui
|
||||
from qtpy import QtWidgets, QtGui
|
||||
|
||||
from openpype import style
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import traceback
|
|||
import functools
|
||||
import datetime
|
||||
|
||||
from Qt import QtWidgets, QtGui, QtCore
|
||||
from qtpy import QtWidgets, QtGui, QtCore
|
||||
|
||||
from openpype.settings.entities import ProjectSettings
|
||||
from openpype.tools.settings import CHILD_OFFSET
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtGui, QtCore
|
||||
from qtpy import QtWidgets, QtGui, QtCore
|
||||
|
||||
PREFIX_ROLE = QtCore.Qt.UserRole + 1
|
||||
LAST_SEGMENT_ROLE = QtCore.Qt.UserRole + 2
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import sys
|
|||
import traceback
|
||||
import contextlib
|
||||
from enum import Enum
|
||||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
import qtawesome
|
||||
|
||||
from openpype.lib import get_openpype_version
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
|
||||
from .item_widgets import InputWidget
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtCore
|
||||
from qtpy import QtCore
|
||||
|
||||
|
||||
DEFAULT_PROJECT_LABEL = "< Default >"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
from openpype.tools.utils.delegates import pretty_date
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
|
||||
from .widgets import (
|
||||
ExpandingWidget,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from uuid import uuid4
|
||||
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
from .base import BaseWidget
|
||||
from .lib import (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from Qt import QtGui
|
||||
from qtpy import QtGui
|
||||
|
||||
|
||||
def get_image_path(image_filename):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype.widgets.sliders import NiceSlider
|
||||
from openpype.tools.settings import CHILD_OFFSET
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtCore
|
||||
from qtpy import QtCore
|
||||
|
||||
from .widgets import SettingsToolBtn
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
from openpype.tools.settings import (
|
||||
CHILD_OFFSET
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
from .widgets import (
|
||||
GridLabelWidget,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtCore, QtGui, QtWidgets
|
||||
from qtpy import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class ComboItemDelegate(QtWidgets.QStyledItemDelegate):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import re
|
||||
import collections
|
||||
|
||||
from Qt import QtCore, QtWidgets, QtGui
|
||||
from qtpy import QtCore, QtWidgets, QtGui
|
||||
|
||||
ENTITY_LABEL_ROLE = QtCore.Qt.UserRole + 1
|
||||
ENTITY_PATH_ROLE = QtCore.Qt.UserRole + 2
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
|
||||
def indented_print(data, indent=0):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import copy
|
||||
import uuid
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import get_projects
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtGui, QtCore
|
||||
from qtpy import QtWidgets, QtGui, QtCore
|
||||
|
||||
from openpype import style
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from uuid import uuid4
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
|
||||
from .widgets import (
|
||||
ExpandingWidget,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.14.9-nightly.3"
|
||||
__version__ = "3.14.9-nightly.4"
|
||||
|
|
|
|||
BIN
website/docs/assets/deadline_job_version.png
Normal file
BIN
website/docs/assets/deadline_job_version.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
38
website/docs/dev_deadline.md
Normal file
38
website/docs/dev_deadline.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
id: dev_deadline
|
||||
title: Deadline integration
|
||||
sidebar_label: Deadline integration
|
||||
toc_max_heading_level: 4
|
||||
---
|
||||
|
||||
Deadline is not host as usual, it is missing most of the host features, but it does have
|
||||
its own set of publishing plugins.
|
||||
|
||||
## How to test OpenPype on Deadline
|
||||
|
||||
### Versions
|
||||
|
||||
Since 3.14 job submitted from OpenPype is bound to OpenPype version used to submit it. So
|
||||
if you submit job with 3.14.8, Deadline will try to find that particular version and use it
|
||||
for rendering. This is handled by `OPENPYPE_VERSION` variable on job - you can delete it from
|
||||
there and then the version set in studio Settings will be used.
|
||||
|
||||

|
||||
|
||||
Deadline needs to bootstrap this version so it will try to look the closest compatible
|
||||
build. So to use version 3.14.8 on Deadline it is enough to have build 3.14.0 or similar - important
|
||||
are the first two version numbers - major and minor. If they match, the version
|
||||
is considered compatible.
|
||||
|
||||
### Testing
|
||||
|
||||
So to test various changes you don't need to build again an again OpenPype and putting
|
||||
it to directory where Deadline is looking for versions - this needs to be done only on
|
||||
minor version change. That build will then be used to bootstrap whatever is set on the
|
||||
job or in the studio Settings.
|
||||
|
||||
So you can either use zip version if it suits you, or better set your sources directory
|
||||
so it will be find as a version - for example with symlink.
|
||||
|
||||
That way you can only modify `OPENPYPE_VERSION` variable on job to point it to version
|
||||
you would like to test.
|
||||
|
|
@ -157,6 +157,7 @@ module.exports = {
|
|||
"dev_host_implementation",
|
||||
"dev_publishing"
|
||||
]
|
||||
}
|
||||
},
|
||||
"dev_deadline"
|
||||
]
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue