Creating geometry in python module of a digital asset?

   665   6   2
User Avatar
Member
73 posts
Joined: April 2020
Online
Hello Experts,

I believe this question has been asked in various ways in various forums, but I haven't been able to apply the results of those discussions successfully.

I need to create some geometry from scratch in a digital asset. I'd like to use the python module on the scripts tab for this, and I'd like to call the geometry creation upon a button press.

What I've found is that I either get an error get the error
"AttributeError: 'Node' object has no attribute 'geometry'"
when I try to do this.

From reading various forum discussions, I *think* I'm seeing that for a digital asset, I have to do this geometry creation in a python node inside a subnet, instead of in the script at the top-level of the asset. That sounds easy enough, and when I create a point in that python node, it does indeed get created without an error. However, I still want to trigger the geometry creation from a button press, and I cannot for the life of me get the callback script for the button press to recognize that the function exists in the python node. I get the error
"AttributeError: 'module' object has no attribute 'main'.

The name of the function is main(), and when I call it directly the point shows up. But when I remove the call to main from the python code, I can't instead trigger it from the button press.

I'd be vastly delighted if someone could offer clues about what I'm doing wrong or misunderstanding about either trying to do this in the script top-level of the asset or in the subnet python node.

I attach a hip file and the hdas for the subnet and top-level versions of the asset.

Thanks very much,
Mary

Attachments:
test-geo-create.hip (96.6 KB)
sop_mgbaker.dev.test_script.1.0.hda (3.6 KB)
sop_mgbaker.dev.test.1.0.hda (3.7 KB)

User Avatar
Member
143 posts
Joined: May 2017
Offline
Hi,
hou.phm().main()
phm is the reference of the current nodes python module, where the function is executed from. So there is no definition for main() in your asset.

I'm not sure what you are up to, but in general I think it's better to generate geometry with vex.

So for your example you could pass the function as a string to the python sop (code parm.) by pressing the button in your asset:

and for the button callback you can use this code:
hou.phm().foo()

Over even uses verbs with python to create geo primitives.

Can you describe in more detail what you have in mind? For example, simply generate random points by clicking a button?
Edited by viklc - April 11, 2024 15:23:52

Attachments:
py_code_01.jpg (26.9 KB)

User Avatar
Member
73 posts
Joined: April 2020
Online
Thanks, viklc. The point creation was just an example to keep my test file small. I'm creating a mesh from a 3mf file that gets imported in an automation workflow. I'll ponder this further, thanks!

Mary
User Avatar
Member
8581 posts
Joined: July 2007
Offline
you need something to hold your created geo, for that you can use Data parm
since you want to output the geo you can use Stash SOP inside and promote it's data parm (stash) to your HDA so that it's editable and you can hide it

then in your HDA Python Module you can have a function that creates and stores geo in this data parm and incoke it through button callback

Attachments:
test-geo-create_fix.hipnc (96.6 KB)

Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
73 posts
Joined: April 2020
Online
Thanks, Tomas, for your help. It sounds as if it's going to be exactly what I need, but I'm not yet understanding it. I've never stumbled across stash nodes or data parms before, and I doubt I'm interpreting your instructions correctly.

Do I understand you correctly that I would have the python code as a Python Module in the scripts tab of the HDA type properties? In the subnet of the HDA I would then have a stash node? In the python code I would write the geometry to a data parameter (or geometry data parameter??) of the stash node by doing something like

stash_node = hou.node('./stash1')
stash_node.parm('stash').set(geo)

And then, if I can figure it out, I would promote the data stored there to a data parameter in the type properties of the HDA so it will show up on my top-level HDA node?

I probably haven't interpreted your instructions correctly. That might be because I don't know how to promote the data parm of the stash in the subnet up to a parameter in the HDA. I know what that means for vops, but not for my subnet here, and so I'm still getting the read-only error, alas.

I attach a hip file with my new attempt that isn't working. Each time the button on the HDA is pressed, it is supposed to run the python code which generates different numbers of points depending on what time it is -- just so I can see if it's doing something different each time it's invoked. I've tried to save the operator definitions to the hip file so I don't also need to attach hda's. (I only just learned about this possibility.)

Your further advice would be greatly appreciated, thanks!

Best wishes,
Mary

Attachments:
test-geo-create.hip (122.5 KB)

User Avatar
Member
8581 posts
Joined: July 2007
Offline
has the file that I attached not worked for you?
let me know since it is the fully working example of what you are after and every time you press button it generates diferently positioned point, so fixing your new file would be just repeating myself


the only confusing part in my file may have been that I have hidden the promoted stash parameter as described

promoting is just dragging the stash data parm to the HDA parameters, or adding it there from From Nodes Section
Edited by tamte - April 15, 2024 02:12:23
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
73 posts
Joined: April 2020
Online
Oh my goodness, Tomas, I'm so sorry -- I didn't notice the attachment! Thank you so much for going to the trouble of providing it. It works beautifully!

Best wishes,
Mary
  • Quick Links