From e696a6923d76687a5b68316d56bfd15c93cd0399 Mon Sep 17 00:00:00 2001 From: Devo Date: Wed, 18 Dec 2024 19:29:11 +0100 Subject: [PATCH 1/2] Houdini Integration - Create Setup #7 Issue #7 POC create_setup() for the Houdini integration. Needs discussion about: - code formatting L7-L54 - node type for the conduct node L20 - file_name L53 --- integration/houdini/Conduct.json | 3 + integration/houdini/MainMenuCommon.xml | 20 +++++++ integration/houdini/README.md | 3 + .../scripts/python/ConductPlugin/__init__.py | 0 .../python/ConductPlugin/select_project.py | 56 +++++++++++++++++++ .../scripts/python/ConductPlugin/utils.py | 27 +++++++++ 6 files changed, 109 insertions(+) create mode 100644 integration/houdini/Conduct.json create mode 100644 integration/houdini/MainMenuCommon.xml create mode 100644 integration/houdini/README.md create mode 100644 integration/houdini/scripts/python/ConductPlugin/__init__.py create mode 100644 integration/houdini/scripts/python/ConductPlugin/select_project.py create mode 100644 integration/houdini/scripts/python/ConductPlugin/utils.py diff --git a/integration/houdini/Conduct.json b/integration/houdini/Conduct.json new file mode 100644 index 0000000..2da8fd8 --- /dev/null +++ b/integration/houdini/Conduct.json @@ -0,0 +1,3 @@ +{ + "hpath" : "$HFS/packages/Conduct" +} diff --git a/integration/houdini/MainMenuCommon.xml b/integration/houdini/MainMenuCommon.xml new file mode 100644 index 0000000..08135f9 --- /dev/null +++ b/integration/houdini/MainMenuCommon.xml @@ -0,0 +1,20 @@ + + + + + + + + + + 0 + + + + + + diff --git a/integration/houdini/README.md b/integration/houdini/README.md new file mode 100644 index 0000000..2dc73b0 --- /dev/null +++ b/integration/houdini/README.md @@ -0,0 +1,3 @@ +# Installation +Place the `Conduct.json` in `Houdini /packages` +Either adjust it's path or place the `MainMenuCommon.xml` file and `scripts` folder into `Houdini /packages/Conduct` diff --git a/integration/houdini/scripts/python/ConductPlugin/__init__.py b/integration/houdini/scripts/python/ConductPlugin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/integration/houdini/scripts/python/ConductPlugin/select_project.py b/integration/houdini/scripts/python/ConductPlugin/select_project.py new file mode 100644 index 0000000..e1b652d --- /dev/null +++ b/integration/houdini/scripts/python/ConductPlugin/select_project.py @@ -0,0 +1,56 @@ +import hou +from . import utils +import os + + +# Thinking about splitting this into multiple functions for better readability +def create_setup(): + path = utils.select_project() + path = hou.expandString(path) + + setup_network: hou.Node = hou.node("/obj").createNode("subnet") + setup_network.setName("setup") + setup_network.setPosition((0, 0)) + + import_network: hou.Node = hou.node("/obj").createNode("subnet") + import_network.setName("import") + setup_network.setPosition((0, -1)) + + # Might using subnet instead of null, cause a null adds an extra object to the scene + data_node: hou.Node = setup_network.createNode("null") + data_node.setName("conduct") + + data_node.addSpareParmTuple( + hou.StringParmTemplate("project", "Project", 1)) + data_node.addSpareParmTuple( + hou.StringParmTemplate("department", "Department", 1)) + data_node.addSpareParmTuple(hou.StringParmTemplate("asset", "Asset", 1)) + data_node.addSpareParmTuple(hou.StringParmTemplate("shot", "Shot", 1)) + + projectParm: hou.Parm = data_node.parm("project") + projectParm.set(path) + + conduct = utils.get_conduct_object() + + result = conduct.setup() + if result['result'] != 'ok': + return {'FINISHED'} + + dialog_data = result['data'] + + deptParm: hou.Parm = data_node.parm("department") + deptParm.set(dialog_data['department']) + + assetParm: hou.Parm = data_node.parm("asset") + assetParm.set(dialog_data['asset']) + + shot = dialog_data['shot'] + if shot is not None: + shotParm: hou.Parm = data_node.parm("shot") + shotParm.set(shot) + + # We have to discuss a properway of doing this. Houdini does not support the \\?\ prefix. Only tested on Windows + file_name = os.path.join(dialog_data['path'][4:] if dialog_data['path'].startswith( + r"\\?") else dialog_data['path'], dialog_data['file_name'] + ".hip") + + hou.hipFile.save(file_name) diff --git a/integration/houdini/scripts/python/ConductPlugin/utils.py b/integration/houdini/scripts/python/ConductPlugin/utils.py new file mode 100644 index 0000000..01c9e87 --- /dev/null +++ b/integration/houdini/scripts/python/ConductPlugin/utils.py @@ -0,0 +1,27 @@ +import os +import hou +from . import conduct + + +def get_conduct_data_node() -> hou.Node: + return hou.node("/obj/setup/conduct") + + +def get_conduct_object() -> conduct.Conduct: + data = get_conduct_data_node() + projectParm: hou.Parm = data.parm("project") + dir = os.path.dirname(projectParm.evalAsString()) + exe = os.path.join(dir, "conduct.exe") + + return conduct.Conduct(exe, "houdini") + + +def select_project(): + file_path = hou.ui.selectFile( + start_directory=hou.hipFile.path(), + title="Select a project", + pattern="*.yml,*.yaml", + chooser_mode=hou.fileChooserMode.Read + ) + + return file_path From 4ea6e1e243840c1b087faca5488a83e85d4308f6 Mon Sep 17 00:00:00 2001 From: Devo Date: Mon, 23 Dec 2024 08:34:38 +0100 Subject: [PATCH 2/2] Houdini Integration - Create Setup #7 Issue #7 POC create_setup() for the Houdini integration. - select project now available through node and menu bar - load asset(s) shows in the menu after a project was selected - error handling - custom conduct node --- integration/houdini/MainMenuCommon.xml | 13 ++++-- .../houdini/otls/LAGMACHINE.Conduct.hdalc | Bin 0 -> 10668 bytes .../python/ConductPlugin/load_asset.py | 2 + .../python/ConductPlugin/select_project.py | 44 +++++++----------- .../scripts/python/ConductPlugin/utils.py | 33 ++++++++----- 5 files changed, 49 insertions(+), 43 deletions(-) create mode 100644 integration/houdini/otls/LAGMACHINE.Conduct.hdalc create mode 100644 integration/houdini/scripts/python/ConductPlugin/load_asset.py diff --git a/integration/houdini/MainMenuCommon.xml b/integration/houdini/MainMenuCommon.xml index 08135f9..6f56779 100644 --- a/integration/houdini/MainMenuCommon.xml +++ b/integration/houdini/MainMenuCommon.xml @@ -5,13 +5,16 @@ - - + + 0 diff --git a/integration/houdini/otls/LAGMACHINE.Conduct.hdalc b/integration/houdini/otls/LAGMACHINE.Conduct.hdalc new file mode 100644 index 0000000000000000000000000000000000000000..fd188bf43c8f0d88faf737301cd1dbc0084f24f8 GIT binary patch literal 10668 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 hou.Node: - return hou.node("/obj/setup/conduct") - - -def get_conduct_object() -> conduct.Conduct: - data = get_conduct_data_node() - projectParm: hou.Parm = data.parm("project") - dir = os.path.dirname(projectParm.evalAsString()) - exe = os.path.join(dir, "conduct.exe") - - return conduct.Conduct(exe, "houdini") + all_nodes = hou.node("/obj").allNodes() + data_node = None + for node in all_nodes: + if node.type().name() == "LAGMACHINE::Conduct" and node.name() == "Conduct": + data_node = node + break + + if data_node is None: + data_node: hou.Node = hou.node( + "/obj").createNode("LAGMACHINE::Conduct") + data_node.setName("Conduct") + data_node.setPosition((0, 0)) + + return data_node + + +def get_conduct_object(manifest_path=None) -> conduct.Conduct: + if manifest_path != None: + return conduct.get_from_manifest_path(manifest_path, "houdini") + else: + return conduct.find_from_current_path(hou.hipFile.path(), "houdini") def select_project():