mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
234 lines
5.7 KiB
Python
234 lines
5.7 KiB
Python
import uuid
|
|
|
|
from contextlib import contextmanager
|
|
|
|
import hou
|
|
|
|
from openpype import lib
|
|
|
|
from avalon import api, io
|
|
from avalon.houdini import lib as houdini
|
|
|
|
|
|
def set_id(node, unique_id, overwrite=False):
|
|
|
|
exists = node.parm("id")
|
|
if not exists:
|
|
houdini.imprint(node, {"id": unique_id})
|
|
|
|
if not exists and overwrite:
|
|
node.setParm("id", unique_id)
|
|
|
|
|
|
def get_id(node):
|
|
"""
|
|
Get the `cbId` attribute of the given node
|
|
Args:
|
|
node (hou.Node): the name of the node to retrieve the attribute from
|
|
|
|
Returns:
|
|
str
|
|
|
|
"""
|
|
|
|
if node is None:
|
|
return
|
|
|
|
id = node.parm("id")
|
|
if node is None:
|
|
return
|
|
return id
|
|
|
|
|
|
def generate_ids(nodes, asset_id=None):
|
|
"""Returns new unique ids for the given nodes.
|
|
|
|
Note: This does not assign the new ids, it only generates the values.
|
|
|
|
To assign new ids using this method:
|
|
>>> nodes = ["a", "b", "c"]
|
|
>>> for node, id in generate_ids(nodes):
|
|
>>> set_id(node, id)
|
|
|
|
To also override any existing values (and assign regenerated ids):
|
|
>>> nodes = ["a", "b", "c"]
|
|
>>> for node, id in generate_ids(nodes):
|
|
>>> set_id(node, id, overwrite=True)
|
|
|
|
Args:
|
|
nodes (list): List of nodes.
|
|
asset_id (str or bson.ObjectId): The database id for the *asset* to
|
|
generate for. When None provided the current asset in the
|
|
active session is used.
|
|
|
|
Returns:
|
|
list: A list of (node, id) tuples.
|
|
|
|
"""
|
|
|
|
if asset_id is None:
|
|
# Get the asset ID from the database for the asset of current context
|
|
asset_data = io.find_one({"type": "asset",
|
|
"name": api.Session["AVALON_ASSET"]},
|
|
projection={"_id": True})
|
|
assert asset_data, "No current asset found in Session"
|
|
asset_id = asset_data['_id']
|
|
|
|
node_ids = []
|
|
for node in nodes:
|
|
_, uid = str(uuid.uuid4()).rsplit("-", 1)
|
|
unique_id = "{}:{}".format(asset_id, uid)
|
|
node_ids.append((node, unique_id))
|
|
|
|
return node_ids
|
|
|
|
|
|
def get_id_required_nodes():
|
|
|
|
valid_types = ["geometry"]
|
|
nodes = {n for n in hou.node("/out").children() if
|
|
n.type().name() in valid_types}
|
|
|
|
return list(nodes)
|
|
|
|
|
|
def get_additional_data(container):
|
|
"""Not implemented yet!"""
|
|
return container
|
|
|
|
|
|
def set_parameter_callback(node, parameter, language, callback):
|
|
"""Link a callback to a parameter of a node
|
|
|
|
Args:
|
|
node(hou.Node): instance of the nodee
|
|
parameter(str): name of the parameter
|
|
language(str): name of the language, e.g.: python
|
|
callback(str): command which needs to be triggered
|
|
|
|
Returns:
|
|
None
|
|
|
|
"""
|
|
|
|
template_grp = node.parmTemplateGroup()
|
|
template = template_grp.find(parameter)
|
|
if not template:
|
|
return
|
|
|
|
script_language = (hou.scriptLanguage.Python if language == "python" else
|
|
hou.scriptLanguage.Hscript)
|
|
|
|
template.setScriptCallbackLanguage(script_language)
|
|
template.setScriptCallback(callback)
|
|
|
|
template.setTags({"script_callback": callback,
|
|
"script_callback_language": language.lower()})
|
|
|
|
# Replace the existing template with the adjusted one
|
|
template_grp.replace(parameter, template)
|
|
|
|
node.setParmTemplateGroup(template_grp)
|
|
|
|
|
|
def set_parameter_callbacks(node, parameter_callbacks):
|
|
"""Set callbacks for multiple parameters of a node
|
|
|
|
Args:
|
|
node(hou.Node): instance of a hou.Node
|
|
parameter_callbacks(dict): collection of parameter and callback data
|
|
example: {"active" :
|
|
{"language": "python",
|
|
"callback": "print('hello world)'"}
|
|
}
|
|
Returns:
|
|
None
|
|
"""
|
|
for parameter, data in parameter_callbacks.items():
|
|
language = data["language"]
|
|
callback = data["callback"]
|
|
|
|
set_parameter_callback(node, parameter, language, callback)
|
|
|
|
|
|
def get_output_parameter(node):
|
|
"""Return the render output parameter name of the given node
|
|
|
|
Example:
|
|
root = hou.node("/obj")
|
|
my_alembic_node = root.createNode("alembic")
|
|
get_output_parameter(my_alembic_node)
|
|
# Result: "output"
|
|
|
|
Args:
|
|
node(hou.Node): node instance
|
|
|
|
Returns:
|
|
hou.Parm
|
|
|
|
"""
|
|
|
|
node_type = node.type().name()
|
|
if node_type == "geometry":
|
|
return node.parm("sopoutput")
|
|
|
|
elif node_type == "alembic":
|
|
return node.parm("filename")
|
|
|
|
else:
|
|
raise TypeError("Node type '%s' not supported" % node_type)
|
|
|
|
|
|
@contextmanager
|
|
def attribute_values(node, data):
|
|
|
|
previous_attrs = {key: node.parm(key).eval() for key in data.keys()}
|
|
try:
|
|
node.setParms(data)
|
|
yield
|
|
except Exception as exc:
|
|
pass
|
|
finally:
|
|
node.setParms(previous_attrs)
|
|
|
|
|
|
def set_scene_fps(fps):
|
|
hou.setFps(fps)
|
|
|
|
|
|
# Valid FPS
|
|
def validate_fps():
|
|
"""Validate current scene FPS and show pop-up when it is incorrect
|
|
|
|
Returns:
|
|
bool
|
|
|
|
"""
|
|
|
|
fps = lib.get_asset()["data"]["fps"]
|
|
current_fps = hou.fps() # returns float
|
|
|
|
if current_fps != fps:
|
|
|
|
from openpype.widgets import popup
|
|
|
|
# Find main window
|
|
parent = hou.ui.mainQtWindow()
|
|
if parent is None:
|
|
pass
|
|
else:
|
|
dialog = popup.Popup2(parent=parent)
|
|
dialog.setModal(True)
|
|
dialog.setWindowTitle("Houdini scene not in line with project")
|
|
dialog.setMessage("The FPS is out of sync, please fix it")
|
|
|
|
# Set new text for button (add optional argument for the popup?)
|
|
toggle = dialog.widgets["toggle"]
|
|
toggle.setEnabled(False)
|
|
dialog.on_show.connect(lambda: set_scene_fps(fps))
|
|
|
|
dialog.show()
|
|
|
|
return False
|
|
|
|
return True
|