Amaranth Addon
[blender-addons-contrib.git] / amaranth / render / samples_scene.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 Cycles: Samples per Scene
16
17 When working in production, it's often more convenient to do lighting and
18 compositing in different scenes (so you can later append the comp scene
19     to bring together nodes, settings, lamps, RenderLayers).
20
21 This would lead to work with more than one scene. When doing render tests
22 you want to know at a glance how many samples the other scenes have,
23 without manually switching. This is the idea behind the feature.
24
25 Find it on the Sampling panel, on Render properties.
26 Developed during Caminandes Open Movie Project
27 """
28
29 import bpy
30 from amaranth import utils
31
32
33 class AMTH_RENDER_OT_cycles_samples_percentage_set(bpy.types.Operator):
34
35     """Save the current number of samples per shader as final (gets saved in .blend)"""
36     bl_idname = "scene.amaranth_cycles_samples_percentage_set"
37     bl_label = "Set as Render Samples"
38
39     def execute(self, context):
40         cycles = context.scene.cycles
41         cycles.use_samples_final = True
42
43         context.scene["amth_cycles_samples_final"] = [
44             cycles.diffuse_samples,
45             cycles.glossy_samples,
46             cycles.transmission_samples,
47             cycles.ao_samples,
48             cycles.mesh_light_samples,
49             cycles.subsurface_samples,
50             cycles.volume_samples]
51
52         self.report({"INFO"}, "Render Samples Saved")
53
54         return {"FINISHED"}
55
56
57 class AMTH_RENDER_OT_cycles_samples_percentage(bpy.types.Operator):
58
59     """Set a percentage of the final render samples"""
60     bl_idname = "scene.amaranth_cycles_samples_percentage"
61     bl_label = "Set Render Samples Percentage"
62
63     percent = bpy.props.IntProperty(
64         name="Percentage",
65         description="Percentage to divide render samples by",
66         subtype="PERCENTAGE", default=0)
67
68     def execute(self, context):
69         percent = self.percent
70         cycles = context.scene.cycles
71         cycles_samples_final = context.scene["amth_cycles_samples_final"]
72
73         cycles.use_samples_final = False
74
75         if percent == 100:
76             cycles.use_samples_final = True
77
78         cycles.diffuse_samples = int((cycles_samples_final[0] / 100) * percent)
79         cycles.glossy_samples = int((cycles_samples_final[1] / 100) * percent)
80         cycles.transmission_samples = int(
81             (cycles_samples_final[2] / 100) * percent)
82         cycles.ao_samples = int((cycles_samples_final[3] / 100) * percent)
83         cycles.mesh_light_samples = int(
84             (cycles_samples_final[4] / 100) * percent)
85         cycles.subsurface_samples = int(
86             (cycles_samples_final[5] / 100) * percent)
87         cycles.volume_samples = int((cycles_samples_final[6] / 100) * percent)
88
89         return {"FINISHED"}
90
91
92 def render_cycles_scene_samples(self, context):
93
94     layout = self.layout
95     scene = context.scene
96     render = scene.render
97     if utils.cycles_exists():
98         cscene = scene.cycles
99         list_sampling = scene.amaranth_cycles_list_sampling
100
101     # Set Render Samples
102     if utils.cycles_exists() and cscene.progressive == "BRANCHED_PATH":
103         layout.separator()
104         split = layout.split()
105         col = split.column()
106
107         col.operator(
108             AMTH_RENDER_OT_cycles_samples_percentage_set.bl_idname,
109             text="%s" %
110             "Set as Render Samples" if cscene.use_samples_final else "Set New Render Samples",
111             icon="%s" %
112             "PINNED" if cscene.use_samples_final else "UNPINNED")
113
114         col = split.column()
115         row = col.row(align=True)
116         row.enabled = True if scene.get("amth_cycles_samples_final") else False
117
118         row.operator(
119             AMTH_RENDER_OT_cycles_samples_percentage.bl_idname,
120             text="100%").percent = 100
121         row.operator(
122             AMTH_RENDER_OT_cycles_samples_percentage.bl_idname,
123             text="75%").percent = 75
124         row.operator(
125             AMTH_RENDER_OT_cycles_samples_percentage.bl_idname,
126             text="50%").percent = 50
127         row.operator(
128             AMTH_RENDER_OT_cycles_samples_percentage.bl_idname,
129             text="25%").percent = 25
130
131     # List Samples
132     if (len(scene.render.layers) > 1) or (len(bpy.data.scenes) > 1):
133
134         box = layout.box()
135         row = box.row(align=True)
136         col = row.column(align=True)
137
138         row = col.row(align=True)
139         row.alignment = "LEFT"
140         row.prop(scene, "amaranth_cycles_list_sampling",
141                  icon="%s" % "TRIA_DOWN" if list_sampling else "TRIA_RIGHT",
142                  emboss=False)
143
144     if list_sampling:
145         if len(scene.render.layers) == 1 and render.layers[0].samples == 0:
146             pass
147         else:
148             col.separator()
149             col.label(text="RenderLayers:", icon="RENDERLAYERS")
150
151             for rl in scene.render.layers:
152                 row = col.row(align=True)
153                 row.label(rl.name, icon="BLANK1")
154                 row.prop(
155                     rl, "samples", text="%s" %
156                     "Samples" if rl.samples > 0 else "Automatic (%s)" %
157                     (cscene.aa_samples if cscene.progressive == "BRANCHED_PATH" else cscene.samples))
158
159         if (len(bpy.data.scenes) > 1):
160             col.separator()
161
162             col.label(text="Scenes:", icon="SCENE_DATA")
163
164             if utils.cycles_exists() and cscene.progressive == "PATH":
165                 for s in bpy.data.scenes:
166                     if s != scene:
167                         row = col.row(align=True)
168                         if s.render.engine == "CYCLES":
169                             cscene = s.cycles
170
171                             row.label(s.name)
172                             row.prop(cscene, "samples", icon="BLANK1")
173                         else:
174                             row.label(
175                                 text="Scene: '%s' is not using Cycles" %
176                                 s.name)
177             else:
178                 for s in bpy.data.scenes:
179                     if s != scene:
180                         row = col.row(align=True)
181                         if s.render.engine == "CYCLES":
182                             cscene = s.cycles
183
184                             row.label(s.name, icon="BLANK1")
185                             row.prop(cscene, "aa_samples",
186                                      text="AA Samples")
187                         else:
188                             row.label(
189                                 text="Scene: '%s' is not using Cycles" %
190                                 s.name)
191
192
193 def init():
194     scene = bpy.types.Scene
195     if utils.cycles_exists():
196         scene.amaranth_cycles_list_sampling = bpy.props.BoolProperty(
197             default=False,
198             name="Samples Per:")
199
200         bpy.types.CyclesRenderSettings.use_samples_final = bpy.props.BoolProperty(
201             name="Use Final Render Samples",
202             description="Use current shader samples as final render samples",
203             default=False)
204
205
206 def clear():
207     wm = bpy.context.window_manager
208     for p in ("amarath_cycles_list_sampling", "use_samples_final"):
209         if p in wm:
210             del wm[p]
211
212
213 def register():
214     init()
215     bpy.utils.register_class(AMTH_RENDER_OT_cycles_samples_percentage)
216     bpy.utils.register_class(AMTH_RENDER_OT_cycles_samples_percentage_set)
217     if utils.cycles_exists():
218         bpy.types.CyclesRender_PT_sampling.append(render_cycles_scene_samples)
219
220
221 def unregister():
222     bpy.utils.unregister_class(AMTH_RENDER_OT_cycles_samples_percentage)
223     bpy.utils.unregister_class(AMTH_RENDER_OT_cycles_samples_percentage_set)
224     if utils.cycles_exists():
225         bpy.types.CyclesRender_PT_sampling.remove(render_cycles_scene_samples)
226     clear()