489df6ae5140bc53fb5fd252d19a518963262bab
[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_addon_info = {
22     "name": "Clay Render",
23     "author": "Fabio Russo <ruesp83@libero.it>",
24     "version": (1, 0),
25     "blender": (2, 5, 5),
26     "api": 33568,
27     "location": "Render > Clay Render",
28     "description": "This script, applies a temporary material to all objects"\
29         " of the scene.",
30     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
31         "Scripts/Clay_Render",
32     "tracker_url": "https://projects.blender.org/tracker/index.php?"\
33         "func=detail&aid=22971&group_id=153&atid=467",
34     "category": "Render"}
35
36 import bpy
37 from bpy.props import BoolProperty
38
39
40 def Create_Mat():
41     id = bpy.data.materials.new("Clay_Render")
42     #diffuse
43     id.diffuse_shader = "OREN_NAYAR"
44     id.diffuse_color = 0.800, 0.741, 0.536
45     id.diffuse_intensity = 1
46     id.roughness = 0.909
47     #specular
48     id.specular_shader = "COOKTORR"
49     id.specular_color = 1, 1, 1
50     id.specular_hardness = 10
51     id.specular_intensity = 0.115
52
53
54 def Alternative_Clay(self, msg):
55     Find = False
56     AM = None
57     i = 0
58     for mat in bpy.data.materials:
59         if (mat.Mat_Clay) and (not Find):
60             Find = True
61             AM = mat
62             i += 1
63
64         else:
65             if (mat.Mat_Clay):
66                 i += 1
67
68     if msg == True:
69         if (i == 1):
70             self.report({'INFO'}, "The material \"" + AM.name + "\" is set "\
71                 "as Clay!")
72         else:
73             if (i > 1):
74                 self.report({'WARNING'}, "Two or more materials are set as "\
75                     "Clay. \"" + AM.name + "\" will be used!")
76
77     return AM
78
79
80 def Get_Mat():
81     Mat = bpy.data.materials["Clay_Render"]
82     return Mat
83
84
85 def Exist_Mat():
86     if bpy.data.materials.get("Clay_Render"):
87         return True
88
89     else:
90         return False
91
92
93 class ClayPinned(bpy.types.Operator):
94     bl_idname = "render.clay_pinned"
95     bl_label = "Clay Pinned"
96     bl_description = "Clay Material Stores"
97
98     def execute(self, context):
99         if bpy.types.Scene.Clay_Pinned:
100             bpy.types.Scene.Clay_Pinned = False
101         else:
102             if bpy.types.Scene.Clay:
103                 if bpy.data.materials[0].users == 0:
104                     bpy.data.materials.remove(Get_Mat())
105                     bpy.types.Scene.Clay_Pinned = True
106
107             else:
108                 bpy.types.Scene.Clay_Pinned = True
109
110         return {'FINISHED'}
111
112
113 class CheckClay(bpy.types.Operator):
114     bl_idname = "render.clay"
115     bl_label = "Clay Render"
116     bl_description = "Use Clay Render"
117
118     def execute(self, context):
119         if bpy.types.Scene.Clay:
120             #Clay Attivato
121             ac = Alternative_Clay(self, True)
122             if ac is None:
123                 if not Exist_Mat():
124                     Create_Mat()
125                 rl = context.scene.render.layers
126                 rl.active.material_override = Get_Mat()
127
128             else:
129                 context.scene.render.layers.active.material_override = ac
130
131             bpy.types.Scene.Clay = False
132
133         else:
134             context.scene.render.layers.active.material_override = None
135             if bpy.types.Scene.Clay_Pinned:
136                 if bpy.data.materials[0].users == 0:
137                     bpy.data.materials.remove(Get_Mat())
138             bpy.types.Scene.Clay = True
139
140         return {'FINISHED'}
141
142
143 def draw_clay_render(self, context):
144     ok_clay = not bpy.types.Scene.Clay
145     pin = not bpy.types.Scene.Clay_Pinned
146
147     rnl = context.scene.render.layers.active
148     split = self.layout.split()
149     col = split.column()
150
151     col.operator(CheckClay.bl_idname, emboss=False, icon='CHECKBOX_HLT'\
152         if ok_clay else 'CHECKBOX_DEHLT')
153     col = split.column()
154     if Alternative_Clay(self, False) is None:
155         if Exist_Mat():
156             if (bpy.data.materials[0].users == 0) or (ok_clay):
157                 row = col.row(align=True)
158                 im = Get_Mat()
159                 row.prop(im, "diffuse_color", text="")
160                 row.operator(ClayPinned.bl_idname, text="", icon='PINNED'\
161                     if pin else 'UNPINNED')
162
163                 if ok_clay:
164                     row.active = True
165
166                 else:
167                     row.active = False
168
169             else:
170                 col.label('Clay Material applied to an object')
171
172     else:
173         col.label('Custom Material Clay')
174
175     self.layout.separator()
176
177
178 def draw_clay_options(self, context):
179     cm = context.material
180     layout = self.layout
181     layout.prop(cm, "Mat_Clay", text="Clay")
182
183
184 def register():
185     bpy.types.Scene.Clay = BoolProperty(
186     name='Clay Render',
187     description='Use Clay Render',
188     default=False)
189
190     bpy.types.Scene.Clay_Pinned = BoolProperty(
191     name='Clay Pinned',
192     description='Clay Material Stores',
193     default=False)
194
195     bpy.types.Material.Mat_Clay = bpy.props.BoolProperty(
196         name='Use as Clay',
197         description='Use as Clay',
198         default=False)
199
200     bpy.types.RENDER_PT_render.prepend(draw_clay_render)
201     bpy.types.MATERIAL_PT_options.append(draw_clay_options)
202
203
204 def unregister():
205     bpy.context.scene.render.layers.active.material_override = None
206     if (Exist_Mat()) and (bpy.data.materials[0].users == 0):
207         bpy.data.materials.remove(Get_Mat())
208     del bpy.types.Scene.Clay
209     del bpy.types.Scene.Clay_Pinned
210     del bpy.types.Material.Mat_Clay
211     bpy.types.RENDER_PT_render.remove(draw_clay_render)
212     bpy.types.MATERIAL_PT_options.remove(draw_clay_options)
213
214
215 if __name__ == "__main__":
216     register()