mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
add some comment
This commit is contained in:
parent
22251f4958
commit
7075d5c445
21 changed files with 573 additions and 45 deletions
|
|
@ -0,0 +1,55 @@
|
|||
from pathlib import Path
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
|
||||
|
||||
class AddPythonScriptToLaunchArgs(PreLaunchHook):
|
||||
"""Add python script to be executed before Blender launch."""
|
||||
|
||||
# Append after file argument
|
||||
order = 15
|
||||
app_groups = [
|
||||
"blender",
|
||||
]
|
||||
|
||||
def execute(self):
|
||||
if not self.launch_context.data.get("python_scripts"):
|
||||
return
|
||||
|
||||
# Add path to workfile to arguments
|
||||
for python_script_path in self.launch_context.data["python_scripts"]:
|
||||
self.log.info(
|
||||
f"Adding python script {python_script_path} to launch"
|
||||
)
|
||||
# Test script path exists
|
||||
python_script_path = Path(python_script_path)
|
||||
if not python_script_path.exists():
|
||||
self.log.warning(
|
||||
f"Python script {python_script_path} doesn't exist. "
|
||||
"Skipped..."
|
||||
)
|
||||
continue
|
||||
|
||||
if "--" in self.launch_context.launch_args:
|
||||
# Insert before separator
|
||||
separator_index = self.launch_context.launch_args.index("--")
|
||||
self.launch_context.launch_args.insert(
|
||||
separator_index,
|
||||
"-P",
|
||||
)
|
||||
self.launch_context.launch_args.insert(
|
||||
separator_index + 1,
|
||||
python_script_path.as_posix(),
|
||||
)
|
||||
else:
|
||||
self.launch_context.launch_args.extend(
|
||||
["-P", python_script_path.as_posix()]
|
||||
)
|
||||
|
||||
# Ensure separator
|
||||
if "--" not in self.launch_context.launch_args:
|
||||
self.launch_context.launch_args.append("--")
|
||||
|
||||
self.launch_context.launch_args.extend(
|
||||
[*self.launch_context.data.get("script_args", [])]
|
||||
)
|
||||
|
|
@ -128,7 +128,14 @@ def get_all_children(parent, node_type=None):
|
|||
|
||||
|
||||
def get_current_renderer():
|
||||
"""get current renderer"""
|
||||
"""
|
||||
Notes:
|
||||
Get current renderer for Max
|
||||
|
||||
Returns:
|
||||
"{Current Renderer}:{Current Renderer}"
|
||||
e.g. "Redshift_Renderer:Redshift_Renderer"
|
||||
"""
|
||||
return rt.renderers.production
|
||||
|
||||
|
||||
|
|
|
|||
18
openpype/hosts/max/plugins/create/create_redshift_proxy.py
Normal file
18
openpype/hosts/max/plugins/create/create_redshift_proxy.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Creator plugin for creating camera."""
|
||||
from openpype.hosts.max.api import plugin
|
||||
from openpype.pipeline import CreatedInstance
|
||||
|
||||
|
||||
class CreateRedshiftProxy(plugin.MaxCreator):
|
||||
identifier = "io.openpype.creators.max.redshiftproxy"
|
||||
label = "Redshift Proxy"
|
||||
family = "redshiftproxy"
|
||||
icon = "gear"
|
||||
|
||||
def create(self, subset_name, instance_data, pre_create_data):
|
||||
|
||||
_ = super(CreateRedshiftProxy, self).create(
|
||||
subset_name,
|
||||
instance_data,
|
||||
pre_create_data) # type: CreatedInstance
|
||||
63
openpype/hosts/max/plugins/load/load_redshift_proxy.py
Normal file
63
openpype/hosts/max/plugins/load/load_redshift_proxy.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import os
|
||||
import clique
|
||||
|
||||
from openpype.pipeline import (
|
||||
load,
|
||||
get_representation_path
|
||||
)
|
||||
from openpype.hosts.max.api.pipeline import containerise
|
||||
from openpype.hosts.max.api import lib
|
||||
|
||||
|
||||
class RedshiftProxyLoader(load.LoaderPlugin):
|
||||
"""Load rs files with Redshift Proxy"""
|
||||
|
||||
label = "Load Redshift Proxy"
|
||||
families = ["redshiftproxy"]
|
||||
representations = ["rs"]
|
||||
order = -9
|
||||
icon = "code-fork"
|
||||
color = "white"
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
from pymxs import runtime as rt
|
||||
|
||||
filepath = self.filepath_from_context(context)
|
||||
rs_proxy = rt.RedshiftProxy()
|
||||
rs_proxy.file = filepath
|
||||
files_in_folder = os.listdir(os.path.dirname(filepath))
|
||||
collections, remainder = clique.assemble(files_in_folder)
|
||||
if collections:
|
||||
rs_proxy.is_sequence = True
|
||||
|
||||
container = rt.container()
|
||||
container.name = name
|
||||
rs_proxy.Parent = container
|
||||
|
||||
asset = rt.getNodeByName(name)
|
||||
|
||||
return containerise(
|
||||
name, [asset], context, loader=self.__class__.__name__)
|
||||
|
||||
def update(self, container, representation):
|
||||
from pymxs import runtime as rt
|
||||
|
||||
path = get_representation_path(representation)
|
||||
node = rt.getNodeByName(container["instance_node"])
|
||||
for children in node.Children:
|
||||
children_node = rt.getNodeByName(children.name)
|
||||
for proxy in children_node.Children:
|
||||
proxy.file = path
|
||||
|
||||
lib.imprint(container["instance_node"], {
|
||||
"representation": str(representation["_id"])
|
||||
})
|
||||
|
||||
def switch(self, container, representation):
|
||||
self.update(container, representation)
|
||||
|
||||
def remove(self, container):
|
||||
from pymxs import runtime as rt
|
||||
|
||||
node = rt.getNodeByName(container["instance_node"])
|
||||
rt.delete(node)
|
||||
62
openpype/hosts/max/plugins/publish/extract_redshift_proxy.py
Normal file
62
openpype/hosts/max/plugins/publish/extract_redshift_proxy.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import os
|
||||
import pyblish.api
|
||||
from openpype.pipeline import publish
|
||||
from pymxs import runtime as rt
|
||||
from openpype.hosts.max.api import maintained_selection
|
||||
|
||||
|
||||
class ExtractRedshiftProxy(publish.Extractor):
|
||||
"""
|
||||
Extract Redshift Proxy with rsProxy
|
||||
"""
|
||||
|
||||
order = pyblish.api.ExtractorOrder - 0.1
|
||||
label = "Extract RedShift Proxy"
|
||||
hosts = ["max"]
|
||||
families = ["redshiftproxy"]
|
||||
|
||||
def process(self, instance):
|
||||
container = instance.data["instance_node"]
|
||||
start = int(instance.context.data.get("frameStart"))
|
||||
end = int(instance.context.data.get("frameEnd"))
|
||||
|
||||
self.log.info("Extracting Redshift Proxy...")
|
||||
stagingdir = self.staging_dir(instance)
|
||||
rs_filename = "{name}.rs".format(**instance.data)
|
||||
rs_filepath = os.path.join(stagingdir, rs_filename)
|
||||
rs_filepath = rs_filepath.replace("\\", "/")
|
||||
|
||||
rs_filenames = self.get_rsfiles(instance, start, end)
|
||||
|
||||
with maintained_selection():
|
||||
# select and export
|
||||
con = rt.getNodeByName(container)
|
||||
rt.select(con.Children)
|
||||
# Redshift rsProxy command
|
||||
# rsProxy fp selected compress connectivity startFrame endFrame
|
||||
# camera warnExisting transformPivotToOrigin
|
||||
rt.rsProxy(rs_filepath, 1, 0, 0, start, end, 0, 1, 1)
|
||||
|
||||
self.log.info("Performing Extraction ...")
|
||||
|
||||
if "representations" not in instance.data:
|
||||
instance.data["representations"] = []
|
||||
|
||||
representation = {
|
||||
'name': 'rs',
|
||||
'ext': 'rs',
|
||||
'files': rs_filenames if len(rs_filenames) > 1 else rs_filenames[0], # noqa
|
||||
"stagingDir": stagingdir,
|
||||
}
|
||||
instance.data["representations"].append(representation)
|
||||
self.log.info("Extracted instance '%s' to: %s" % (instance.name,
|
||||
stagingdir))
|
||||
|
||||
def get_rsfiles(self, instance, startFrame, endFrame):
|
||||
rs_filenames = []
|
||||
rs_name = instance.data["name"]
|
||||
for frame in range(startFrame, endFrame + 1):
|
||||
rs_filename = "%s.%04d.rs" % (rs_name, frame)
|
||||
rs_filenames.append(rs_filename)
|
||||
|
||||
return rs_filenames
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
from openpype.pipeline import PublishValidationError
|
||||
from pymxs import runtime as rt
|
||||
from openpype.pipeline.publish import RepairAction
|
||||
from openpype.hosts.max.api.lib import get_current_renderer
|
||||
|
||||
|
||||
class ValidateRendererRedshiftProxy(pyblish.api.InstancePlugin):
|
||||
"""
|
||||
Validates Redshift as the current renderer for creating
|
||||
Redshift Proxy
|
||||
"""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
families = ["redshiftproxy"]
|
||||
hosts = ["max"]
|
||||
label = "Redshift Renderer"
|
||||
actions = [RepairAction]
|
||||
|
||||
def process(self, instance):
|
||||
invalid = self.get_redshift_renderer(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError("Please install Redshift for 3dsMax"
|
||||
" before using the Redshift proxy instance") # noqa
|
||||
invalid = self.get_current_renderer(instance)
|
||||
if invalid:
|
||||
raise PublishValidationError("The Redshift proxy extraction"
|
||||
"discontinued since the current renderer is not Redshift") # noqa
|
||||
|
||||
def get_redshift_renderer(self, instance):
|
||||
invalid = list()
|
||||
max_renderers_list = str(rt.RendererClass.classes)
|
||||
if "Redshift_Renderer" not in max_renderers_list:
|
||||
invalid.append(max_renderers_list)
|
||||
|
||||
return invalid
|
||||
|
||||
def get_current_renderer(self, instance):
|
||||
invalid = list()
|
||||
renderer_class = get_current_renderer()
|
||||
current_renderer = str(renderer_class).split(":")[0]
|
||||
if current_renderer != "Redshift_Renderer":
|
||||
invalid.append(current_renderer)
|
||||
|
||||
return invalid
|
||||
|
||||
@classmethod
|
||||
def repair(cls, instance):
|
||||
for Renderer in rt.RendererClass.classes:
|
||||
renderer = Renderer()
|
||||
if "Redshift_Renderer" in str(renderer):
|
||||
rt.renderers.production = renderer
|
||||
break
|
||||
0
openpype/hosts/nuke/startup/__init__.py
Normal file
0
openpype/hosts/nuke/startup/__init__.py
Normal file
|
|
@ -68,6 +68,7 @@ def main():
|
|||
if knob["name"] == "file_type":
|
||||
ext = knob["value"]
|
||||
for w in write_selected_nodes:
|
||||
# data for mapping the path
|
||||
data = {
|
||||
"work": os.getenv("AVALON_WORKDIR"),
|
||||
"subset": w["name"].value(),
|
||||
|
|
|
|||
47
openpype/hosts/nuke/startup/frame_setting_for_read_nodes.py
Normal file
47
openpype/hosts/nuke/startup/frame_setting_for_read_nodes.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
""" OpenPype custom script for resetting read nodes start frame values """
|
||||
|
||||
import nuke
|
||||
import nukescripts
|
||||
|
||||
|
||||
class FrameSettingsPanel(nukescripts.PythonPanel):
|
||||
""" Frame Settings Panel """
|
||||
def __init__(self):
|
||||
nukescripts.PythonPanel.__init__(self, "Set Frame Start (Read Node)")
|
||||
|
||||
# create knobs
|
||||
self.frame = nuke.Int_Knob(
|
||||
'frame', 'Frame Number')
|
||||
self.selected = nuke.Boolean_Knob("selection")
|
||||
# add knobs to panel
|
||||
self.addKnob(self.selected)
|
||||
self.addKnob(self.frame)
|
||||
|
||||
# set values
|
||||
self.selected.setValue(False)
|
||||
self.frame.setValue(nuke.root().firstFrame())
|
||||
|
||||
def process(self):
|
||||
""" Process the panel values. """
|
||||
# get values
|
||||
frame = self.frame.value()
|
||||
if self.selected.value():
|
||||
# selected nodes processing
|
||||
if not nuke.selectedNodes():
|
||||
return
|
||||
for rn_ in nuke.selectedNodes():
|
||||
if rn_.Class() != "Read":
|
||||
continue
|
||||
rn_["frame_mode"].setValue("start_at")
|
||||
rn_["frame"].setValue(str(frame))
|
||||
else:
|
||||
# all nodes processing
|
||||
for rn_ in nuke.allNodes(filter="Read"):
|
||||
rn_["frame_mode"].setValue("start_at")
|
||||
rn_["frame"].setValue(str(frame))
|
||||
|
||||
|
||||
def main():
|
||||
p_ = FrameSettingsPanel()
|
||||
if p_.showModalDialog():
|
||||
print(p_.process())
|
||||
|
|
@ -43,18 +43,22 @@ def open_file(filepath):
|
|||
"""
|
||||
Loading project
|
||||
"""
|
||||
|
||||
from . import bmdvr
|
||||
|
||||
pm = get_project_manager()
|
||||
page = bmdvr.GetCurrentPage()
|
||||
if page is not None:
|
||||
# Save current project only if Resolve has an active page, otherwise
|
||||
# we consider Resolve being in a pre-launch state (no open UI yet)
|
||||
project = pm.GetCurrentProject()
|
||||
print(f"Saving current project: {project}")
|
||||
pm.SaveProject()
|
||||
|
||||
file = os.path.basename(filepath)
|
||||
fname, _ = os.path.splitext(file)
|
||||
dname, _ = fname.split("_v")
|
||||
|
||||
# deal with current project
|
||||
project = pm.GetCurrentProject()
|
||||
log.info(f"Test `pm`: {pm}")
|
||||
pm.SaveProject()
|
||||
|
||||
try:
|
||||
log.info(f"Test `dname`: {dname}")
|
||||
if not set_project_manager_to_folder_name(dname):
|
||||
raise
|
||||
# load project from input path
|
||||
|
|
@ -72,6 +76,7 @@ def open_file(filepath):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def current_file():
|
||||
pm = get_project_manager()
|
||||
current_dir = os.getenv("AVALON_WORKDIR")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import os
|
||||
|
||||
from openpype.lib import PreLaunchHook
|
||||
import openpype.hosts.resolve
|
||||
|
||||
|
||||
class ResolveLaunchLastWorkfile(PreLaunchHook):
|
||||
"""Special hook to open last workfile for Resolve.
|
||||
|
||||
Checks 'start_last_workfile', if set to False, it will not open last
|
||||
workfile. This property is set explicitly in Launcher.
|
||||
"""
|
||||
|
||||
# Execute after workfile template copy
|
||||
order = 10
|
||||
app_groups = ["resolve"]
|
||||
|
||||
def execute(self):
|
||||
if not self.data.get("start_last_workfile"):
|
||||
self.log.info("It is set to not start last workfile on start.")
|
||||
return
|
||||
|
||||
last_workfile = self.data.get("last_workfile_path")
|
||||
if not last_workfile:
|
||||
self.log.warning("Last workfile was not collected.")
|
||||
return
|
||||
|
||||
if not os.path.exists(last_workfile):
|
||||
self.log.info("Current context does not have any workfile yet.")
|
||||
return
|
||||
|
||||
# Add path to launch environment for the startup script to pick up
|
||||
self.log.info(f"Setting OPENPYPE_RESOLVE_OPEN_ON_LAUNCH to launch "
|
||||
f"last workfile: {last_workfile}")
|
||||
key = "OPENPYPE_RESOLVE_OPEN_ON_LAUNCH"
|
||||
self.launch_context.env[key] = last_workfile
|
||||
|
||||
# Set the openpype prelaunch startup script path for easy access
|
||||
# in the LUA .scriptlib code
|
||||
op_resolve_root = os.path.dirname(openpype.hosts.resolve.__file__)
|
||||
script_path = os.path.join(op_resolve_root, "startup.py")
|
||||
key = "OPENPYPE_RESOLVE_STARTUP_SCRIPT"
|
||||
self.launch_context.env[key] = script_path
|
||||
self.log.info("Setting OPENPYPE_RESOLVE_STARTUP_SCRIPT to: "
|
||||
f"{script_path}")
|
||||
62
openpype/hosts/resolve/startup.py
Normal file
62
openpype/hosts/resolve/startup.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"""This script is used as a startup script in Resolve through a .scriptlib file
|
||||
|
||||
It triggers directly after the launch of Resolve and it's recommended to keep
|
||||
it optimized for fast performance since the Resolve UI is actually interactive
|
||||
while this is running. As such, there's nothing ensuring the user isn't
|
||||
continuing manually before any of the logic here runs. As such we also try
|
||||
to delay any imports as much as possible.
|
||||
|
||||
This code runs in a separate process to the main Resolve process.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
import openpype.hosts.resolve.api
|
||||
|
||||
|
||||
def ensure_installed_host():
|
||||
"""Install resolve host with openpype and return the registered host.
|
||||
|
||||
This function can be called multiple times without triggering an
|
||||
additional install.
|
||||
"""
|
||||
from openpype.pipeline import install_host, registered_host
|
||||
host = registered_host()
|
||||
if host:
|
||||
return host
|
||||
|
||||
install_host(openpype.hosts.resolve.api)
|
||||
return registered_host()
|
||||
|
||||
|
||||
def launch_menu():
|
||||
print("Launching Resolve OpenPype menu..")
|
||||
ensure_installed_host()
|
||||
openpype.hosts.resolve.api.launch_pype_menu()
|
||||
|
||||
|
||||
def open_file(path):
|
||||
# Avoid the need to "install" the host
|
||||
host = ensure_installed_host()
|
||||
host.open_file(path)
|
||||
|
||||
|
||||
def main():
|
||||
# Open last workfile
|
||||
workfile_path = os.environ.get("OPENPYPE_RESOLVE_OPEN_ON_LAUNCH")
|
||||
if workfile_path:
|
||||
open_file(workfile_path)
|
||||
else:
|
||||
print("No last workfile set to open. Skipping..")
|
||||
|
||||
# Launch OpenPype menu
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.pipeline.context_tools import get_current_project_name
|
||||
project_name = get_current_project_name()
|
||||
settings = get_project_settings(project_name)
|
||||
if settings.get("resolve", {}).get("launch_openpype_menu_on_start", True):
|
||||
launch_menu()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
-- Run OpenPype's Python launch script for resolve
|
||||
function file_exists(name)
|
||||
local f = io.open(name, "r")
|
||||
return f ~= nil and io.close(f)
|
||||
end
|
||||
|
||||
|
||||
openpype_startup_script = os.getenv("OPENPYPE_RESOLVE_STARTUP_SCRIPT")
|
||||
if openpype_startup_script ~= nil then
|
||||
script = fusion:MapPath(openpype_startup_script)
|
||||
|
||||
if file_exists(script) then
|
||||
-- We must use RunScript to ensure it runs in a separate
|
||||
-- process to Resolve itself to avoid a deadlock for
|
||||
-- certain imports of OpenPype libraries or Qt
|
||||
print("Running launch script: " .. script)
|
||||
fusion:RunScript(script)
|
||||
else
|
||||
print("Launch script not found at: " .. script)
|
||||
end
|
||||
end
|
||||
|
|
@ -29,6 +29,9 @@ def setup(env):
|
|||
log.info("Utility Scripts Dir: `{}`".format(util_scripts_paths))
|
||||
log.info("Utility Scripts: `{}`".format(scripts))
|
||||
|
||||
# Make sure scripts dir exists
|
||||
os.makedirs(util_scripts_dir, exist_ok=True)
|
||||
|
||||
# make sure no script file is in folder
|
||||
for script in os.listdir(util_scripts_dir):
|
||||
path = os.path.join(util_scripts_dir, script)
|
||||
|
|
@ -50,6 +53,14 @@ def setup(env):
|
|||
|
||||
src = os.path.join(directory, script)
|
||||
dst = os.path.join(util_scripts_dir, script)
|
||||
|
||||
# TODO: Make this a less hacky workaround
|
||||
if script == "openpype_startup.scriptlib":
|
||||
# Handle special case for scriptlib that needs to be a folder
|
||||
# up from the Comp folder in the Fusion scripts
|
||||
dst = os.path.join(os.path.dirname(util_scripts_dir),
|
||||
script)
|
||||
|
||||
log.info("Copying `{}` to `{}`...".format(src, dst))
|
||||
if os.path.isdir(src):
|
||||
shutil.copytree(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue