1 # gpl author: Ryan Inch (Imaginer)
4 from bpy
.types
import Menu
5 from . import utils_core
8 class TextureMenu(Menu
):
9 bl_label
= "Texture Options"
10 bl_idname
= "VIEW3D_MT_sv3_texture_menu"
13 def poll(self
, context
):
14 return utils_core
.get_mode() in (
20 def draw(self
, context
):
23 if utils_core
.get_mode() == 'SCULPT':
24 self
.sculpt(layout
, context
)
26 elif utils_core
.get_mode() == 'VERTEX_PAINT':
27 self
.vertpaint(layout
, context
)
30 self
.texpaint(layout
, context
)
32 def sculpt(self
, layout
, context
):
33 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
34 tex_slot
= has_brush
.texture_slot
if has_brush
else None
37 layout
.row().menu(Textures
.bl_idname
)
38 layout
.row().menu(TextureMapMode
.bl_idname
)
39 layout
.row().separator()
43 if tex_slot
.map_mode
!= '3D':
44 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE', 'AREA_PLANE'):
45 layout
.row().prop(tex_slot
, "use_rake", toggle
=True)
46 layout
.row().prop(tex_slot
, "use_random", toggle
=True)
49 layout
.row().prop(tex_slot
, "angle",
50 text
=utils_core
.PIW
+ "Angle", slider
=True)
52 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE') and tex_slot
.use_random
:
53 layout
.row().prop(tex_slot
, "random_angle",
54 text
=utils_core
.PIW
+ "Random Angle", slider
=True)
57 if tex_slot
.map_mode
== 'STENCIL':
58 if has_brush
.texture
and has_brush
.texture
.type == 'IMAGE':
59 layout
.row().operator("brush.stencil_fit_image_aspect")
61 layout
.row().operator("brush.stencil_reset_transform")
64 layout
.row().label(text
="No Texture Slot available", icon
="INFO")
66 def vertpaint(self
, layout
, context
):
67 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
68 tex_slot
= has_brush
.texture_slot
if has_brush
else None
71 layout
.row().menu(Textures
.bl_idname
)
72 layout
.row().menu(TextureMapMode
.bl_idname
)
76 if tex_slot
.map_mode
!= '3D':
77 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE'):
78 layout
.row().prop(tex_slot
, "use_rake", toggle
=True)
79 layout
.row().prop(tex_slot
, "use_random", toggle
=True)
82 layout
.row().prop(tex_slot
, "angle",
83 text
=utils_core
.PIW
+ "Angle", slider
=True)
85 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE') and tex_slot
.use_random
:
86 layout
.row().prop(tex_slot
, "random_angle",
87 text
=utils_core
.PIW
+ "Random Angle", slider
=True)
90 if tex_slot
.map_mode
== 'STENCIL':
91 if has_brush
.texture
and has_brush
.texture
.type == 'IMAGE':
92 layout
.row().operator("brush.stencil_fit_image_aspect")
94 layout
.row().operator("brush.stencil_reset_transform")
97 layout
.row().label(text
="No Texture Slot available", icon
="INFO")
99 def texpaint(self
, layout
, context
):
100 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
101 tex_slot
= has_brush
.texture_slot
if has_brush
else None
102 mask_tex_slot
= has_brush
.mask_texture_slot
if has_brush
else None
105 layout
.row().label(text
="Texture", icon
='TEXTURE')
108 layout
.row().menu(Textures
.bl_idname
)
109 layout
.row().menu(TextureMapMode
.bl_idname
)
113 if tex_slot
.map_mode
!= '3D':
114 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE'):
115 layout
.row().prop(tex_slot
, "use_rake", toggle
=True)
116 layout
.row().prop(tex_slot
, "use_random", toggle
=True)
119 layout
.row().prop(tex_slot
, "angle",
120 text
=utils_core
.PIW
+ "Angle", slider
=True)
122 if tex_slot
.map_mode
in ('RANDOM', 'VIEW_PLANE') and tex_slot
.use_random
:
123 layout
.row().prop(tex_slot
, "random_angle",
124 text
=utils_core
.PIW
+ "Random Angle", slider
=True)
127 if tex_slot
.map_mode
== 'STENCIL':
128 if has_brush
.texture
and has_brush
.texture
.type == 'IMAGE':
129 layout
.row().operator("brush.stencil_fit_image_aspect")
131 layout
.row().operator("brush.stencil_reset_transform")
134 layout
.row().label(text
="No Texture Slot available", icon
="INFO")
136 layout
.row().separator()
138 # Texture Mask Section
139 layout
.row().label(text
="Texture Mask", icon
='MOD_MASK')
142 layout
.row().menu(MaskTextures
.bl_idname
)
143 layout
.row().menu(MaskMapMode
.bl_idname
)
144 layout
.row().menu(MaskPressureModeMenu
.bl_idname
)
148 if mask_tex_slot
.mask_map_mode
in ('RANDOM', 'VIEW_PLANE'):
149 layout
.row().prop(mask_tex_slot
, "use_rake", toggle
=True)
150 layout
.row().prop(mask_tex_slot
, "use_random", toggle
=True)
153 layout
.row().prop(mask_tex_slot
, "angle",
154 text
=utils_core
.PIW
+ "Angle", icon_value
=5, slider
=True)
156 if mask_tex_slot
.mask_map_mode
in ('RANDOM', 'VIEW_PLANE') and mask_tex_slot
.use_random
:
157 layout
.row().prop(mask_tex_slot
, "random_angle",
158 text
=utils_core
.PIW
+ "Random Angle", slider
=True)
161 if mask_tex_slot
.mask_map_mode
== 'STENCIL':
162 if has_brush
.mask_texture
and has_brush
.mask_texture
.type == 'IMAGE':
163 layout
.row().operator("brush.stencil_fit_image_aspect")
165 prop
= layout
.row().operator("brush.stencil_reset_transform")
169 layout
.row().label(text
="Mask Texture not available", icon
="INFO")
172 class Textures(Menu
):
173 bl_label
= "Brush Texture"
174 bl_idname
= "VIEW3D_MT_sv3_texture_list"
177 if utils_core
.get_mode() == 'SCULPT':
178 datapath
= "tool_settings.sculpt.brush.texture"
180 elif utils_core
.get_mode() == 'VERTEX_PAINT':
181 datapath
= "tool_settings.vertex_paint.brush.texture"
183 elif utils_core
.get_mode() == 'TEXTURE_PAINT':
184 datapath
= "tool_settings.image_paint.brush.texture"
191 def draw(self
, context
):
192 datapath
= self
.init()
193 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
194 current_texture
= eval("bpy.context.{}".format(datapath
)) if \
198 # get the current texture's name
200 current_texture
= current_texture
.name
202 layout
.row().label(text
="Brush Texture")
203 layout
.row().separator()
205 # add an item to set the texture to None
206 utils_core
.menuprop(layout
.row(), "None", "None",
207 datapath
, icon
='RADIOBUT_OFF', disable
=True,
208 disable_icon
='RADIOBUT_ON',
209 custom_disable_exp
=(None, current_texture
),
213 for item
in bpy
.data
.textures
:
214 utils_core
.menuprop(layout
.row(), item
.name
,
215 'bpy.data.textures["%s"]' % item
.name
,
216 datapath
, icon
='RADIOBUT_OFF',
218 disable_icon
='RADIOBUT_ON',
219 custom_disable_exp
=(item
.name
, current_texture
),
223 class TextureMapMode(Menu
):
224 bl_label
= "Brush Mapping"
225 bl_idname
= "VIEW3D_MT_sv3_texture_map_mode"
227 def draw(self
, context
):
229 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
231 layout
.row().label(text
="Brush Mapping")
232 layout
.row().separator()
235 if utils_core
.get_mode() == 'SCULPT':
236 path
= "tool_settings.sculpt.brush.texture_slot.map_mode"
239 for item
in has_brush
. \
240 texture_slot
.bl_rna
.properties
['map_mode'].enum_items
:
242 layout
.row(), item
.name
, item
.identifier
, path
,
245 disable_icon
='RADIOBUT_ON'
247 elif utils_core
.get_mode() == 'VERTEX_PAINT':
248 path
= "tool_settings.vertex_paint.brush.texture_slot.map_mode"
251 for item
in has_brush
. \
252 texture_slot
.bl_rna
.properties
['map_mode'].enum_items
:
254 layout
.row(), item
.name
, item
.identifier
, path
,
257 disable_icon
='RADIOBUT_ON'
260 path
= "tool_settings.image_paint.brush.texture_slot.map_mode"
263 for item
in has_brush
. \
264 texture_slot
.bl_rna
.properties
['map_mode'].enum_items
:
266 layout
.row(), item
.name
, item
.identifier
, path
,
269 disable_icon
='RADIOBUT_ON'
272 layout
.row().label(text
="No brushes available", icon
="INFO")
275 class MaskTextures(Menu
):
276 bl_label
= "Mask Texture"
277 bl_idname
= "VIEW3D_MT_sv3_mask_texture_list"
279 def draw(self
, context
):
281 datapath
= "tool_settings.image_paint.brush.mask_texture"
282 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
283 current_texture
= eval("bpy.context.{}".format(datapath
)) if \
286 layout
.row().label(text
="Mask Texture")
287 layout
.row().separator()
290 # get the current texture's name
292 current_texture
= current_texture
.name
294 # add an item to set the texture to None
296 layout
.row(), "None", "None",
297 datapath
, icon
='RADIOBUT_OFF', disable
=True,
298 disable_icon
='RADIOBUT_ON',
299 custom_disable_exp
=(None, current_texture
),
304 for item
in bpy
.data
.textures
:
306 layout
.row(), item
.name
, 'bpy.data.textures["%s"]' % item
.name
,
307 datapath
, icon
='RADIOBUT_OFF', disable
=True,
308 disable_icon
='RADIOBUT_ON',
309 custom_disable_exp
=(item
.name
, current_texture
),
313 layout
.row().label(text
="No brushes available", icon
="INFO")
316 class MaskMapMode(Menu
):
317 bl_label
= "Mask Mapping"
318 bl_idname
= "VIEW3D_MT_sv3_mask_map_mode"
320 def draw(self
, context
):
322 path
= "tool_settings.image_paint.brush.mask_texture_slot.mask_map_mode"
323 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
325 layout
.row().label(text
="Mask Mapping")
326 layout
.row().separator()
329 mask_texture_slot
.bl_rna
.properties
['mask_map_mode'].enum_items
333 layout
.row(), item
.name
, item
.identifier
, path
,
336 disable_icon
='RADIOBUT_ON'
339 layout
.row().label(text
="No brushes available", icon
="INFO")
342 class TextureAngleSource(Menu
):
343 bl_label
= "Texture Angle Source"
344 bl_idname
= "VIEW3D_MT_sv3_texture_angle_source"
346 def draw(self
, context
):
348 has_brush
= utils_core
.get_brush_link(context
, types
="brush")
351 if utils_core
.get_mode() == 'SCULPT':
353 bl_rna
.properties
['texture_angle_source_random'].enum_items
354 path
= "tool_settings.sculpt.brush.texture_angle_source_random"
356 elif utils_core
.get_mode() == 'VERTEX_PAINT':
358 bl_rna
.properties
['texture_angle_source_random'].enum_items
359 path
= "tool_settings.vertex_paint.brush.texture_angle_source_random"
363 bl_rna
.properties
['texture_angle_source_random'].enum_items
364 path
= "tool_settings.image_paint.brush.texture_angle_source_random"
369 layout
.row(), item
[0], item
[1], path
,
372 disable_icon
='RADIOBUT_ON'
375 layout
.row().label(text
="No brushes available", icon
="INFO")
377 class MaskPressureModeMenu(Menu
):
378 bl_label
= "Mask Pressure Mode"
379 bl_idname
= "VIEW3D_MT_sv3_mask_pressure_mode_menu"
381 def draw(self
, context
):
383 path
= "tool_settings.image_paint.brush.use_pressure_masking"
385 layout
.row().label(text
="Mask Pressure Mode")
386 layout
.row().separator()
389 for item
in context
.tool_settings
.image_paint
.brush
. \
390 bl_rna
.properties
['use_pressure_masking'].enum_items
:
392 layout
.row(), item
.name
, item
.identifier
, path
,
395 disable_icon
='RADIOBUT_ON'
411 bpy
.utils
.register_class(cls
)
415 bpy
.utils
.unregister_class(cls
)