This AOV selector will show you all the layers a Exr read node, and allow you to select the pass you need and create merge node automatically.
Move the layers you want to process from the ‘Available Layers’ to the ‘Selected Layers’ list. This is a multi-select UI, so you can choose as many layers as you want.

Now, click the ‘Create Shuffle Nodes’ button, and watch the magic happen. The tool creates a Dot node for each Shuffle, connects it neatly, and even merges all the Shuffle nodes together using proper alignment.
I’m putting the Source code here heel free to edit and use it for you own use
import nuke
from PySide2 import QtWidgets, QtCore
# Global variable to keep reference to the UI window
layer_selection_window = None
class LayerSelectionUI(QtWidgets.QWidget):
def __init__(self, layers):
super(LayerSelectionUI, self).__init__()
# Sort layers alphabetically
layers.sort()
# Main Layout
layout = QtWidgets.QHBoxLayout()
# Left side (Available layers)
self.available_layers_list = QtWidgets.QListWidget()
self.available_layers_list.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) # Enable multi-select only with Ctrl/Shift
for layer in layers:
self.available_layers_list.addItem(layer)
layout.addWidget(self.available_layers_list)
# Button layout (now centered between lists, horizontally)
button_layout = QtWidgets.QVBoxLayout()
button_layout.addStretch(1) # Add stretch before buttons to center them
# Button to move selected layer to the right
move_layer_button = QtWidgets.QPushButton(">> Move Layer >>")
move_layer_button.clicked.connect(self.move_layer)
button_layout.addWidget(move_layer_button)
# Button to move selected layer back to the left
move_back_button = QtWidgets.QPushButton("<< Move Layer Back <<")
move_back_button.clicked.connect(self.move_back_layer)
button_layout.addWidget(move_back_button)
# Button to create Shuffle nodes
shuffle_button = QtWidgets.QPushButton("Create Shuffle Node(s)")
shuffle_button.clicked.connect(self.create_shuffle_nodes)
button_layout.addWidget(shuffle_button)
button_layout.addStretch(1) # Add stretch after buttons to center them
layout.addLayout(button_layout)
# Right side (Selected layers)
self.selected_layers_list = QtWidgets.QListWidget()
self.selected_layers_list.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) # Enable multi-select only with Ctrl/Shift
layout.addWidget(self.selected_layers_list)
self.setLayout(layout)
def move_layer(self):
selected_items = self.available_layers_list.selectedItems()
for item in selected_items:
# Move the item from available layers to selected layers
self.selected_layers_list.addItem(item.text())
self.available_layers_list.takeItem(self.available_layers_list.row(item))
def move_back_layer(self):
selected_items = self.selected_layers_list.selectedItems()
for item in selected_items:
# Move the item from selected layers back to available layers
self.available_layers_list.addItem(item.text())
self.selected_layers_list.takeItem(self.selected_layers_list.row(item))
def create_shuffle_nodes(self):
selected_items = [self.selected_layers_list.item(i).text() for i in range(self.selected_layers_list.count())]
# Get the selected node in Nuke (e.g., the Read node)
selected_node = nuke.selectedNode()
previous_merge_node = None # Track the previous Merge node for merging
# Set initial x and y positions for nodes
x_pos = selected_node.xpos()
y_pos = selected_node.ypos() + 100 # Start below the selected node
for index, layer in enumerate(selected_items):
# Create a Shuffle node
shuffle_node = nuke.createNode("Shuffle2")
shuffle_node.setInput(0, selected_node) # Connect each Shuffle to the original selected node
shuffle_node['in1'].setValue(layer) # Set the input layer for the Shuffle node
shuffle_node.setName(f"Shuffle_{layer}")
shuffle_node.setXpos(x_pos + index * 150) # Offset each Shuffle node horizontally
shuffle_node.setYpos(y_pos)
if previous_merge_node:
# Create a Merge node to combine with the previous Shuffle node
merge_node = nuke.createNode("Merge")
merge_node.setInput(0, previous_merge_node) # Connect input A to the previous Merge node
merge_node.setInput(1, shuffle_node) # Connect input B to the current Shuffle node
merge_node['operation'].setValue('plus') # Set the merge operation if desired
#merge_node.setName(f"Merge_{previous_merge_node.name()}_{shuffle_node.name()}")
merge_node.setXpos(x_pos + (index - 1) * 150 + 75) # Center the Merge node between Shuffle nodes
merge_node.setYpos(y_pos + 100) # Place below the Shuffle nodes
# Update previous_merge_node for the next iteration
previous_merge_node = merge_node
else:
# First merge, set the previous_merge_node to the first Shuffle node
previous_merge_node = shuffle_node
def get_layers_from_selected_node():
# Get the selected node in Nuke
node = nuke.selectedNode()
# Retrieve the layer names from the node's channels
layers = list(set([channel.split('.')[0] for channel in node.channels()]))
return layers
def show_layer_selection_ui():
global layer_selection_window
# Get the layers from the selected node in Nuke
layers = get_layers_from_selected_node()
# Create the UI and assign it to the global variable to prevent garbage collection
layer_selection_window = LayerSelectionUI(layers)
layer_selection_window.setWindowTitle('Layer Selection')
layer_selection_window.resize(600, 600)
layer_selection_window.show()
# To run in Nuke
if __name__ == '__main__':
show_layer_selection_ui()
Nuke Chatgpt