如何在Nuke(Python)中取消正在执行的写入节点
我一直在用Python编写Nuke渲染管理器,但遇到了一个问题:如何在Nuke(Python)中取消正在执行的写入节点,python,multithreading,render,nodes,nuke,Python,Multithreading,Render,Nodes,Nuke,我一直在用Python编写Nuke渲染管理器,但遇到了一个问题: nuke.cancel()。 我的python脚本创建一个主类并连接到一个服务器(用Java编写),然后进入一个无限循环,每次获得一个新任务(以JSON对象的形式)。它得到的每个循环都会打开一个脚本?查找写入节点并执行它们。为了向服务器报告进度,我添加了回调: nuke.addBeforeFrameRender(lambda:self.\u pre\u frame\u render()) 和 nuke.addAfterFrameR
nuke.cancel()。
我的python脚本创建一个主类并连接到一个服务器(用Java编写),然后进入一个无限循环,每次获得一个新任务(以JSON对象的形式)。它得到的每个循环都会打开一个脚本?查找写入节点并执行它们。为了向服务器报告进度,我添加了回调:
nuke.addBeforeFrameRender(lambda:self.\u pre\u frame\u render())
和
nuke.addAfterFrameRender(lambda:self.\u post\u frame\u render())
在哪里
要在服务器上启用cancel
方法,我有一个单独的线程,在渲染处于活动状态时运行,并等待“cancel”请求
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\u回调
定义为
def _cancel_callback(self):
nuke.cancel()
self._is_canceled = True
在循环开始之前,我启动CancelHandler
线程,在每次迭代中设置run\u set
操作,并在清除后让主线程通信。在此期间,在不同的阶段,我检查是否设置了cancel\u set
,以防出现“取消”请求
除了一件事:nuke.execute()。我曾尝试将其放入nuke.addBeforeFrameRender
和nuke.addAfterFrameRender
回调中,但没有任何效果。我还认为它可能在错误的线程中执行,所以我尝试了nuke.executeInMainThread(nuke.cancel)
,但没有成功
草案内容如下:
执行(nameOrNode、start、end、incr、views、continueOnError=False)
...
如果Nuke在GUI打开的情况下运行,这将弹出一个进度表。如果用户点击取消按钮,此命令将返回“取消”错误。
如果从Nuke命令行运行Nuke(即Nuke是通过-t开关启动的),则execute()会在运行过程中打印一个文本百分比。
如果用户键入^C,它将中止execute()并返回“取消”错误
所以我尝试用os.kill(os.getpid(),signal.CTRL\u C\u事件)替换nuke.cancel()
这实际上停止了渲染,但execute()
从未返回,因此脚本无法继续
因为execute()
应该
返回“已取消”错误
我试图从execute()
和os.kill(os.getpid(),signal.CTRL\u C\u事件)
代码中捕获nuke.cancelederror
异常,但没有抛出
奇怪的是,当我运行此回调时:
def _cancel_callback(self):
self._is_canceled = True
os.kill(os.getpid(), signal.CTRL_C_EVENT)
print "Cancelled"
执行了打印
行
我对python相当陌生,所以这可能是noob的错误,但有人知道我可能做错了什么,或者这是API中的错误吗?
或者也许有人能想出一个更好的解决问题的办法-那将是非常感谢
到目前为止,我所看到的摆脱这种情况的唯一方法是简单地关闭worker进程,然后启动一个新的进程,但每次有人想取消一个工作时,这都是一件很糟糕的事情
使用Nuke 9.0v3
完整的源代码可以在PYTHON目录中找到,这是一个很好的问题,我希望知道答案。不是一个答案,但是你可以考虑使用一个渲染排队系统,就像大多数软件一样。它(以及其他类似的工具)的工作方式是每次都通过一个干净的命令行渲染。Nuke命令行渲染器只需几秒钟即可启动,因此可能不值得尝试在渲染之间保持活动状态。是的,对于渲染来说,代价不是很大,但我的任务包括使用指定节点批量创建脚本(主要用于通过高质量分辨率或降噪等处理进行代码转换),而这些可能需要不到一秒钟的时间。如果我找不到可行的解决方案,我只会在需要取消渲染时终止该过程。我建议写信给铸造厂。这听起来确实像一个bug,而且他们通常对这些都很敏感。如果您找到了解决方案,请在此处“回答您自己的问题”,以帮助未来的访问者。
def _cancel_callback(self):
self._is_canceled = True
os.kill(os.getpid(), signal.CTRL_C_EVENT)
print "Cancelled"