.. _customizing: Advanced: Customising the render process ======================================== smartRender works out of the box producing fast render results. However, you can customize the actual render process command modules to your needs. If you have some python programming knowledge then you can edit the command modules and add your own commands to them. This can become very useful if you need to tailor smartRender to your existing pipeline. Feel free to edit both command modules to your needs. smartRender includes two modules that you can edit: **render_cmd.py:** This module creates the terminal input commands **render_process.py:** This module will be executed from your terminal when it comes to processing a frame Both modules can be found inside the **custom** folder in the smartRender package. If you installed smartRender using connect it can be found here: **Linux:** ``/home/[username]/.nuke/cragl/_cragl_tools/smartRender_vX.X/cpXX/smartRender/custom/`` **Mac:** ``/Users/[username]/.nuke/cragl/_cragl_tools/smartRender_vX.X/cpXX/smartRender/custom/`` **Windows:** ``C:\Users\[username]\.nuke/cragl/_cragl_tools/smartRender_vX.X/cpXX/smartRender/custom/`` Where ``cpXX`` is the python version you are using (Nuke14 and higher: cp39, Nuke13: cp37, Nuke12 and older: cp27). If you installed smartRender using the manual method then the custom folder can be found at the according location inside the smartRender package. .. warning:: CAUTION: CHANGING BOTH MODULES COULD POTENTIALLY BREAK SMARTRENDER FROM WORKING CORRECTLY. WE HIGHLY RECOMMEND MAKING A BACKUP OF BOTH MODULES BEFORE CHANGING THEM. PLEASE HANDLE WITH CAUTION. The render_cmd module --------------------- The *render_cmd* module contains one function ``create_cmd()`` which assembles a render command for the worker threads to be executed it in NUKE's terminal mode. The command is returned as a string. .. image:: img/17.png By default, a render command is build out of NUKE internal flags and some additional arguments and looks like this: .. code-block:: python -i -t job_id thread_id script write frame views where: **:** Absolute path of nuke executable that will run in terminal mode. **-i:** Flag to tell NUKE to use an interactive (nuke_i) FLEXlm license key. If you happen to have enough render licenses, you might skip this flag so that no interactive licenses will be used. **-t:** Flag to tell NUKE to run in terminal mode. **:** Absolute path to the render batch script called *render_process* that will be processed. The absolute path will be assembled by smartRender automatically. **job_id:** A unique job id for identifying the current job in log file and writing process to log file. A job id looks like this: ``current_timestamp_unique-job-id`` Example: ``1460975662_facc80e8`` **thread_id:** The id of the thread that will process the current job. Threads are named as ``Thread-1``, ``Thread-2``, ``Thread-3``, ... **script:** The absolute path of nuke script to process. **frame:** The Frame to process. Named as ``f1`` for frame 1, ``f2`` for frame 2, ... **views:** The views to render. In most cases this might be ``main`` if the current working file is not a stereo working file. Multiple views are separated by comma like ``main``, ``left``, ``right``, ... In detail ````````` The first three arguments (nuke executable, -i, -t) are NUKE internal flags that will be called. - The NUKE executable is pointing to the absolute path of the executable nuke application that will run in terminal mode. - The NUKE executable will be executed using the ``-i`` flag to use an interactive (nuke_i) FLEXlm license key. - The NUKE executable will run with the ``-t`` flag which means it will run in *terminal mode* without any GUI (graphical user interface) being loaded. The following arguments are additional arguments that will be used in the render_process module which is documented in render_process_module_. - **render_process.py:** The absolute path of the renderProcess module that will be executed. - **job_id:** This is the internal job id as it will be used for logging information. - **thread_id:** This is the internal thread id as it will be used for logging information. - **script:** Absolute path of the NUKE script that will be opened in terminal mode and executed. - **frame:** The frame to process. The frame will need to be casted as a String for being send as an argument and will look like ``f1`` for frame 1, ``f10`` for frame 10 and so on. Once being in render_process.py, this string will be casted back to an integer like 1, 10, ... - **views:** Views to render. The default is *main*. Additional external resources ----------------------------- When customizing the render process, chances are high that you might want to have a look at the following two resources. The NUKE terminal documentation can be found here: `https://www.thefoundry.co.uk/products/nuke/developers/63/pythondevguide/command_line.html `_ A list of additional NUKE internal flags please can be found here: `http://help.thefoundry.co.uk/nuke/8.0/content/user_guide/configuring_nuke/command_line_operations.html `_ .. _render_process_module: The render_process module ------------------------- The render_process module will be executed in NUKE's terminal mode. Each thread calls this render batch script. .. image:: img/18.png The module includes two functions: ``framelog()`` and ``render()`` ``framelog()`` `````````````` This function creates an std out which will be fetched internally by smartRender to write log information. ``render()`` ```````````` This is the render function that will be executed to process a frame. Inside the function these commands will be executed: - Re-cast the frame argument back to an integer. - Open the nuke script. - Check for some script errors (disabled write node, error in tree) and log the information about the frame that was processed. - Try to render the frame and log the information. Trigger custom functions before/after render submission ------------------------------------------------------- In version 3.5 smartRender gained an additional feature to trigger any custom function before/after render submission. For that, you will find the following module in which you can implement your custom functions: ``/cpXX/smartRender/custom/render_callbacks.py`` Where ``path to smartRender_vX.X`` is the absolute path of your smartRender installation and ``cpXX`` is the python version you are using (Nuke14 and higher: cp39, Nuke13: cp37, Nuke12 and older: cp27). Here you can register any function to be triggered before and/or after a job gets submitted to smartRender. You can run any function that gets executed immediately when clicking smartRender's **render** button. This function will be executed -before- the actual render job gets processed. For that, define a function in the render_callbacks module and register it to smartRender using: ``osl.register_before_render_submit()`` You can also execute a function that gets triggered -after- the job has been send to the terminal. For that you need to register the callable using: ``osl.register_after_render_submit()`` **Note:** This function call expects a callable, so -do not- call the function directly in here by using round brackets. See the version up function in the render_callbacks module for an example callable to trigger. Trigger custom functions after a job has finished rendering ------------------------------------------------------------ The following describes how to trigger custom functions once a job has finished rendering. Please note that this differs from the previous section `Trigger custom functions before/after render submission' `_ which dealt with triggering custom functions before/after a job has been submitted. That being said, here we deal with events that trigger once a job has finished rendering all its frames. As an example, after render finished callbacks can be used to register your renderings into your production database, trigger additional jobs, move the renderings to a different location, zip it and send it to somewhere, etc. You are completely free in doing whatever you would like to do. In version 3.19 smartRender gained an additional feature to trigger any custom function after a job has finished rendering. For that, you will find the following module in which you can implement your custom functions: ``/cpXX/smartRender/custom/after_render_finished_callbacks.py`` Where ``path to smartRender_vX.X`` is the absolute path of your smartRender installation and ``cpXX`` is the python version you are using (Nuke14 and higher: cp39, Nuke13: cp37, Nuke12 and older: cp27). Here you can register any function to be triggered after a job that ran throgh smartRender has finished rendering. For that you need to register the callable using: ``osl.register_after_render_finished()`` **Note:** This function call expects a callable, so -do not- call the function directly in here by using round brackets. See the ``example_after_render_finished`` function in ``after_render_finished_callbacks.py`` for an example callable to trigger. This module gives you also a hint how to test your callables so you don't need to wait for a test rendering to finish to test your custom callbacks.