Bug fix
[blender-addons-contrib.git] / render_clay.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 bl_info = {
22     "name": "Clay Render",
23     "author": "Fabio Russo <ruesp83@libero.it>",
24     "version": (1, 2),
25     "blender": (2, 5, 6),
26     "location": "Render > Clay Render",
27     "description": "This script, applies a temporary material to all objects"\
28         " of the scene.",
29     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
30         "Scripts/Clay_Render",
31     "tracker_url": "https://projects.blender.org/tracker/index.php?"\
32         "func=detail&aid=22971",
33     "category": "Render"}
34
35 import bpy
36 from bpy.props import BoolProperty
37
38
39 def Create_Mat():
40     id = bpy.data.materials.new("Clay_Render")
41     #diffuse
42     id.diffuse_shader = "OREN_NAYAR"
43     id.diffuse_color = 0.800, 0.741, 0.536
44     id.diffuse_intensity = 1
45     id.roughness = 0.909
46     #specular
47     id.specular_shader = "COOKTORR"
48     id.specular_color = 1, 1, 1
49     id.specular_hardness = 10
50     id.specular_intensity = 0.115
51
52
53 def Alternative_Clay(self, msg):
54     Find = False
55     AM = None
56     i = 0
57     for mat in bpy.data.materials:
58         if (mat.Mat_Clay) and (not Find):
59             Find = True
60             AM = mat
61             i += 1
62
63         else:
64             if (mat.Mat_Clay):
65                 i += 1
66
67     if msg == True:
68         if (i == 1):
69             self.report({'INFO'}, "The material \"" + AM.name + "\" is set "\
70                 "as Clay!")
71         else:
72             if (i > 1):
73                 self.report({'WARNING'}, "Two or more materials are set as "\
74                     "Clay. \"" + AM.name + "\" will be used!")
75
76     return AM
77
78
79 def Get_Mat():
80     Mat = bpy.data.materials["Clay_Render"]
81     return Mat
82
83
84 def Exist_Mat():
85     if bpy.data.materials.get("Clay_Render"):
86         return True
87
88     else:
89         return False
90
91
92 class ClayPinned(bpy.types.Operator):
93     bl_idname = "render.clay_pinned"
94     bl_label = "Clay Pinned"
95     bl_description = "Clay Material Stores"
96
97     def execute(self, context):
98         if bpy.types.Scene.Clay_Pinned:
99             bpy.types.Scene.Clay_Pinned = False
100         else:
101             if bpy.types.Scene.Clay:
102                 if bpy.data.materials[0].users == 0:
103                     bpy.data.materials.remove(Get_Mat())
104                     bpy.types.Scene.Clay_Pinned = True
105
106             else:
107                 bpy.types.Scene.Clay_Pinned = True
108
109         return {'FINISHED'}
110
111
112 class CheckClay(bpy.types.Operator):
113     bl_idname = "render.clay"
114     bl_label = "Clay Render"
115     bl_description = "Use Clay Render"
116
117     def execute(self, context):
118         if bpy.types.Scene.Clay:
119             #Clay Attivato
120             ac = Alternative_Clay(self, True)
121             if ac is None:
122                 if not Exist_Mat():
123                     Create_Mat()
124                 rl = context.scene.render.layers
125                 rl.active.material_override = Get_Mat()
126
127             else:
128                 context.scene.render.layers.active.material_override = ac
129
130             bpy.types.Scene.Clay = False
131
132         else:
133             context.scene.render.layers.active.material_override = None
134             if bpy.types.Scene.Clay_Pinned:
135                 if bpy.data.materials[0].users == 0:
136                     bpy.data.materials.remove(Get_Mat())
137             bpy.types.Scene.Clay = True
138
139         return {'FINISHED'}
140
141
142 def draw_clay_render(self, context):
143     ok_clay = not bpy.types.Scene.Clay
144     pin = not bpy.types.Scene.Clay_Pinned
145
146     rnl = context.scene.render.layers.active
147     split = self.layout.split()
148     col = split.column()
149
150     col.operator(CheckClay.bl_idname, emboss=False, icon='CHECKBOX_HLT'\
151         if ok_clay else 'CHECKBOX_DEHLT')
152     col = split.column()
153     if Alternative_Clay(self, False) is None:
154         if Exist_Mat():
155             if (bpy.data.materials[0].users == 0) or (ok_clay):
156                 row = col.row(align=True)
157                 im = Get_Mat()
158                 row.prop(im, "diffuse_color", text="")
159                 row.operator(ClayPinned.bl_idname, text="", icon='PINNED'\
160                     if pin else 'UNPINNED')
161
162                 if ok_clay:
163                     row.active = True
164
165                 else:
166                     row.active = False
167
168             else:
169                 col.label('Clay Material applied to an object')
170
171     else:
172         col.label('Custom Material Clay')
173
174     self.layout.separator()
175
176
177 def draw_clay_options(self, context):
178     cm = context.material
179     layout = self.layout
180     layout.prop(cm, "Mat_Clay", text="Clay")
181
182
183 def draw_clay_warning(self, context):
184     if not bpy.types.Scene.Clay:
185         self.layout.label("Render Clay Enabled", "ERROR")
186
187
188 def register():
189     bpy.types.Scene.Clay = BoolProperty(
190     name='Clay Render',
191     description='Use Clay Render',
192     default=False)
193
194     bpy.types.Scene.Clay_Pinned = BoolProperty(
195     name='Clay Pinned',
196     description='Clay Material Stores',
197     default=False)
198
199     bpy.types.Material.Mat_Clay = bpy.props.BoolProperty(
200         name='Use as Clay',
201         description='Use as Clay',
202         default=False)
203
204     bpy.utils.register_class(ClayPinned)
205     bpy.utils.register_class(CheckClay)
206     bpy.types.RENDER_PT_render.prepend(draw_clay_render)
207     bpy.types.MATERIAL_PT_options.append(draw_clay_options)
208     bpy.types.INFO_HT_header.append(draw_clay_warning)
209
210
211 def unregister():
212     bpy.context.scene.render.layers.active.material_override = None
213     if (Exist_Mat()) and (bpy.data.materials[0].users == 0):
214         bpy.data.materials.remove(Get_Mat())
215     del bpy.types.Scene.Clay
216     del bpy.types.Scene.Clay_Pinned
217     del bpy.types.Material.Mat_Clay
218     bpy.utils.unregister_class(ClayPinned)
219     bpy.utils.unregister_class(CheckClay)
220     bpy.types.RENDER_PT_render.remove(draw_clay_render)
221     bpy.types.MATERIAL_PT_options.remove(draw_clay_options)
222     bpy.types.INFO_HT_header.remove(draw_clay_warning)
223
224
225 if __name__ == "__main__":
226     register()