mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
Merge branch 'develop' of https://github.com/ynput/ayon-core into enhancement/create_context_typing
This commit is contained in:
commit
cc8ec32831
13 changed files with 157 additions and 314 deletions
|
|
@ -4,10 +4,6 @@ from .pipeline import (
|
|||
containerise
|
||||
)
|
||||
|
||||
from .plugin import (
|
||||
Creator,
|
||||
)
|
||||
|
||||
from .lib import (
|
||||
lsattr,
|
||||
lsattrs,
|
||||
|
|
@ -23,8 +19,6 @@ __all__ = [
|
|||
"ls",
|
||||
"containerise",
|
||||
|
||||
"Creator",
|
||||
|
||||
# Utility functions
|
||||
"lsattr",
|
||||
"lsattrs",
|
||||
|
|
|
|||
|
|
@ -148,89 +148,6 @@ def validate_fps():
|
|||
return True
|
||||
|
||||
|
||||
def create_remote_publish_node(force=True):
|
||||
"""Function to create a remote publish node in /out
|
||||
|
||||
This is a hacked "Shell" node that does *nothing* except for triggering
|
||||
`colorbleed.lib.publish_remote()` as pre-render script.
|
||||
|
||||
All default attributes of the Shell node are hidden to the Artist to
|
||||
avoid confusion.
|
||||
|
||||
Additionally some custom attributes are added that can be collected
|
||||
by a Collector to set specific settings for the publish, e.g. whether
|
||||
to separate the jobs per instance or process in one single job.
|
||||
|
||||
"""
|
||||
|
||||
cmd = "import colorbleed.lib; colorbleed.lib.publish_remote()"
|
||||
|
||||
existing = hou.node("/out/REMOTE_PUBLISH")
|
||||
if existing:
|
||||
if force:
|
||||
log.warning("Removing existing '/out/REMOTE_PUBLISH' node..")
|
||||
existing.destroy()
|
||||
else:
|
||||
raise RuntimeError("Node already exists /out/REMOTE_PUBLISH. "
|
||||
"Please remove manually or set `force` to "
|
||||
"True.")
|
||||
|
||||
# Create the shell node
|
||||
out = hou.node("/out")
|
||||
node = out.createNode("shell", node_name="REMOTE_PUBLISH")
|
||||
node.moveToGoodPosition()
|
||||
|
||||
# Set color make it stand out (avalon/pyblish color)
|
||||
node.setColor(hou.Color(0.439, 0.709, 0.933))
|
||||
|
||||
# Set the pre-render script
|
||||
node.setParms({
|
||||
"prerender": cmd,
|
||||
"lprerender": "python" # command language
|
||||
})
|
||||
|
||||
# Lock the attributes to ensure artists won't easily mess things up.
|
||||
node.parm("prerender").lock(True)
|
||||
node.parm("lprerender").lock(True)
|
||||
|
||||
# Lock up the actual shell command
|
||||
command_parm = node.parm("command")
|
||||
command_parm.set("")
|
||||
command_parm.lock(True)
|
||||
shellexec_parm = node.parm("shellexec")
|
||||
shellexec_parm.set(False)
|
||||
shellexec_parm.lock(True)
|
||||
|
||||
# Get the node's parm template group so we can customize it
|
||||
template = node.parmTemplateGroup()
|
||||
|
||||
# Hide default tabs
|
||||
template.hideFolder("Shell", True)
|
||||
template.hideFolder("Scripts", True)
|
||||
|
||||
# Hide default settings
|
||||
template.hide("execute", True)
|
||||
template.hide("renderdialog", True)
|
||||
template.hide("trange", True)
|
||||
template.hide("f", True)
|
||||
template.hide("take", True)
|
||||
|
||||
# Add custom settings to this node.
|
||||
parm_folder = hou.FolderParmTemplate("folder", "Submission Settings")
|
||||
|
||||
# Separate Jobs per Instance
|
||||
parm = hou.ToggleParmTemplate(name="separateJobPerInstance",
|
||||
label="Separate Job per Instance",
|
||||
default_value=False)
|
||||
parm_folder.addParmTemplate(parm)
|
||||
|
||||
# Add our custom Submission Settings folder
|
||||
template.append(parm_folder)
|
||||
|
||||
# Apply template back to the node
|
||||
node.setParmTemplateGroup(template)
|
||||
|
||||
|
||||
def render_rop(ropnode):
|
||||
"""Render ROP node utility for Publishing.
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ import hou
|
|||
import pyblish.api
|
||||
from ayon_core.pipeline import (
|
||||
CreatorError,
|
||||
LegacyCreator,
|
||||
Creator as NewCreator,
|
||||
Creator,
|
||||
CreatedInstance,
|
||||
AYON_INSTANCE_ID,
|
||||
AVALON_INSTANCE_ID,
|
||||
|
|
@ -26,80 +25,6 @@ from .lib import imprint, read, lsattr, add_self_publish_button
|
|||
SETTINGS_CATEGORY = "houdini"
|
||||
|
||||
|
||||
class Creator(LegacyCreator):
|
||||
"""Creator plugin to create instances in Houdini
|
||||
|
||||
To support the wide range of node types for render output (Alembic, VDB,
|
||||
Mantra) the Creator needs a node type to create the correct instance
|
||||
|
||||
By default, if none is given, is `geometry`. An example of accepted node
|
||||
types: geometry, alembic, ifd (mantra)
|
||||
|
||||
Please check the Houdini documentation for more node types.
|
||||
|
||||
Tip: to find the exact node type to create press the `i` left of the node
|
||||
when hovering over a node. The information is visible under the name of
|
||||
the node.
|
||||
|
||||
Deprecated:
|
||||
This creator is deprecated and will be removed in future version.
|
||||
|
||||
"""
|
||||
defaults = ['Main']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Creator, self).__init__(*args, **kwargs)
|
||||
self.nodes = []
|
||||
|
||||
def process(self):
|
||||
"""This is the base functionality to create instances in Houdini
|
||||
|
||||
The selected nodes are stored in self to be used in an override method.
|
||||
This is currently necessary in order to support the multiple output
|
||||
types in Houdini which can only be rendered through their own node.
|
||||
|
||||
Default node type if none is given is `geometry`
|
||||
|
||||
It also makes it easier to apply custom settings per instance type
|
||||
|
||||
Example of override method for Alembic:
|
||||
|
||||
def process(self):
|
||||
instance = super(CreateEpicNode, self, process()
|
||||
# Set parameters for Alembic node
|
||||
instance.setParms(
|
||||
{"sop_path": "$HIP/%s.abc" % self.nodes[0]}
|
||||
)
|
||||
|
||||
Returns:
|
||||
hou.Node
|
||||
|
||||
"""
|
||||
try:
|
||||
if (self.options or {}).get("useSelection"):
|
||||
self.nodes = hou.selectedNodes()
|
||||
|
||||
# Get the node type and remove it from the data, not needed
|
||||
node_type = self.data.pop("node_type", None)
|
||||
if node_type is None:
|
||||
node_type = "geometry"
|
||||
|
||||
# Get out node
|
||||
out = hou.node("/out")
|
||||
instance = out.createNode(node_type, node_name=self.name)
|
||||
instance.moveToGoodPosition()
|
||||
|
||||
imprint(instance, self.data)
|
||||
|
||||
self._process(instance)
|
||||
|
||||
except hou.Error as er:
|
||||
six.reraise(
|
||||
CreatorError,
|
||||
CreatorError("Creator error: {}".format(er)),
|
||||
sys.exc_info()[2])
|
||||
|
||||
|
||||
class HoudiniCreatorBase(object):
|
||||
@staticmethod
|
||||
def cache_instance_data(shared_data):
|
||||
|
|
@ -175,7 +100,7 @@ class HoudiniCreatorBase(object):
|
|||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class HoudiniCreator(NewCreator, HoudiniCreatorBase):
|
||||
class HoudiniCreator(Creator, HoudiniCreatorBase):
|
||||
"""Base class for most of the Houdini creator plugins."""
|
||||
selected_nodes = []
|
||||
settings_name = None
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
import hou
|
||||
import pyblish.api
|
||||
|
||||
from ayon_core.pipeline.publish import RepairAction
|
||||
from ayon_houdini.api import lib, plugin
|
||||
|
||||
|
||||
class CollectRemotePublishSettings(plugin.HoudiniContextPlugin):
|
||||
"""Collect custom settings of the Remote Publish node."""
|
||||
|
||||
order = pyblish.api.CollectorOrder
|
||||
families = ["*"]
|
||||
targets = ["deadline"]
|
||||
label = "Remote Publish Submission Settings"
|
||||
actions = [RepairAction]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
node = hou.node("/out/REMOTE_PUBLISH")
|
||||
if not node:
|
||||
return
|
||||
|
||||
attributes = lib.read(node)
|
||||
|
||||
# Debug the settings we have collected
|
||||
for key, value in sorted(attributes.items()):
|
||||
self.log.debug("Collected %s: %s" % (key, value))
|
||||
|
||||
context.data.update(attributes)
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
# -*-coding: utf-8 -*-
|
||||
import hou
|
||||
|
||||
import pyblish.api
|
||||
from ayon_core.pipeline.publish import RepairContextAction
|
||||
from ayon_core.pipeline import PublishValidationError
|
||||
|
||||
from ayon_houdini.api import lib, plugin
|
||||
|
||||
|
||||
class ValidateRemotePublishOutNode(plugin.HoudiniContextPlugin):
|
||||
"""Validate the remote publish out node exists for Deadline to trigger."""
|
||||
|
||||
order = pyblish.api.ValidatorOrder - 0.4
|
||||
families = ["*"]
|
||||
targets = ["deadline"]
|
||||
label = "Remote Publish ROP node"
|
||||
actions = [RepairContextAction]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
cmd = "import colorbleed.lib; colorbleed.lib.publish_remote()"
|
||||
|
||||
node = hou.node("/out/REMOTE_PUBLISH")
|
||||
if not node:
|
||||
raise RuntimeError("Missing REMOTE_PUBLISH node.")
|
||||
|
||||
# We ensure it's a shell node and that it has the pre-render script
|
||||
# set correctly. Plus the shell script it will trigger should be
|
||||
# completely empty (doing nothing)
|
||||
if node.type().name() != "shell":
|
||||
self.raise_error("Must be shell ROP node")
|
||||
if node.parm("command").eval() != "":
|
||||
self.raise_error("Must have no command")
|
||||
if node.parm("shellexec").eval():
|
||||
self.raise_error("Must not execute in shell")
|
||||
if node.parm("prerender").eval() != cmd:
|
||||
self.raise_error("REMOTE_PUBLISH node does not have "
|
||||
"correct prerender script.")
|
||||
if node.parm("lprerender").eval() != "python":
|
||||
self.raise_error("REMOTE_PUBLISH node prerender script "
|
||||
"type not set to 'python'")
|
||||
|
||||
@classmethod
|
||||
def repair(cls, context):
|
||||
"""(Re)create the node if it fails to pass validation."""
|
||||
lib.create_remote_publish_node(force=True)
|
||||
|
||||
def raise_error(self, message):
|
||||
raise PublishValidationError(message)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import hou
|
||||
|
||||
import pyblish.api
|
||||
from ayon_core.pipeline.publish import RepairContextAction
|
||||
from ayon_core.pipeline import PublishValidationError
|
||||
|
||||
from ayon_houdini.api import plugin
|
||||
|
||||
|
||||
class ValidateRemotePublishEnabled(plugin.HoudiniContextPlugin):
|
||||
"""Validate the remote publish node is *not* bypassed."""
|
||||
|
||||
order = pyblish.api.ValidatorOrder - 0.39
|
||||
families = ["*"]
|
||||
targets = ["deadline"]
|
||||
label = "Remote Publish ROP enabled"
|
||||
actions = [RepairContextAction]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
node = hou.node("/out/REMOTE_PUBLISH")
|
||||
if not node:
|
||||
raise PublishValidationError(
|
||||
"Missing REMOTE_PUBLISH node.", title=self.label)
|
||||
|
||||
if node.isBypassed():
|
||||
raise PublishValidationError(
|
||||
"REMOTE_PUBLISH must not be bypassed.", title=self.label)
|
||||
|
||||
@classmethod
|
||||
def repair(cls, context):
|
||||
"""(Re)create the node if it fails to pass validation."""
|
||||
|
||||
node = hou.node("/out/REMOTE_PUBLISH")
|
||||
if not node:
|
||||
raise PublishValidationError(
|
||||
"Missing REMOTE_PUBLISH node.", title=cls.label)
|
||||
|
||||
cls.log.info("Disabling bypass on /out/REMOTE_PUBLISH")
|
||||
node.bypass(False)
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring AYON addon 'houdini' version."""
|
||||
__version__ = "0.3.4"
|
||||
__version__ = "0.3.6"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name = "houdini"
|
||||
title = "Houdini"
|
||||
version = "0.3.4"
|
||||
version = "0.3.6"
|
||||
|
||||
client_dir = "ayon_houdini"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue