mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge pull request #2603 from BigRoy/hou_arnold
Houdini: Implement Arnold .ass standin extraction from Houdini (also support .ass.gz)
This commit is contained in:
commit
64e99a72b1
6 changed files with 165 additions and 4 deletions
|
|
@ -182,8 +182,11 @@ def get_output_parameter(node):
|
|||
return node.parm("filename")
|
||||
elif node_type == "comp":
|
||||
return node.parm("copoutput")
|
||||
else:
|
||||
raise TypeError("Node type '%s' not supported" % node_type)
|
||||
elif node_type == "arnold":
|
||||
if node.evalParm("ar_ass_export_enable"):
|
||||
return node.parm("ar_ass_file")
|
||||
|
||||
raise TypeError("Node type '%s' not supported" % node_type)
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
|
|
|||
53
openpype/hosts/houdini/plugins/create/create_arnold_ass.py
Normal file
53
openpype/hosts/houdini/plugins/create/create_arnold_ass.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
from avalon import houdini
|
||||
|
||||
|
||||
class CreateArnoldAss(houdini.Creator):
|
||||
"""Arnold .ass Archive"""
|
||||
|
||||
label = "Arnold ASS"
|
||||
family = "ass"
|
||||
icon = "magic"
|
||||
defaults = ["Main"]
|
||||
|
||||
# Default extension: `.ass` or `.ass.gz`
|
||||
ext = ".ass"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CreateArnoldAss, self).__init__(*args, **kwargs)
|
||||
|
||||
# Remove the active, we are checking the bypass flag of the nodes
|
||||
self.data.pop("active", None)
|
||||
|
||||
self.data.update({"node_type": "arnold"})
|
||||
|
||||
def process(self):
|
||||
node = super(CreateArnoldAss, self).process()
|
||||
|
||||
basename = node.name()
|
||||
node.setName(basename + "_ASS", unique_name=True)
|
||||
|
||||
# Hide Properties Tab on Arnold ROP since that's used
|
||||
# for rendering instead of .ass Archive Export
|
||||
parm_template_group = node.parmTemplateGroup()
|
||||
parm_template_group.hideFolder("Properties", True)
|
||||
node.setParmTemplateGroup(parm_template_group)
|
||||
|
||||
filepath = '$HIP/pyblish/`chs("subset")`.$F4{}'.format(self.ext)
|
||||
parms = {
|
||||
# Render frame range
|
||||
"trange": 1,
|
||||
|
||||
# Arnold ROP settings
|
||||
"ar_ass_file": filepath,
|
||||
"ar_ass_export_enable": 1
|
||||
}
|
||||
node.setParms(parms)
|
||||
|
||||
# Lock the ASS export attribute
|
||||
node.parm("ar_ass_export_enable").lock(True)
|
||||
|
||||
# Lock some Avalon attributes
|
||||
to_lock = ["family", "id"]
|
||||
for name in to_lock:
|
||||
parm = node.parm(name)
|
||||
parm.lock(True)
|
||||
|
|
@ -6,12 +6,21 @@ import pyblish.api
|
|||
from openpype.hosts.houdini.api import lib
|
||||
|
||||
|
||||
def splitext(name, allowed_multidot_extensions):
|
||||
|
||||
for ext in allowed_multidot_extensions:
|
||||
if name.endswith(ext):
|
||||
return name[:-len(ext)], ext
|
||||
|
||||
return os.path.splitext(name)
|
||||
|
||||
|
||||
class CollectFrames(pyblish.api.InstancePlugin):
|
||||
"""Collect all frames which would be saved from the ROP nodes"""
|
||||
|
||||
order = pyblish.api.CollectorOrder
|
||||
label = "Collect Frames"
|
||||
families = ["vdbcache", "imagesequence"]
|
||||
families = ["vdbcache", "imagesequence", "ass"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
@ -29,7 +38,8 @@ class CollectFrames(pyblish.api.InstancePlugin):
|
|||
self.log.warning("Using current frame: {}".format(hou.frame()))
|
||||
output = output_parm.eval()
|
||||
|
||||
_, ext = os.path.splitext(output)
|
||||
_, ext = splitext(output,
|
||||
allowed_multidot_extensions=[".ass.gz"])
|
||||
file_name = os.path.basename(output)
|
||||
result = file_name
|
||||
|
||||
|
|
|
|||
55
openpype/hosts/houdini/plugins/publish/extract_ass.py
Normal file
55
openpype/hosts/houdini/plugins/publish/extract_ass.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import os
|
||||
|
||||
import pyblish.api
|
||||
import openpype.api
|
||||
from openpype.hosts.houdini.api.lib import render_rop
|
||||
|
||||
|
||||
class ExtractAss(openpype.api.Extractor):
|
||||
|
||||
order = pyblish.api.ExtractorOrder + 0.1
|
||||
label = "Extract Ass"
|
||||
families = ["ass"]
|
||||
hosts = ["houdini"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
ropnode = instance[0]
|
||||
|
||||
# Get the filename from the filename parameter
|
||||
# `.evalParm(parameter)` will make sure all tokens are resolved
|
||||
output = ropnode.evalParm("ar_ass_file")
|
||||
staging_dir = os.path.dirname(output)
|
||||
instance.data["stagingDir"] = staging_dir
|
||||
file_name = os.path.basename(output)
|
||||
|
||||
# We run the render
|
||||
self.log.info("Writing ASS '%s' to '%s'" % (file_name, staging_dir))
|
||||
|
||||
render_rop(ropnode)
|
||||
|
||||
# Unfortunately user interrupting the extraction does not raise an
|
||||
# error and thus still continues to the integrator. To capture that
|
||||
# we make sure all files exist
|
||||
files = instance.data["frames"]
|
||||
missing = [fname for fname in files
|
||||
if not os.path.exists(os.path.join(staging_dir, fname))]
|
||||
if missing:
|
||||
raise RuntimeError("Failed to complete Arnold ass extraction. "
|
||||
"Missing output files: {}".format(missing))
|
||||
|
||||
if "representations" not in instance.data:
|
||||
instance.data["representations"] = []
|
||||
|
||||
# Allow ass.gz extension as well
|
||||
ext = "ass.gz" if file_name.endswith(".ass.gz") else "ass"
|
||||
|
||||
representation = {
|
||||
'name': 'ass',
|
||||
'ext': ext,
|
||||
"files": files,
|
||||
"stagingDir": staging_dir,
|
||||
"frameStart": instance.data["frameStart"],
|
||||
"frameEnd": instance.data["frameEnd"],
|
||||
}
|
||||
instance.data["representations"].append(representation)
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
{
|
||||
"create": {
|
||||
"CreateArnoldAss": {
|
||||
"enabled": true,
|
||||
"defaults": [],
|
||||
"ext": ".ass"
|
||||
},
|
||||
"CreateAlembicCamera": {
|
||||
"enabled": true,
|
||||
"defaults": []
|
||||
|
|
|
|||
|
|
@ -4,6 +4,41 @@
|
|||
"key": "create",
|
||||
"label": "Creator plugins",
|
||||
"children": [
|
||||
{
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"key": "CreateArnoldAss",
|
||||
"label": "Create Arnold Ass",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "defaults",
|
||||
"label": "Default Subsets",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "enum",
|
||||
"key": "ext",
|
||||
"label": "Default Output Format (extension)",
|
||||
"multiselection": false,
|
||||
"enum_items": [
|
||||
{
|
||||
".ass": ".ass"
|
||||
},
|
||||
{
|
||||
".ass.gz": ".ass.gz (gzipped)"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_create_plugin",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue