-
Notifications
You must be signed in to change notification settings - Fork 0
Houdini Integration - Create Setup #7 #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "hpath" : "$HFS/packages/Conduct" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
|
|
||
| <mainMenu> | ||
| <menuBar> | ||
|
|
||
| <subMenu id="conduct_menu"> | ||
| <label>Conduct</label> | ||
| <scriptItem id="conduct"> | ||
| <labelExpression><![CDATA["Select Project" if not getattr(hou.session, "projectImported", False) else "Load Asset(s)"]]></labelExpression> | ||
| <insertAtIndex>0</insertAtIndex> | ||
| <scriptCode><![CDATA[ | ||
| if not getattr(hou.session, "projectImported", False): | ||
| import ConductPlugin.select_project as select_project | ||
| select_project.create_setup() | ||
| else: | ||
| import ConductPlugin.load_asset as load_asset | ||
| load_asset.load() | ||
| ]]> | ||
| </scriptCode> | ||
| </scriptItem> | ||
| </subMenu> | ||
| </menuBar> | ||
| </mainMenu> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Installation | ||
| Place the `Conduct.json` in `Houdini <version_name>/packages` | ||
| Either adjust it's path or place the `MainMenuCommon.xml` file and `scripts` folder into `Houdini <version_name>/packages/Conduct` |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you unpack this hda to text format?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an issue with the limited commercial version: I still get an output. Here is the download. Repacking says:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fucking proprietary software... looking at the contents of the zip file you provided, I think the node was still successfully unpacked. I can see your
Houdini should be able to load the hda directly from unpacked state, so converting back to packed format shouldn't be necessary. Could you see if you can load without converting? if so I think we can go ahead with this |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| def load(): | ||
| print("Hello, World!") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import hou | ||
| from . import utils | ||
| import os | ||
|
|
||
|
|
||
| def create_setup(): | ||
| path = utils.select_project() | ||
| if path == "": | ||
| return {'FINISHED'} | ||
| path = hou.expandString(path) | ||
|
|
||
| if hou.licenseCategory() != hou.licenseCategoryType.Commercial: | ||
| fileExtension = ".hiplc" if hou.licenseCategory( | ||
| ) == hou.licenseCategoryType.Indie else ".hipnc" | ||
| else: | ||
| fileExtension = ".hip" | ||
|
|
||
| conduct = utils.get_conduct_object(path) | ||
|
|
||
| result = conduct.setup(fileExtension) | ||
| if result['result'] != 'ok': | ||
| return {'FINISHED'} | ||
|
|
||
| data_node = utils.get_conduct_data_node() | ||
|
|
||
| pSelectedParm: hou.Parm = data_node.parm("project_selected") | ||
| pSelectedParm.set(True) | ||
|
|
||
| projectParm: hou.Parm = data_node.parm("project") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont think we need to store this, and if we did it would only be a valid path for the person who initially did this. If i opened the project on a machine where the project is stored elsewhere, it wouldn't be accurate anymore
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree on the project path.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe could just check if the the current file is saved, if you feel like it also could check that its saved to a valid project location - doing so would have some extra io calls so im not sure if there would be a performance impact. Generally I would prefer to avoid hidden parms like this where possible, it can be prone to adding weird behaviour
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my opinion is setUserData() probably the best approach, as you mentioned in the original issue.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe, for me I prefer to store as little information as possible, and to derive this kind of state from elsewhere - the way I see it the more state you are storing, the more chances there are to end up in weird invalid states |
||
| projectParm.set(path) | ||
|
|
||
| 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) | ||
|
|
||
| setattr(hou.session, "projectImported", True) | ||
| hou.hipFile.save(file_name=os.path.join(dialog_data['path'])) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import hou | ||
| from . import conduct | ||
|
|
||
|
|
||
| # Not sure about the efficiency | ||
| def get_conduct_data_node() -> hou.Node: | ||
| all_nodes = hou.node("/obj").allNodes() | ||
Devostated marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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") | ||
Devostated marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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(): | ||
| 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 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: is it possible to set this up as two menu items, where each one hides itself by some expression when it shouldn't be available, instead of as one menu item which switches between two states?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or not necessarily hidden, but im pretty sure there is a way for menu items to be disabled/grayed out based on an expression, which would be preferable i think - it might be more intuitive for me to try and implement it this way in blender too...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was definitely the easiest solution instead of having two entries that hide.
But greying out should be easy, assuming there is a native way to grey them out, which Im really confident about.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I have no idea how to do that.
The only menu item I found that has such feature was the redo/undo function.
It uses following for that:
No idea where undo.menu is coming from.
Another Menu had , but I didn't manage to get it working, it always told me that it's an unknown command.
While writing this I found following:
"It is not currently possible to dynamically enable and disable user-defined menus/items."
https://www.sidefx.com/docs/houdini/basics/config_menus.html#menu-items
I'm not sure if that is just the top level item in the menu bar or also it's scriptItems
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could still split that into two
<scriptItems>and use an<expression>to en-/disable them accordingly, if you would prefer that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah thats a shame... I think splitting them in to two menus will be less prone to bugs. I can see a scenario where the two expressions for controlling the text and the logic for the single menu become out of sync and lead to unexpected behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, it's not much stored. Department, Asset, Shot and if it's imported. Could also just do a check if department exists. Usually try to avoid working with strings as much as possible, that's why I didn't like the idea of hardcoding the conduct node path.