Amaranth Addon
[blender-addons-contrib.git] / amaranth / render / remember_layers.py
1 #  This program is free software; you can redistribute it and/or
2 #  modify it under the terms of the GNU General Public License
3 #  as published by the Free Software Foundation; either version 2
4 #  of the License, or (at your option) any later version.
5 #
6 #  This program is distributed in the hope that it will be useful,
7 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
8 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9 #  GNU General Public License for more details.
10 #
11 #  You should have received a copy of the GNU General Public License
12 #  along with this program; if not, write to the Free Software Foundation,
13 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 """
15 Remember Layers for Render
16 If you're doing lighting/rendering tasks, you'll probably have a bunch of
17 layers that you want/need to be enabled for final renders.
18
19 When tweaking lighting, or if somebody else has to open the file to check
20 something, you/they are likely to tweak the layers visibility and forget
21 which ones were needed for the render to look good.
22
23 In the Render Layers properties, you'll now find a "Save Current Layers for
24 Render" button, this will save the currently visible scene layers as those
25 that should be enabled for render. You can adjust this further by clicking
26 on the slots on the right.
27
28 Now all you need to do before saving your file for rendering is press the
29 "View Layers for Render". Find it on the Render Layers properties.
30 """
31
32 import bpy
33
34
35 # FEATURE: Set Layers to Render
36 class AMTH_SCENE_OT_layers_render_save(bpy.types.Operator):
37
38     """Save the current scene layers as those that should be enabled for final renders"""
39     bl_idname = "scene.amaranth_layers_render_save"
40     bl_label = "Save as Layers for Render"
41
42     def execute(self, context):
43         which = []
44         n = -1
45
46         for l in context.scene.layers:
47             n += 1
48             if l:
49                 which.append(n)
50
51         context.scene["amth_layers_for_render"] = which
52         self.report({"INFO"}, "Layers for Render Saved")
53
54         return {"FINISHED"}
55
56
57 class AMTH_SCENE_OT_layers_render_view(bpy.types.Operator):
58
59     """Enable the scene layers that should be active for final renders"""
60     bl_idname = "scene.amaranth_layers_render_view"
61     bl_label = "View Layers for Render"
62
63     def execute(self, context):
64         scene = context.scene
65         layers_render = scene["amth_layers_for_render"]
66
67         for window in bpy.context.window_manager.windows:
68             screen = window.screen
69
70             for area in screen.areas:
71                 if area.type == "VIEW_3D":
72                     override = {
73                         "window": window,
74                         "screen": screen,
75                         "scene": scene,
76                         "area": area,
77                         "region": area.regions[4],
78                         "blend_data": context.blend_data}
79
80                     if layers_render:
81                         bpy.ops.view3d.layers(
82                             override,
83                             nr=layers_render[0]+1,
84                             extend=False,
85                             toggle=False)
86
87                         for n in layers_render:
88                             context.scene.layers[n] = True
89                     else:
90                         bpy.ops.view3d.layers(
91                             override,
92                             nr=1,
93                             extend=False,
94                             toggle=False)
95                         self.report({"INFO"}, "No layers set for render")
96
97                     break
98
99         return {"FINISHED"}
100
101
102 class AMTH_SCENE_OT_layers_render_set_individual(bpy.types.Operator):
103
104     """Whether this layer should be enabled or not for final renders"""
105     bl_idname = "scene.amaranth_layers_render_set_individual"
106     bl_label = "Set This Layer for Render"
107
108     toggle = bpy.props.BoolProperty()
109     number = bpy.props.IntProperty()
110
111     def execute(self, context):
112         number = self.number
113
114         new_layers = []
115
116         for la in context.scene["amth_layers_for_render"]:
117             new_layers.append(la)
118
119         if len(context.scene["amth_layers_for_render"]) and number in new_layers:
120             new_layers.remove(number)
121         else:
122             new_layers.append(number)
123
124         # Remove Duplicates
125         new_layers = list(set(new_layers))
126         context.scene["amth_layers_for_render"] = new_layers
127
128         bpy.ops.scene.amaranth_layers_render_view()
129
130         return {"FINISHED"}
131
132
133 class AMTH_SCENE_OT_layers_render_clear(bpy.types.Operator):
134
135     """Clear layers for render"""
136     bl_idname = "scene.amaranth_layers_render_clear"
137     bl_label = "Clear Layers for Render"
138
139     def execute(self, context):
140
141         if context.scene.get("amth_layers_for_render"):
142             context.scene["amth_layers_for_render"] = []
143
144         return {"FINISHED"}
145
146
147 def ui_layers_for_render(self, context):
148
149     preferences = context.user_preferences.addons["amaranth"].preferences
150
151     if preferences.use_layers_for_render:
152         lfr_available = context.scene.get("amth_layers_for_render")
153         if lfr_available:
154             lfr = context.scene["amth_layers_for_render"]
155
156         layout = self.layout
157         layout.label("Layers for Rendering:")
158         split = layout.split()
159         col = split.column(align=True)
160         row = col.row(align=True)
161         row.operator(
162             AMTH_SCENE_OT_layers_render_save.bl_idname,
163             text="Replace Layers" if lfr_available else "Save Current Layers for Render",
164             icon="FILE_REFRESH" if lfr_available else "LAYER_USED")
165
166         if lfr_available:
167             row.operator(
168                 AMTH_SCENE_OT_layers_render_clear.bl_idname,
169                 icon="X", text="")
170             col = col.column(align=True)
171             col.enabled = True if lfr_available else False
172             col.operator(
173                 AMTH_SCENE_OT_layers_render_view.bl_idname,
174                 icon="RESTRICT_VIEW_OFF")
175
176             split = split.split()
177             col = split.column(align=True)
178             row = col.row(align=True)
179
180             for n in range(0, 5):
181                 row.operator(
182                     AMTH_SCENE_OT_layers_render_set_individual.bl_idname,
183                     text="",
184                     icon="LAYER_ACTIVE" if n in lfr else "BLANK1").number = n
185             row = col.row(align=True)
186             for n in range(10, 15):
187                 row.operator(
188                     AMTH_SCENE_OT_layers_render_set_individual.bl_idname,
189                     text="",
190                     icon="LAYER_ACTIVE" if n in lfr else "BLANK1").number = n
191
192             split = split.split()
193             col = split.column(align=True)
194             row = col.row(align=True)
195
196             for n in range(5, 10):
197                 row.operator(
198                     AMTH_SCENE_OT_layers_render_set_individual.bl_idname,
199                     text="",
200                     icon="LAYER_ACTIVE" if n in lfr else "BLANK1").number = n
201             row = col.row(align=True)
202             for n in range(15, 20):
203                 row.operator(
204                     AMTH_SCENE_OT_layers_render_set_individual.bl_idname,
205                     text="",
206                     icon="LAYER_ACTIVE" if n in lfr else "BLANK1").number = n
207
208
209 def ui_layers_for_render_header(self, context):
210
211     preferences = context.user_preferences.addons["amaranth"].preferences
212
213     if preferences.use_layers_for_render:
214         if context.scene.get("amth_layers_for_render"):
215             self.layout.operator(
216                 AMTH_SCENE_OT_layers_render_view.bl_idname,
217                 text="", icon="IMGDISPLAY")
218
219 # // FEATURE: Set Layers to Render
220
221
222 def register():
223     bpy.utils.register_class(AMTH_SCENE_OT_layers_render_clear)
224     bpy.utils.register_class(AMTH_SCENE_OT_layers_render_save)
225     bpy.utils.register_class(AMTH_SCENE_OT_layers_render_set_individual)
226     bpy.utils.register_class(AMTH_SCENE_OT_layers_render_view)
227     bpy.types.VIEW3D_HT_header.append(ui_layers_for_render_header)
228     bpy.types.RENDERLAYER_PT_layers.append(ui_layers_for_render)
229
230
231 def unregister():
232     bpy.utils.unregister_class(AMTH_SCENE_OT_layers_render_clear)
233     bpy.utils.unregister_class(AMTH_SCENE_OT_layers_render_save)
234     bpy.utils.unregister_class(AMTH_SCENE_OT_layers_render_set_individual)
235     bpy.utils.unregister_class(AMTH_SCENE_OT_layers_render_view)
236     bpy.types.VIEW3D_HT_header.remove(ui_layers_for_render_header)
237     bpy.types.RENDERLAYER_PT_layers.remove(ui_layers_for_render)