我一直在用Python编写Nuke渲染管理器并遇到了一个问题:
nuke.cancel()
似乎无法正常工作。
我的python脚本创建一个主类并连接到服务器(用Java编写),然后进入无限循环,每次都获得一个新任务(以JSON对象的形式)。它获得的每个循环打开一个脚本?找到写节点并执行它们。要将进度报告回服务器,我添加了回调:
nuke.addBeforeFrameRender(lambda: self._pre_frame_render())
和
nuke.addAfterFrameRender(lambda: self._post_frame_render())
其中
def _pre_frame_render(self):
self._host_socket.send(struct.pack('>b', 1))
self._host_socket.send(struct.pack('>i', nuke.frame()))
def _post_frame_render(self):
self._host_socket.send(struct.pack('>b', 2))
self._host_socket.send(struct.pack('>i', nuke.frame()))
要在服务器上启用cancel
方法,我有一个单独的线程在渲染处于活动状态时运行并等待“取消”#39;请求
class CancelHandler(threading.Thread):
def __init__(self, input_socket, cancel_callback):
threading.Thread.__init__(self)
self.cancel_set = threading.Event()
self.run_set = threading.Event()
self._input_socket = input_socket
self._cancel_callback = cancel_callback
def run(self):
while True:
if self.run_set.is_set():
msg_raw = recv_msg(self._input_socket)
msg = json.loads(msg_raw)
if 'mode' in msg and msg['mode'] == 'cancel':
print msg_raw
self.cancel_set.set()
self.run_set.clear()
self._cancel_callback()
cancel_callback
定义为
def _cancel_callback(self):
nuke.cancel()
self._is_canceled = True
在循环开始之前,我启动CancelHandler
线程,并在每次迭代时设置run_set
操作,然后 - 清除后让主线程进行通信。在不同阶段之间我检查是否已设置cancel_set
以防“取消”#39}。请求已经到了。
以上所有内容似乎都运行正常,除了一件事:nuke.execute()
绝对没有 - 渲染只是继续。我已尝试将其放入nuke.addBeforeFrameRender
和nuke.addAfterFrameRender
回调中,但这样做无效。另外我认为它可能是在错误的线程中执行所以我尝试nuke.executeInMainThread(nuke.cancel)
没有运气。
执行(nameOrNode,start,end,incr,views,continueOnError = False) ... 如果使用GUI运行Nuke,则会弹出进度表。如果用户点击取消按钮,该命令将返回'取消'错误。 如果Nuke是从nuke命令行运行的(即nuke是使用-t开关启动的话),则execute()会在进行时打印文本百分比。 如果用户输入^ C,它将中止execute()并返回'取消'错误。
所以我尝试用nuke.cancel()
替换os.kill(os.getpid(), signal.CTRL_C_EVENT)
这实际上停止了渲染,但execute()
从未返回,因此脚本无法继续
由于execute()
应该
退回'取消'错误
我试图从nuke.CancelledError
和execute()
代码中捕获os.kill(os.getpid(), signal.CTRL_C_EVENT)
例外,但它没有被抛出。
奇怪的是,当我运行这个回调时:
def _cancel_callback(self):
self._is_canceled = True
os.kill(os.getpid(), signal.CTRL_C_EVENT)
print "Cancelled"
print
行已执行
我对python很新,所以它可能是一个noob的错误但有人知道我可能做错了什么,或者它是否是API中的错误? 或者也许有人会提出更好的解决问题的方法 - 非常感谢!
到目前为止,我看到的唯一解决方法是简单地关闭工作流程然后启动一个新流程,但每次有人想取消工作时,这都是一件很难看的事情。< / p>
使用Nuke 9.0v3 可以在PYTHON目录中的https://bitbucket.org/andrey_glebov/nukerendermanager/src找到完整的源代码