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:
Ondřej Samohel 2022-02-11 15:01:23 +01:00 committed by GitHub
commit 64e99a72b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 165 additions and 4 deletions

View file

@ -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

View 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)

View file

@ -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

View 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)

View file

@ -1,5 +1,10 @@
{
"create": {
"CreateArnoldAss": {
"enabled": true,
"defaults": [],
"ext": ".ass"
},
"CreateAlembicCamera": {
"enabled": true,
"defaults": []

View file

@ -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",