Jump to content
berkhak

Interrupt SOP Cooking with time limit (Python)

Recommended Posts

I am curious if it is possible to clock how long it takes to cook a surface operator and interrupt if it goes above a certain limit, preferably within a python SOP?

Backstory; there are cases when a polyexpand2D node takes excessively long time to cook. I've contacted SideFX for this unexpected behavior. Long story short, this is what they recommended: 

Quote

“The algorithm works by triangulating the plane and processing triangle collapses during the wavefront propagation. There's a lot of number crunching and decision making happening. Another trick that can sometimes work is to randomly adjust the positions of the input very slightly to knock it out of whatever worst case scenario is playing out.”


And it does, when you translate the input geometry of the ‘polyexpand2d’ SOP the results do vary. So now I am trying to figure out a way to clock a particular section of the network tree, and if it takes longer than X amount of time, I want to translate the input ever so slightly. Hopefully this will help it so it doesn't take +1 hour to cook (average is somewhere between 1-5 seconds). I have been looking into hou.perfMon but that didn't really lead me anywhere. Let me know if anyone has any suggestions. 


Pseudo Code:

import time
trans_node = hou.node("../translate1")
cook_node = hou.node("../COOK_THIS")
start = time.time()
time_limit = 5.0

rot= 0.0
while current_time < time_limit:
  try:
  	cook_node.cook()
  except Timeout:
    rot= random(0.0, 360.0)
    trans_node.parm("rx").set(rot)
    cook_node.cook()
    continue


Thank you! 

Share this post


Link to post
Share on other sites

Hi, 
Great idea than one can wrap the node verb function around a decorator to limit the cook time. 

Found this tread that help me implement the decorator if anyone else is interested: 
https://stackoverflow.com/questions/492519/timeout-on-a-function-call

Test Code for Houdini: 

import sys
import threading
from time import sleep
try:
    import thread
except ImportError:
    import _thread as thread

def quit_function(fn_name):
    print(str(fn_name) + ' took too long')
    thread.interrupt_main() # raises KeyboardInterrupt
    
def exit_after(s):
    def outer(fn):
        def inner(*args, **kwargs):
            timer = threading.Timer(s, quit_function, args=[fn.__name__])
            timer.start()
            try:
                result = fn(*args, **kwargs)
            finally:
                timer.cancel()
            return result
        return inner
    return outer
    
@exit_after(2)
def countdown(n): # some function that can be run within Python SOP
    print('countdown started')
    for i in range(n, -1, -1):
        print(str(i) + ', ')
        sleep(1)
    print('countdown finished')
    
try:
    countdown(5)
except:
    print('do something else')
        

Tesekkurler Yunus! 

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×