From 1aca840cf74ce6c1553a33eaaee06869be8734a1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 4 Oct 2024 01:13:41 +0200 Subject: [PATCH 01/10] Replace the Load LOPs parm callbacks with expressions on the file parms to support Solaris Context Options (Draft) --- client/ayon_houdini/api/hda_utils.py | 76 +++++++++---------- .../otls/ayon_lop_import.hda/INDEX__SECTION | 2 +- .../DialogScript | 22 ++---- .../DialogScript | 20 +---- 4 files changed, 44 insertions(+), 76 deletions(-) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index 617f121258..dc19e643dd 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -33,6 +33,14 @@ import hou +def get_session_cache() -> dict: + """Get a persistent `hou.session.ayon_cache` dict""" + cache = getattr(hou.session, "ayon_cache", None) + if cache is None: + hou.session.ayon_cache = cache = {} + return cache + + def is_valid_uuid(value) -> bool: """Return whether value is a valid UUID""" try: @@ -155,36 +163,21 @@ def _get_thumbnail(project_name: str, version_id: str, thumbnail_dir: str): return path -def set_representation(node, representation_id: str): - file_parm = node.parm("file") - if not representation_id: - # Clear filepath and thumbnail - with _unlocked_parm(file_parm): - file_parm.set("") - set_node_thumbnail(node, None) - return - - project_name = ( - node.evalParm("project_name") - or get_current_project_name() - ) - +def get_representation_path( + project_name: str, + representation_id: str, + use_ayon_entity_uri: bool +) -> str: # Ignore invalid representation ids silently # TODO remove - added for backwards compatibility with OpenPype scenes if not is_valid_uuid(representation_id): - return + return "" repre_entity = get_representation_by_id(project_name, representation_id) if not repre_entity: - return + return "" context = get_representation_context(project_name, repre_entity) - update_info(node, context) - - if node.parm("use_ayon_entity_uri"): - use_ayon_entity_uri = node.evalParm("use_ayon_entity_uri") - else: - use_ayon_entity_uri = False if use_ayon_entity_uri: path = get_ayon_entity_uri_from_representation_context(context) else: @@ -193,8 +186,22 @@ def set_representation(node, representation_id: str): # fails to resolve @sourcename var with backslashed # paths correctly. So we force forward slashes path = path.replace("\\", "/") - with _unlocked_parm(file_parm): - file_parm.set(path) + return path + + +def set_representation(node, representation_id: str): + # TODO: Unused currently; add support again for thumbnail updates + if not representation_id: + set_node_thumbnail(node, None) + return + + project_name = ( + node.evalParm("project_name") + or get_current_project_name() + ) + repre_entity = get_representation_by_id(project_name, representation_id) + context = get_representation_context(project_name, repre_entity) + update_info(node, context) if node.evalParm("show_thumbnail"): # Update thumbnail @@ -264,19 +271,9 @@ def on_representation_id_changed(node): set_representation(node, repre_id) -def on_representation_parms_changed(node, force=False): - """ - Usually used as callback to the project, folder, product, version and - representation parms which on change - would result in a different - representation id to be resolved. - - Args: - node (hou.Node): Node to update. - force (Optional[bool]): Whether to force the callback to retrigger - even if the representation id already matches. For example, when - needing to resolve the filepath in a different way. - """ - project_name = node.evalParm("project_name") or get_current_project_name() +def get_node_expected_representation_id(node) -> str: + project_name = node.evalParm( + "project_name") or get_current_project_name() representation_id = get_representation_id( project_name=project_name, folder_path=node.evalParm("folder_path"), @@ -289,10 +286,7 @@ def on_representation_parms_changed(node, force=False): representation_id = "" else: representation_id = str(representation_id) - - if force or node.evalParm("representation") != representation_id: - node.parm("representation").set(representation_id) - node.parm("representation").pressButton() # trigger callback + return representation_id def get_representation_id( diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index f101cdfeb0..331f88cba9 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -10,5 +10,5 @@ Inputs: 0 to 1 Subnet: true Python: false Empty: false -Modified: Tue Jul 30 12:57:14 2024 +Modified: Fri Oct 4 00:58:20 2024 diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index f18c00d472..647d7ed8ed 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -34,8 +34,6 @@ default { "$AYON_PROJECT_NAME" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "folder_path" @@ -44,8 +42,6 @@ default { "$AYON_FOLDER_PATH" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "folder_name" @@ -60,7 +56,7 @@ default { "usdAsset" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_product_name;select_product_name(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" } + parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])" } parmtag { "script_callback_language" "python" } } parm { @@ -80,16 +76,12 @@ [ "return result" ] language python } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "representation_name" label "Representation" type string default { "usd" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "load_refresh" @@ -99,7 +91,7 @@ default { "0" } help "Click to refresh and retry applying the product load parameters to load the correct file" parmtag { "button_icon" "" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } + parmtag { "script_callback" "" } parmtag { "script_callback_language" "python" } } parm { @@ -128,17 +120,15 @@ name "file" label "File" type string - default { "" } + default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_path\", {})\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nrepre_id = hou.evalParm(\"representation\")\nuse_entity_uri = hou.evalParm(\"use_ayon_entity_uri\")\nhash_value = project_name, repre_id, use_entity_uri\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\npath = hda_utils.get_representation_path(project_name, repre_id, use_entity_uri)\ncache[hash_value] = path\nreturn path\n" python ] } parmtag { "script_callback_language" "python" } } parm { name "use_ayon_entity_uri" label "Use AYON Entity URI" - help "When enabled, loads the filepath using the AYON Entity URI instead of the resolved filepath." type toggle default { "0" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'], force=True)" } - parmtag { "script_callback_language" "python" } + help "When enabled, loads the filepath using the AYON Entity URI instead of the resolved filepath." } parm { name "primpath1" @@ -336,9 +326,7 @@ name "representation" label "Representation ID" type string - default { "" } - parmtag { "script_callback" "hou.phm().on_representation_id_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } + default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_ids\", {})\n\n\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nfolder_path = hou.evalParm(\"folder_path\")\nproduct_name = hou.evalParm(\"product_name\")\nversion = hou.evalParm(\"version\")\nrepresentation_name = hou.evalParm(\"representation_name\")\n\nnode = hou.pwd()\nhash_value = \">\".join([project_name, folder_path, product_name, version, representation_name])\nprint(f\"Expression: {node.path()} {datetime.datetime.now()} {hash_value}\")\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\nrepre_id = hda_utils.get_node_expected_representation_id(node)\ncache[hash_value] = repre_id\n" python ] } } parm { name "version_name" diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript index 140a1f0cb9..eb72b48d9d 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript @@ -34,8 +34,6 @@ default { "$AYON_PROJECT_NAME" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "folder_path" @@ -44,8 +42,6 @@ default { "$AYON_FOLDER_PATH" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "product_name" @@ -54,7 +50,7 @@ default { "usdShot" } parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_product_name;select_product_name(kwargs['node'])" } parmtag { "script_action_icon" "BUTTONS_reselect" } - parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" } + parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])" } parmtag { "script_callback_language" "python" } } parm { @@ -74,16 +70,12 @@ [ "return result" ] language python } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "representation_name" label "Representation" type string default { "usd" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "load_refresh" @@ -93,8 +85,6 @@ default { "0" } help "Click to refresh and retry applying the product load parameters to load the correct file" parmtag { "button_icon" "" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } } parm { name "load_message" @@ -122,7 +112,7 @@ name "file" label "File" type string - default { "" } + default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_path\", {})\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nrepre_id = hou.evalParm(\"representation\")\nuse_entity_uri = hou.evalParm(\"use_ayon_entity_uri\")\nhash_value = project_name, repre_id, use_entity_uri\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\npath = hda_utils.get_representation_path(project_name, repre_id, use_entity_uri)\ncache[hash_value] = path\nreturn path\n" python ] } parmtag { "script_callback_language" "python" } } parm { @@ -131,8 +121,6 @@ help "When enabled, loads the filepath using the AYON Entity URI instead of the resolved filepath." type toggle default { "0" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'], force=True)" } - parmtag { "script_callback_language" "python" } } groupcollapsible { name "extra_options" @@ -263,9 +251,7 @@ name "representation" label "Representation ID" type string - default { "" } - parmtag { "script_callback" "hou.phm().on_representation_id_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } + default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_ids\", {})\n\n\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nfolder_path = hou.evalParm(\"folder_path\")\nproduct_name = hou.evalParm(\"product_name\")\nversion = hou.evalParm(\"version\")\nrepresentation_name = hou.evalParm(\"representation_name\")\n\nnode = hou.pwd()\nhash_value = \">\".join([project_name, folder_path, product_name, version, representation_name])\nprint(f\"Expression: {node.path()} {datetime.datetime.now()} {hash_value}\")\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\nrepre_id = hda_utils.get_node_expected_representation_id(node)\ncache[hash_value] = repre_id\n" python ] } } parm { name "version_name" From 61e31d5c5867359c9c31cf965bdabb9e25a4b517 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 4 Oct 2024 01:19:04 +0200 Subject: [PATCH 02/10] Revert redundant change --- .../startup/otls/ayon_lop_import.hda/INDEX__SECTION | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index 331f88cba9..520c4e6c37 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -10,5 +10,4 @@ Inputs: 0 to 1 Subnet: true Python: false Empty: false -Modified: Fri Oct 4 00:58:20 2024 - +Modified: Tue Jul 30 12:57:14 2024 From 46335d3601c668f6d166763c88350d93d139f1ea Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 4 Oct 2024 01:21:20 +0200 Subject: [PATCH 03/10] Revert redundant change --- .../ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index 520c4e6c37..f101cdfeb0 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -11,3 +11,4 @@ Subnet: true Python: false Empty: false Modified: Tue Jul 30 12:57:14 2024 + From ce5063b99f53be76c750de4f97be3c39d6f8af3e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 4 Oct 2024 02:06:14 +0200 Subject: [PATCH 04/10] Remove removed function --- .../ayon_8_8Lop_1lop__import_8_81.0/PythonModule | 1 - .../ayon_8_8Lop_1load__shot_8_81.0/PythonModule | 1 - 2 files changed, 2 deletions(-) diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule index 0e91d023b2..901c00e19d 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule @@ -2,7 +2,6 @@ from ayon_houdini.api.hda_utils import ( on_thumbnail_show_changed, on_thumbnail_size_changed, on_representation_id_changed, - on_representation_parms_changed, setup_flag_changed_callback, get_available_versions, select_product_name, diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/PythonModule b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/PythonModule index 0e91d023b2..901c00e19d 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/PythonModule +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/PythonModule @@ -2,7 +2,6 @@ from ayon_houdini.api.hda_utils import ( on_thumbnail_show_changed, on_thumbnail_size_changed, on_representation_id_changed, - on_representation_parms_changed, setup_flag_changed_callback, get_available_versions, select_product_name, From bbee3344e214426c29420f6ee662614a3e6c9d20 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 10:43:05 +0200 Subject: [PATCH 05/10] Move expression functions into `hda_utils` for re-use and easier code reviews in `git` --- client/ayon_houdini/api/hda_utils.py | 53 +++++++++++++++++++ .../DialogScript | 4 +- .../DialogScript | 4 +- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index dc19e643dd..15a0fbfe6b 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -708,3 +708,56 @@ def set_to_latest_version(node): versions = get_available_versions(node) if versions: node.parm("version").set(str(versions[0])) + + +# region Parm Expressions +# Callbacks used for expression on HDAs (e.g. Load Asset or Load Shot LOP) +# Note that these are called many times, sometimes even multiple times when +# the Parameters tab is open on the node. So some caching is performed to +# avoid expensive re-querying. +def expression_clear_cache(subkey=None) -> bool: + # Clear full cache if no subkey provided + if subkey is None: + if hasattr(hou.session, "ayon_cache"): + delattr(hou.session, "ayon_cache") + return True + return False + + # Clear only key in cache if provided + cache = getattr(hou.session, "ayon_cache", {}) + if subkey in cache: + cache.pop(subkey) + return True + return False + + +def expression_get_representation_id() -> str: + project_name = hou.evalParm("project_name") + folder_path = hou.evalParm("folder_path") + product_name = hou.evalParm("product_name") + version = hou.evalParm("version") + representation_name = hou.evalParm("representation_name") + + node = hou.pwd() + hash_value = (project_name, folder_path, product_name, version, + representation_name) + cache = get_session_cache().setdefault("representation_ids", {}) + if hash_value in cache: + return cache[hash_value] + + repre_id = get_node_expected_representation_id(node) + cache[hash_value] = repre_id + + +def expression_get_representation_path() -> str: + cache = get_session_cache().setdefault("representation_path", {}) + project_name = hou.evalParm("project_name") + repre_id = hou.evalParm("representation") + use_entity_uri = hou.evalParm("use_ayon_entity_uri") + hash_value = project_name, repre_id, use_entity_uri + if hash_value in cache: + return cache[hash_value] + + path = get_representation_path(project_name, repre_id, use_entity_uri) + cache[hash_value] = path + return path diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 647d7ed8ed..392ddb09a6 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -120,7 +120,7 @@ name "file" label "File" type string - default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_path\", {})\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nrepre_id = hou.evalParm(\"representation\")\nuse_entity_uri = hou.evalParm(\"use_ayon_entity_uri\")\nhash_value = project_name, repre_id, use_entity_uri\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\npath = hda_utils.get_representation_path(project_name, repre_id, use_entity_uri)\ncache[hash_value] = path\nreturn path\n" python ] } + default { [ "from ayon_houdini.api import hda_utils\nreturn hda_utils.expression_get_representation_path()" python ] } parmtag { "script_callback_language" "python" } } parm { @@ -326,7 +326,7 @@ name "representation" label "Representation ID" type string - default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_ids\", {})\n\n\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nfolder_path = hou.evalParm(\"folder_path\")\nproduct_name = hou.evalParm(\"product_name\")\nversion = hou.evalParm(\"version\")\nrepresentation_name = hou.evalParm(\"representation_name\")\n\nnode = hou.pwd()\nhash_value = \">\".join([project_name, folder_path, product_name, version, representation_name])\nprint(f\"Expression: {node.path()} {datetime.datetime.now()} {hash_value}\")\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\nrepre_id = hda_utils.get_node_expected_representation_id(node)\ncache[hash_value] = repre_id\n" python ] } + default { [ "from ayon_houdini.api import hda_utils\nreturn hda_utils.expression_get_representation_id()" python ] } } parm { name "version_name" diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript index eb72b48d9d..b23a95dd43 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript @@ -112,7 +112,7 @@ name "file" label "File" type string - default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_path\", {})\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nrepre_id = hou.evalParm(\"representation\")\nuse_entity_uri = hou.evalParm(\"use_ayon_entity_uri\")\nhash_value = project_name, repre_id, use_entity_uri\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\npath = hda_utils.get_representation_path(project_name, repre_id, use_entity_uri)\ncache[hash_value] = path\nreturn path\n" python ] } + default { [ "from ayon_houdini.api import hda_utils\nreturn hda_utils.expression_get_representation_path()" python ] } parmtag { "script_callback_language" "python" } } parm { @@ -251,7 +251,7 @@ name "representation" label "Representation ID" type string - default { [ "# This triggers very often, for whatever reason. So we need to\n# optimize and cache to avoid heavy querying for each call.\nimport datetime\nimport hou.session\n\nfrom ayon_houdini.api import hda_utils\nimport importlib\nimportlib.reload(hda_utils)\n\ncache = hda_utils.get_session_cache().setdefault(\"representation_ids\", {})\n\n\n\n# Set up input dependencies (by calling these Houdini links\n# there attributes as input dependencies and will update the\n# expression if any of them changes)\nproject_name = hou.evalParm(\"project_name\")\nfolder_path = hou.evalParm(\"folder_path\")\nproduct_name = hou.evalParm(\"product_name\")\nversion = hou.evalParm(\"version\")\nrepresentation_name = hou.evalParm(\"representation_name\")\n\nnode = hou.pwd()\nhash_value = \">\".join([project_name, folder_path, product_name, version, representation_name])\nprint(f\"Expression: {node.path()} {datetime.datetime.now()} {hash_value}\")\nif hash_value in cache:\n return cache[hash_value]\n\n\nprint(\"Compute\")\nrepre_id = hda_utils.get_node_expected_representation_id(node)\ncache[hash_value] = repre_id\n" python ] } + default { [ "from ayon_houdini.api import hda_utils\nreturn hda_utils.expression_get_representation_id()" python ] } } parm { name "version_name" From 4167536db044edbf2253800fe28e4c226e429164 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 11:00:30 +0200 Subject: [PATCH 06/10] Add todo --- client/ayon_houdini/api/hda_utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index 15a0fbfe6b..2801fb5652 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -312,6 +312,11 @@ def get_representation_id( Optional[str]: Representation id or None if not found. """ + # TODO: This is now used in an expression in LOPs and preferably should + # not trigger setting additional parameters. As such, we should maybe + # somehow offload the warning message to the "cook" or some other way + # of identifying whether the parms are all valid without requiring + # more queries of the database. if not all([ project_name, folder_path, product_name, version, representation_name From 4b43df5c904dcfd72a38ce58b07cae379b433256 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 15:20:58 +0200 Subject: [PATCH 07/10] Fix shown warning on the LOP node by force computing them when needed --- client/ayon_houdini/api/hda_utils.py | 66 +++----- .../Contents.dir/Contents.createtimes | 5 +- .../Contents.dir/Contents.houdini_versions | 7 +- .../Contents.dir/Contents.mime | 156 +++++++++++++++--- .../Contents.dir/Contents.modtimes | 9 +- .../DialogScript | 19 --- 6 files changed, 175 insertions(+), 87 deletions(-) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index 2801fb5652..f4620d0868 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -274,19 +274,13 @@ def on_representation_id_changed(node): def get_node_expected_representation_id(node) -> str: project_name = node.evalParm( "project_name") or get_current_project_name() - representation_id = get_representation_id( - project_name=project_name, - folder_path=node.evalParm("folder_path"), - product_name=node.evalParm("product_name"), - version=node.evalParm("version"), - representation_name=node.evalParm("representation_name"), - load_message_parm=node.parm("load_message") + return get_representation_id( + project_name=project_name, + folder_path=node.evalParm("folder_path"), + product_name=node.evalParm("product_name"), + version=node.evalParm("version"), + representation_name=node.evalParm("representation_name"), ) - if representation_id is None: - representation_id = "" - else: - representation_id = str(representation_id) - return representation_id def get_representation_id( @@ -295,7 +289,6 @@ def get_representation_id( product_name, version, representation_name, - load_message_parm, ): """Get representation id. @@ -305,19 +298,14 @@ def get_representation_id( product_name (str): Product name version (str): Version name as string representation_name (str): Representation name - load_message_parm (hou.Parm): A string message parm to report - any error messages to. Returns: - Optional[str]: Representation id or None if not found. + str: Representation id or None if not found. - """ - # TODO: This is now used in an expression in LOPs and preferably should - # not trigger setting additional parameters. As such, we should maybe - # somehow offload the warning message to the "cook" or some other way - # of identifying whether the parms are all valid without requiring - # more queries of the database. + Raises: + ValueError: If the entity could not be resolved with input values. + """ if not all([ project_name, folder_path, product_name, version, representation_name ]): @@ -329,15 +317,14 @@ def get_representation_id( "representation": representation_name } missing = ", ".join(key for key, value in labels.items() if not value) - load_message_parm.set(f"Load info incomplete. Found empty: {missing}") - return + raise ValueError(f"Load info incomplete. Found empty: {missing}") try: version = int(version.strip()) except ValueError: - load_message_parm.set(f"Invalid version format: '{version}'\n" - "Make sure to set a valid version number.") - return + raise ValueError( + f"Invalid version format: '{version}'\n" + "Make sure to set a valid version number.") folder_entity = get_folder_by_path(project_name, folder_path=folder_path, @@ -346,10 +333,8 @@ def get_representation_id( # This may be due to the project not existing - so let's validate # that first if not get_project(project_name): - load_message_parm.set(f"Project not found: '{project_name}'") - return - load_message_parm.set(f"Folder not found: '{folder_path}'") - return + raise ValueError(f"Project not found: '{project_name}'") + raise ValueError(f"Folder not found: '{folder_path}'") product_entity = get_product_by_name( project_name, @@ -357,25 +342,23 @@ def get_representation_id( folder_id=folder_entity["id"], fields={"id"}) if not product_entity: - load_message_parm.set(f"Product not found: '{product_name}'") - return + raise ValueError(f"Product not found: '{product_name}'") + version_entity = get_version_by_name( project_name, version, product_id=product_entity["id"], fields={"id"}) if not version_entity: - load_message_parm.set(f"Version not found: '{version}'") - return + raise ValueError(f"Version not found: '{version}'") + representation_entity = get_representation_by_name( project_name, representation_name, version_id=version_entity["id"], fields={"id"}) if not representation_entity: - load_message_parm.set( - f"Representation not found: '{representation_name}'.") - return + raise ValueError(f"Representation not found: '{representation_name}'.") return representation_entity["id"] @@ -750,7 +733,12 @@ def expression_get_representation_id() -> str: if hash_value in cache: return cache[hash_value] - repre_id = get_node_expected_representation_id(node) + try: + repre_id = get_node_expected_representation_id(node) + except ValueError: + # Ignore invalid parameters + repre_id = "" + cache[hash_value] = repre_id diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.createtimes b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.createtimes index 2d6bdf00aa..3047376d77 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.createtimes +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.createtimes @@ -1,6 +1,7 @@ { + "hdaroot/switch_load_warnings.def":1728298521, "hdaroot/warn_no_representation_set.def":1708980551, - "hdaroot/reference.def":1698150558, "hdaroot/output0.def":1698215383, - "hdaroot.def":1717451587 + "hdaroot.def":1728285340, + "hdaroot/reference.def":1698150558 } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.houdini_versions b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.houdini_versions index fb7f024db3..5c591db892 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.houdini_versions +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.houdini_versions @@ -1,9 +1,10 @@ { - "values":["20.0.703" + "values":["20.5.370" ], "indexes":{ - "hdaroot/warn_no_representation_set.userdata":0, + "hdaroot/output0.userdata":0, + "hdaroot/switch_load_warnings.userdata":0, "hdaroot/reference.userdata":0, - "hdaroot/output0.userdata":0 + "hdaroot/warn_no_representation_set.userdata":0 } } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime index ec12230a75..1f6aea588a 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime @@ -19,26 +19,28 @@ Content-Disposition: attachment; filename="hdaroot.def" Content-Type: text/plain comment "" -position -1.67827 1.26636 -connectornextid 0 +position -4.36447 -0.693346 +connectornextid 1 flags = lock off model off template off footprint off xray off bypass off display on render on highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { } inputsNamed3 { +0 cube1 0 1 "input1" } inputs { +0 cube1 0 1 } stat { create -1 modify -1 - author Mustafa_Taher@Major-Kalawy + author User@HP-Z820-03 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -77,9 +79,9 @@ Content-Disposition: attachment; filename="hdaroot/output0.def" Content-Type: text/plain comment "" -position -1.13898e-08 2.03328 +position -0.346993 0.925092 connectornextid 1 -flags = lock off model off template off footprint off xray off bypass off display off render on highlight off unload off savedata off compress on colordefault on exposed on debug off +flags = lock off model off template off footprint off xray off bypass off display on render on highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { } @@ -98,7 +100,7 @@ stat author Maqina-05@Maqina-05 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -136,7 +138,7 @@ Content-Disposition: attachment; filename="hdaroot/reference.def" Content-Type: text/plain comment "" -position -0.00125004 4.19692 +position -0.348243 2.45537 connectornextid 2 flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 @@ -145,11 +147,11 @@ outputsNamed3 } inputsNamed3 { -1 warn_no_representation_set 1 1 "input1" +1 switch_load_warnings 1 1 "input1" } inputs { -0 warn_no_representation_set 0 1 +0 switch_load_warnings 0 1 } stat { @@ -158,7 +160,7 @@ stat author Maqina-05@Maqina-05 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -302,9 +304,9 @@ Content-Disposition: attachment; filename="hdaroot/warn_no_representation_set.de Content-Type: text/plain comment "" -position -1.13898e-08 5.20999 +position 1.06093 5.41052 connectornextid 2 -flags = lock off model off template off footprint off xray off bypass off display on render off highlight off unload off savedata off compress on colordefault on exposed on debug off +flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { 1 "output1" @@ -324,7 +326,7 @@ stat author User@HP-Z820-03 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -334,12 +336,31 @@ Content-Disposition: attachment; filename="hdaroot/warn_no_representation_set.ch Content-Type: text/plain { - channel enable1 { + channel errormsg1 { lefttype = extend righttype = extend + defaultString = "\"from ayon_houdini.api import hda_utils + +# Parent node +node = hou.pwd().parent() +try: + hda_utils.get_node_expected_representation_id(node) +except ValueError as exc: + return str(exc) + +return \\\"Unable to get representation\\\"\"" flags = 0 - start = 39.800000000000004 - segment { length = 0 expr = "if(ch(\"../representation\"), 0, 1)" } + start = 40 + segment { length = 0 expr = "from ayon_houdini.api import hda_utils + +# Parent node +node = hou.pwd().parent() +try: + hda_utils.get_node_expected_representation_id(node) +except ValueError as exc: + return str(exc) + +return \"Unable to get representation.\"" language = python } } } @@ -350,9 +371,9 @@ Content-Type: text/plain { version 0.8 numerror [ 0 locks=0 ] ( 1 ) -errormsg1 [ 0 locks=0 ] ( `chs(\"../load_message\")` ) +errormsg1 [ 0 locks=0 ] ( [ errormsg1 "" ] ) severity1 [ 0 locks=0 ] ( "warn" ) -enable1 [ 0 locks=0 ] ( [ enable1 0 ] ) +enable1 [ 0 locks=0 ] ( 1 ) } --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY @@ -366,14 +387,109 @@ Content-Type: text/plain } } +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.init" +Content-Type: text/plain + +type = switch +matchesdef = 1 + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.def" +Content-Type: text/plain + +comment "" +position -0.154899 4.11657 +connectornextid 3 +flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off +outputsNamed3 +{ +1 "output1" +} +inputsNamed3 +{ +2 (0) "" 1 "input1" +0 warn_no_representation_set 1 1 "input2" +} +inputs +{ +0 (0) 0 1 +1 warn_no_representation_set 0 1 +} +stat +{ + create -1 + modify -1 + author User@HP-Z820-03 + access 0777 +} +color UT_Color RGB 0.8 1 0.7 +delscript "" +exprlanguage hscript +end + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.editableinputdata" +Content-Type: text/plain + +[ + { + }, + { + } +] + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.chn" +Content-Type: text/plain + +{ + channel input { + lefttype = extend + righttype = extend + flags = 0 + start = 40 + segment { length = 0 expr = "if(ch(\"../representation\"), 0, 1)" } + } + } + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.parm" +Content-Type: text/plain + +{ +version 0.8 +chooseinputbyname [ 0 locks=0 ] ( "off" ) +input [ 0 locks=0 ] ( [ input 0 ] ) +selectinputname [ 0 locks=0 ] ( "" ) +selectinputvalue [ 0 locks=0 ] ( "" ) +config_separator [ 0 locks=0 ] ( ) +badinput [ 0 locks=0 ] ( ignore ) +fallback [ 0 locks=0 ] ( 0 ) +selectfallbackname [ 0 locks=0 ] ( "" ) +inputname [ 0 locks=0 ] ( "`opinput(\".\", @input)`" ) +} + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.userdata" +Content-Type: text/plain + +{ + "___Version___":{ + "type":"string", + "value":"___EXTERNAL___" + } +} + --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY Content-Disposition: attachment; filename="hdaroot.order" Content-Type: text/plain -3 +4 output0 reference warn_no_representation_set +switch_load_warnings --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY Content-Disposition: attachment; filename="hdaroot.net" diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.modtimes b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.modtimes index dbbe22dd33..bfe25fab51 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.modtimes +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.modtimes @@ -1,6 +1,7 @@ { - "hdaroot/warn_no_representation_set.def":1711565807, - "hdaroot/reference.def":1711565598, - "hdaroot/output0.def":1708980807, - "hdaroot.def":1717451686 + "hdaroot/switch_load_warnings.def":1728299309, + "hdaroot/warn_no_representation_set.def":1728299277, + "hdaroot/output0.def":1728299301, + "hdaroot.def":1728299413, + "hdaroot/reference.def":1728299301 } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 392ddb09a6..e475f8e1f1 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -83,25 +83,6 @@ type string default { "usd" } } - parm { - name "load_refresh" - label "Refresh" - type button - joinnext - default { "0" } - help "Click to refresh and retry applying the product load parameters to load the correct file" - parmtag { "button_icon" "" } - parmtag { "script_callback" "" } - parmtag { "script_callback_language" "python" } - } - parm { - name "load_message" - label "Message" - type label - default { "" } - hidewhen "{ load_message == \"\" }" - parmtag { "sidefx::look" "block" } - } parm { name "sepparm" label "Separator" From d1587bbfbf795d13ccf52819d8235b5d7ae481fa Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 15:26:33 +0200 Subject: [PATCH 08/10] Fix shown warning on the LOP node by force computing them when needed (now for Load Shot LOP) --- .../Contents.dir/Contents.createtimes | 3 +- .../Contents.dir/Contents.houdini_versions | 7 +- .../Contents.dir/Contents.mime | 257 +++++++++++++----- .../Contents.dir/Contents.modtimes | 9 +- .../DialogScript | 19 +- 5 files changed, 197 insertions(+), 98 deletions(-) diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.createtimes b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.createtimes index 3b50c1d798..6b4cc961c5 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.createtimes +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.createtimes @@ -1,6 +1,7 @@ { + "hdaroot/switch_load_warnings.def":1728298521, "hdaroot/sublayer.def":1720045839, "hdaroot/warn_no_representation_set.def":1708980551, "hdaroot/output0.def":1698215383, - "hdaroot.def":1720046536 + "hdaroot.def":1728307343 } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.houdini_versions b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.houdini_versions index c685293feb..b7dda90c76 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.houdini_versions +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.houdini_versions @@ -1,9 +1,10 @@ { - "values":["20.0.724" + "values":["20.5.370" ], "indexes":{ + "hdaroot/output0.userdata":0, + "hdaroot/switch_load_warnings.userdata":0, "hdaroot/sublayer.userdata":0, - "hdaroot/warn_no_representation_set.userdata":0, - "hdaroot/output0.userdata":0 + "hdaroot/warn_no_representation_set.userdata":0 } } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.mime b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.mime index d890e71afa..8ecf304212 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.mime +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.mime @@ -19,12 +19,11 @@ Content-Disposition: attachment; filename="hdaroot.def" Content-Type: text/plain comment "" -position -3.46569 1.07549 -connectornextid 1 -flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off +position -0.987179 -0.326068 +connectornextid 0 +flags = lock off model off template off footprint off xray off bypass off display on render off highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { -0 "output1" } inputsNamed3 { @@ -82,9 +81,9 @@ Content-Disposition: attachment; filename="hdaroot/output0.def" Content-Type: text/plain comment "" -position -1.13898e-08 2.03328 +position -1.18363 1.36997 connectornextid 1 -flags = lock off model off template off footprint off xray off bypass off display off render on highlight off unload off savedata off compress on colordefault on exposed on debug off +flags = lock off model off template off footprint off xray off bypass off display on render on highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { } @@ -129,6 +128,122 @@ Content-Type: text/plain } } +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/sublayer.init" +Content-Type: text/plain + +type = sublayer +matchesdef = 1 + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/sublayer.def" +Content-Type: text/plain + +comment "" +position -1.18488 2.62985 +connectornextid 2 +flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off +outputsNamed3 +{ +1 "output1" +} +inputsNamed3 +{ +0 switch_load_warnings 1 1 "input1" +} +inputs +{ +0 switch_load_warnings 0 1 +} +stat +{ + create -1 + modify -1 + author User@HP-Z820-03 + access 0777 +} +color UT_Color RGB 0.8 0.8 0.8 +delscript "" +exprlanguage hscript +end + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/sublayer.chn" +Content-Type: text/plain + +{ + channel reload { + lefttype = extend + righttype = extend + flags = 0 + start = 40 + segment { length = 0 expr = ch(\"../reload\") } + } + channel mute1 { + lefttype = extend + righttype = extend + flags = 0 + start = 40 + segment { length = 0 expr = ch(\"../mute1\") } + } + channel timeoffset1 { + lefttype = extend + righttype = extend + flags = 0 + start = 40 + segment { length = 0 expr = ch(\"../timeoffset1\") } + } + channel timescale1 { + lefttype = extend + righttype = extend + default = 1 + flags = 0 + start = 40 + segment { length = 0 value = 1 1 expr = ch(\"../timescale1\") } + } + } + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/sublayer.parm" +Content-Type: text/plain + +{ +version 0.8 +parentlayer_group [ 0 locks=0 ] ( 0 ) +loadpayloads [ 0 locks=0 ] ( "on" ) +setstagemetadata [ 0 locks=0 ] ( auto ) +editrootlayer [ 0 locks=0 ] ( "on" ) +findsublayers [ 0 locks=0 ] ( "" ) +removefoundsublayers [ 0 locks=0 ] ( "on" ) +composition_group [ 0 locks=0 ] ( 0 ) +sublayertype [ 0 locks=0 ] ( filesandinputs ) +handlemissingfiles [ 0 locks=0 ] ( error ) +positiontype [ 0 locks=0 ] ( strongest ) +positionindex [ 0 locks=0 ] ( 0 ) +files_separator [ 0 locks=0 ] ( ) +num_files [ 0 locks=0 ] ( 1 ) +reload [ 0 locks=0 ] ( [ reload 0 ] ) +inputs_separator [ 0 locks=0 ] ( ) +enable [ 0 locks=0 ] ( "on" ) +sublayerfile_group1 [ 0 locks=0 ] ( 1 ) +enable1 [ 0 locks=0 ] ( "on" ) +filepath1 [ 0 locks=0 ] ( `chs(\"../file\")` ) +mute1 [ 0 locks=0 ] ( [ mute1 0 ] ) +timeoffset1 [ 0 locks=0 ] ( [ timeoffset1 0 ] ) +timescale1 [ 0 locks=0 ] ( [ timescale1 1 ] ) +} + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/sublayer.userdata" +Content-Type: text/plain + +{ + "___Version___":{ + "type":"string", + "value":"___EXTERNAL___" + } +} + --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY Content-Disposition: attachment; filename="hdaroot/warn_no_representation_set.init" Content-Type: text/plain @@ -141,9 +256,9 @@ Content-Disposition: attachment; filename="hdaroot/warn_no_representation_set.de Content-Type: text/plain comment "" -position -1.13898e-08 5.20999 +position 0.0322012 4.82456 connectornextid 2 -flags = lock off model off template off footprint off xray off bypass off display on render off highlight off unload off savedata off compress on colordefault on exposed on debug off +flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { 1 "output1" @@ -173,12 +288,31 @@ Content-Disposition: attachment; filename="hdaroot/warn_no_representation_set.ch Content-Type: text/plain { - channel enable1 { + channel errormsg1 { lefttype = extend righttype = extend + defaultString = "\"from ayon_houdini.api import hda_utils + +# Parent node +node = hou.pwd().parent() +try: + hda_utils.get_node_expected_representation_id(node) +except ValueError as exc: + return str(exc) + +return \\\"Unable to get representation\\\"\"" flags = 0 - start = 39.800000000000004 - segment { length = 0 expr = "if(ch(\"../representation\"), 0, 1)" } + start = 40 + segment { length = 0 expr = "from ayon_houdini.api import hda_utils + +# Parent node +node = hou.pwd().parent() +try: + hda_utils.get_node_expected_representation_id(node) +except ValueError as exc: + return str(exc) + +return \"Unable to get representation.\"" language = python } } } @@ -189,9 +323,9 @@ Content-Type: text/plain { version 0.8 numerror [ 0 locks=0 ] ( 1 ) -errormsg1 [ 0 locks=0 ] ( `chs(\"../load_message\")` ) +errormsg1 [ 0 locks=0 ] ( [ errormsg1 "" ] ) severity1 [ 0 locks=0 ] ( "warn" ) -enable1 [ 0 locks=0 ] ( [ enable1 0 ] ) +enable1 [ 0 locks=0 ] ( 1 ) } --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY @@ -206,19 +340,19 @@ Content-Type: text/plain } --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY -Content-Disposition: attachment; filename="hdaroot/sublayer.init" +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.init" Content-Type: text/plain -type = sublayer +type = switch matchesdef = 1 --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY -Content-Disposition: attachment; filename="hdaroot/sublayer.def" +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.def" Content-Type: text/plain comment "" -position -0.00125004 4.03316 -connectornextid 2 +position -1.18363 3.53061 +connectornextid 3 flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { @@ -226,11 +360,13 @@ outputsNamed3 } inputsNamed3 { -0 warn_no_representation_set 1 1 "input1" +2 (0) "" 1 "input1" +0 warn_no_representation_set 1 1 "input2" } inputs { -0 warn_no_representation_set 0 1 +0 (0) 0 1 +1 warn_no_representation_set 0 1 } stat { @@ -239,79 +375,55 @@ stat author User@HP-Z820-03 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 1 0.7 delscript "" exprlanguage hscript end --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY -Content-Disposition: attachment; filename="hdaroot/sublayer.chn" +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.editableinputdata" +Content-Type: text/plain + +[ + { + }, + { + } +] + +--HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.chn" Content-Type: text/plain { - channel reload { - lefttype = extend - righttype = extend - flags = 0 - start = 40 - segment { length = 0 expr = ch(\"../reload\") } - } - channel mute1 { - lefttype = extend - righttype = extend - flags = 0 - start = 40 - segment { length = 0 expr = ch(\"../mute1\") } - } - channel timeoffset1 { + channel input { lefttype = extend righttype = extend flags = 0 start = 40 - segment { length = 0 expr = ch(\"../timeoffset1\") } - } - channel timescale1 { - lefttype = extend - righttype = extend - default = 1 - flags = 0 - start = 40 - segment { length = 0 value = 1 1 expr = ch(\"../timescale1\") } + segment { length = 0 expr = "if(ch(\"../representation\"), 0, 1)" } } } --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY -Content-Disposition: attachment; filename="hdaroot/sublayer.parm" +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.parm" Content-Type: text/plain { version 0.8 -parentlayer_group [ 0 locks=0 ] ( 0 ) -loadpayloads [ 0 locks=0 ] ( "on" ) -setstagemetadata [ 0 locks=0 ] ( auto ) -editrootlayer [ 0 locks=0 ] ( "on" ) -findsublayers [ 0 locks=0 ] ( "" ) -removefoundsublayers [ 0 locks=0 ] ( "on" ) -composition_group [ 0 locks=0 ] ( 0 ) -sublayertype [ 0 locks=0 ] ( filesandinputs ) -handlemissingfiles [ 0 locks=0 ] ( error ) -positiontype [ 0 locks=0 ] ( strongest ) -positionindex [ 0 locks=0 ] ( 0 ) -files_separator [ 0 locks=0 ] ( ) -num_files [ 0 locks=0 ] ( 1 ) -reload [ 0 locks=0 ] ( [ reload 0 ] ) -inputs_separator [ 0 locks=0 ] ( ) -enable [ 0 locks=0 ] ( "on" ) -sublayerfile_group1 [ 0 locks=0 ] ( 1 ) -enable1 [ 0 locks=0 ] ( "on" ) -filepath1 [ 0 locks=0 ] ( `chs(\"../file\")` ) -mute1 [ 0 locks=0 ] ( [ mute1 0 ] ) -timeoffset1 [ 0 locks=0 ] ( [ timeoffset1 0 ] ) -timescale1 [ 0 locks=0 ] ( [ timescale1 1 ] ) +chooseinputbyname [ 0 locks=0 ] ( "off" ) +input [ 0 locks=0 ] ( [ input 0 ] ) +selectinputname [ 0 locks=0 ] ( "" ) +selectinputvalue [ 0 locks=0 ] ( "" ) +config_separator [ 0 locks=0 ] ( ) +badinput [ 0 locks=0 ] ( ignore ) +fallback [ 0 locks=0 ] ( 0 ) +selectfallbackname [ 0 locks=0 ] ( "" ) +inputname [ 0 locks=0 ] ( "`opinput(\".\", @input)`" ) } --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY -Content-Disposition: attachment; filename="hdaroot/sublayer.userdata" +Content-Disposition: attachment; filename="hdaroot/switch_load_warnings.userdata" Content-Type: text/plain { @@ -325,10 +437,11 @@ Content-Type: text/plain Content-Disposition: attachment; filename="hdaroot.order" Content-Type: text/plain -3 +4 output0 -warn_no_representation_set sublayer +warn_no_representation_set +switch_load_warnings --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY Content-Disposition: attachment; filename="hdaroot.net" diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.modtimes b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.modtimes index 5ac7842a55..75c57beaa5 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.modtimes +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/Contents.dir/Contents.modtimes @@ -1,6 +1,7 @@ { - "hdaroot/sublayer.def":1720045978, - "hdaroot/warn_no_representation_set.def":1720045871, - "hdaroot/output0.def":1720045871, - "hdaroot.def":1720046571 + "hdaroot/switch_load_warnings.def":1728307536, + "hdaroot/sublayer.def":1728307536, + "hdaroot/warn_no_representation_set.def":1728307536, + "hdaroot/output0.def":1728307536, + "hdaroot.def":1728307791 } diff --git a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript index b23a95dd43..ea59aff1b3 100644 --- a/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript +++ b/client/ayon_houdini/startup/otls/ayon_lop_load_shot.hda/ayon_8_8Lop_1load__shot_8_81.0/DialogScript @@ -77,23 +77,6 @@ type string default { "usd" } } - parm { - name "load_refresh" - label "Refresh" - type button - joinnext - default { "0" } - help "Click to refresh and retry applying the product load parameters to load the correct file" - parmtag { "button_icon" "" } - } - parm { - name "load_message" - label "Message" - type label - default { "" } - hidewhen "{ load_message == \"\" }" - parmtag { "sidefx::look" "block" } - } parm { name "sepparm" label "Separator" @@ -118,9 +101,9 @@ parm { name "use_ayon_entity_uri" label "Use AYON Entity URI" - help "When enabled, loads the filepath using the AYON Entity URI instead of the resolved filepath." type toggle default { "0" } + help "When enabled, loads the filepath using the AYON Entity URI instead of the resolved filepath." } groupcollapsible { name "extra_options" From b8fae23c46c91d76c2f2ab582ff28f0425463226 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 15:27:56 +0200 Subject: [PATCH 09/10] Remove unused context manager --- client/ayon_houdini/api/hda_utils.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index f4620d0868..305789c1d9 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -1,7 +1,6 @@ """Helper functions for load HDA""" import os -import contextlib import uuid from typing import List @@ -50,16 +49,6 @@ def is_valid_uuid(value) -> bool: return True -@contextlib.contextmanager -def _unlocked_parm(parm): - """Unlock parm during context; will always lock after""" - try: - parm.lock(False) - yield - finally: - parm.lock(True) - - def get_available_versions(node): """Return the versions list for node. From 58ee40ed2013146dbe97a28f3464c01cf6df23ca Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 7 Oct 2024 17:39:08 +0200 Subject: [PATCH 10/10] Cleanup --- client/ayon_houdini/api/hda_utils.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/ayon_houdini/api/hda_utils.py b/client/ayon_houdini/api/hda_utils.py index 305789c1d9..0018233736 100644 --- a/client/ayon_houdini/api/hda_utils.py +++ b/client/ayon_houdini/api/hda_utils.py @@ -96,7 +96,7 @@ def get_available_versions(node): return version_names -def update_info(node, context): +def set_node_representation_from_context(node, context): """Update project, folder, product, version, representation name parms. Arguments: @@ -125,11 +125,6 @@ def update_info(node, context): } parms = {key: value for key, value in parms.items() if node.evalParm(key) != value} - parms["load_message"] = "" # clear any warnings/errors - - # Note that these never trigger any parm callbacks since we do not - # trigger the `parm.pressButton` and programmatically setting values - # in Houdini does not trigger callbacks automatically node.setParms(parms) @@ -179,6 +174,11 @@ def get_representation_path( def set_representation(node, representation_id: str): + # For now this only updates the thumbnail, but it may update more over time + _update_thumbnail(node, representation_id) + + +def _update_thumbnail(node, representation_id): # TODO: Unused currently; add support again for thumbnail updates if not representation_id: set_node_thumbnail(node, None) @@ -189,9 +189,6 @@ def set_representation(node, representation_id: str): or get_current_project_name() ) repre_entity = get_representation_by_id(project_name, representation_id) - context = get_representation_context(project_name, repre_entity) - update_info(node, context) - if node.evalParm("show_thumbnail"): # Update thumbnail # TODO: Cache thumbnail path as well @@ -743,3 +740,6 @@ def expression_get_representation_path() -> str: path = get_representation_path(project_name, repre_id, use_entity_uri) cache[hash_value] = path return path + +# endregion +