moved houdini into openpype

This commit is contained in:
Jakub Trllo 2022-02-04 18:24:31 +01:00
parent f2a9543712
commit 7c22eee4d9
8 changed files with 707 additions and 187 deletions

View file

@ -2,9 +2,11 @@ import uuid
import logging
from contextlib import contextmanager
from openpype.api import get_asset
import six
from avalon import api, io
from avalon.houdini import lib as houdini
from openpype.api import get_asset
import hou
@ -15,11 +17,11 @@ def get_asset_fps():
"""Return current asset fps."""
return get_asset()["data"].get("fps")
def set_id(node, unique_id, overwrite=False):
def set_id(node, unique_id, overwrite=False):
exists = node.parm("id")
if not exists:
houdini.imprint(node, {"id": unique_id})
imprint(node, {"id": unique_id})
if not exists and overwrite:
node.setParm("id", unique_id)
@ -342,3 +344,183 @@ def render_rop(ropnode):
import traceback
traceback.print_exc()
raise RuntimeError("Render failed: {0}".format(exc))
def children_as_string(node):
return [c.name() for c in node.children()]
def imprint(node, data):
"""Store attributes with value on a node
Depending on the type of attribute it creates the correct parameter
template. Houdini uses a template per type, see the docs for more
information.
http://www.sidefx.com/docs/houdini/hom/hou/ParmTemplate.html
Args:
node(hou.Node): node object from Houdini
data(dict): collection of attributes and their value
Returns:
None
"""
parm_group = node.parmTemplateGroup()
parm_folder = hou.FolderParmTemplate("folder", "Extra")
for key, value in data.items():
if value is None:
continue
if isinstance(value, float):
parm = hou.FloatParmTemplate(name=key,
label=key,
num_components=1,
default_value=(value,))
elif isinstance(value, bool):
parm = hou.ToggleParmTemplate(name=key,
label=key,
default_value=value)
elif isinstance(value, int):
parm = hou.IntParmTemplate(name=key,
label=key,
num_components=1,
default_value=(value,))
elif isinstance(value, six.string_types):
parm = hou.StringParmTemplate(name=key,
label=key,
num_components=1,
default_value=(value,))
else:
raise TypeError("Unsupported type: %r" % type(value))
parm_folder.addParmTemplate(parm)
parm_group.append(parm_folder)
node.setParmTemplateGroup(parm_group)
def lsattr(attr, value=None):
if value is None:
nodes = list(hou.node("/obj").allNodes())
return [n for n in nodes if n.parm(attr)]
return lsattrs({attr: value})
def lsattrs(attrs):
"""Return nodes matching `key` and `value`
Arguments:
attrs (dict): collection of attribute: value
Example:
>> lsattrs({"id": "myId"})
["myNode"]
>> lsattr("id")
["myNode", "myOtherNode"]
Returns:
list
"""
matches = set()
nodes = list(hou.node("/obj").allNodes()) # returns generator object
for node in nodes:
for attr in attrs:
if not node.parm(attr):
continue
elif node.evalParm(attr) != attrs[attr]:
continue
else:
matches.add(node)
return list(matches)
def read(node):
"""Read the container data in to a dict
Args:
node(hou.Node): Houdini node
Returns:
dict
"""
# `spareParms` returns a tuple of hou.Parm objects
return {parameter.name(): parameter.eval() for
parameter in node.spareParms()}
def unique_name(name, format="%03d", namespace="", prefix="", suffix="",
separator="_"):
"""Return unique `name`
The function takes into consideration an optional `namespace`
and `suffix`. The suffix is included in evaluating whether a
name exists - such as `name` + "_GRP" - but isn't included
in the returned value.
If a namespace is provided, only names within that namespace
are considered when evaluating whether the name is unique.
Arguments:
format (str, optional): The `name` is given a number, this determines
how this number is formatted. Defaults to a padding of 2.
E.g. my_name01, my_name02.
namespace (str, optional): Only consider names within this namespace.
suffix (str, optional): Only consider names with this suffix.
Example:
>>> name = hou.node("/obj").createNode("geo", name="MyName")
>>> assert hou.node("/obj/MyName")
True
>>> unique = unique_name(name)
>>> assert hou.node("/obj/{}".format(unique))
False
"""
iteration = 1
parts = [prefix, name, format % iteration, suffix]
if namespace:
parts.insert(0, namespace)
unique = separator.join(parts)
children = children_as_string(hou.node("/obj"))
while unique in children:
iteration += 1
unique = separator.join(parts)
if suffix:
return unique[:-len(suffix)]
return unique
@contextmanager
def maintained_selection():
"""Maintain selection during context
Example:
>>> with maintained_selection():
... # Modify selection
... node.setSelected(on=False, clear_all_selected=True)
>>> # Selection restored
"""
previous_selection = hou.selectedNodes()
try:
yield
finally:
# Clear the selection
# todo: does hou.clearAllSelected() do the same?
for node in hou.selectedNodes():
node.setSelected(on=False)
if previous_selection:
for node in previous_selection:
node.setSelected(on=True)