Jump to content

[Python] Re-execute class method at each frame


Recommended Posts

Hi there!


I've been scripting in Maya for some years now and I decided to give Houdini a try but I still have some issues understanding how cooking works.


I'm trying to implement my own cellular automata (a classical 3D Game of Life). The algorythm is pretty simple: my class first generates a virtual 3D grid which is made of livings cells (1) and dead cells (0). Then, at each iteration of a custom user input parameter, it analyses the current grid and does some work to modify it.


But I have a hard time figuring how to do this. How can I have my script memorize its current state at each frame? For now the node just cooks entirely at each iteration, which is obviously pointless. Is there a way to execute only one method of my class? I thought about using a callback on the iteration parameter but I can't understand how it works in Houdini (I just made a "New Operator Type" and wrote my script inside the "Code" tab).


Sorry if this sounds stupid, I'm still learning! And I couldn't find anything useful on Google.. :(


Thanks in advance for your help!

Link to comment
Share on other sites

Your script needs to fetch the data from a stored location rather than just running as a 1st run each frame.

You can store data as attributes on geometry or userData on the python node itself.


Here is an example of userData I recently created. I needed to examine all the nodes in an imported rig and remove any animation so I can control them directly from code. I don't want to do this every frame, however, so I need a way to determine if i have done this before.


node_path = r"/obj/my_subnet/"
node_root = hou.node('%s%s' % (node_path,"my_node_name"))
if node_root != None:
    #Check to see if we have done this before?
    n = node_root.userData("my_data_name")
    if n == None:
        # Do work.
        node_root.setUserData("my_data_name",str(1))           # Set our flag so we don't do this everytime.
        # n is now a string that contains the value fetched from the userData.
        print float(n)
Edited by Atom
Link to comment
Share on other sites

In my case I think it was proper, I only needed to run code once. The iterative case of life seems more appropriate for a solver, however.


I was only using setUserData because the object I was storing the information on, was a bone controller which was a null. Initially I wanted to store an attribute in the object but the null does not have any Geometry, which is where attributes are stored, so I fell back to userData. You can use attributes as a kind of global storage system too.

Link to comment
Share on other sites

Thanks for your help guys.

I've been trying to play with the solver but it's still a little complicated for me to have something entirely opaque for the user (this is a class project and the teacher wants it to be super user-friendly).


I'll keep trying to use a solver but I was wondering about something: is it a good way to do all the stuff inside a Python Module created in the Scripts tab? So that I can modify the grid using callbacks?

Say I have 2 parameters: a grid initial state and an iteration parameter which is supposed to be animated. I could call a function to create the grid when the initial state parameter is modified and then use a callback on the iteration parameter to modify that grid?


Or I could keep the core algorythm inside the Code tab and fetch the grid from the callbacks if it's possible?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...