mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into feature/PYPE-654-nks-cut-reference-videos
This commit is contained in:
commit
0c5b7b7ab9
18 changed files with 112 additions and 177 deletions
|
|
@ -3,7 +3,7 @@ import os
|
|||
from pyblish import api as pyblish
|
||||
from avalon import api as avalon
|
||||
from .lib import filter_pyblish_plugins
|
||||
from pypeapp import config, Roots
|
||||
from pypeapp import config, Anatomy
|
||||
|
||||
|
||||
import logging
|
||||
|
|
@ -100,8 +100,9 @@ def install():
|
|||
avalon.register_plugin_path(avalon.InventoryAction, path)
|
||||
|
||||
if project_name:
|
||||
root_obj = Roots(project_name)
|
||||
avalon.register_root(root_obj.roots)
|
||||
anatomy = Anatomy(project_name)
|
||||
anatomy.set_root_environments()
|
||||
avalon.register_root(anatomy.roots)
|
||||
# apply monkey patched discover to original one
|
||||
avalon.discover = patched_discover
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,9 @@ class AvalonApps:
|
|||
def show_launcher(self):
|
||||
# if app_launcher don't exist create it/otherwise only show main window
|
||||
if self.app_launcher is None:
|
||||
root = os.path.realpath(os.environ["AVALON_PROJECTS"])
|
||||
io.install()
|
||||
APP_PATH = launcher_lib.resource("qml", "main.qml")
|
||||
self.app_launcher = launcher_widget.Launcher(root, APP_PATH)
|
||||
self.app_launcher = launcher_widget.Launcher(APP_PATH)
|
||||
self.app_launcher.window.show()
|
||||
|
||||
def show_library_loader(self):
|
||||
|
|
|
|||
|
|
@ -42,36 +42,8 @@ class DeleteOldVersions(BaseAction):
|
|||
return False
|
||||
|
||||
def interface(self, session, entities, event):
|
||||
# TODO Add roots existence validation
|
||||
items = []
|
||||
root = os.environ.get("AVALON_PROJECTS")
|
||||
if not root:
|
||||
msg = "Root path to projects is not set."
|
||||
items.append({
|
||||
"type": "label",
|
||||
"value": "<i><b>ERROR:</b> {}</i>".format(msg)
|
||||
})
|
||||
self.show_interface(
|
||||
items=items, title=self.inteface_title, event=event
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
"message": msg
|
||||
}
|
||||
|
||||
if not os.path.exists(root):
|
||||
msg = "Root path does not exists \"{}\".".format(str(root))
|
||||
items.append({
|
||||
"type": "label",
|
||||
"value": "<i><b>ERROR:</b> {}</i>".format(msg)
|
||||
})
|
||||
self.show_interface(
|
||||
items=items, title=self.inteface_title, event=event
|
||||
)
|
||||
return {
|
||||
"success": False,
|
||||
"message": msg
|
||||
}
|
||||
|
||||
values = event["data"].get("values")
|
||||
if values:
|
||||
versions_count = int(values["last_versions_count"])
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ class Delivery(BaseAction):
|
|||
|
||||
repre_path = self.path_from_represenation(repre, anatomy)
|
||||
# TODO add backup solution where root of path from component
|
||||
# is repalced with AVALON_PROJECTS root
|
||||
# is repalced with root
|
||||
if not frame:
|
||||
self.process_single_file(
|
||||
repre_path, anatomy, anatomy_name, anatomy_data
|
||||
|
|
|
|||
|
|
@ -177,9 +177,16 @@ def format_anatomy(data):
|
|||
log.debug("__ anatomy.templates: {}".format(anatomy.templates))
|
||||
|
||||
try:
|
||||
padding = int(anatomy.templates['render']['padding'])
|
||||
# TODO: bck compatibility with old anatomy template
|
||||
padding = int(
|
||||
anatomy.templates["render"].get(
|
||||
"frame_padding",
|
||||
anatomy.templates["render"].get("padding")
|
||||
)
|
||||
)
|
||||
except KeyError as e:
|
||||
msg = ("`padding` key is not in `render` "
|
||||
"or `frame_padding` on is not available in "
|
||||
"Anatomy template. Please, add it there and restart "
|
||||
"the pipeline (padding: \"4\"): `{}`").format(e)
|
||||
|
||||
|
|
@ -973,7 +980,9 @@ class WorkfileSettings(object):
|
|||
self.set_colorspace()
|
||||
|
||||
def set_favorites(self):
|
||||
projects_root = os.getenv("AVALON_PROJECTS")
|
||||
anatomy = get_anatomy()
|
||||
work_template = anatomy.templates["work"]["path"]
|
||||
projects_root = anatomy.root_value_for_template(work_template)
|
||||
work_dir = os.getenv("AVALON_WORKDIR")
|
||||
asset = os.getenv("AVALON_ASSET")
|
||||
project = os.getenv("AVALON_PROJECT")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pyblish.api
|
|||
import avalon.api as avalon
|
||||
from avalon.vendor.Qt import (QtWidgets, QtGui)
|
||||
import pype.api as pype
|
||||
from pypeapp import Logger
|
||||
from pypeapp import Logger, Anatomy
|
||||
|
||||
log = Logger().get_logger(__name__, "nukestudio")
|
||||
|
||||
|
|
@ -30,12 +30,17 @@ def set_workfiles():
|
|||
# show workfile gui
|
||||
workfiles.show(workdir)
|
||||
|
||||
|
||||
def sync_avalon_data_to_workfile():
|
||||
# import session to get project dir
|
||||
S = avalon.Session
|
||||
active_project_root = os.path.normpath(
|
||||
os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT'])
|
||||
)
|
||||
project_name = avalon.Session["AVALON_PROJECT"]
|
||||
|
||||
anatomy = Anatomy(project_name)
|
||||
work_template = anatomy.templates["work"]["path"]
|
||||
work_root = anatomy.root_value_for_template(work_template)
|
||||
active_project_root = (
|
||||
os.path.join(work_root, project_name)
|
||||
).replace("\\", "/")
|
||||
# getting project
|
||||
project = hiero.core.projects()[-1]
|
||||
|
||||
|
|
@ -350,17 +355,19 @@ def CreateNukeWorkfile(nodes=None,
|
|||
# create root node and save all metadata
|
||||
root_node = hiero.core.nuke.RootNode()
|
||||
|
||||
root_path = os.environ["AVALON_PROJECTS"]
|
||||
anatomy = Anatomy(os.environ["AVALON_PROJECT"])
|
||||
work_template = anatomy.templates["work"]["path"]
|
||||
root_path = anatomy.root_value_for_template(work_template)
|
||||
|
||||
nuke_script.addNode(root_node)
|
||||
|
||||
# here to call pype.nuke.lib.BuildWorkfile
|
||||
script_builder = nklib.BuildWorkfile(
|
||||
root_node=root_node,
|
||||
root_path=root_path,
|
||||
nodes=nuke_script.getNodes(),
|
||||
**kwargs
|
||||
)
|
||||
root_node=root_node,
|
||||
root_path=root_path,
|
||||
nodes=nuke_script.getNodes(),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
class ClipLoader:
|
||||
|
|
|
|||
|
|
@ -39,10 +39,8 @@ class CollectContextDataFromAport(pyblish.api.ContextPlugin):
|
|||
# get avalon session data and convert \ to /
|
||||
_S = avalon.session
|
||||
|
||||
projects = Path(_S["AVALON_PROJECTS"]).resolve()
|
||||
asset = _S["AVALON_ASSET"]
|
||||
workdir = Path(_S["AVALON_WORKDIR"]).resolve()
|
||||
_S["AVALON_PROJECTS"] = str(projects)
|
||||
_S["AVALON_WORKDIR"] = str(workdir)
|
||||
|
||||
context.data["avalonSession"] = _S
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
"""
|
||||
Requires:
|
||||
environment -> DEADLINE_PATH
|
||||
|
||||
Provides:
|
||||
context -> deadlineUser (str)
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import pyblish.api
|
||||
from pype.plugin import contextplugin_should_run
|
||||
|
||||
CREATE_NO_WINDOW = 0x08000000
|
||||
|
||||
|
||||
def deadline_command(cmd):
|
||||
# Find Deadline
|
||||
path = os.environ.get("DEADLINE_PATH", None)
|
||||
assert path is not None, "Variable 'DEADLINE_PATH' must be set"
|
||||
|
||||
executable = os.path.join(path, "deadlinecommand")
|
||||
if os.name == "nt":
|
||||
executable += ".exe"
|
||||
assert os.path.exists(
|
||||
executable), "Deadline executable not found at %s" % executable
|
||||
assert cmd, "Must have a command"
|
||||
|
||||
query = (executable, cmd)
|
||||
|
||||
process = subprocess.Popen(query, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
creationflags=CREATE_NO_WINDOW)
|
||||
out, err = process.communicate()
|
||||
|
||||
return out
|
||||
|
||||
|
||||
class CollectDeadlineUser(pyblish.api.ContextPlugin):
|
||||
"""Retrieve the local active Deadline user"""
|
||||
|
||||
order = pyblish.api.CollectorOrder + 0.499
|
||||
label = "Deadline User"
|
||||
hosts = ['maya', 'fusion']
|
||||
families = ["renderlayer", "saver.deadline"]
|
||||
|
||||
def process(self, context):
|
||||
"""Inject the current working file"""
|
||||
|
||||
# Workaround bug pyblish-base#250
|
||||
if not contextplugin_should_run(self, context):
|
||||
return
|
||||
|
||||
user = deadline_command("GetCurrentUserName").strip()
|
||||
|
||||
if not user:
|
||||
self.log.warning("No Deadline user found. "
|
||||
"Do you have Deadline installed?")
|
||||
return
|
||||
|
||||
self.log.info("Found Deadline user: {}".format(user))
|
||||
context.data['deadlineUser'] = user
|
||||
|
|
@ -356,8 +356,11 @@ class IntegrateMasterVersion(pyblish.api.InstancePlugin):
|
|||
_anatomy_filled = anatomy.format(anatomy_data)
|
||||
_template_filled = _anatomy_filled["master"]["path"]
|
||||
head, tail = _template_filled.split(frame_splitter)
|
||||
padding = (
|
||||
anatomy.templates["render"]["padding"]
|
||||
padding = int(
|
||||
anatomy.templates["render"].get(
|
||||
"frame_padding",
|
||||
anatomy.templates["render"].get("padding")
|
||||
)
|
||||
)
|
||||
|
||||
dst_col = clique.Collection(
|
||||
|
|
|
|||
|
|
@ -343,10 +343,11 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
index_frame_start = None
|
||||
|
||||
if repre.get("frameStart"):
|
||||
# TODO: bck compatibility `templates["render"]["padding"]`
|
||||
frame_start_padding = anatomy.templates.get(
|
||||
"frame_padding",
|
||||
anatomy.templates["render"].get("padding")
|
||||
frame_start_padding = int(
|
||||
anatomy.templates["render"].get(
|
||||
"frame_padding",
|
||||
anatomy.templates["render"].get("padding")
|
||||
)
|
||||
)
|
||||
|
||||
index_frame_start = int(repre.get("frameStart"))
|
||||
|
|
@ -656,7 +657,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
source = context.data["currentFile"]
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
success, rootless_path = (
|
||||
anatomy.roots_obj.find_root_template_from_path(source)
|
||||
anatomy.find_root_template_from_path(source)
|
||||
)
|
||||
if success:
|
||||
source = rootless_path
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
output_dir = instance.data["outputDir"]
|
||||
# Convert output dir to `{root}/rest/of/path/...` with Anatomy
|
||||
success, rootless_path = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(output_dir)
|
||||
self.anatomy.find_root_template_from_path(output_dir)
|
||||
)
|
||||
if not success:
|
||||
# `rootless_path` is not set to `output_dir` if none of roots match
|
||||
|
|
@ -262,7 +262,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
# self.log.info(json.dumps(payload, indent=4, sort_keys=True))
|
||||
|
||||
url = "{}/api/jobs".format(self.DEADLINE_REST_URL)
|
||||
response = requests.post(url, json=payload)
|
||||
response = requests.post(url, json=payload, timeout=10)
|
||||
if not response.ok:
|
||||
raise Exception(response.text)
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
|
||||
staging = os.path.dirname(list(cols[0])[0])
|
||||
success, rootless_staging_dir = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(staging)
|
||||
self.anatomy.find_root_template_from_path(staging)
|
||||
)
|
||||
if success:
|
||||
staging = rootless_staging_dir
|
||||
|
|
@ -471,7 +471,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
|
||||
staging = os.path.dirname(list(collection)[0])
|
||||
success, rootless_staging_dir = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(staging)
|
||||
self.anatomy.find_root_template_from_path(staging)
|
||||
)
|
||||
if success:
|
||||
staging = rootless_staging_dir
|
||||
|
|
@ -506,7 +506,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
|
||||
staging = os.path.dirname(remainder)
|
||||
success, rootless_staging_dir = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(staging)
|
||||
self.anatomy.find_root_template_from_path(staging)
|
||||
)
|
||||
if success:
|
||||
staging = rootless_staging_dir
|
||||
|
|
@ -619,7 +619,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
source = context.data["currentFile"]
|
||||
|
||||
success, rootless_path = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(source)
|
||||
self.anatomy.find_root_template_from_path(source)
|
||||
)
|
||||
if success:
|
||||
source = rootless_path
|
||||
|
|
@ -684,7 +684,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin):
|
|||
staging_dir = repre.get("stagingDir")
|
||||
if staging_dir:
|
||||
success, rootless_staging_dir = (
|
||||
self.anatomy.roots_obj.find_root_template_from_path(
|
||||
self.anatomy.find_root_template_from_path(
|
||||
staging_dir
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -352,6 +352,8 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
if 'verify' not in kwargs:
|
||||
kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa
|
||||
# add 10sec timeout before bailing out
|
||||
kwargs['timeout'] = 10
|
||||
return requests.post(*args, **kwargs)
|
||||
|
||||
def _requests_get(self, *args, **kwargs):
|
||||
|
|
@ -366,4 +368,6 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
if 'verify' not in kwargs:
|
||||
kwargs['verify'] = False if os.getenv("PYPE_DONT_VERIFY_SSL", True) else True # noqa
|
||||
# add 10sec timeout before bailing out
|
||||
kwargs['timeout'] = 10
|
||||
return requests.get(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -37,50 +37,71 @@ class ValidateAssRelativePaths(pyblish.api.InstancePlugin):
|
|||
|
||||
scene_dir, scene_basename = os.path.split(cmds.file(q=True, loc=True))
|
||||
scene_name, _ = os.path.splitext(scene_basename)
|
||||
project_root = "{}{}{}".format(
|
||||
os.environ.get("AVALON_PROJECTS"),
|
||||
os.path.sep,
|
||||
os.environ.get("AVALON_PROJECT")
|
||||
)
|
||||
assert self.maya_is_true(relative_texture) is not True, \
|
||||
("Texture path is set to be absolute")
|
||||
assert self.maya_is_true(relative_procedural) is not True, \
|
||||
("Procedural path is set to be absolute")
|
||||
|
||||
texture_search_path = texture_search_path.replace("\\", "/")
|
||||
procedural_search_path = procedural_search_path.replace("\\", "/")
|
||||
project_root = project_root.replace("\\", "/")
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
|
||||
assert project_root in texture_search_path, \
|
||||
("Project root is not in texture_search_path")
|
||||
assert project_root in procedural_search_path, \
|
||||
("Project root is not in procedural_search_path")
|
||||
# Use project root variables for multiplatform support, see:
|
||||
# https://docs.arnoldrenderer.com/display/A5AFMUG/Search+Path
|
||||
# ':' as path separator is supported by Arnold for all platforms.
|
||||
keys = anatomy.root_environments().keys()
|
||||
paths = []
|
||||
for k in keys:
|
||||
paths.append("[{}]".format(k))
|
||||
|
||||
self.log.info("discovered roots: {}".format(":".join(paths)))
|
||||
|
||||
assert ":".join(paths) in texture_search_path, (
|
||||
"Project roots are not in texture_search_path"
|
||||
)
|
||||
|
||||
assert ":".join(paths) in procedural_search_path, (
|
||||
"Project roots are not in procedural_search_path"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
texture_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.tspath"
|
||||
texture_path = cmds.getAttr("defaultArnoldRenderOptions.tspath")
|
||||
procedural_path = cmds.getAttr("defaultArnoldRenderOptions.pspath")
|
||||
|
||||
# Use project root variables for multiplatform support, see:
|
||||
# https://docs.arnoldrenderer.com/display/A5AFMUG/Search+Path
|
||||
# ':' as path separator is supported by Arnold for all platforms.
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
keys = anatomy.root_environments().keys()
|
||||
paths = []
|
||||
for k in keys:
|
||||
paths.append("[{}]".format(k))
|
||||
|
||||
cmds.setAttr(
|
||||
"defaultArnoldRenderOptions.tspath",
|
||||
":".join([p for p in paths + [texture_path] if p]),
|
||||
type="string"
|
||||
)
|
||||
procedural_search_path = cmds.getAttr(
|
||||
"defaultArnoldRenderOptions.pspath"
|
||||
cmds.setAttr(
|
||||
"defaultArnoldRenderOptions.absolute_texture_paths",
|
||||
False
|
||||
)
|
||||
|
||||
project_root = "{}{}{}".format(
|
||||
os.environ.get("AVALON_PROJECTS"),
|
||||
os.path.sep,
|
||||
os.environ.get("AVALON_PROJECT"),
|
||||
).replace("\\", "/")
|
||||
cmds.setAttr(
|
||||
"defaultArnoldRenderOptions.pspath",
|
||||
":".join([p for p in paths + [procedural_path] if p]),
|
||||
type="string"
|
||||
)
|
||||
cmds.setAttr(
|
||||
"defaultArnoldRenderOptions.absolute_procedural_paths",
|
||||
False
|
||||
)
|
||||
|
||||
cmds.setAttr("defaultArnoldRenderOptions.tspath",
|
||||
project_root + os.pathsep + texture_search_path,
|
||||
type="string")
|
||||
cmds.setAttr("defaultArnoldRenderOptions.pspath",
|
||||
project_root + os.pathsep + procedural_search_path,
|
||||
type="string")
|
||||
cmds.setAttr("defaultArnoldRenderOptions.absolute_procedural_paths",
|
||||
False)
|
||||
cmds.setAttr("defaultArnoldRenderOptions.absolute_texture_paths",
|
||||
False)
|
||||
@staticmethod
|
||||
def find_absolute_path(relative_path, all_root_paths):
|
||||
for root_path in all_root_paths:
|
||||
possible_path = os.path.join(root_path, relative_path)
|
||||
if os.path.exists(possible_path):
|
||||
return possible_path
|
||||
|
||||
def maya_is_true(self, attr_val):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin):
|
|||
self.expected_files(instance, render_path)
|
||||
self.log.debug("__ expectedFiles: `{}`".format(
|
||||
instance.data["expectedFiles"]))
|
||||
response = requests.post(self.deadline_url, json=payload)
|
||||
response = requests.post(self.deadline_url, json=payload, timeout=10)
|
||||
|
||||
if not response.ok:
|
||||
raise Exception(response.text)
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
import pyblish.api
|
||||
import avalon.api as avalon
|
||||
import os
|
||||
|
||||
class CollectActiveProjectRoot(pyblish.api.ContextPlugin):
|
||||
"""Inject the active project into context"""
|
||||
|
||||
label = "Collect Project Root"
|
||||
order = pyblish.api.CollectorOrder - 0.1
|
||||
|
||||
def process(self, context):
|
||||
S = avalon.Session
|
||||
context.data["projectroot"] = os.path.normpath(
|
||||
os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT'])
|
||||
)
|
||||
|
|
@ -18,7 +18,7 @@ def main(env):
|
|||
# Register Host (and it's pyblish plugins)
|
||||
host_name = env["AVALON_APP"]
|
||||
# TODO not sure if use "pype." or "avalon." for host import
|
||||
host_import_str = f"avalon.{host_name}"
|
||||
host_import_str = f"pype.{host_name}"
|
||||
|
||||
try:
|
||||
host_module = importlib.import_module(host_import_str)
|
||||
|
|
|
|||
BIN
res/app_icons/harmony.png
Normal file
BIN
res/app_icons/harmony.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
|
|
@ -9,7 +9,6 @@
|
|||
"additionalProperties": true,
|
||||
|
||||
"required": [
|
||||
"AVALON_PROJECTS",
|
||||
"AVALON_PROJECT",
|
||||
"AVALON_ASSET",
|
||||
"AVALON_CONFIG"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue