render_renderslot.py 4.6 KB
Newer Older
kostex's avatar
kostex committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# ##### 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 #####

kostex's avatar
kostex committed
19 20
import bpy
from bpy.types import Operator
21
from bpy.props import IntProperty, BoolProperty
kostex's avatar
kostex committed
22 23 24 25
from sys import platform
from bpy.app.handlers import persistent


kostex's avatar
kostex committed
26 27
bl_info = {
    "name": "KTX RenderSlot",
kostex's avatar
kostex committed
28
    "description": "Display/select renderslot in the render tab",
kostex's avatar
kostex committed
29
    "author": "Roel Koster, @koelooptiemanna, irc:kostex",
30
    "version": (1, 3, 4),
kostex's avatar
kostex committed
31
    "blender": (2, 80, 0),
kostex's avatar
kostex committed
32
    "location": "Properties Editor > Render > Render",
kostex's avatar
kostex committed
33
    "warning": "",
34
    "doc_url": "https://github.com/kostex/blenderscripts/",
kostex's avatar
kostex committed
35
    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
kostex's avatar
kostex committed
36 37 38 39 40 41
    "category": "Render"}


nullpath = '/nul' if platform == 'win32' else '/dev/null'


42
class OccupiedSlots:
kostex's avatar
kostex committed
43 44 45
    data = '00000000'


46
class KTXRENDERSLOT_Prefs(bpy.types.AddonPreferences):
47 48
    bl_idname = __name__

kostex's avatar
kostex committed
49
    advanced_mode : bpy.props.BoolProperty(
50 51 52 53 54 55 56 57 58
        name="Advanced Mode",
        description="Gives the addon some advanced options",
        default=False)

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "advanced_mode")


59
class KTXRENDERSLOT_OT_Select(Operator):
kostex's avatar
kostex committed
60
    bl_label = "Select Render Slot"
61
    bl_idname = "ktxrenderslot.select"
kostex's avatar
kostex committed
62
    bl_description = ("Select Render Slot\n"
kostex's avatar
kostex committed
63 64
                      "Note: Dot next to number means slot has image data\n"
                      "[x] is active slot")
kostex's avatar
kostex committed
65

kostex's avatar
kostex committed
66
    number : IntProperty()
kostex's avatar
kostex committed
67 68 69 70 71 72 73

    def execute(self, context):
        bpy.data.images['Render Result'].render_slots.active_index = self.number

        return {'FINISHED'}


74 75 76 77 78
@persistent
def checkslots(scene):
    img = bpy.data.images['Render Result']
    active = img.render_slots.active_index
    slots = ''
79
    for i in range(0,len(img.render_slots)):
80 81 82 83 84 85
        img.render_slots.active_index = i
        try:
            img.save_render(nullpath)
            slots = slots + '1'
        except RuntimeError:
            slots = slots + '0'
kostex's avatar
kostex committed
86

87 88
    if scene.ktx_auto_advance_slot:
        active += 1
89 90 91 92 93
        if active == len(img.render_slots):
            img.render_slots.new()
            slots = slots + '0'

    scene.ktx_occupied_render_slots.data = slots
94
    img.render_slots.active_index = active
kostex's avatar
kostex committed
95 96 97


def ui(self, context):
98 99 100 101
    scn = context.scene
    layout = self.layout
    row = layout.row(align=True)
    row.alignment = 'LEFT'
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
    img = bpy.data.images['Render Result']
    active = img.render_slots.active_index
    if bpy.context.preferences.addons[__name__].preferences.advanced_mode:
        row.prop(scn, 'ktx_auto_advance_slot', text='Auto Advance')
    items = 0
    row = layout.row(align=True)
    row.alignment = 'EXPAND'
    for i in range(0,len(img.render_slots)):
        is_active = bool(i == active)
        test_active = bool(scn.ktx_occupied_render_slots.data[i] == '1')
        icons = "LAYER_ACTIVE" if test_active else "BLANK1"
        label = "[{}]".format(str(i + 1)) if is_active else str(i + 1)
        row.operator('ktxrenderslot.select', text=label, icon=icons).number = i
        items+=1
        if items == 8:
            items=0
            row = layout.row(align=True)
            row.alignment = 'EXPAND'
kostex's avatar
kostex committed
120 121


kostex's avatar
kostex committed
122
classes = (
123 124
    KTXRENDERSLOT_OT_Select,
    KTXRENDERSLOT_Prefs
kostex's avatar
kostex committed
125 126 127
)


kostex's avatar
kostex committed
128
def register():
kostex's avatar
kostex committed
129
    from bpy.utils import register_class
kostex's avatar
kostex committed
130

kostex's avatar
kostex committed
131
    bpy.types.RENDER_PT_context.prepend(ui)
132 133
    bpy.types.Scene.ktx_auto_advance_slot = BoolProperty(default=False, description="Auto Advance to Next Slot after a Render")
    bpy.types.Scene.ktx_occupied_render_slots = OccupiedSlots
kostex's avatar
kostex committed
134

135
    bpy.app.handlers.render_post.append(checkslots)
kostex's avatar
kostex committed
136

kostex's avatar
kostex committed
137 138 139
    for cls in classes:
        register_class(cls)

kostex's avatar
kostex committed
140

kostex's avatar
kostex committed
141
def unregister():
kostex's avatar
kostex committed
142
    from bpy.utils import unregister_class
143

kostex's avatar
kostex committed
144
    bpy.types.RENDER_PT_context.remove(ui)
kostex's avatar
kostex committed
145
    del bpy.types.Scene.ktx_occupied_render_slots
146
    del bpy.types.Scene.ktx_auto_advance_slot
kostex's avatar
kostex committed
147

148
    bpy.app.handlers.render_post.remove(checkslots)
kostex's avatar
kostex committed
149

kostex's avatar
kostex committed
150 151 152
    for cls in classes:
        unregister_class(cls)

kostex's avatar
kostex committed
153 154 155

if __name__ == "__main__":
    register()