Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save p2or/77a206ded20a3c73b20723ba31f47c25 to your computer and use it in GitHub Desktop.
Save p2or/77a206ded20a3c73b20723ba31f47c25 to your computer and use it in GitHub Desktop.
Auto file output node connection #Blender
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
"name": "Automatic File Output Node Connections",
"description": "",
"author": "Christian Brinkmann (p2or)",
"version": (0, 0, 3),
"blender": (2, 81, 0),
"location": "Compositor",
"warning": "", # used for warning icon and text in addons panel
"wiki_url": "",
"tracker_url": "",
"category": "Render"
}
import bpy
# ------------------------------------------------------------------------
# Operators
# ------------------------------------------------------------------------
class RV_OT_OutputSockets(bpy.types.Operator):
"""Add Slots to File Output Node"""
bl_idname = "rv.create_file_output_slots"
bl_label = "Create File Output Slots"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
nodes_selected = context.selected_nodes
inode, onode = ('R_LAYERS', 'OUTPUT_FILE')
tree = context.scene.node_tree
links = tree.links
nodes = tree.nodes
# Basic Error handling
out_nodes = [o for o in nodes_selected if o.type == onode]
if not out_nodes:
self.report({'ERROR'}, "No Output Node in Selection")
return {'CANCELLED'}
candidates = [n for n in nodes_selected if not n.type == onode]
if not candidates:
self.report({'ERROR'}, "Nothing selected")
return {'CANCELLED'}
# Sort nodes by location
if len(candidates) > 1:
candidates = sorted(candidates, key=lambda n: n.location.y, reverse=True)
# Lookup for nodes and their sockets
node_sockets = {}
for node in candidates:
out_sockets = {}
for o in node.outputs:
if o.enabled:
out_sockets.setdefault(o.name, o)
node_sockets.setdefault(node.name, {})["Outputs"] = out_sockets
# Naming of sockets per type of node
if node.type == inode:
if len(context.scene.view_layers) > 1:
socket_prefix = node.layer
elif len(bpy.data.scenes) > 1:
socket_prefix = "{}_{}".format(node.scene.name, node.layer)
else:
socket_prefix = node.label if node.label else node.name
elif node.type == 'IMAGE':
if node.label:
socket_prefix = node.label
elif node.image:
socket_prefix = path.splitext(node.image.name)[0]
else:
socket_prefix = node.name
else:
socket_prefix = node.label if node.label else node.name
# Handle spaces and dots in name strings
socket_prefix = socket_prefix.replace(" ", "").replace('.', '-')
# Add dynamic prefix to the dict
node_sockets[node.name]["OutSocketPrefix"] = socket_prefix
file_node = out_nodes[0]
file_node.width = 350
# Create slots and noodles
for key, val in node_sockets.items():
prefix = val.get("OutSocketPrefix")
for name, socket in val.get("Outputs").items():
file_socket_name = "{}_{}".format(prefix, name)
file_socket = file_node.layer_slots.new(file_socket_name)
links.new(socket, file_socket)
return {'FINISHED'}
# ------------------------------------------------------------------------
# Registration
# ------------------------------------------------------------------------
classes = (
RV_OT_OutputSockets,
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment