How to cancel node write execution in Nuke (Python)

I wrote a Nuke visualization manager in Python and ran into a problem: nuke.cancel() did not seem to work correctly. My python script creates the main class and connects to the server (written in Java) and then enters an infinite loop, each time receiving a new task (as a JSON object). Does every loop it receives open a script? finds recording nodes and executes them. To report progress on the server, I added callbacks: nuke.addBeforeFrameRender(lambda: self._pre_frame_render()) as well as nuke.addAfterFrameRender(lambda: self._post_frame_render()) where

 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())) 

To enable the cancel method on the server, I have a separate thread that runs while the rendering is active and waiting for a cancel request

 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 defined as

 def _cancel_callback(self): nuke.cancel() self._is_canceled = True 

Before starting the loop, I start the CancelHandler stream, and the run_set action is set at each iteration, and after that it is cleared to transmit the main stream. Meanwhile, at different stages I check whether cancel_set was set in case of a β€œcancel” request.

All of the above works fine, except for one thing: nuke.execute() does nothing - the rendering only continues. I tried putting it in nuke.addBeforeFrameRender and nuke.addAfterFrameRender , but that does nothing. Also, I thought this might be executing in the wrong thread, so I tried nuke.executeInMainThread(nuke.cancel) with no luck.

The documentation reads:

execute (nameOrNode, start, end, incr, views, continueOnError = False) ... If Nuke starts with a graphical interface, this will display a progress bar. If the user presses the cancel button, this command will return a "canceled" error. If Nuke is started from the nuke command line (i.e., nuke is started with the -t switch) execute () prints the percentage of the text as it moves. If the user types ^ C, he will abort () and return a Cancel error.

so I tried replacing nuke.cancel() with os.kill(os.getpid(), signal.CTRL_C_EVENT) This actually stopped the render, but execute() never returned, so the script could not continue

Since execute() should

returns a canceled error

I tried to catch the nuke.CancelledError exception nuke.CancelledError both the execute() code and os.kill(os.getpid(), signal.CTRL_C_EVENT) , but it was not os.kill(os.getpid(), signal.CTRL_C_EVENT) .

Curious when I ran this callback:

 def _cancel_callback(self): self._is_canceled = True os.kill(os.getpid(), signal.CTRL_C_EVENT) print "Cancelled" 

print line completed

I'm new to python, so this may be a noob error, but does anyone know what I can do wrong or if it is an error in the API? Or maybe someone from Kamchatka will come up with a better solution to the problem - it will be very useful!

So far, the only way out of this situation, I see, is simply to close the workflow and then start a new one, but it would be ugly when every time someone wants to cancel the work.

Using Nuke 9.0v3 Full source code can be found at https://bitbucket.org/andrey_glebov/nukerendermanager/src in the PYTHON directory

+5
source share

Source: https://habr.com/ru/post/1213393/


All Articles