2.5 UI:
[blender.git] / release / scripts / startup / bl_ui / space_view3d_toolbar.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 import bpy
21
22
23 class View3DPanel():
24     bl_space_type = 'VIEW_3D'
25     bl_region_type = 'TOOLS'
26
27
28 # **************** standard tool clusters ******************
29
30 # History/Repeat tools
31 def draw_repeat_tools(context, layout):
32     col = layout.column(align=True)
33     col.label(text="Repeat:")
34     col.operator("screen.repeat_last")
35     col.operator("screen.repeat_history", text="History...")
36
37
38 # Keyframing tools
39 def draw_keyframing_tools(context, layout):
40     col = layout.column(align=True)
41     col.label(text="Keyframes:")
42     row = col.row()
43     row.operator("anim.keyframe_insert_menu", text="Insert")
44     row.operator("anim.keyframe_delete_v3d", text="Remove")
45
46
47 # Grease Pencil tools
48 def draw_gpencil_tools(context, layout):
49     col = layout.column(align=True)
50
51     col.label(text="Grease Pencil:")
52
53     row = col.row()
54     row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
55     row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
56     row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
57
58     row = col.row()
59     row.prop(context.tool_settings, "use_grease_pencil_sessions")
60
61 # ********** default tools for objectmode ****************
62
63
64 class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
65     bl_context = "objectmode"
66     bl_label = "Object Tools"
67
68     def draw(self, context):
69         layout = self.layout
70
71         col = layout.column(align=True)
72         col.label(text="Transform:")
73         col.operator("transform.translate")
74         col.operator("transform.rotate")
75         col.operator("transform.resize", text="Scale")
76
77         col = layout.column(align=True)
78         col.operator("object.origin_set", text="Origin")
79
80         col = layout.column(align=True)
81         col.label(text="Object:")
82         col.operator("object.duplicate_move")
83         col.operator("object.delete")
84         col.operator("object.join")
85
86         active_object = context.active_object
87         if active_object and active_object.type == 'MESH':
88
89             col = layout.column(align=True)
90             col.label(text="Shading:")
91             col.operator("object.shade_smooth", text="Smooth")
92             col.operator("object.shade_flat", text="Flat")
93
94         draw_keyframing_tools(context, layout)
95
96         col = layout.column(align=True)
97         col.label(text="Motion Paths:")
98         col.operator("object.paths_calculate", text="Calculate Paths")
99         col.operator("object.paths_clear", text="Clear Paths")
100
101         draw_repeat_tools(context, layout)
102
103         draw_gpencil_tools(context, layout)
104
105 # ********** default tools for editmode_mesh ****************
106
107
108 class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
109     bl_context = "mesh_edit"
110     bl_label = "Mesh Tools"
111
112     def draw(self, context):
113         layout = self.layout
114
115         col = layout.column(align=True)
116         col.label(text="Transform:")
117         col.operator("transform.translate")
118         col.operator("transform.rotate")
119         col.operator("transform.resize", text="Scale")
120         col.operator("transform.shrink_fatten", text="Along Normal")
121
122         col = layout.column(align=True)
123         col.label(text="Deform:")
124         col.operator("transform.edge_slide")
125         col.operator("mesh.rip_move")
126         col.operator("mesh.noise")
127         col.operator("mesh.vertices_smooth")
128
129         col = layout.column(align=True)
130         col.label(text="Add:")
131         col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
132         col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
133         col.operator("mesh.subdivide")
134         col.operator("mesh.loopcut_slide")
135         col.operator("mesh.duplicate_move", text="Duplicate")
136         col.operator("mesh.spin")
137         col.operator("mesh.screw")
138
139         col = layout.column(align=True)
140         col.label(text="Remove:")
141         col.operator("mesh.delete")
142         col.operator("mesh.merge")
143         col.operator("mesh.remove_doubles")
144
145         col = layout.column(align=True)
146         col.label(text="Normals:")
147         col.operator("mesh.normals_make_consistent", text="Recalculate")
148         col.operator("mesh.flip_normals", text="Flip Direction")
149
150         col = layout.column(align=True)
151         col.label(text="UV Mapping:")
152         col.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
153         col.operator("mesh.mark_seam")
154         col.operator("mesh.mark_seam", text="Clear Seam").clear = True
155
156         col = layout.column(align=True)
157         col.label(text="Shading:")
158         col.operator("mesh.faces_shade_smooth", text="Smooth")
159         col.operator("mesh.faces_shade_flat", text="Flat")
160
161         draw_repeat_tools(context, layout)
162
163         draw_gpencil_tools(context, layout)
164
165
166 class VIEW3D_PT_tools_meshedit_options(View3DPanel, bpy.types.Panel):
167     bl_context = "mesh_edit"
168     bl_label = "Mesh Options"
169
170     def draw(self, context):
171         layout = self.layout
172
173         ob = context.active_object
174
175         if ob:
176             mesh = context.active_object.data
177             col = layout.column(align=True)
178             col.prop(mesh, "use_mirror_x")
179             sub = col.column()
180             sub.active = ob.data.use_mirror_x
181             sub.prop(mesh, "use_mirror_topology")
182
183             ts = context.tool_settings
184
185             col.label("Edge Select Mode")
186             col.prop(ts, "edge_path_mode", text="")
187             col.prop(context.tool_settings, "edge_path_live_unwrap")
188
189 # ********** default tools for editmode_curve ****************
190
191
192 class VIEW3D_PT_tools_curveedit(View3DPanel, bpy.types.Panel):
193     bl_context = "curve_edit"
194     bl_label = "Curve Tools"
195
196     def draw(self, context):
197         layout = self.layout
198
199         col = layout.column(align=True)
200         col.label(text="Transform:")
201         col.operator("transform.translate")
202         col.operator("transform.rotate")
203         col.operator("transform.resize", text="Scale")
204
205         col = layout.column(align=True)
206         col.operator("transform.transform", text="Tilt").mode = 'TILT'
207         col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN'
208
209         col = layout.column(align=True)
210         col.label(text="Curve:")
211         col.operator("curve.duplicate")
212         col.operator("curve.delete")
213         col.operator("curve.cyclic_toggle")
214         col.operator("curve.switch_direction")
215         col.operator("curve.spline_type_set")
216
217         col = layout.column(align=True)
218         col.label(text="Handles:")
219         row = col.row()
220         row.operator("curve.handle_type_set", text="Auto").type = 'AUTOMATIC'
221         row.operator("curve.handle_type_set", text="Vector").type = 'VECTOR'
222         row = col.row()
223         row.operator("curve.handle_type_set", text="Align").type = 'ALIGNED'
224         row.operator("curve.handle_type_set", text="Free").type = 'FREE_ALIGN'
225
226         col = layout.column(align=True)
227         col.label(text="Modeling:")
228         col.operator("curve.extrude")
229         col.operator("curve.subdivide")
230
231         draw_repeat_tools(context, layout)
232
233         draw_gpencil_tools(context, layout)
234
235 # ********** default tools for editmode_surface ****************
236
237
238 class VIEW3D_PT_tools_surfaceedit(View3DPanel, bpy.types.Panel):
239     bl_context = "surface_edit"
240     bl_label = "Surface Tools"
241
242     def draw(self, context):
243         layout = self.layout
244
245         col = layout.column(align=True)
246         col.label(text="Transform:")
247         col.operator("transform.translate")
248         col.operator("transform.rotate")
249         col.operator("transform.resize", text="Scale")
250
251         col = layout.column(align=True)
252         col.label(text="Curve:")
253         col.operator("curve.duplicate")
254         col.operator("curve.delete")
255         col.operator("curve.cyclic_toggle")
256         col.operator("curve.switch_direction")
257
258         col = layout.column(align=True)
259         col.label(text="Modeling:")
260         col.operator("curve.extrude")
261         col.operator("curve.subdivide")
262
263         draw_repeat_tools(context, layout)
264
265         draw_gpencil_tools(context, layout)
266
267 # ********** default tools for editmode_text ****************
268
269
270 class VIEW3D_PT_tools_textedit(View3DPanel, bpy.types.Panel):
271     bl_context = "text_edit"
272     bl_label = "Text Tools"
273
274     def draw(self, context):
275         layout = self.layout
276
277         col = layout.column(align=True)
278         col.label(text="Text Edit:")
279         col.operator("font.text_copy", text="Copy")
280         col.operator("font.text_cut", text="Cut")
281         col.operator("font.text_paste", text="Paste")
282
283         col = layout.column(align=True)
284         col.label(text="Set Case:")
285         col.operator("font.case_set", text="To Upper").case = 'UPPER'
286         col.operator("font.case_set", text="To Lower").case = 'LOWER'
287
288         col = layout.column(align=True)
289         col.label(text="Style:")
290         col.operator("font.style_toggle", text="Bold").style = 'BOLD'
291         col.operator("font.style_toggle", text="Italic").style = 'ITALIC'
292         col.operator("font.style_toggle", text="Underline").style = 'UNDERLINE'
293
294         draw_repeat_tools(context, layout)
295
296
297 # ********** default tools for editmode_armature ****************
298
299
300 class VIEW3D_PT_tools_armatureedit(View3DPanel, bpy.types.Panel):
301     bl_context = "armature_edit"
302     bl_label = "Armature Tools"
303
304     def draw(self, context):
305         layout = self.layout
306
307         col = layout.column(align=True)
308         col.label(text="Transform:")
309         col.operator("transform.translate")
310         col.operator("transform.rotate")
311         col.operator("transform.resize", text="Scale")
312
313         col = layout.column(align=True)
314         col.label(text="Bones:")
315         col.operator("armature.bone_primitive_add", text="Add")
316         col.operator("armature.duplicate_move", text="Duplicate")
317         col.operator("armature.delete", text="Delete")
318
319         col = layout.column(align=True)
320         col.label(text="Modeling:")
321         col.operator("armature.extrude_move")
322         col.operator("armature.subdivide", text="Subdivide")
323
324         draw_repeat_tools(context, layout)
325
326         draw_gpencil_tools(context, layout)
327
328
329 class VIEW3D_PT_tools_armatureedit_options(View3DPanel, bpy.types.Panel):
330     bl_context = "armature_edit"
331     bl_label = "Armature Options"
332
333     def draw(self, context):
334         layout = self.layout
335
336         arm = context.active_object.data
337
338         col = layout.column(align=True)
339         col.prop(arm, "use_mirror_x")
340
341 # ********** default tools for editmode_mball ****************
342
343
344 class VIEW3D_PT_tools_mballedit(View3DPanel, bpy.types.Panel):
345     bl_context = "mball_edit"
346     bl_label = "Meta Tools"
347
348     def draw(self, context):
349         layout = self.layout
350
351         col = layout.column(align=True)
352         col.label(text="Transform:")
353         col.operator("transform.translate")
354         col.operator("transform.rotate")
355         col.operator("transform.resize", text="Scale")
356
357         draw_repeat_tools(context, layout)
358
359         draw_gpencil_tools(context, layout)
360
361 # ********** default tools for editmode_lattice ****************
362
363
364 class VIEW3D_PT_tools_latticeedit(View3DPanel, bpy.types.Panel):
365     bl_context = "lattice_edit"
366     bl_label = "Lattice Tools"
367
368     def draw(self, context):
369         layout = self.layout
370
371         col = layout.column(align=True)
372         col.label(text="Transform:")
373         col.operator("transform.translate")
374         col.operator("transform.rotate")
375         col.operator("transform.resize", text="Scale")
376
377         col = layout.column(align=True)
378         col.operator("lattice.make_regular")
379
380         draw_repeat_tools(context, layout)
381
382         draw_gpencil_tools(context, layout)
383
384
385 # ********** default tools for posemode ****************
386
387
388 class VIEW3D_PT_tools_posemode(View3DPanel, bpy.types.Panel):
389     bl_context = "posemode"
390     bl_label = "Pose Tools"
391
392     def draw(self, context):
393         layout = self.layout
394
395         col = layout.column(align=True)
396         col.label(text="Transform:")
397         col.operator("transform.translate")
398         col.operator("transform.rotate")
399         col.operator("transform.resize", text="Scale")
400
401         col = layout.column(align=True)
402         col.label(text="In-Between:")
403         row = col.row()
404         row.operator("pose.push", text="Push")
405         row.operator("pose.relax", text="Relax")
406         col.operator("pose.breakdown", text="Breakdowner")
407
408         col = layout.column(align=True)
409         col.label(text="Pose:")
410         row = col.row()
411         row.operator("pose.copy", text="Copy")
412         row.operator("pose.paste", text="Paste")
413
414         col = layout.column(align=True)
415         col.operator("poselib.pose_add", text="Add To Library")
416
417         draw_keyframing_tools(context, layout)
418
419         col = layout.column(align=True)
420         col.label(text="Motion Paths:")
421         col.operator("pose.paths_calculate", text="Calculate Paths")
422         col.operator("pose.paths_clear", text="Clear Paths")
423
424         draw_repeat_tools(context, layout)
425
426         draw_gpencil_tools(context, layout)
427
428
429 class VIEW3D_PT_tools_posemode_options(View3DPanel, bpy.types.Panel):
430     bl_context = "posemode"
431     bl_label = "Pose Options"
432
433     def draw(self, context):
434         layout = self.layout
435
436         arm = context.active_object.data
437
438         col = layout.column(align=True)
439         col.prop(arm, "use_auto_ik")
440
441 # ********** default tools for paint modes ****************
442
443
444 class PaintPanel():
445     bl_space_type = 'VIEW_3D'
446     bl_region_type = 'TOOLS'
447
448     @staticmethod
449     def paint_settings(context):
450         ts = context.tool_settings
451
452         if context.sculpt_object:
453             return ts.sculpt
454         elif context.vertex_paint_object:
455             return ts.vertex_paint
456         elif context.weight_paint_object:
457             return ts.weight_paint
458         elif context.image_paint_object:
459             return ts.image_paint
460         elif context.particle_edit_object:
461             return ts.particle_edit
462
463         return None
464
465
466 class VIEW3D_PT_tools_brush(PaintPanel, bpy.types.Panel):
467     bl_label = "Brush"
468
469     @classmethod
470     def poll(cls, context):
471         return cls.paint_settings(context)
472
473     def draw(self, context):
474         layout = self.layout
475
476         settings = __class__.paint_settings(context)
477         brush = settings.brush
478
479         if not context.particle_edit_object:
480             col = layout.split().column()
481             col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
482
483         # Particle Mode #
484
485         # XXX This needs a check if psys is editable.
486         if context.particle_edit_object:
487             # XXX Select Particle System
488             layout.column().prop(settings, "tool", expand=True)
489
490             if settings.tool != 'NONE':
491                 col = layout.column()
492                 col.prop(brush, "size", slider=True)
493                 if settings.tool != 'ADD':
494                     col.prop(brush, "strength", slider=True)
495
496             if settings.tool == 'ADD':
497                 col.prop(brush, "count")
498                 col = layout.column()
499                 col.prop(settings, "use_default_interpolate")
500                 sub = col.column(align=True)
501                 sub.active = settings.use_default_interpolate
502                 sub.prop(brush, "steps", slider=True)
503                 sub.prop(settings, "default_key_count", slider=True)
504             elif settings.tool == 'LENGTH':
505                 layout.prop(brush, "length_mode", expand=True)
506             elif settings.tool == 'PUFF':
507                 layout.prop(brush, "puff_mode", expand=True)
508                 layout.prop(brush, "use_puff_volume")
509
510         # Sculpt Mode #
511
512         elif context.sculpt_object and brush:
513
514             col = layout.column()
515
516             col.separator()
517
518             row = col.row(align=True)
519
520             if brush.use_locked_size:
521                 row.prop(brush, "use_locked_size", toggle=True, text="", icon='LOCKED')
522                 row.prop(brush, "unprojected_radius", text="Radius", slider=True)
523             else:
524                 row.prop(brush, "use_locked_size", toggle=True, text="", icon='UNLOCKED')
525                 row.prop(brush, "size", slider=True)
526
527             row.prop(brush, "use_pressure_size", toggle=True, text="")
528
529             if brush.sculpt_tool not in {'SNAKE_HOOK', 'GRAB', 'ROTATE'}:
530                 col.separator()
531
532                 row = col.row(align=True)
533
534                 if brush.use_space and brush.sculpt_tool not in {'SMOOTH'}:
535                     if brush.use_space_atten:
536                         row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED')
537                     else:
538                         row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
539
540                 row.prop(brush, "strength", text="Strength", slider=True)
541                 row.prop(brush, "use_pressure_strength", text="")
542
543             if brush.sculpt_tool not in {'SMOOTH'}:
544                 col.separator()
545
546                 row = col.row(align=True)
547                 row.prop(brush, "auto_smooth_factor", slider=True)
548                 row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
549
550             if brush.sculpt_tool in {'GRAB', 'SNAKE_HOOK'}:
551                 col.separator()
552
553                 row = col.row(align=True)
554                 row.prop(brush, "normal_weight", slider=True)
555
556             if brush.sculpt_tool in {'CREASE', 'BLOB'}:
557                 col.separator()
558
559                 row = col.row(align=True)
560                 row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
561
562             if brush.sculpt_tool not in {'PINCH', 'INFLATE', 'SMOOTH'}:
563                 row = col.row(align=True)
564
565                 col.separator()
566
567                 if brush.use_original_normal:
568                     row.prop(brush, "use_original_normal", toggle=True, text="", icon='LOCKED')
569                 else:
570                     row.prop(brush, "use_original_normal", toggle=True, text="", icon='UNLOCKED')
571
572                 row.prop(brush, "sculpt_plane", text="")
573
574             #if brush.sculpt_tool in {'CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'}:
575             if brush.sculpt_tool in {'CLAY', 'FLATTEN', 'FILL', 'SCRAPE'}:
576                 row = col.row(align=True)
577                 row.prop(brush, "plane_offset", slider=True)
578                 row.prop(brush, "use_offset_pressure", text="")
579
580                 col.separator()
581
582                 row = col.row()
583                 row.prop(brush, "use_plane_trim", text="Trim")
584                 row = col.row()
585                 row.active = brush.use_plane_trim
586                 row.prop(brush, "plane_trim", slider=True, text="Distance")
587
588             if brush.sculpt_tool == 'LAYER':
589                 row = col.row()
590                 row.prop(brush, "height", slider=True, text="Height")
591
592             col.separator()
593
594             row = col.row()
595             row.prop(brush, "use_frontface", text="Front Faces Only")
596
597             col.separator()
598             col.row().prop(brush, "direction", expand=True)
599
600             if brush.sculpt_tool in {'DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'}:
601                 col.separator()
602
603                 col.prop(brush, "use_accumulate")
604
605             if brush.sculpt_tool == 'LAYER':
606                 col.separator()
607
608                 ob = context.sculpt_object
609                 do_persistent = True
610
611                 # not supported yet for this case
612                 for md in ob.modifiers:
613                     if md.type == 'MULTIRES':
614                         do_persistent = False
615
616                 if do_persistent:
617                     col.prop(brush, "use_persistent")
618                     col.operator("sculpt.set_persistent_base")
619
620         # Texture Paint Mode #
621
622         elif context.image_paint_object and brush:
623             col = layout.column()
624             col.template_color_wheel(brush, "color", value_slider=True)
625             col.prop(brush, "color", text="")
626
627             row = col.row(align=True)
628             row.prop(brush, "size", slider=True)
629             row.prop(brush, "use_pressure_size", toggle=True, text="")
630
631             row = col.row(align=True)
632             row.prop(brush, "strength", text="Strength", slider=True)
633             row.prop(brush, "use_pressure_strength", toggle=True, text="")
634
635             row = col.row(align=True)
636             row.prop(brush, "jitter", slider=True)
637             row.prop(brush, "use_pressure_jitter", toggle=True, text="")
638
639             col.prop(brush, "blend", text="Blend")
640
641             col = layout.column()
642             col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
643             col.prop(brush, "use_alpha")
644
645         # Weight Paint Mode #
646         elif context.weight_paint_object and brush:
647             layout.prop(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
648             layout.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize")
649
650             col = layout.column()
651
652             row = col.row(align=True)
653             row.prop(brush, "size", slider=True)
654             row.prop(brush, "use_pressure_size", toggle=True, text="")
655
656             row = col.row(align=True)
657             row.prop(brush, "strength", text="Strength", slider=True)
658             row.prop(brush, "use_pressure_strength", toggle=True, text="")
659
660             row = col.row(align=True)
661             row.prop(brush, "jitter", slider=True)
662             row.prop(brush, "use_pressure_jitter", toggle=True, text="")
663
664         # Vertex Paint Mode #
665         elif context.vertex_paint_object and brush:
666             col = layout.column()
667             col.template_color_wheel(brush, "color", value_slider=True)
668             col.prop(brush, "color", text="")
669
670             row = col.row(align=True)
671             row.prop(brush, "size", slider=True)
672             row.prop(brush, "use_pressure_size", toggle=True, text="")
673
674             row = col.row(align=True)
675             row.prop(brush, "strength", text="Strength", slider=True)
676             row.prop(brush, "use_pressure_strength", toggle=True, text="")
677
678             # XXX - TODO
679             #row = col.row(align=True)
680             #row.prop(brush, "jitter", slider=True)
681             #row.prop(brush, "use_pressure_jitter", toggle=True, text="")
682
683
684 class VIEW3D_PT_tools_brush_texture(PaintPanel, bpy.types.Panel):
685     bl_label = "Texture"
686     bl_options = {'DEFAULT_CLOSED'}
687
688     @classmethod
689     def poll(cls, context):
690         settings = cls.paint_settings(context)
691         return (settings and settings.brush and (context.sculpt_object or
692                              context.image_paint_object))
693
694     def draw(self, context):
695         layout = self.layout
696
697         settings = __class__.paint_settings(context)
698         brush = settings.brush
699         tex_slot = brush.texture_slot
700
701         col = layout.column()
702
703         col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
704         if brush.use_paint_image:
705             col.prop(brush, "use_fixed_texture")
706
707         if context.sculpt_object:
708             #XXX duplicated from properties_texture.py
709
710             col.separator()
711
712             col.label(text="Brush Mapping:")
713             row = col.row(align=True)
714             row.prop(tex_slot, "map_mode", expand=True)
715
716             col.separator()
717
718             col = layout.column()
719             col.active = tex_slot.map_mode in {'FIXED'}
720             col.label(text="Angle:")
721
722             col = layout.column()
723             if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}:
724                 col.prop(brush, "texture_angle_source_random", text="")
725             else:
726                 col.prop(brush, "texture_angle_source_no_random", text="")
727
728             #row = col.row(align=True)
729             #row.label(text="Angle:")
730             #row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
731
732             #row = col.row(align=True)
733
734             #col = row.column()
735             #col.active = tex_slot.map_mode in {'FIXED'}
736             #col.prop(brush, "use_rake", toggle=True, icon='PARTICLEMODE', text="")
737
738             col = layout.column()
739             col.prop(tex_slot, "angle", text="")
740             col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
741
742             #col = layout.column()
743             #col.prop(brush, "use_random_rotation")
744             #col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'}
745
746             split = layout.split()
747
748             col = split.column()
749             col.prop(tex_slot, "offset")
750
751             col = split.column()
752
753             col.prop(tex_slot, "scale")
754
755             col = layout.column()
756
757             row = col.row(align=True)
758             row.label(text="Sample Bias:")
759             row = col.row(align=True)
760             row.prop(brush, "texture_sample_bias", slider=True, text="")
761
762             row = col.row(align=True)
763             row.label(text="Overlay:")
764             row.active = tex_slot.map_mode in {'FIXED', 'TILED'}
765
766             row = col.row(align=True)
767
768             col = row.column()
769
770             if brush.use_texture_overlay:
771                 col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_OFF')
772             else:
773                 col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_ON')
774
775             col.active = tex_slot.map_mode in {'FIXED', 'TILED'}
776
777             col = row.column()
778             col.prop(brush, "texture_overlay_alpha", text="Alpha")
779             col.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay
780
781
782 class VIEW3D_PT_tools_brush_tool(PaintPanel, bpy.types.Panel):
783     bl_label = "Tool"
784     bl_options = {'DEFAULT_CLOSED'}
785
786     @classmethod
787     def poll(cls, context):
788         settings = cls.paint_settings(context)
789         return (settings and settings.brush and
790             (context.sculpt_object or context.image_paint_object or
791             context.vertex_paint_object or context.weight_paint_object))
792
793     def draw(self, context):
794         layout = self.layout
795
796         settings = __class__.paint_settings(context)
797         brush = settings.brush
798         ## Unused
799         # image_paint = context.image_paint_object
800         # sculpt = context.sculpt_object
801
802         col = layout.column(align=True)
803
804         if context.sculpt_object:
805             col.prop(brush, "sculpt_tool", expand=False, text="")
806             col.operator("brush.reset")
807         elif context.image_paint_object:
808             col.prop(brush, "image_tool", expand=False, text="")
809         elif context.vertex_paint_object or context.weight_paint_object:
810             col.prop(brush, "vertex_tool", expand=False, text="")
811
812         row = layout.row(align=True)
813         row.prop(brush, "use_paint_sculpt", text="", icon='SCULPTMODE_HLT')
814         row.prop(brush, "use_paint_vertex", text="", icon='VPAINT_HLT')
815         row.prop(brush, "use_paint_weight", text="", icon='WPAINT_HLT')
816         row.prop(brush, "use_paint_image", text="", icon='TPAINT_HLT')
817
818
819 class VIEW3D_PT_tools_brush_stroke(PaintPanel, bpy.types.Panel):
820     bl_label = "Stroke"
821     bl_options = {'DEFAULT_CLOSED'}
822
823     @classmethod
824     def poll(cls, context):
825         settings = cls.paint_settings(context)
826         return (settings and settings.brush and (context.sculpt_object or
827                              context.vertex_paint_object or
828                              context.weight_paint_object or
829                              context.image_paint_object))
830
831     def draw(self, context):
832         layout = self.layout
833
834         settings = __class__.paint_settings(context)
835         brush = settings.brush
836         image_paint = context.image_paint_object
837
838         col = layout.column()
839
840         if context.sculpt_object:
841             col.label(text="Stroke Method:")
842             col.prop(brush, "stroke_method", text="")
843
844             if brush.use_anchor:
845                 col.separator()
846                 row = col.row()
847                 row.prop(brush, "use_edge_to_edge", "Edge To Edge")
848
849             if brush.use_airbrush:
850                 col.separator()
851                 row = col.row()
852                 row.prop(brush, "rate", text="Rate", slider=True)
853
854             if brush.use_space:
855                 col.separator()
856                 row = col.row()
857                 row.active = brush.use_space
858                 row.prop(brush, "spacing", text="Spacing")
859
860             if (brush.sculpt_tool not in {'GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE'}) and (not brush.use_anchor) and (not brush.use_restore_mesh):
861                 col = layout.column()
862                 col.separator()
863
864                 col.prop(brush, "use_smooth_stroke")
865
866                 sub = col.column()
867                 sub.active = brush.use_smooth_stroke
868                 sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
869                 sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
870
871                 col.separator()
872
873                 row = col.row(align=True)
874                 row.prop(brush, "jitter", slider=True)
875                 row.prop(brush, "use_pressure_jitter", toggle=True, text="")
876
877         else:
878             row = col.row()
879             row.prop(brush, "use_airbrush")
880
881             row = col.row()
882             row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor)
883             row.prop(brush, "rate", slider=True)
884
885             col.separator()
886
887             if not image_paint:
888                 row = col.row()
889                 row.prop(brush, "use_smooth_stroke")
890
891                 col = layout.column()
892                 col.active = brush.use_smooth_stroke
893                 col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
894                 col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
895
896             col.separator()
897
898             col = layout.column()
899             col.active = (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'})
900
901             row = col.row()
902             row.prop(brush, "use_space")
903
904             row = col.row()
905             row.active = brush.use_space
906             row.prop(brush, "spacing", text="Spacing")
907
908             #col.prop(brush, "use_space_atten", text="Adaptive Strength")
909             #col.prop(brush, "use_adaptive_space", text="Adaptive Spacing")
910
911             #col.separator()
912
913             #if image_paint:
914             #    row.prop(brush, "use_pressure_spacing", toggle=True, text="")
915
916
917 class VIEW3D_PT_tools_brush_curve(PaintPanel, bpy.types.Panel):
918     bl_label = "Curve"
919     bl_options = {'DEFAULT_CLOSED'}
920
921     @classmethod
922     def poll(cls, context):
923         settings = cls.paint_settings(context)
924         return (settings and settings.brush and settings.brush.curve)
925
926     def draw(self, context):
927         layout = self.layout
928
929         settings = self.paint_settings(context)
930
931         brush = settings.brush
932
933         layout.template_curve_mapping(brush, "curve", brush=True)
934
935         row = layout.row(align=True)
936         row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH'
937         row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND'
938         row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT'
939         row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP'
940         row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE'
941         row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX'
942
943
944 class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
945     bl_label = "Options"
946     bl_options = {'DEFAULT_CLOSED'}
947
948     @classmethod
949     def poll(cls, context):
950         return (context.sculpt_object and context.tool_settings.sculpt)
951
952     def draw(self, context):
953         layout = self.layout
954
955         tool_settings = context.tool_settings
956         sculpt = tool_settings.sculpt
957         settings = __class__.paint_settings(context)
958
959         split = layout.split()
960
961         col = split.column()
962
963         col.prop(sculpt, "use_threaded", text="Threaded Sculpt")
964         col.prop(sculpt, "show_low_resolution")
965         col.prop(sculpt, "show_brush")
966
967         col.label(text="Unified Settings:")
968         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
969         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
970
971         col = split.column()
972
973         col.label(text="Lock:")
974         row = col.row(align=True)
975         row.prop(sculpt, "lock_x", text="X", toggle=True)
976         row.prop(sculpt, "lock_y", text="Y", toggle=True)
977         row.prop(sculpt, "lock_z", text="Z", toggle=True)
978
979
980 class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
981     bl_label = "Symmetry"
982     bl_options = {'DEFAULT_CLOSED'}
983
984     @classmethod
985     def poll(cls, context):
986         return (context.sculpt_object and context.tool_settings.sculpt)
987
988     def draw(self, context):
989
990         layout = self.layout
991
992         sculpt = context.tool_settings.sculpt
993         settings = __class__.paint_settings(context)
994
995         split = layout.split()
996
997         col = split.column()
998
999         col.label(text="Mirror:")
1000         col.prop(sculpt, "use_symmetry_x", text="X")
1001         col.prop(sculpt, "use_symmetry_y", text="Y")
1002         col.prop(sculpt, "use_symmetry_z", text="Z")
1003
1004         col = split.column()
1005
1006         col.prop(sculpt, "radial_symmetry", text="Radial")
1007
1008         col = layout.column()
1009
1010         col.separator()
1011
1012         col.prop(sculpt, "use_symmetry_feather", text="Feather")
1013
1014
1015 class VIEW3D_PT_tools_brush_appearance(PaintPanel, bpy.types.Panel):
1016     bl_label = "Appearance"
1017     bl_options = {'DEFAULT_CLOSED'}
1018
1019     @classmethod
1020     def poll(cls, context):
1021         return (context.sculpt_object and context.tool_settings.sculpt) or (context.vertex_paint_object and context.tool_settings.vertex_paint) or (context.weight_paint_object and context.tool_settings.weight_paint) or (context.image_paint_object and context.tool_settings.image_paint)
1022
1023     def draw(self, context):
1024         layout = self.layout
1025
1026         settings = __class__.paint_settings(context)
1027         brush = settings.brush
1028
1029         col = layout.column()
1030
1031         if context.sculpt_object and context.tool_settings.sculpt:
1032             #if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'}:
1033             if brush.sculpt_tool in {'DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'}:
1034                 col.prop(brush, "cursor_color_add", text="Add Color")
1035                 col.prop(brush, "cursor_color_subtract", text="Subtract Color")
1036             else:
1037                 col.prop(brush, "cursor_color_add", text="Color")
1038         else:
1039             col.prop(brush, "cursor_color_add", text="Color")
1040
1041         col = layout.column()
1042         col.label(text="Icon:")
1043
1044         row = col.row(align=True)
1045         row.prop(brush, "use_custom_icon")
1046         if brush.use_custom_icon:
1047             row = col.row(align=True)
1048             row.prop(brush, "icon_filepath", text="")
1049
1050 # ********** default tools for weightpaint ****************
1051
1052
1053 class VIEW3D_PT_tools_weightpaint(View3DPanel, bpy.types.Panel):
1054     bl_context = "weightpaint"
1055     bl_label = "Weight Tools"
1056
1057     def draw(self, context):
1058         layout = self.layout
1059
1060         ob = context.active_object
1061
1062         col = layout.column()
1063         col.active = ob.vertex_groups.active != None
1064         col.operator("object.vertex_group_normalize_all", text="Normalize All")
1065         col.operator("object.vertex_group_normalize", text="Normalize")
1066         col.operator("object.vertex_group_invert", text="Invert")
1067         col.operator("object.vertex_group_clean", text="Clean")
1068         col.operator("object.vertex_group_levels", text="Levels")
1069
1070
1071 class VIEW3D_PT_tools_weightpaint_options(View3DPanel, bpy.types.Panel):
1072     bl_context = "weightpaint"
1073     bl_label = "Options"
1074
1075     def draw(self, context):
1076         layout = self.layout
1077
1078         tool_settings = context.tool_settings
1079         wpaint = tool_settings.weight_paint
1080
1081         col = layout.column()
1082         col.prop(wpaint, "use_all_faces")
1083         col.prop(wpaint, "use_normal")
1084         col.prop(wpaint, "use_spray")
1085
1086         obj = context.weight_paint_object
1087         if obj.type == 'MESH':
1088             mesh = obj.data
1089             col.prop(mesh, "use_mirror_x")
1090             col.prop(mesh, "use_mirror_topology")
1091
1092         col.label(text="Unified Settings:")
1093         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1094         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1095
1096 # Commented out because the Apply button isn't an operator yet, making these settings useless
1097 #               col.label(text="Gamma:")
1098 #               col.prop(wpaint, "gamma", text="")
1099 #               col.label(text="Multiply:")
1100 #               col.prop(wpaint, "mul", text="")
1101
1102 # Also missing now:
1103 # Soft, Vgroup, X-Mirror and "Clear" Operator.
1104
1105 # ********** default tools for vertexpaint ****************
1106
1107
1108 class VIEW3D_PT_tools_vertexpaint(View3DPanel, bpy.types.Panel):
1109     bl_context = "vertexpaint"
1110     bl_label = "Options"
1111
1112     def draw(self, context):
1113         layout = self.layout
1114
1115         tool_settings = context.tool_settings
1116         vpaint = tool_settings.vertex_paint
1117
1118         col = layout.column()
1119         #col.prop(vpaint, "mode", text="")
1120         col.prop(vpaint, "use_all_faces")
1121         col.prop(vpaint, "use_normal")
1122         col.prop(vpaint, "use_spray")
1123
1124         col.label(text="Unified Settings:")
1125         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1126         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1127
1128 # Commented out because the Apply button isn't an operator yet, making these settings useless
1129 #               col.label(text="Gamma:")
1130 #               col.prop(vpaint, "gamma", text="")
1131 #               col.label(text="Multiply:")
1132 #               col.prop(vpaint, "mul", text="")
1133
1134 # ********** default tools for texturepaint ****************
1135
1136
1137 class VIEW3D_PT_tools_projectpaint(View3DPanel, bpy.types.Panel):
1138     bl_context = "imagepaint"
1139     bl_label = "Project Paint"
1140
1141     @classmethod
1142     def poll(cls, context):
1143         brush = context.tool_settings.image_paint.brush
1144         return (brush and brush.image_tool != 'SOFTEN')
1145
1146     def draw_header(self, context):
1147         ipaint = context.tool_settings.image_paint
1148
1149         self.layout.prop(ipaint, "use_projection", text="")
1150
1151     def draw(self, context):
1152         layout = self.layout
1153
1154         ipaint = context.tool_settings.image_paint
1155         settings = context.tool_settings.image_paint
1156         use_projection = ipaint.use_projection
1157
1158         col = layout.column()
1159         sub = col.column()
1160         sub.active = use_projection
1161         sub.prop(ipaint, "use_occlude")
1162         sub.prop(ipaint, "use_backface_culling")
1163
1164         split = layout.split()
1165
1166         col = split.column()
1167         col.active = (use_projection)
1168         col.prop(ipaint, "use_normal_falloff")
1169
1170         col = split.column()
1171         col.active = (ipaint.use_normal_falloff and use_projection)
1172         col.prop(ipaint, "normal_angle", text="")
1173
1174         col = layout.column(align=False)
1175         row = col.row()
1176         row.active = (use_projection)
1177         row.prop(ipaint, "use_stencil_layer", text="Stencil")
1178
1179         row2 = row.row(align=False)
1180         row2.active = (use_projection and ipaint.use_stencil_layer)
1181         row2.menu("VIEW3D_MT_tools_projectpaint_stencil", text=context.active_object.data.uv_texture_stencil.name)
1182         row2.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
1183
1184         col = layout.column()
1185         sub = col.column()
1186         row = sub.row()
1187         row.active = (settings.brush.image_tool == 'CLONE')
1188
1189         row.prop(ipaint, "use_clone_layer", text="Layer")
1190         row.menu("VIEW3D_MT_tools_projectpaint_clone", text=context.active_object.data.uv_texture_clone.name)
1191
1192         sub = col.column()
1193         sub.prop(ipaint, "seam_bleed")
1194
1195         col.label(text="External Editing")
1196         row = col.split(align=True, percentage=0.55)
1197         row.operator("image.project_edit", text="Quick Edit")
1198         row.operator("image.project_apply", text="Apply")
1199         row = col.row(align=True)
1200         row.prop(ipaint, "screen_grab_size", text="")
1201
1202         sub = col.column()
1203         sub.operator("paint.project_image", text="Apply Camera Image")
1204
1205         sub.operator("image.save_dirty", text="Save All Edited")
1206
1207
1208 class VIEW3D_PT_imagepaint_options(PaintPanel):
1209     bl_label = "Options"
1210     bl_options = {'DEFAULT_CLOSED'}
1211
1212     @classmethod
1213     def poll(cls, context):
1214         return (context.image_paint_object and context.tool_settings.image_paint)
1215
1216     def draw(self, context):
1217         layout = self.layout
1218
1219         col = layout.column()
1220
1221         tool_settings = context.tool_settings
1222         col.label(text="Unified Settings:")
1223         col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
1224         col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
1225
1226
1227 class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):
1228     bl_label = "Clone Layer"
1229
1230     def draw(self, context):
1231         layout = self.layout
1232         for i, tex in enumerate(context.active_object.data.uv_textures):
1233             prop = layout.operator("wm.context_set_int", text=tex.name)
1234             prop.data_path = "active_object.data.uv_texture_clone_index"
1235             prop.value = i
1236
1237
1238 class VIEW3D_MT_tools_projectpaint_stencil(bpy.types.Menu):
1239     bl_label = "Mask Layer"
1240
1241     def draw(self, context):
1242         layout = self.layout
1243         for i, tex in enumerate(context.active_object.data.uv_textures):
1244             prop = layout.operator("wm.context_set_int", text=tex.name)
1245             prop.data_path = "active_object.data.uv_texture_stencil_index"
1246             prop.value = i
1247
1248
1249 class VIEW3D_PT_tools_particlemode(View3DPanel, bpy.types.Panel):
1250     '''default tools for particle mode'''
1251     bl_context = "particlemode"
1252     bl_label = "Options"
1253
1254     def draw(self, context):
1255         layout = self.layout
1256
1257         pe = context.tool_settings.particle_edit
1258         ob = pe.object
1259
1260         layout.prop(pe, "type", text="")
1261
1262         ptcache = None
1263
1264         if pe.type == 'PARTICLES':
1265             if ob.particle_systems:
1266                 if len(ob.particle_systems) > 1:
1267                     layout.template_list(ob, "particle_systems", ob.particle_systems, "active_index", type='ICONS')
1268
1269                 ptcache = ob.particle_systems.active.point_cache
1270         else:
1271             for md in ob.modifiers:
1272                 if md.type == pe.type:
1273                     ptcache = md.point_cache
1274
1275         if ptcache and len(ptcache.point_caches) > 1:
1276             layout.template_list(ptcache, "point_caches", ptcache.point_caches, "active_index", type='ICONS')
1277
1278         if not pe.is_editable:
1279             layout.label(text="Point cache must be baked")
1280             layout.label(text="in memory to enable editing!")
1281
1282         col = layout.column(align=True)
1283         if pe.is_hair:
1284             col.active = pe.is_editable
1285             col.prop(pe, "use_emitter_deflect", text="Deflect emitter")
1286             sub = col.row()
1287             sub.active = pe.use_emitter_deflect
1288             sub.prop(pe, "emitter_distance", text="Distance")
1289
1290         col = layout.column(align=True)
1291         col.active = pe.is_editable
1292         col.label(text="Keep:")
1293         col.prop(pe, "use_preserve_length", text="Lengths")
1294         col.prop(pe, "use_preserve_root", text="Root")
1295         if not pe.is_hair:
1296             col.label(text="Correct:")
1297             col.prop(pe, "use_auto_velocity", text="Velocity")
1298         col.prop(ob.data, "use_mirror_x")
1299
1300         col = layout.column(align=True)
1301         col.active = pe.is_editable
1302         col.label(text="Draw:")
1303         col.prop(pe, "draw_step", text="Path Steps")
1304         if pe.is_hair:
1305             col.prop(pe, "show_particles", text="Children")
1306         else:
1307             if pe.type == 'PARTICLES':
1308                 col.prop(pe, "show_particles", text="Particles")
1309             col.prop(pe, "use_fade_time")
1310             sub = col.row()
1311             sub.active = pe.use_fade_time
1312             sub.prop(pe, "fade_frames", slider=True)