Removed UI for point cache users.
[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 from bpy.types import Menu, Panel, UIList
22 from bl_ui.properties_grease_pencil_common import (
23         GreasePencilDrawingToolsPanel,
24         GreasePencilStrokeEditPanel,
25         GreasePencilStrokeSculptPanel
26         )
27 from bl_ui.properties_paint_common import (
28         UnifiedPaintPanel,
29         brush_texture_settings,
30         brush_texpaint_common,
31         brush_mask_texture_settings,
32         )
33
34
35 class View3DPanel:
36     bl_space_type = 'VIEW_3D'
37     bl_region_type = 'TOOLS'
38
39
40 # **************** standard tool clusters ******************
41
42 # Keyframing tools
43 def draw_keyframing_tools(context, layout):
44     col = layout.column(align=True)
45     col.label(text="Keyframes:")
46     row = col.row(align=True)
47     row.operator("anim.keyframe_insert_menu", text="Insert")
48     row.operator("anim.keyframe_delete_v3d", text="Remove")
49
50
51 # ********** default tools for object-mode ****************
52
53
54 class VIEW3D_PT_tools_transform(View3DPanel, Panel):
55     bl_category = "Tools"
56     bl_context = "objectmode"
57     bl_label = "Transform"
58
59     def draw(self, context):
60         layout = self.layout
61
62         col = layout.column(align=True)
63         col.operator("transform.translate")
64         col.operator("transform.rotate")
65         col.operator("transform.resize", text="Scale")
66
67         col = layout.column(align=True)
68         col.operator("transform.mirror", text="Mirror")
69
70
71 class VIEW3D_PT_tools_object(View3DPanel, Panel):
72     bl_category = "Tools"
73     bl_context = "objectmode"
74     bl_label = "Edit"
75
76     def draw(self, context):
77         layout = self.layout
78
79         col = layout.column(align=True)
80         col.operator("object.duplicate_move", text="Duplicate")
81         col.operator("object.duplicate_move_linked", text="Duplicate Linked")
82
83         col.operator("object.delete")
84
85         obj = context.active_object
86         if obj:
87             obj_type = obj.type
88
89             if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE'}:
90                 col = layout.column(align=True)
91                 col.operator("object.join")
92
93             if obj_type in {'MESH', 'CURVE', 'SURFACE', 'ARMATURE', 'FONT', 'LATTICE'}:
94                 col = layout.column(align=True)
95                 col.operator_menu_enum("object.origin_set", "type", text="Set Origin")
96
97             if obj_type in {'MESH', 'CURVE', 'SURFACE'}:
98                 col = layout.column(align=True)
99                 col.label(text="Shading:")
100                 row = col.row(align=True)
101                 row.operator("object.shade_smooth", text="Smooth")
102                 row.operator("object.shade_flat", text="Flat")
103
104             if obj_type == 'MESH':
105                 col = layout.column(align=True)
106                 col.label(text="Data Transfer:")
107                 row = col.row(align=True)
108                 row.operator("object.data_transfer", text="Data")
109                 row.operator("object.datalayout_transfer", text="Data Layout")
110
111
112 class VIEW3D_PT_tools_add_object(View3DPanel, Panel):
113     bl_category = "Create"
114     bl_context = "objectmode"
115     bl_label = "Add Primitive"
116
117     @staticmethod
118     def draw_add_mesh(layout, label=False):
119         if label:
120             layout.label(text="Primitives:")
121         layout.operator("mesh.primitive_plane_add", text="Plane", icon='MESH_PLANE')
122         layout.operator("mesh.primitive_cube_add", text="Cube", icon='MESH_CUBE')
123         layout.operator("mesh.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
124         layout.operator("mesh.primitive_uv_sphere_add", text="UV Sphere", icon='MESH_UVSPHERE')
125         layout.operator("mesh.primitive_ico_sphere_add", text="Ico Sphere", icon='MESH_ICOSPHERE')
126         layout.operator("mesh.primitive_cylinder_add", text="Cylinder", icon='MESH_CYLINDER')
127         layout.operator("mesh.primitive_cone_add", text="Cone", icon='MESH_CONE')
128         layout.operator("mesh.primitive_torus_add", text="Torus", icon='MESH_TORUS')
129
130         if label:
131             layout.label(text="Special:")
132         else:
133             layout.separator()
134         layout.operator("mesh.primitive_grid_add", text="Grid", icon='MESH_GRID')
135         layout.operator("mesh.primitive_monkey_add", text="Monkey", icon='MESH_MONKEY')
136
137     @staticmethod
138     def draw_add_curve(layout, label=False):
139
140         if label:
141             layout.label(text="Bezier:")
142         layout.operator("curve.primitive_bezier_curve_add", text="Bezier", icon='CURVE_BEZCURVE')
143         layout.operator("curve.primitive_bezier_circle_add", text="Circle", icon='CURVE_BEZCIRCLE')
144
145         if label:
146             layout.label(text="Nurbs:")
147         else:
148             layout.separator()
149         layout.operator("curve.primitive_nurbs_curve_add", text="Nurbs Curve", icon='CURVE_NCURVE')
150         layout.operator("curve.primitive_nurbs_circle_add", text="Nurbs Circle", icon='CURVE_NCIRCLE')
151         layout.operator("curve.primitive_nurbs_path_add", text="Path", icon='CURVE_PATH')
152
153         layout.separator()
154
155         layout.operator("curve.draw", icon='LINE_DATA')
156
157     @staticmethod
158     def draw_add_surface(layout):
159         layout.operator("surface.primitive_nurbs_surface_curve_add", text="Nurbs Curve", icon='SURFACE_NCURVE')
160         layout.operator("surface.primitive_nurbs_surface_circle_add", text="Nurbs Circle", icon='SURFACE_NCIRCLE')
161         layout.operator("surface.primitive_nurbs_surface_surface_add", text="Nurbs Surface", icon='SURFACE_NSURFACE')
162         layout.operator("surface.primitive_nurbs_surface_cylinder_add", text="Nurbs Cylinder", icon='SURFACE_NCYLINDER')
163         layout.operator("surface.primitive_nurbs_surface_sphere_add", text="Nurbs Sphere", icon='SURFACE_NSPHERE')
164         layout.operator("surface.primitive_nurbs_surface_torus_add", text="Nurbs Torus", icon='SURFACE_NTORUS')
165
166     @staticmethod
167     def draw_add_mball(layout):
168         layout.operator_enum("object.metaball_add", "type")
169
170     @staticmethod
171     def draw_add_lamp(layout):
172         layout.operator_enum("object.lamp_add", "type")
173
174     @staticmethod
175     def draw_add_other(layout):
176         layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
177         layout.operator("object.armature_add", text="Armature", icon='OUTLINER_OB_ARMATURE')
178         layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
179         layout.operator("object.empty_add", text="Empty", icon='OUTLINER_OB_EMPTY').type = 'PLAIN_AXES'
180         layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
181         layout.operator("object.camera_add", text="Camera", icon='OUTLINER_OB_CAMERA')
182
183     def draw(self, context):
184         layout = self.layout
185
186         col = layout.column(align=True)
187         col.label(text="Mesh:")
188         self.draw_add_mesh(col)
189
190         col = layout.column(align=True)
191         col.label(text="Curve:")
192         self.draw_add_curve(col)
193
194         # not used here:
195         # draw_add_surface
196         # draw_add_mball
197
198         col = layout.column(align=True)
199         col.label(text="Lamp:")
200         self.draw_add_lamp(col)
201
202         col = layout.column(align=True)
203         col.label(text="Other:")
204         self.draw_add_other(col)
205
206
207 class VIEW3D_PT_tools_relations(View3DPanel, Panel):
208     bl_category = "Relations"
209     bl_context = "objectmode"
210     bl_label = "Relations"
211
212     def draw(self, context):
213         layout = self.layout
214
215         col = layout.column(align=True)
216
217         col.label(text="Group:")
218         col.operator("group.create", text="New Group")
219         col.operator("group.objects_add_active", text="Add to Active")
220         col.operator("group.objects_remove", text="Remove from Group")
221
222         col.separator()
223
224         col.label(text="Parent:")
225         row = col.row(align=True)
226         row.operator("object.parent_set", text="Set")
227         row.operator("object.parent_clear", text="Clear")
228
229         col.separator()
230
231         col.label(text="Object Data:")
232         col.operator("object.make_links_data")
233         col.operator("object.make_single_user")
234
235         col.separator()
236
237         col.label(text="Linked Objects:")
238         col.operator("object.make_local")
239         col.operator("object.proxy_make")
240
241
242 class VIEW3D_PT_tools_animation(View3DPanel, Panel):
243     bl_category = "Animation"
244     bl_context = "objectmode"
245     bl_label = "Animation"
246
247     def draw(self, context):
248         layout = self.layout
249
250         ob = context.active_object
251         mpath = ob.motion_path if ob else None
252
253         draw_keyframing_tools(context, layout)
254
255         col = layout.column(align=True)
256         col.label(text="Motion Paths:")
257         if mpath:
258             row = col.row(align=True)
259             row.operator("object.paths_update", text="Update")
260             row.operator("object.paths_clear", text="", icon='X')
261         else:
262             col.operator("object.paths_calculate", text="Calculate")
263
264         col.separator()
265
266         col.label(text="Action:")
267         col.operator("nla.bake", text="Bake Action")
268
269
270 class VIEW3D_PT_tools_rigid_body(View3DPanel, Panel):
271     bl_category = "Physics"
272     bl_context = "objectmode"
273     bl_label = "Rigid Body Tools"
274
275     def draw(self, context):
276         layout = self.layout
277
278         col = layout.column(align=True)
279         col.label(text="Add/Remove:")
280         row = col.row(align=True)
281         row.operator("rigidbody.objects_add", text="Add Active").type = 'ACTIVE'
282         row.operator("rigidbody.objects_add", text="Add Passive").type = 'PASSIVE'
283         row = col.row(align=True)
284         row.operator("rigidbody.objects_remove", text="Remove")
285
286         col = layout.column(align=True)
287         col.label(text="Object Tools:")
288         col.operator("rigidbody.shape_change", text="Change Shape")
289         col.operator("rigidbody.mass_calculate", text="Calculate Mass")
290         col.operator("rigidbody.object_settings_copy", text="Copy from Active")
291         col.operator("object.visual_transform_apply", text="Apply Transformation")
292         col.operator("rigidbody.bake_to_keyframes", text="Bake To Keyframes")
293         col.label(text="Constraints:")
294         col.operator("rigidbody.connect", text="Connect")
295
296
297 # ********** default tools for editmode_mesh ****************
298
299 class VIEW3D_PT_tools_transform_mesh(View3DPanel, Panel):
300     bl_category = "Tools"
301     bl_context = "mesh_edit"
302     bl_label = "Transform"
303
304     def draw(self, context):
305         layout = self.layout
306
307         col = layout.column(align=True)
308         col.operator("transform.translate")
309         col.operator("transform.rotate")
310         col.operator("transform.resize", text="Scale")
311         col.operator("transform.shrink_fatten", text="Shrink/Fatten")
312         col.operator("transform.push_pull", text="Push/Pull")
313
314
315 class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
316     bl_category = "Tools"
317     bl_context = "mesh_edit"
318     bl_label = "Mesh Tools"
319
320     def draw(self, context):
321         layout = self.layout
322
323         col = layout.column(align=True)
324         col.label(text="Deform:")
325         row = col.row(align=True)
326         row.operator("transform.edge_slide", text="Slide Edge")
327         row.operator("transform.vert_slide", text="Vertex")
328         col.operator("mesh.noise")
329         col.operator("mesh.vertices_smooth")
330         col.operator("transform.vertex_random")
331
332         col = layout.column(align=True)
333         col.label(text="Add:")
334
335         col.menu("VIEW3D_MT_edit_mesh_extrude")
336         col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
337         col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
338         col.operator("mesh.inset", text="Inset Faces")
339         col.operator("mesh.edge_face_add")
340         col.operator("mesh.subdivide")
341         col.operator("mesh.loopcut_slide")
342         col.operator("mesh.offset_edge_loops_slide")
343         col.operator("mesh.duplicate_move", text="Duplicate")
344         row = col.row(align=True)
345         row.operator("mesh.spin")
346         row.operator("mesh.screw")
347
348         row = col.row(align=True)
349         props = row.operator("mesh.knife_tool", text="Knife")
350         props.use_occlude_geometry = True
351         props.only_selected = False
352         props = row.operator("mesh.knife_tool", text="Select")
353         props.use_occlude_geometry = False
354         props.only_selected = True
355         col.operator("mesh.knife_project")
356         col.operator("mesh.bisect")
357
358         col = layout.column(align=True)
359         col.label(text="Remove:")
360         col.menu("VIEW3D_MT_edit_mesh_delete")
361         col.operator_menu_enum("mesh.merge", "type")
362         col.operator("mesh.remove_doubles")
363
364
365 class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
366     bl_category = "Tools"
367     bl_context = "mesh_edit"
368     bl_label = "Weight Tools"
369     bl_options = {'DEFAULT_CLOSED'}
370
371     # Used for Weight-Paint mode and Edit-Mode
372     @staticmethod
373     def draw_generic(layout):
374         col = layout.column()
375         col.operator("object.vertex_group_normalize_all", text="Normalize All")
376         col.operator("object.vertex_group_normalize", text="Normalize")
377         col.operator("object.vertex_group_mirror", text="Mirror")
378         col.operator("object.vertex_group_invert", text="Invert")
379         col.operator("object.vertex_group_clean", text="Clean")
380         col.operator("object.vertex_group_quantize", text="Quantize")
381         col.operator("object.vertex_group_levels", text="Levels")
382         col.operator("object.vertex_group_smooth", text="Smooth")
383         col.operator("object.vertex_group_limit_total", text="Limit Total")
384         col.operator("object.vertex_group_fix", text="Fix Deforms")
385
386     def draw(self, context):
387         layout = self.layout
388         self.draw_generic(layout)
389
390
391 class VIEW3D_PT_tools_add_mesh_edit(View3DPanel, Panel):
392     bl_category = "Create"
393     bl_context = "mesh_edit"
394     bl_label = "Add Meshes"
395
396     def draw(self, context):
397         layout = self.layout
398
399         col = layout.column(align=True)
400
401         VIEW3D_PT_tools_add_object.draw_add_mesh(col, label=True)
402
403
404 class VIEW3D_PT_tools_shading(View3DPanel, Panel):
405     bl_category = "Shading / UVs"
406     bl_context = "mesh_edit"
407     bl_label = "Shading"
408
409     def draw(self, context):
410         layout = self.layout
411
412         col = layout.column(align=True)
413         col.label(text="Faces:")
414         row = col.row(align=True)
415         row.operator("mesh.faces_shade_smooth", text="Smooth")
416         row.operator("mesh.faces_shade_flat", text="Flat")
417         col.label(text="Edges:")
418         row = col.row(align=True)
419         row.operator("mesh.mark_sharp", text="Smooth").clear = True
420         row.operator("mesh.mark_sharp", text="Sharp")
421         col.label(text="Vertices:")
422         row = col.row(align=True)
423         props = row.operator("mesh.mark_sharp", text="Smooth")
424         props.use_verts = True
425         props.clear = True
426         row.operator("mesh.mark_sharp", text="Sharp").use_verts = True
427
428         col = layout.column(align=True)
429         col.label(text="Normals:")
430         col.operator("mesh.normals_make_consistent", text="Recalculate")
431         col.operator("mesh.flip_normals", text="Flip Direction")
432
433
434 class VIEW3D_PT_tools_uvs(View3DPanel, Panel):
435     bl_category = "Shading / UVs"
436     bl_context = "mesh_edit"
437     bl_label = "UVs"
438
439     def draw(self, context):
440         layout = self.layout
441
442         col = layout.column(align=True)
443         col.label(text="UV Mapping:")
444         col.menu("VIEW3D_MT_uv_map", text="Unwrap")
445         col.operator("mesh.mark_seam").clear = False
446         col.operator("mesh.mark_seam", text="Clear Seam").clear = True
447
448
449 class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
450     bl_category = "Options"
451     bl_context = "mesh_edit"
452     bl_label = "Mesh Options"
453
454     @classmethod
455     def poll(cls, context):
456         return context.active_object
457
458     def draw(self, context):
459         layout = self.layout
460
461         ob = context.active_object
462
463         tool_settings = context.tool_settings
464         mesh = ob.data
465
466         col = layout.column(align=True)
467         col.prop(mesh, "use_mirror_x")
468
469         row = col.row(align=True)
470         row.active = ob.data.use_mirror_x
471         row.prop(mesh, "use_mirror_topology")
472
473         col = layout.column(align=True)
474         col.label("Edge Select Mode:")
475         col.prop(tool_settings, "edge_path_mode", text="")
476         col.prop(tool_settings, "edge_path_live_unwrap")
477         col.label("Double Threshold:")
478         col.prop(tool_settings, "double_threshold", text="")
479
480         if mesh.show_weight:
481             col.label("Show Zero Weights:")
482             col.row().prop(tool_settings, "vertex_group_user", expand=True)
483
484 # ********** default tools for editmode_curve ****************
485
486
487 class VIEW3D_PT_tools_transform_curve(View3DPanel, Panel):
488     bl_category = "Tools"
489     bl_context = "curve_edit"
490     bl_label = "Transform"
491
492     def draw(self, context):
493         layout = self.layout
494
495         col = layout.column(align=True)
496         col.operator("transform.translate")
497         col.operator("transform.rotate")
498         col.operator("transform.resize", text="Scale")
499
500         col = layout.column(align=True)
501         col.operator("transform.tilt", text="Tilt")
502         col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN'
503
504
505 class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
506     bl_category = "Tools"
507     bl_context = "curve_edit"
508     bl_label = "Curve Tools"
509
510     def draw(self, context):
511         layout = self.layout
512
513         col = layout.column(align=True)
514         col.label(text="Curve:")
515         col.operator("curve.duplicate_move", text="Duplicate")
516         col.operator("curve.delete")
517         col.operator("curve.cyclic_toggle")
518         col.operator("curve.switch_direction")
519         col.operator("curve.spline_type_set")
520         col.operator("curve.radius_set")
521
522         col = layout.column(align=True)
523         col.label(text="Handles:")
524         row = col.row(align=True)
525         row.operator("curve.handle_type_set", text="Auto").type = 'AUTOMATIC'
526         row.operator("curve.handle_type_set", text="Vector").type = 'VECTOR'
527         row = col.row(align=True)
528         row.operator("curve.handle_type_set", text="Align").type = 'ALIGNED'
529         row.operator("curve.handle_type_set", text="Free").type = 'FREE_ALIGN'
530
531         col = layout.column(align=True)
532         col.operator("curve.normals_make_consistent")
533
534         col = layout.column(align=True)
535         col.label(text="Modeling:")
536         col.operator("curve.extrude_move", text="Extrude")
537         col.operator("curve.subdivide")
538         col.operator("curve.smooth")
539         col.operator("transform.vertex_random")
540
541
542 class VIEW3D_PT_tools_add_curve_edit(View3DPanel, Panel):
543     bl_category = "Create"
544     bl_context = "curve_edit"
545     bl_label = "Add Curves"
546
547     def draw(self, context):
548         layout = self.layout
549
550         col = layout.column(align=True)
551
552         VIEW3D_PT_tools_add_object.draw_add_curve(col, label=True)
553
554
555 class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel):
556     bl_category = "Options"
557     bl_context = "curve_edit"
558     bl_label = "Curve Stroke"
559
560     def draw(self, context):
561         layout = self.layout
562
563         tool_settings = context.tool_settings
564         cps = tool_settings.curve_paint_settings
565
566         col = layout.column()
567
568         col.prop(cps, "curve_type")
569
570         if cps.curve_type == 'BEZIER':
571             col.label("Bezier Options:")
572             col.prop(cps, "error_threshold")
573             col.prop(cps, "use_corners_detect")
574
575             col = layout.column()
576             col.active = cps.use_corners_detect
577             col.prop(cps, "corner_angle")
578
579         col.label("Pressure Radius:")
580         row = layout.row(align=True)
581         rowsub = row.row(align=True)
582         rowsub.prop(cps, "radius_min", text="Min")
583         rowsub.prop(cps, "radius_max", text="Max")
584
585         row.prop(cps, "use_pressure_radius", text="", icon_only=True)
586
587         col = layout.column()
588         col.label("Taper Radius:")
589         row = layout.row(align=True)
590         row.prop(cps, "radius_taper_start", text="Start")
591         row.prop(cps, "radius_taper_end", text="End")
592
593         col = layout.column()
594         col.label("Projection Depth:")
595         row = layout.row(align=True)
596         row.prop(cps, "depth_mode", expand=True)
597
598         col = layout.column()
599         if cps.depth_mode == 'SURFACE':
600             col.prop(cps, "radius_offset")
601             col.prop(cps, "use_stroke_endpoints")
602             if cps.use_stroke_endpoints:
603                 colsub = layout.column(align=True)
604                 colsub.prop(cps, "surface_plane", expand=True)
605
606 # ********** default tools for editmode_surface ****************
607
608 class VIEW3D_PT_tools_transform_surface(View3DPanel, Panel):
609     bl_category = "Tools"
610     bl_context = "surface_edit"
611     bl_label = "Transform"
612
613     def draw(self, context):
614         layout = self.layout
615
616         col = layout.column(align=True)
617         col.operator("transform.translate")
618         col.operator("transform.rotate")
619         col.operator("transform.resize", text="Scale")
620
621
622 class VIEW3D_PT_tools_surfaceedit(View3DPanel, Panel):
623     bl_category = "Tools"
624     bl_context = "surface_edit"
625     bl_label = "Surface Tools"
626
627     def draw(self, context):
628         layout = self.layout
629
630         col = layout.column(align=True)
631         col.label(text="Curve:")
632         col.operator("curve.duplicate_move", text="Duplicate")
633         col.operator("curve.delete")
634         col.operator("curve.cyclic_toggle")
635         col.operator("curve.switch_direction")
636
637         col = layout.column(align=True)
638         col.label(text="Modeling:")
639         col.operator("curve.extrude", text="Extrude")
640         col.operator("curve.spin")
641         col.operator("curve.subdivide")
642
643         col = layout.column(align=True)
644         col.label(text="Deform:")
645         col.operator("transform.vertex_random")
646
647
648 class VIEW3D_PT_tools_add_surface_edit(View3DPanel, Panel):
649     bl_category = "Create"
650     bl_context = "surface_edit"
651     bl_label = "Add Surfaces"
652
653     def draw(self, context):
654         layout = self.layout
655
656         col = layout.column(align=True)
657
658         VIEW3D_PT_tools_add_object.draw_add_surface(col)
659
660
661 # ********** default tools for editmode_text ****************
662
663
664 class VIEW3D_PT_tools_textedit(View3DPanel, Panel):
665     bl_category = "Tools"
666     bl_context = "text_edit"
667     bl_label = "Text Tools"
668
669     def draw(self, context):
670         layout = self.layout
671
672         col = layout.column(align=True)
673         col.label(text="Set Case:")
674         col.operator("font.case_set", text="To Upper").case = 'UPPER'
675         col.operator("font.case_set", text="To Lower").case = 'LOWER'
676
677         col = layout.column(align=True)
678         col.label(text="Style:")
679         col.operator("font.style_toggle", text="Bold").style = 'BOLD'
680         col.operator("font.style_toggle", text="Italic").style = 'ITALIC'
681         col.operator("font.style_toggle", text="Underline").style = 'UNDERLINE'
682
683
684 # ********** default tools for editmode_armature ****************
685
686
687 class VIEW3D_PT_tools_armatureedit_transform(View3DPanel, Panel):
688     bl_category = "Tools"
689     bl_context = "armature_edit"
690     bl_label = "Transform"
691
692     def draw(self, context):
693         layout = self.layout
694
695         col = layout.column(align=True)
696         col.operator("transform.translate")
697         col.operator("transform.rotate")
698         col.operator("transform.resize", text="Scale")
699
700
701 class VIEW3D_PT_tools_armatureedit(View3DPanel, Panel):
702     bl_category = "Tools"
703     bl_context = "armature_edit"
704     bl_label = "Armature Tools"
705
706     def draw(self, context):
707         layout = self.layout
708
709         col = layout.column(align=True)
710         col.label(text="Bones:")
711         col.operator("armature.bone_primitive_add", text="Add")
712         col.operator("armature.duplicate_move", text="Duplicate")
713         col.operator("armature.delete", text="Delete")
714
715         col = layout.column(align=True)
716         col.label(text="Modeling:")
717         col.operator("armature.extrude_move")
718         col.operator("armature.subdivide", text="Subdivide")
719
720         col = layout.column(align=True)
721         col.label(text="Deform:")
722         col.operator("transform.vertex_random")
723
724
725 class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
726     bl_category = "Options"
727     bl_context = "armature_edit"
728     bl_label = "Armature Options"
729
730     def draw(self, context):
731         arm = context.active_object.data
732
733         self.layout.prop(arm, "use_mirror_x")
734
735
736 # ********** default tools for editmode_mball ****************
737
738
739 class VIEW3D_PT_tools_mballedit(View3DPanel, Panel):
740     bl_category = "Tools"
741     bl_context = "mball_edit"
742     bl_label = "Meta Tools"
743
744     def draw(self, context):
745         layout = self.layout
746
747         col = layout.column(align=True)
748         col.label(text="Transform:")
749         col.operator("transform.translate")
750         col.operator("transform.rotate")
751         col.operator("transform.resize", text="Scale")
752
753         col = layout.column(align=True)
754         col.label(text="Deform:")
755         col.operator("transform.vertex_random")
756
757
758 class VIEW3D_PT_tools_add_mball_edit(View3DPanel, Panel):
759     bl_category = "Create"
760     bl_context = "mball_edit"
761     bl_label = "Add Metaball"
762
763     def draw(self, context):
764         layout = self.layout
765
766         col = layout.column(align=True)
767
768         VIEW3D_PT_tools_add_object.draw_add_mball(col)
769
770
771 # ********** default tools for editmode_lattice ****************
772
773
774 class VIEW3D_PT_tools_latticeedit(View3DPanel, Panel):
775     bl_category = "Tools"
776     bl_context = "lattice_edit"
777     bl_label = "Lattice Tools"
778
779     def draw(self, context):
780         layout = self.layout
781
782         col = layout.column(align=True)
783         col.label(text="Transform:")
784         col.operator("transform.translate")
785         col.operator("transform.rotate")
786         col.operator("transform.resize", text="Scale")
787
788         col = layout.column(align=True)
789         col.operator("lattice.make_regular")
790
791         col = layout.column(align=True)
792         col.label(text="Deform:")
793         col.operator("transform.vertex_random")
794
795
796 # ********** default tools for pose-mode ****************
797
798
799 class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
800     bl_category = "Tools"
801     bl_context = "posemode"
802     bl_label = "Pose Tools"
803
804     def draw(self, context):
805         layout = self.layout
806
807         col = layout.column(align=True)
808         col.label(text="Transform:")
809         col.operator("transform.translate")
810         col.operator("transform.rotate")
811         col.operator("transform.resize", text="Scale")
812
813         col = layout.column(align=True)
814         col.label(text="In-Between:")
815         row = col.row(align=True)
816         row.operator("pose.push", text="Push")
817         row.operator("pose.relax", text="Relax")
818         col.operator("pose.breakdown", text="Breakdowner")
819
820         col = layout.column(align=True)
821         col.label(text="Pose:")
822         row = col.row(align=True)
823         row.operator("pose.copy", text="Copy")
824         row.operator("pose.paste", text="Paste")
825
826         row = layout.row(align=True)
827         row.operator("pose.propagate", text="Propagate")
828         row.menu("VIEW3D_MT_pose_propagate", icon='TRIA_RIGHT', text="")
829
830         col = layout.column(align=True)
831         col.operator("poselib.pose_add", text="Add To Library")
832
833         draw_keyframing_tools(context, layout)
834
835         pchan = context.active_pose_bone
836         mpath = pchan.motion_path if pchan else None
837
838         col = layout.column(align=True)
839         col.label(text="Motion Paths:")
840         if mpath:
841             row = col.row(align=True)
842             row.operator("pose.paths_update", text="Update")
843             row.operator("pose.paths_clear", text="", icon='X')
844         else:
845             col.operator("pose.paths_calculate", text="Calculate")
846
847
848 class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
849     bl_category = "Options"
850     bl_context = "posemode"
851     bl_label = "Pose Options"
852
853     def draw(self, context):
854         arm = context.active_object.data
855
856         self.layout.prop(arm, "use_auto_ik")
857
858 # ********** default tools for paint modes ****************
859
860
861 class View3DPaintPanel(UnifiedPaintPanel):
862     bl_space_type = 'VIEW_3D'
863     bl_region_type = 'TOOLS'
864
865
866 class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
867     bl_category = "Tools"
868     bl_label = "Missing Data"
869
870     @classmethod
871     def poll(cls, context):
872         toolsettings = context.tool_settings.image_paint
873         return context.image_paint_object and not toolsettings.detect_data()
874
875     def draw(self, context):
876         layout = self.layout
877         toolsettings = context.tool_settings.image_paint
878
879         col = layout.column()
880         col.label("Missing Data", icon='ERROR')
881         if toolsettings.missing_uvs:
882             col.separator()
883             col.label("Missing UVs", icon='INFO')
884             col.label("Unwrap the mesh in edit mode or generate a simple UV layer")
885             col.operator("paint.add_simple_uvs")
886
887         if toolsettings.mode == 'MATERIAL':
888             if toolsettings.missing_materials:
889                 col.separator()
890                 col.label("Missing Materials", icon='INFO')
891                 col.label("Add a material and paint slot below")
892                 col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
893             elif toolsettings.missing_texture:
894                 ob = context.active_object
895                 mat = ob.active_material
896
897                 col.separator()
898                 if mat:
899                     col.label("Missing Texture Slots", icon='INFO')
900                     col.label("Add a paint slot below")
901                     col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
902                 else:
903                     col.label("Missing Materials", icon='INFO')
904                     col.label("Add a material and paint slot below")
905                     col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
906
907         elif toolsettings.mode == 'IMAGE':
908             if toolsettings.missing_texture:
909                 col.separator()
910                 col.label("Missing Canvas", icon='INFO')
911                 col.label("Add or assign a canvas image below")
912                 col.label("Canvas Image")
913                 col.template_ID(toolsettings, "canvas")
914                 col.operator("image.new", text="New").gen_context = 'PAINT_CANVAS'
915
916         if toolsettings.missing_stencil:
917             col.separator()
918             col.label("Missing Stencil", icon='INFO')
919             col.label("Add or assign a stencil image below")
920             col.label("Stencil Image")
921             col.template_ID(toolsettings, "stencil_image")
922             col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
923
924
925 class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
926     bl_category = "Tools"
927     bl_label = "Brush"
928
929     @classmethod
930     def poll(cls, context):
931         return cls.paint_settings(context)
932
933     def draw(self, context):
934         layout = self.layout
935
936         toolsettings = context.tool_settings
937         settings = self.paint_settings(context)
938         brush = settings.brush
939
940         col = layout.split().column()
941         col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
942
943         # Sculpt Mode #
944
945         if context.sculpt_object and brush:
946             capabilities = brush.sculpt_capabilities
947
948             col = layout.column()
949
950             col.separator()
951
952             row = col.row(align=True)
953
954             ups = toolsettings.unified_paint_settings
955             if ((ups.use_unified_size and ups.use_locked_size) or
956                     ((not ups.use_unified_size) and brush.use_locked_size)):
957                 self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED')
958                 self.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius")
959             else:
960                 self.prop_unified_size(row, context, brush, "use_locked_size", icon='UNLOCKED')
961                 self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
962
963             self.prop_unified_size(row, context, brush, "use_pressure_size")
964
965             # strength, use_strength_pressure, and use_strength_attenuation
966             col.separator()
967             row = col.row(align=True)
968
969             if capabilities.has_space_attenuation:
970                 row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True)
971
972             self.prop_unified_strength(row, context, brush, "strength", text="Strength")
973
974             if capabilities.has_strength_pressure:
975                 self.prop_unified_strength(row, context, brush, "use_pressure_strength")
976
977             # auto_smooth_factor and use_inverse_smooth_pressure
978             if capabilities.has_auto_smooth:
979                 col.separator()
980
981                 row = col.row(align=True)
982                 row.prop(brush, "auto_smooth_factor", slider=True)
983                 row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
984
985             # normal_weight
986             if capabilities.has_normal_weight:
987                 col.separator()
988                 row = col.row(align=True)
989                 row.prop(brush, "normal_weight", slider=True)
990
991             # crease_pinch_factor
992             if capabilities.has_pinch_factor:
993                 col.separator()
994                 row = col.row(align=True)
995                 row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
996
997             # rake_factor
998             if capabilities.has_rake_factor:
999                 col.separator()
1000                 row = col.row(align=True)
1001                 row.prop(brush, "rake_factor", slider=True)
1002
1003             # use_original_normal and sculpt_plane
1004             if capabilities.has_sculpt_plane:
1005                 col.separator()
1006                 row = col.row(align=True)
1007
1008                 row.prop(brush, "use_original_normal", toggle=True, icon_only=True)
1009
1010                 row.prop(brush, "sculpt_plane", text="")
1011
1012             if brush.sculpt_tool == 'MASK':
1013                 col.prop(brush, "mask_tool", text="")
1014
1015             # plane_offset, use_offset_pressure, use_plane_trim, plane_trim
1016             if capabilities.has_plane_offset:
1017                 row = col.row(align=True)
1018                 row.prop(brush, "plane_offset", slider=True)
1019                 row.prop(brush, "use_offset_pressure", text="")
1020
1021                 col.separator()
1022
1023                 row = col.row()
1024                 row.prop(brush, "use_plane_trim", text="Trim")
1025                 row = col.row()
1026                 row.active = brush.use_plane_trim
1027                 row.prop(brush, "plane_trim", slider=True, text="Distance")
1028
1029             # height
1030             if capabilities.has_height:
1031                 row = col.row()
1032                 row.prop(brush, "height", slider=True, text="Height")
1033
1034             # use_frontface
1035             col.separator()
1036             row = col.row()
1037             row.prop(brush, "use_frontface", text="Front Faces Only")
1038
1039             # direction
1040             col.separator()
1041             col.row().prop(brush, "direction", expand=True)
1042
1043             # use_accumulate
1044             if capabilities.has_accumulate:
1045                 col.separator()
1046
1047                 col.prop(brush, "use_accumulate")
1048
1049             # use_persistent, set_persistent_base
1050             if capabilities.has_persistence:
1051                 col.separator()
1052
1053                 ob = context.sculpt_object
1054                 do_persistent = True
1055
1056                 # not supported yet for this case
1057                 for md in ob.modifiers:
1058                     if md.type == 'MULTIRES':
1059                         do_persistent = False
1060                         break
1061
1062                 if do_persistent:
1063                     col.prop(brush, "use_persistent")
1064                     col.operator("sculpt.set_persistent_base")
1065
1066         # Texture Paint Mode #
1067
1068         elif context.image_paint_object and brush:
1069             brush_texpaint_common(self, context, layout, brush, settings, True)
1070
1071         # Weight Paint Mode #
1072         elif context.weight_paint_object and brush:
1073
1074             col = layout.column()
1075
1076             row = col.row(align=True)
1077             self.prop_unified_weight(row, context, brush, "weight", slider=True, text="Weight")
1078
1079             row = col.row(align=True)
1080             self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
1081             self.prop_unified_size(row, context, brush, "use_pressure_size")
1082
1083             row = col.row(align=True)
1084             self.prop_unified_strength(row, context, brush, "strength", text="Strength")
1085             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
1086
1087             col.prop(brush, "vertex_tool", text="Blend")
1088
1089             if brush.vertex_tool == 'BLUR':
1090                 col.prop(brush, "use_accumulate")
1091                 col.separator()
1092
1093             col = layout.column()
1094             col.prop(toolsettings, "use_auto_normalize", text="Auto Normalize")
1095             col.prop(toolsettings, "use_multipaint", text="Multi-Paint")
1096
1097         # Vertex Paint Mode #
1098         elif context.vertex_paint_object and brush:
1099             col = layout.column()
1100             self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
1101             if settings.palette:
1102                 col.template_palette(settings, "palette", color=True)
1103             self.prop_unified_color(col, context, brush, "color", text="")
1104
1105             col.separator()
1106             row = col.row(align=True)
1107             self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
1108             self.prop_unified_size(row, context, brush, "use_pressure_size")
1109
1110             row = col.row(align=True)
1111             self.prop_unified_strength(row, context, brush, "strength", text="Strength")
1112             self.prop_unified_strength(row, context, brush, "use_pressure_strength")
1113
1114             # XXX - TODO
1115             # row = col.row(align=True)
1116             # row.prop(brush, "jitter", slider=True)
1117             # row.prop(brush, "use_pressure_jitter", toggle=True, text="")
1118             col.separator()
1119             col.prop(brush, "vertex_tool", text="Blend")
1120
1121             col.separator()
1122             col.template_ID(settings, "palette", new="palette.new")
1123
1124
1125 class TEXTURE_UL_texpaintslots(UIList):
1126     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
1127         mat = data
1128
1129         if self.layout_type in {'DEFAULT', 'COMPACT'}:
1130             layout.prop(item, "name", text="", emboss=False, icon_value=icon)
1131             if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}:
1132                 mtex_index = mat.texture_paint_slots[index].index
1133                 layout.prop(mat, "use_textures", text="", index=mtex_index)
1134         elif self.layout_type == 'GRID':
1135             layout.alignment = 'CENTER'
1136             layout.label(text="")
1137
1138
1139 class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
1140     bl_label = "Clone Layer"
1141
1142     def draw(self, context):
1143         layout = self.layout
1144
1145         for i, tex in enumerate(context.active_object.data.uv_textures):
1146             props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
1147             props.data_path = "active_object.data.uv_textures.active_index"
1148             props.value = i
1149
1150
1151 class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
1152     bl_context = "imagepaint"
1153     bl_label = "Slots"
1154     bl_category = "Slots"
1155
1156     @classmethod
1157     def poll(cls, context):
1158         brush = context.tool_settings.image_paint.brush
1159         ob = context.active_object
1160         return (brush is not None and ob is not None)
1161
1162     def draw(self, context):
1163         layout = self.layout
1164
1165         settings = context.tool_settings.image_paint
1166         # brush = settings.brush
1167
1168         ob = context.active_object
1169         col = layout.column()
1170
1171         col.label("Painting Mode")
1172         col.prop(settings, "mode", text="")
1173         col.separator()
1174
1175         if settings.mode == 'MATERIAL':
1176             if len(ob.material_slots) > 1:
1177                 col.label("Materials")
1178                 col.template_list("MATERIAL_UL_matslots", "layers",
1179                                   ob, "material_slots",
1180                                   ob, "active_material_index", rows=2)
1181
1182             mat = ob.active_material
1183             if mat:
1184                 col.label("Available Paint Slots")
1185                 col.template_list("TEXTURE_UL_texpaintslots", "",
1186                                   mat, "texture_paint_images",
1187                                   mat, "paint_active_slot", rows=2)
1188
1189                 if mat.texture_paint_slots:
1190                     slot = mat.texture_paint_slots[mat.paint_active_slot]
1191                 else:
1192                     slot = None
1193
1194                 if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}:
1195                     row = col.row(align=True)
1196                     row.operator_menu_enum("paint.add_texture_paint_slot", "type")
1197                     row.operator("paint.delete_texture_paint_slot", text="", icon='X')
1198
1199                     if slot:
1200                         col.prop(mat.texture_slots[slot.index], "blend_type")
1201                         col.separator()
1202
1203                 if slot and slot.index != -1:
1204                     col.label("UV Map")
1205                     col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
1206
1207         elif settings.mode == 'IMAGE':
1208             mesh = ob.data
1209             uv_text = mesh.uv_textures.active.name if mesh.uv_textures.active else ""
1210             col.label("Canvas Image")
1211             col.template_ID(settings, "canvas")
1212             col.operator("image.new", text="New").gen_context = 'PAINT_CANVAS'
1213             col.label("UV Map")
1214             col.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
1215
1216         col.separator()
1217         col.operator("image.save_dirty", text="Save All Images")
1218
1219
1220 class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
1221     bl_context = "imagepaint"
1222     bl_label = "Mask"
1223     bl_category = "Slots"
1224
1225     @classmethod
1226     def poll(cls, context):
1227         brush = context.tool_settings.image_paint.brush
1228         ob = context.active_object
1229         return (brush is not None and ob is not None)
1230
1231     def draw_header(self, context):
1232         ipaint = context.tool_settings.image_paint
1233         self.layout.prop(ipaint, "use_stencil_layer", text="")
1234
1235     def draw(self, context):
1236         layout = self.layout
1237
1238         toolsettings = context.tool_settings
1239         ipaint = toolsettings.image_paint
1240         ob = context.active_object
1241         mesh = ob.data
1242
1243         col = layout.column()
1244         col.active = ipaint.use_stencil_layer
1245
1246         stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else ""
1247         col.label("UV Map")
1248         col.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
1249
1250         col.label("Stencil Image")
1251         col.template_ID(ipaint, "stencil_image")
1252         col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
1253
1254         col.label("Visualization")
1255         row = col.row(align=True)
1256         row.prop(ipaint, "stencil_color", text="")
1257         row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
1258
1259
1260 class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel):
1261     bl_category = "Options"
1262     bl_label = "Overlay"
1263
1264     @classmethod
1265     def poll(cls, context):
1266         settings = cls.paint_settings(context)
1267         return (settings and
1268                 settings.brush and
1269                 (context.sculpt_object or
1270                  context.vertex_paint_object or
1271                  context.weight_paint_object or
1272                  context.image_paint_object))
1273
1274     def draw(self, context):
1275         layout = self.layout
1276
1277         settings = self.paint_settings(context)
1278         brush = settings.brush
1279         tex_slot = brush.texture_slot
1280         tex_slot_mask = brush.mask_texture_slot
1281
1282         col = layout.column()
1283
1284         col.label(text="Curve:")
1285
1286         row = col.row(align=True)
1287         if brush.use_cursor_overlay:
1288             row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
1289         else:
1290             row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
1291
1292         sub = row.row(align=True)
1293         sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
1294         sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
1295
1296         col.active = brush.brush_capabilities.has_overlay
1297
1298         if context.image_paint_object or context.sculpt_object or context.vertex_paint_object:
1299             col.label(text="Texture:")
1300             row = col.row(align=True)
1301             if tex_slot.map_mode != 'STENCIL':
1302                 if brush.use_primary_overlay:
1303                     row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
1304                 else:
1305                     row.prop(brush, "use_primary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
1306
1307             sub = row.row(align=True)
1308             sub.prop(brush, "texture_overlay_alpha", text="Alpha")
1309             sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
1310
1311         if context.image_paint_object:
1312             col.label(text="Mask Texture:")
1313
1314             row = col.row(align=True)
1315             if tex_slot_mask.map_mode != 'STENCIL':
1316                 if brush.use_secondary_overlay:
1317                     row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
1318                 else:
1319                     row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
1320
1321             sub = row.row(align=True)
1322             sub.prop(brush, "mask_overlay_alpha", text="Alpha")
1323             sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
1324
1325
1326 class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
1327     bl_category = "Tools"
1328     bl_label = "Texture"
1329     bl_options = {'DEFAULT_CLOSED'}
1330
1331     @classmethod
1332     def poll(cls, context):
1333         settings = cls.paint_settings(context)
1334         return (settings and settings.brush and
1335                 (context.sculpt_object or context.image_paint_object or context.vertex_paint_object))
1336
1337     def draw(self, context):
1338         layout = self.layout
1339
1340         settings = self.paint_settings(context)
1341         brush = settings.brush
1342
1343         col = layout.column()
1344
1345         col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
1346
1347         brush_texture_settings(col, brush, context.sculpt_object)
1348
1349
1350 class VIEW3D_PT_tools_mask_texture(Panel, View3DPaintPanel):
1351     bl_category = "Tools"
1352     bl_context = "imagepaint"
1353     bl_label = "Texture Mask"
1354     bl_options = {'DEFAULT_CLOSED'}
1355
1356     @classmethod
1357     def poll(cls, context):
1358         settings = cls.paint_settings(context)
1359         return (settings and settings.brush and context.image_paint_object)
1360
1361     def draw(self, context):
1362         layout = self.layout
1363
1364         brush = context.tool_settings.image_paint.brush
1365
1366         col = layout.column()
1367
1368         col.template_ID_preview(brush, "mask_texture", new="texture.new", rows=3, cols=8)
1369
1370         brush_mask_texture_settings(col, brush)
1371
1372
1373 class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
1374     bl_category = "Tools"
1375     bl_label = "Stroke"
1376     bl_options = {'DEFAULT_CLOSED'}
1377
1378     @classmethod
1379     def poll(cls, context):
1380         settings = cls.paint_settings(context)
1381         return (settings and
1382                 settings.brush and
1383                 (context.sculpt_object or
1384                  context.vertex_paint_object or
1385                  context.weight_paint_object or
1386                  context.image_paint_object))
1387
1388     def draw(self, context):
1389         layout = self.layout
1390
1391         settings = self.paint_settings(context)
1392         brush = settings.brush
1393
1394         col = layout.column()
1395
1396         col.label(text="Stroke Method:")
1397
1398         col.prop(brush, "stroke_method", text="")
1399
1400         if brush.use_anchor:
1401             col.separator()
1402             col.prop(brush, "use_edge_to_edge", "Edge To Edge")
1403
1404         if brush.use_airbrush:
1405             col.separator()
1406             col.prop(brush, "rate", text="Rate", slider=True)
1407
1408         if brush.use_space:
1409             col.separator()
1410             row = col.row(align=True)
1411             row.prop(brush, "spacing", text="Spacing")
1412             row.prop(brush, "use_pressure_spacing", toggle=True, text="")
1413
1414         if brush.use_line or brush.use_curve:
1415             col.separator()
1416             row = col.row(align=True)
1417             row.prop(brush, "spacing", text="Spacing")
1418
1419         if brush.use_curve:
1420             col.separator()
1421             col.template_ID(brush, "paint_curve", new="paintcurve.new")
1422             col.operator("paintcurve.draw")
1423
1424         if context.sculpt_object:
1425             if brush.sculpt_capabilities.has_jitter:
1426                 col.separator()
1427
1428                 row = col.row(align=True)
1429                 row.prop(brush, "use_relative_jitter", icon_only=True)
1430                 if brush.use_relative_jitter:
1431                     row.prop(brush, "jitter", slider=True)
1432                 else:
1433                     row.prop(brush, "jitter_absolute")
1434                 row.prop(brush, "use_pressure_jitter", toggle=True, text="")
1435
1436             if brush.sculpt_capabilities.has_smooth_stroke:
1437                 col = layout.column()
1438                 col.separator()
1439
1440                 col.prop(brush, "use_smooth_stroke")
1441
1442                 sub = col.column()
1443                 sub.active = brush.use_smooth_stroke
1444                 sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
1445                 sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
1446         else:
1447             col.separator()
1448
1449             row = col.row(align=True)
1450             row.prop(brush, "use_relative_jitter", icon_only=True)
1451             if brush.use_relative_jitter:
1452                 row.prop(brush, "jitter", slider=True)
1453             else:
1454                 row.prop(brush, "jitter_absolute")
1455             row.prop(brush, "use_pressure_jitter", toggle=True, text="")
1456
1457             col = layout.column()
1458             col.separator()
1459
1460             if brush.brush_capabilities.has_smooth_stroke:
1461                 col.prop(brush, "use_smooth_stroke")
1462
1463                 sub = col.column()
1464                 sub.active = brush.use_smooth_stroke
1465                 sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
1466                 sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
1467
1468         layout.prop(settings, "input_samples")
1469
1470
1471 class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
1472     bl_category = "Tools"
1473     bl_label = "Curve"
1474     bl_options = {'DEFAULT_CLOSED'}
1475
1476     @classmethod
1477     def poll(cls, context):
1478         settings = cls.paint_settings(context)
1479         return (settings and settings.brush and settings.brush.curve)
1480
1481     def draw(self, context):
1482         layout = self.layout
1483
1484         settings = self.paint_settings(context)
1485
1486         brush = settings.brush
1487
1488         layout.template_curve_mapping(brush, "curve", brush=True)
1489
1490         col = layout.column(align=True)
1491         row = col.row(align=True)
1492         row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
1493         row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
1494         row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
1495         row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
1496         row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
1497         row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
1498
1499
1500 class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
1501     bl_category = "Tools"
1502     bl_label = "Dyntopo"
1503     bl_options = {'DEFAULT_CLOSED'}
1504
1505     @classmethod
1506     def poll(cls, context):
1507         return (context.sculpt_object and context.tool_settings.sculpt)
1508
1509     def draw(self, context):
1510         layout = self.layout
1511
1512         toolsettings = context.tool_settings
1513         sculpt = toolsettings.sculpt
1514         settings = self.paint_settings(context)
1515         brush = settings.brush
1516
1517         if context.sculpt_object.use_dynamic_topology_sculpting:
1518             layout.operator("sculpt.dynamic_topology_toggle", icon='X', text="Disable Dyntopo")
1519         else:
1520             layout.operator("sculpt.dynamic_topology_toggle", icon='SCULPT_DYNTOPO', text="Enable Dyntopo")
1521
1522         col = layout.column()
1523         col.active = context.sculpt_object.use_dynamic_topology_sculpting
1524         sub = col.column(align=True)
1525         sub.active = (brush and brush.sculpt_tool != 'MASK')
1526         if (sculpt.detail_type_method == 'CONSTANT'):
1527             row = sub.row(align=True)
1528             row.prop(sculpt, "constant_detail")
1529             row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
1530         elif (sculpt.detail_type_method == 'BRUSH'):
1531             sub.prop(sculpt, "detail_percent")
1532         else:
1533             sub.prop(sculpt, "detail_size")
1534         sub.prop(sculpt, "detail_refine_method", text="")
1535         sub.prop(sculpt, "detail_type_method", text="")
1536         col.separator()
1537         col.prop(sculpt, "use_smooth_shading")
1538         col.operator("sculpt.optimize")
1539         if (sculpt.detail_type_method == 'CONSTANT'):
1540             col.operator("sculpt.detail_flood_fill")
1541         col.separator()
1542         col.prop(sculpt, "symmetrize_direction")
1543         col.operator("sculpt.symmetrize")
1544
1545
1546 class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
1547     bl_category = "Options"
1548     bl_label = "Options"
1549     bl_options = {'DEFAULT_CLOSED'}
1550
1551     @classmethod
1552     def poll(cls, context):
1553         return (context.sculpt_object and context.tool_settings.sculpt)
1554
1555     def draw(self, context):
1556         layout = self.layout
1557         # scene = context.scene
1558
1559         toolsettings = context.tool_settings
1560         sculpt = toolsettings.sculpt
1561         capabilities = sculpt.brush.sculpt_capabilities
1562
1563         col = layout.column(align=True)
1564         col.active = capabilities.has_gravity
1565         col.label(text="Gravity:")
1566         col.prop(sculpt, "gravity", slider=True, text="Factor")
1567         col.prop(sculpt, "gravity_object")
1568         col.separator()
1569
1570         layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
1571         layout.prop(sculpt, "show_low_resolution")
1572         layout.prop(sculpt, "use_deform_only")
1573         layout.prop(sculpt, "show_diffuse_color")
1574
1575         self.unified_paint_settings(layout, context)
1576
1577
1578 class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
1579     bl_category = "Tools"
1580     bl_label = "Symmetry / Lock"
1581     bl_options = {'DEFAULT_CLOSED'}
1582
1583     @classmethod
1584     def poll(cls, context):
1585         return (context.sculpt_object and context.tool_settings.sculpt)
1586
1587     def draw(self, context):
1588         layout = self.layout
1589
1590         sculpt = context.tool_settings.sculpt
1591
1592         col = layout.column(align=True)
1593         col.label(text="Mirror:")
1594         row = col.row(align=True)
1595         row.prop(sculpt, "use_symmetry_x", text="X", toggle=True)
1596         row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True)
1597         row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True)
1598
1599         layout.column().prop(sculpt, "radial_symmetry", text="Radial")
1600         layout.prop(sculpt, "use_symmetry_feather", text="Feather")
1601
1602         layout.label(text="Lock:")
1603
1604         row = layout.row(align=True)
1605         row.prop(sculpt, "lock_x", text="X", toggle=True)
1606         row.prop(sculpt, "lock_y", text="Y", toggle=True)
1607         row.prop(sculpt, "lock_z", text="Z", toggle=True)
1608
1609         layout.label(text="Tiling:")
1610
1611         row = layout.row(align=True)
1612         row.prop(sculpt, "tile_x", text="X", toggle=True)
1613         row.prop(sculpt, "tile_y", text="Y", toggle=True)
1614         row.prop(sculpt, "tile_z", text="Z", toggle=True)
1615
1616         layout.column().prop(sculpt, "tile_offset", text="Tile Offset")
1617
1618
1619 class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
1620     bl_category = "Options"
1621     bl_label = "Appearance"
1622
1623     @classmethod
1624     def poll(cls, context):
1625         settings = cls.paint_settings(context)
1626         return (settings is not None)
1627
1628     def draw(self, context):
1629         layout = self.layout
1630
1631         settings = self.paint_settings(context)
1632         brush = settings.brush
1633
1634         if brush is None:  # unlikely but can happen
1635             layout.label(text="Brush Unset")
1636             return
1637
1638         col = layout.column()
1639         col.prop(settings, "show_brush")
1640
1641         sub = col.column()
1642         sub.active = settings.show_brush
1643
1644         if context.sculpt_object and context.tool_settings.sculpt:
1645             if brush.sculpt_capabilities.has_secondary_color:
1646                 sub.row().prop(brush, "cursor_color_add", text="Add")
1647                 sub.row().prop(brush, "cursor_color_subtract", text="Subtract")
1648             else:
1649                 sub.prop(brush, "cursor_color_add", text="")
1650         else:
1651             sub.prop(brush, "cursor_color_add", text="")
1652
1653         col.separator()
1654
1655         col = col.column(align=True)
1656         col.prop(brush, "use_custom_icon")
1657         sub = col.column()
1658         sub.active = brush.use_custom_icon
1659         sub.prop(brush, "icon_filepath", text="")
1660
1661 # ********** default tools for weight-paint ****************
1662
1663
1664 class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
1665     bl_category = "Tools"
1666     bl_context = "weightpaint"
1667     bl_label = "Weight Tools"
1668
1669     def draw(self, context):
1670         layout = self.layout
1671         VIEW3D_PT_tools_meshweight.draw_generic(layout)
1672
1673         col = layout.column()
1674         col.operator("paint.weight_gradient")
1675         props = col.operator("object.data_transfer", text="Transfer Weights")
1676         props.use_reverse_transfer = True
1677         props.data_type = 'VGROUP_WEIGHTS'
1678
1679
1680 class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
1681     bl_category = "Options"
1682     bl_context = "weightpaint"
1683     bl_label = "Options"
1684
1685     def draw(self, context):
1686         layout = self.layout
1687
1688         tool_settings = context.tool_settings
1689         wpaint = tool_settings.weight_paint
1690
1691         col = layout.column()
1692         row = col.row()
1693
1694         row.prop(wpaint, "use_normal")
1695         col = layout.column()
1696         row = col.row()
1697         row.prop(wpaint, "use_spray")
1698         row.prop(wpaint, "use_group_restrict")
1699
1700         obj = context.weight_paint_object
1701         if obj.type == 'MESH':
1702             mesh = obj.data
1703             col.prop(mesh, "use_mirror_x")
1704             row = col.row()
1705             row.active = mesh.use_mirror_x
1706             row.prop(mesh, "use_mirror_topology")
1707
1708         col.label("Show Zero Weights:")
1709         sub = col.row()
1710         sub.prop(tool_settings, "vertex_group_user", expand=True)
1711
1712         self.unified_paint_settings(col, context)
1713
1714 # ********** default tools for vertex-paint ****************
1715
1716
1717 class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
1718     bl_category = "Options"
1719     bl_context = "vertexpaint"
1720     bl_label = "Options"
1721
1722     def draw(self, context):
1723         layout = self.layout
1724
1725         toolsettings = context.tool_settings
1726         vpaint = toolsettings.vertex_paint
1727
1728         col = layout.column()
1729         row = col.row()
1730         # col.prop(vpaint, "mode", text="")
1731         row.prop(vpaint, "use_normal")
1732         col.prop(vpaint, "use_spray")
1733
1734         self.unified_paint_settings(col, context)
1735
1736 # Commented out because the Apply button isn't an operator yet, making these settings useless
1737 #~         col.label(text="Gamma:")
1738 #~         col.prop(vpaint, "gamma", text="")
1739 #~         col.label(text="Multiply:")
1740 #~         col.prop(vpaint, "mul", text="")
1741
1742 # ********** default tools for texture-paint ****************
1743
1744
1745 class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
1746     bl_category = "Tools"
1747     bl_context = "imagepaint"
1748     bl_label = "External"
1749     bl_options = {'DEFAULT_CLOSED'}
1750
1751     def draw(self, context):
1752         layout = self.layout
1753
1754         toolsettings = context.tool_settings
1755         ipaint = toolsettings.image_paint
1756
1757         col = layout.column()
1758         row = col.split(align=True, percentage=0.55)
1759         row.operator("image.project_edit", text="Quick Edit")
1760         row.operator("image.project_apply", text="Apply")
1761
1762         col.row().prop(ipaint, "screen_grab_size", text="")
1763
1764         col.operator("paint.project_image", text="Apply Camera Image")
1765
1766
1767 class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
1768     bl_category = "Tools"
1769     bl_context = "imagepaint"
1770     bl_label = "Symmetry"
1771     bl_options = {'DEFAULT_CLOSED'}
1772
1773     def draw(self, context):
1774         layout = self.layout
1775
1776         toolsettings = context.tool_settings
1777         ipaint = toolsettings.image_paint
1778
1779         col = layout.column(align=True)
1780         row = col.row(align=True)
1781         row.prop(ipaint, "use_symmetry_x", text="X", toggle=True)
1782         row.prop(ipaint, "use_symmetry_y", text="Y", toggle=True)
1783         row.prop(ipaint, "use_symmetry_z", text="Z", toggle=True)
1784
1785
1786 class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
1787     bl_category = "Options"
1788     bl_context = "imagepaint"
1789     bl_label = "Project Paint"
1790
1791     @classmethod
1792     def poll(cls, context):
1793         brush = context.tool_settings.image_paint.brush
1794         return (brush is not None)
1795
1796     def draw(self, context):
1797         layout = self.layout
1798
1799         toolsettings = context.tool_settings
1800         ipaint = toolsettings.image_paint
1801
1802         col = layout.column()
1803
1804         col.prop(ipaint, "use_occlude")
1805         col.prop(ipaint, "use_backface_culling")
1806
1807         row = layout.row()
1808         row.prop(ipaint, "use_normal_falloff")
1809
1810         sub = row.row()
1811         sub.active = (ipaint.use_normal_falloff)
1812         sub.prop(ipaint, "normal_angle", text="")
1813
1814         layout.prop(ipaint, "use_cavity")
1815         if ipaint.use_cavity:
1816             layout.template_curve_mapping(ipaint, "cavity_curve", brush=True)
1817
1818         layout.prop(ipaint, "seam_bleed")
1819         layout.prop(ipaint, "dither")
1820         self.unified_paint_settings(layout, context)
1821
1822
1823 class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
1824     bl_category = "Options"
1825     bl_label = "Options"
1826
1827     @classmethod
1828     def poll(cls, context):
1829         return (context.image_paint_object and context.tool_settings.image_paint)
1830
1831     def draw(self, context):
1832         layout = self.layout
1833
1834         col = layout.column()
1835         self.unified_paint_settings(col, context)
1836
1837
1838 class VIEW3D_MT_tools_projectpaint_stencil(Menu):
1839     bl_label = "Mask Layer"
1840
1841     def draw(self, context):
1842         layout = self.layout
1843         for i, tex in enumerate(context.active_object.data.uv_textures):
1844             props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
1845             props.data_path = "active_object.data.uv_texture_stencil_index"
1846             props.value = i
1847
1848
1849 # Grease Pencil drawing tools
1850 class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
1851     bl_space_type = 'VIEW_3D'
1852
1853
1854 # Grease Pencil stroke editing tools
1855 class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
1856     bl_space_type = 'VIEW_3D'
1857
1858
1859 # Grease Pencil stroke sculpting tools
1860 class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
1861     bl_space_type = 'VIEW_3D'
1862
1863
1864 # Note: moved here so that it's always in last position in 'Tools' panels!
1865 class VIEW3D_PT_tools_history(View3DPanel, Panel):
1866     bl_category = "Tools"
1867     # No bl_context, we are always available!
1868     bl_label = "History"
1869     bl_options = {'DEFAULT_CLOSED'}
1870
1871     def draw(self, context):
1872         layout = self.layout
1873         obj = context.object
1874
1875         col = layout.column(align=True)
1876         row = col.row(align=True)
1877         row.operator("ed.undo")
1878         row.operator("ed.redo")
1879         if obj is None or obj.mode != 'SCULPT':
1880             # Sculpt mode does not generate an undo menu it seems...
1881             col.operator("ed.undo_history")
1882
1883         col = layout.column(align=True)
1884         col.label(text="Repeat:")
1885         col.operator("screen.repeat_last")
1886         col.operator("screen.repeat_history", text="History...")
1887
1888
1889 if __name__ == "__main__":  # only for live edit.
1890     bpy.utils.register_module(__name__)