如何取消Nuke中的执行写入节点(Python)

时间:2015-02-14 21:13:01

标签: python multithreading render nodes nuke

我一直在用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.addBeforeFrameRendernuke.addAfterFrameRender回调中,但这样做无效。另外我认为它可能是在错误的线程中执行所以我尝试nuke.executeInMainThread(nuke.cancel)没有运气。

documentation读取:

  

执行(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.CancelledErrorexecute()代码中捕获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找到完整的源代码

0 个答案:

没有答案