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

and*_*rey 5 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()))
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

cancel_callback被定义为

def _cancel_callback(self):
        nuke.cancel()
        self._is_canceled = True
Run Code Online (Sandbox Code Playgroud)

在循环开始之前,我启动CancelHandler线程,并在每次迭代时run_set设置操作,然后 - 清除后让主线程进行通信.在不同阶段之间我检查是否cancel_set已经设置以防"取消"请求到达.

所有上述内容似乎都可以正常工作,除了一件事:nuke.execute()绝对没有 - 渲染只是继续.我已经尝试将它放入nuke.addBeforeFrameRendernuke.addAfterFrameRender回调中,但这没有任何作用.另外我认为它可能是在错误的线程中执行所以我试着nuke.executeInMainThread(nuke.cancel)没有运气.

文件内容如下:

execute(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"
Run Code Online (Sandbox Code Playgroud)

print条线被执行了

我对python相当新,所以它可能是一个noob的错误,但有人知道我可能做错了什么或者它是否是API中的错误?或者也许有人会提出更好的解决方案来解决这个问题 - 非常感谢!

到目前为止,我看到的唯一出路就是关闭工作流程然后启动一个新流程,但每次有人想取消工作时,这都是一件很难看的事情.

使用Nuke 9.0v3完整的源代码可以在PYTHON目录下的https://bitbucket.org/andrey_glebov/nukerendermanager/src找到

ARG*_*Geo 0

以下命令取消Progress窗口,因此它也停止渲染过程。

nuke.toNode('Write1')['disable'].setValue(1)
Run Code Online (Sandbox Code Playgroud)