1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
21 from bpy.types import Menu, Panel, UIList
22 from .properties_grease_pencil_common import (
23 GreasePencilStrokeEditPanel,
24 GreasePencilStrokeSculptPanel,
25 GreasePencilSculptOptionsPanel,
26 GreasePencilAppearancePanel,
28 from .properties_paint_common import (
30 brush_mask_texture_settings,
31 brush_texpaint_common,
32 brush_texture_settings,
34 from bl_operators.presets import PresetMenu
38 bl_space_type = 'PROPERTIES'
39 bl_region_type = 'WINDOW'
42 # **************** standard tool clusters ******************
45 def draw_keyframing_tools(context, layout):
46 col = layout.column(align=True)
47 col.label(text="Keyframes:")
48 row = col.row(align=True)
49 row.operator("anim.keyframe_insert_menu", text="Insert")
50 row.operator("anim.keyframe_delete_v3d", text="Remove")
53 # Used by vertex & weight paint
54 def draw_vpaint_symmetry(layout, vpaint):
56 split = layout.split()
59 col.alignment = 'RIGHT'
60 col.label(text="Mirror")
63 row = col.row(align=True)
64 row.prop(vpaint, "use_symmetry_x", text="X", toggle=True)
65 row.prop(vpaint, "use_symmetry_y", text="Y", toggle=True)
66 row.prop(vpaint, "use_symmetry_z", text="Z", toggle=True)
69 col.use_property_split = True
70 col.use_property_decorate = False
71 col.prop(vpaint, "radial_symmetry", text="Radial")
73 # Most of these panels should not be visible in GP edit modes
76 def is_not_gpencil_edit_mode(context):
78 context.active_object and
79 context.active_object.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}
84 # ********** default tools for editmode_mesh ****************
87 class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
88 bl_category = "Options"
89 bl_context = ".mesh_edit" # dot on purpose (access from topbar)
90 bl_label = "Mesh Options"
91 bl_options = {'DEFAULT_CLOSED'}
94 def poll(cls, context):
95 return context.active_object
97 def draw(self, context):
100 layout.use_property_split = True
101 layout.use_property_decorate = False
103 ob = context.active_object
105 tool_settings = context.tool_settings
108 col = layout.column(align=True)
109 col.prop(mesh, "use_mirror_x")
111 row = col.row(align=True)
112 row.active = ob.data.use_mirror_x
113 row.prop(mesh, "use_mirror_topology")
115 layout.prop(tool_settings, "use_edge_path_live_unwrap")
116 layout.prop(tool_settings, "use_mesh_automerge")
118 layout.prop(tool_settings, "double_threshold")
119 layout.prop(tool_settings, "edge_path_mode")
121 # ********** default tools for editmode_curve ****************
124 class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel):
125 bl_category = "Options"
126 bl_context = ".curve_edit" # dot on purpose (access from topbar)
127 bl_label = "Curve Stroke"
129 def draw(self, context):
132 tool_settings = context.tool_settings
133 cps = tool_settings.curve_paint_settings
135 col = layout.column()
137 col.prop(cps, "curve_type")
139 if cps.curve_type == 'BEZIER':
140 col.label(text="Bezier Options:")
141 col.prop(cps, "error_threshold")
142 col.prop(cps, "fit_method")
143 col.prop(cps, "use_corners_detect")
145 col = layout.column()
146 col.active = cps.use_corners_detect
147 col.prop(cps, "corner_angle")
149 col.label(text="Pressure Radius:")
150 row = layout.row(align=True)
151 rowsub = row.row(align=True)
152 rowsub.prop(cps, "radius_min", text="Min")
153 rowsub.prop(cps, "radius_max", text="Max")
155 row.prop(cps, "use_pressure_radius", text="", icon_only=True)
157 col = layout.column()
158 col.label(text="Taper Radius:")
159 row = layout.row(align=True)
160 row.prop(cps, "radius_taper_start", text="Start")
161 row.prop(cps, "radius_taper_end", text="End")
163 col = layout.column()
164 col.label(text="Projection Depth:")
165 row = layout.row(align=True)
166 row.prop(cps, "depth_mode", expand=True)
168 col = layout.column()
169 if cps.depth_mode == 'SURFACE':
170 col.prop(cps, "surface_offset")
171 col.prop(cps, "use_offset_absolute")
172 col.prop(cps, "use_stroke_endpoints")
173 if cps.use_stroke_endpoints:
174 colsub = layout.column(align=True)
175 colsub.prop(cps, "surface_plane", expand=True)
178 # ********** default tools for editmode_armature ****************
181 class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
182 bl_category = "Options"
183 bl_context = ".armature_edit" # dot on purpose (access from topbar)
184 bl_label = "Armature Options"
186 def draw(self, context):
187 arm = context.active_object.data
189 self.layout.prop(arm, "use_mirror_x")
192 # ********** default tools for pose-mode ****************
194 class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
195 bl_category = "Options"
196 bl_context = ".posemode" # dot on purpose (access from topbar)
197 bl_label = "Pose Options"
199 def draw(self, context):
200 arm = context.active_object.data
202 self.layout.prop(arm, "use_auto_ik")
203 self.layout.prop(arm, "use_mirror_x")
205 # ********** default tools for paint modes ****************
208 class View3DPaintPanel(UnifiedPaintPanel):
209 bl_space_type = 'PROPERTIES'
210 bl_region_type = 'WINDOW'
213 # TODO, move to space_view3d.py
214 class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
215 bl_context = ".paint_common" # dot on purpose (access from topbar)
219 def poll(cls, context):
220 return cls.paint_settings(context)
222 def draw(self, context):
225 tool_settings = context.tool_settings
226 settings = self.paint_settings(context)
227 brush = settings.brush
229 if not context.particle_edit_object:
230 col = layout.split().column()
231 col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8)
234 if context.particle_edit_object:
238 layout.column().prop(settings, "tool")
239 col = layout.column()
240 col.prop(brush, "size", slider=True)
242 col.prop(brush, "count")
244 col = layout.column()
245 col.prop(settings, "use_default_interpolate")
246 col.prop(brush, "steps", slider=True)
247 col.prop(settings, "default_key_count", slider=True)
249 col.prop(brush, "strength", slider=True)
252 layout.row().prop(brush, "length_mode", expand=True)
254 layout.row().prop(brush, "puff_mode", expand=True)
255 layout.prop(brush, "use_puff_volume")
259 elif context.sculpt_object and brush:
260 from .properties_paint_common import (
261 brush_basic_sculpt_settings,
264 capabilities = brush.sculpt_capabilities
266 col = layout.column()
270 if not self.is_popover:
271 brush_basic_sculpt_settings(col, context, brush)
273 # topology_rake_factor
274 if (capabilities.has_topology_rake and
275 context.sculpt_object.use_dynamic_topology_sculpting
279 row.prop(brush, "topology_rake_factor", slider=True)
281 # auto_smooth_factor and use_inverse_smooth_pressure
282 if capabilities.has_auto_smooth:
285 row = col.row(align=True)
286 row.prop(brush, "auto_smooth_factor", slider=True)
287 row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
290 if capabilities.has_normal_weight:
292 row = col.row(align=True)
293 row.prop(brush, "normal_weight", slider=True)
295 # crease_pinch_factor
296 if capabilities.has_pinch_factor:
298 row = col.row(align=True)
299 row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
302 if capabilities.has_rake_factor:
304 row = col.row(align=True)
305 row.prop(brush, "rake_factor", slider=True)
307 # use_original_normal and sculpt_plane
308 if capabilities.has_sculpt_plane:
310 row = col.row(align=True)
312 row.prop(brush, "use_original_normal", toggle=True, icon_only=True)
314 row.prop(brush, "sculpt_plane", text="")
316 if brush.sculpt_tool == 'MASK':
317 col.prop(brush, "mask_tool", text="")
319 # plane_offset, use_offset_pressure, use_plane_trim, plane_trim
320 if capabilities.has_plane_offset:
321 row = col.row(align=True)
322 row.prop(brush, "plane_offset", slider=True)
323 row.prop(brush, "use_offset_pressure", text="")
328 row.prop(brush, "use_plane_trim", text="Trim")
330 row.active = brush.use_plane_trim
331 row.prop(brush, "plane_trim", slider=True, text="Distance")
334 if capabilities.has_height:
336 row.prop(brush, "height", slider=True, text="Height")
340 col.prop(brush, "use_frontface", text="Front Faces Only")
341 col.prop(brush, "use_projected")
344 if capabilities.has_accumulate:
347 col.prop(brush, "use_accumulate")
349 # use_persistent, set_persistent_base
350 if capabilities.has_persistence:
353 ob = context.sculpt_object
356 # not supported yet for this case
357 for md in ob.modifiers:
358 if md.type == 'MULTIRES':
359 do_persistent = False
363 col.prop(brush, "use_persistent")
364 col.operator("sculpt.set_persistent_base")
366 # Texture Paint Mode #
368 elif context.image_paint_object and brush:
369 brush_texpaint_common(self, context, layout, brush, settings, True)
371 # Weight Paint Mode #
372 elif context.weight_paint_object and brush:
373 from .properties_paint_common import (
374 brush_basic_wpaint_settings,
377 col = layout.column()
379 if not self.is_popover:
380 brush_basic_wpaint_settings(col, context, brush)
382 if brush.weight_tool != 'SMEAR':
383 col.prop(brush, "use_accumulate")
386 col.prop(brush, "use_frontface", text="Front Faces Only")
388 row.prop(brush, "use_frontface_falloff", text="Falloff Angle")
390 sub.active = brush.use_frontface_falloff
391 sub.prop(brush, "falloff_angle", text="")
393 col.prop(brush, "use_projected")
395 col = layout.column()
396 col.prop(tool_settings, "use_auto_normalize", text="Auto Normalize")
397 col.prop(tool_settings, "use_multipaint", text="Multi-Paint")
399 # Vertex Paint Mode #
400 elif context.vertex_paint_object and brush:
401 from .properties_paint_common import (
402 brush_basic_vpaint_settings,
405 col = layout.column()
406 self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
408 col.template_palette(settings, "palette", color=True)
409 row = col.row(align=True)
410 self.prop_unified_color(row, context, brush, "color", text="")
411 self.prop_unified_color(row, context, brush, "secondary_color", text="")
413 row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="")
417 if not self.is_popover:
418 brush_basic_vpaint_settings(col, context, brush)
420 col.prop(brush, "use_alpha")
422 if brush.vertex_tool != 'SMEAR':
423 col.prop(brush, "use_accumulate")
426 col.prop(brush, "use_frontface", text="Front Faces Only")
428 row.prop(brush, "use_frontface_falloff", text="Falloff Angle")
430 sub.active = brush.use_frontface_falloff
431 sub.prop(brush, "falloff_angle", text="")
433 col.prop(brush, "use_projected")
436 col.template_ID(settings, "palette", new="palette.new")
439 class TEXTURE_UL_texpaintslots(UIList):
440 def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
443 if self.layout_type in {'DEFAULT', 'COMPACT'}:
444 layout.prop(item, "name", text="", emboss=False, icon_value=icon)
445 elif self.layout_type == 'GRID':
446 layout.alignment = 'CENTER'
447 layout.label(text="")
450 class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
451 bl_label = "Clone Layer"
453 def draw(self, context):
456 for i, uv_layer in enumerate(context.active_object.data.uv_layers):
457 props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False)
458 props.data_path = "active_object.data.uv_layers.active_index"
462 class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
463 bl_context = ".imagepaint" # dot on purpose (access from topbar)
464 bl_label = "Texture Slots"
467 def poll(cls, context):
468 brush = context.tool_settings.image_paint.brush
469 ob = context.active_object
470 return (brush is not None and ob is not None)
472 def draw(self, context):
474 layout.use_property_split = True
475 layout.use_property_decorate = False
477 settings = context.tool_settings.image_paint
479 ob = context.active_object
481 layout.prop(settings, "mode", text="Mode")
484 if settings.mode == 'MATERIAL':
485 if len(ob.material_slots) > 1:
486 layout.template_list("MATERIAL_UL_matslots", "layers",
487 ob, "material_slots",
488 ob, "active_material_index", rows=2)
489 mat = ob.active_material
490 if mat and mat.texture_paint_images:
492 row.template_list("TEXTURE_UL_texpaintslots", "",
493 mat, "texture_paint_images",
494 mat, "paint_active_slot", rows=2)
496 if mat.texture_paint_slots:
497 slot = mat.texture_paint_slots[mat.paint_active_slot]
501 have_image = slot is not None
506 box.label(text="No Textures")
509 sub = row.column(align=True)
510 sub.operator_menu_enum("paint.add_texture_paint_slot", "type", icon='ADD', text="")
512 elif settings.mode == 'IMAGE':
514 uv_text = mesh.uv_layers.active.name if mesh.uv_layers.active else ""
515 layout.template_ID(settings, "canvas", new="image.new", open="image.open")
516 if settings.missing_uvs:
517 layout.operator("paint.add_simple_uvs", icon='ADD', text="Add UVs")
519 layout.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
520 have_image = settings.canvas is not None
522 layout.prop(settings, "interpolation", text="")
524 if settings.missing_uvs:
526 split = layout.split()
527 split.label(text="UV Map Needed", icon='INFO')
528 split.operator("paint.add_simple_uvs", icon='ADD', text="Add Simple UVs")
531 layout.operator("image.save_dirty", text="Save All Images", icon='FILE_TICK')
533 # TODO, move to space_view3d.py
536 class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
537 bl_context = ".imagepaint" # dot on purpose (access from topbar)
539 bl_options = {'DEFAULT_CLOSED'}
542 def poll(cls, context):
543 brush = context.tool_settings.image_paint.brush
544 ob = context.active_object
545 return (brush is not None and ob is not None)
547 def draw_header(self, context):
548 ipaint = context.tool_settings.image_paint
549 self.layout.prop(ipaint, "use_stencil_layer", text="")
551 def draw(self, context):
553 layout.use_property_split = True
554 layout.use_property_decorate = False
556 tool_settings = context.tool_settings
557 ipaint = tool_settings.image_paint
558 ob = context.active_object
561 col = layout.column()
562 col.active = ipaint.use_stencil_layer
564 stencil_text = mesh.uv_layer_stencil.name if mesh.uv_layer_stencil else ""
565 split = col.split(factor=0.5)
566 colsub = split.column()
567 colsub.alignment = 'RIGHT'
568 colsub.label(text="UV Layer")
569 split.column().menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
571 # todo this should be combinded into a single row
572 split = col.split(factor=0.5)
573 colsub = split.column()
574 colsub.alignment = 'RIGHT'
575 colsub.label(text="Stencil Image")
576 colsub = split.column()
577 colsub.template_ID(ipaint, "stencil_image", new="image.new", open="image.open")
579 row = col.row(align=True)
580 row.prop(ipaint, "stencil_color", text="Display Color")
581 row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
584 # TODO, move to space_view3d.py
585 class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel):
586 bl_context = ".paint_common" # dot on purpose (access from topbar)
588 bl_options = {'DEFAULT_CLOSED'}
591 def poll(cls, context):
592 settings = cls.paint_settings(context)
595 (context.sculpt_object or
596 context.vertex_paint_object or
597 context.weight_paint_object or
598 context.image_paint_object))
600 def draw(self, context):
602 layout.use_property_split = True
603 layout.use_property_decorate = False
605 settings = self.paint_settings(context)
606 brush = settings.brush
607 tex_slot = brush.texture_slot
608 tex_slot_mask = brush.mask_texture_slot
610 col = layout.column()
612 row = col.row(align=True)
614 sub = row.row(align=True)
615 sub.prop(brush, "cursor_overlay_alpha", text="Curve Alpha")
616 sub.prop(brush, "use_cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
618 brush, "use_cursor_overlay", text="", toggle=True,
619 icon='HIDE_OFF' if brush.use_cursor_overlay else 'HIDE_ON',
622 col.active = brush.brush_capabilities.has_overlay
624 if context.image_paint_object or context.sculpt_object or context.vertex_paint_object:
625 row = col.row(align=True)
627 sub = row.row(align=True)
628 sub.prop(brush, "texture_overlay_alpha", text="Texture Alpha")
629 sub.prop(brush, "use_primary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
630 if tex_slot.map_mode != 'STENCIL':
632 brush, "use_primary_overlay", text="", toggle=True,
633 icon='HIDE_OFF' if brush.use_primary_overlay else 'HIDE_ON',
636 if context.image_paint_object:
637 row = col.row(align=True)
639 sub = row.row(align=True)
640 sub.prop(brush, "mask_overlay_alpha", text="Mask Texture Alpha")
641 sub.prop(brush, "use_secondary_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
642 if tex_slot_mask.map_mode != 'STENCIL':
644 brush, "use_secondary_overlay", text="", toggle=True,
645 icon='HIDE_OFF' if brush.use_secondary_overlay else 'HIDE_ON',
649 # TODO, move to space_view3d.py
650 class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
651 bl_context = ".paint_common" # dot on purpose (access from topbar)
653 bl_options = {'DEFAULT_CLOSED'}
656 def poll(cls, context):
657 settings = cls.paint_settings(context)
658 return (settings and settings.brush and
659 (context.sculpt_object or context.image_paint_object or context.vertex_paint_object))
661 def draw(self, context):
664 settings = self.paint_settings(context)
665 brush = settings.brush
667 col = layout.column()
669 col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
671 brush_texture_settings(col, brush, context.sculpt_object)
674 # TODO, move to space_view3d.py
675 class VIEW3D_PT_tools_mask_texture(Panel, View3DPaintPanel):
676 bl_context = ".imagepaint" # dot on purpose (access from topbar)
677 bl_label = "Texture Mask"
678 bl_options = {'DEFAULT_CLOSED'}
681 def poll(cls, context):
682 settings = cls.paint_settings(context)
683 return (settings and settings.brush and context.image_paint_object)
685 def draw(self, context):
688 brush = context.tool_settings.image_paint.brush
690 col = layout.column()
692 col.template_ID_preview(brush, "mask_texture", new="texture.new", rows=3, cols=8)
694 brush_mask_texture_settings(col, brush)
697 # TODO, move to space_view3d.py
698 class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
699 bl_context = ".paint_common" # dot on purpose (access from topbar)
701 bl_options = {'DEFAULT_CLOSED'}
704 def poll(cls, context):
705 settings = cls.paint_settings(context)
708 (context.sculpt_object or
709 context.vertex_paint_object or
710 context.weight_paint_object or
711 context.image_paint_object))
713 def draw(self, context):
716 settings = self.paint_settings(context)
717 brush = settings.brush
718 layout.use_property_split = True
719 layout.use_property_decorate = False
721 col = layout.column()
723 col.prop(brush, "stroke_method")
726 col.prop(brush, "use_edge_to_edge", text="Edge To Edge")
728 if brush.use_airbrush:
729 col.prop(brush, "rate", text="Rate", slider=True)
732 row = col.row(align=True)
733 row.prop(brush, "spacing", text="Spacing")
734 row.prop(brush, "use_pressure_spacing", toggle=True, text="")
736 if brush.use_line or brush.use_curve:
737 row = col.row(align=True)
738 row.prop(brush, "spacing", text="Spacing")
741 col.template_ID(brush, "paint_curve", new="paintcurve.new")
742 col.operator("paintcurve.draw")
744 if context.sculpt_object:
745 if brush.sculpt_capabilities.has_jitter:
747 row = col.row(align=True)
748 if brush.use_relative_jitter:
749 row.prop(brush, "jitter", slider=True)
751 row.prop(brush, "jitter_absolute")
752 row.prop(brush, "use_relative_jitter", icon_only=True)
753 row.prop(brush, "use_pressure_jitter", toggle=True, text="")
757 row = col.row(align=True)
758 if brush.use_relative_jitter:
759 row.prop(brush, "jitter", slider=True)
761 row.prop(brush, "jitter_absolute")
762 row.prop(brush, "use_relative_jitter", icon_only=True)
763 row.prop(brush, "use_pressure_jitter", toggle=True, text="")
765 col = layout.column()
767 layout.prop(settings, "input_samples")
770 class VIEW3D_PT_tools_brush_stroke_smooth_stroke(Panel, View3DPaintPanel):
771 bl_context = ".paint_common" # dot on purpose (access from topbar)
772 bl_label = "Smooth Stroke"
773 bl_parent_id = "VIEW3D_PT_tools_brush_stroke"
774 bl_options = {'DEFAULT_CLOSED'}
777 def poll(cls, context):
778 settings = cls.paint_settings(context)
779 brush = settings.brush
780 if brush.brush_capabilities.has_smooth_stroke:
783 def draw_header(self, context):
784 settings = self.paint_settings(context)
785 brush = settings.brush
787 self.layout.prop(brush, "use_smooth_stroke", text="")
789 def draw(self, context):
791 layout.use_property_split = True
792 layout.use_property_decorate = False
794 settings = self.paint_settings(context)
795 brush = settings.brush
797 col = layout.column()
798 col.active = brush.use_smooth_stroke
799 col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
800 col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
803 # TODO, move to space_view3d.py
804 class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
805 bl_context = ".paint_common" # dot on purpose (access from topbar)
807 bl_options = {'DEFAULT_CLOSED'}
810 def poll(cls, context):
811 settings = cls.paint_settings(context)
812 return (settings and settings.brush and settings.brush.curve)
814 def draw(self, context):
817 settings = self.paint_settings(context)
819 brush = settings.brush
821 layout.template_curve_mapping(brush, "curve", brush=True)
823 col = layout.column(align=True)
824 row = col.row(align=True)
825 row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
826 row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
827 row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
828 row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
829 row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
830 row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
833 # TODO, move to space_view3d.py
834 class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
835 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
837 bl_options = {'DEFAULT_CLOSED'}
841 def poll(cls, context):
842 return (context.sculpt_object and context.tool_settings.sculpt)
844 def draw_header(self, context):
845 is_popover = self.is_popover
848 "sculpt.dynamic_topology_toggle",
849 icon='CHECKBOX_HLT' if context.sculpt_object.use_dynamic_topology_sculpting else 'CHECKBOX_DEHLT',
854 def draw(self, context):
856 layout.use_property_split = True
857 layout.use_property_decorate = False
859 tool_settings = context.tool_settings
860 sculpt = tool_settings.sculpt
861 settings = self.paint_settings(context)
862 brush = settings.brush
864 col = layout.column()
865 col.active = context.sculpt_object.use_dynamic_topology_sculpting
868 sub.active = (brush and brush.sculpt_tool != 'MASK')
869 if sculpt.detail_type_method in {'CONSTANT', 'MANUAL'}:
870 row = sub.row(align=True)
871 row.prop(sculpt, "constant_detail_resolution")
872 row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
873 elif (sculpt.detail_type_method == 'BRUSH'):
874 sub.prop(sculpt, "detail_percent")
876 sub.prop(sculpt, "detail_size")
877 sub.prop(sculpt, "detail_refine_method", text="Refine Method")
878 sub.prop(sculpt, "detail_type_method", text="Detailing")
880 col.prop(sculpt, "use_smooth_shading")
883 class VIEW3D_PT_sculpt_dyntopo_remesh(Panel, View3DPaintPanel):
884 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
886 bl_parent_id = "VIEW3D_PT_sculpt_dyntopo"
887 bl_options = {'DEFAULT_CLOSED'}
890 def draw(self, context):
892 layout.use_property_split = True
893 layout.use_property_decorate = False
895 tool_settings = context.tool_settings
896 sculpt = tool_settings.sculpt
898 col = layout.column()
899 col.active = context.sculpt_object.use_dynamic_topology_sculpting
901 col.prop(sculpt, "symmetrize_direction")
903 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
906 col.operator("sculpt.symmetrize")
908 col.operator("sculpt.optimize")
909 if sculpt.detail_type_method in {'CONSTANT', 'MANUAL'}:
911 col.operator("sculpt.detail_flood_fill")
913 # TODO, move to space_view3d.py
916 class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
917 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
919 bl_options = {'DEFAULT_CLOSED'}
922 def poll(cls, context):
923 return (context.sculpt_object and context.tool_settings.sculpt)
925 def draw(self, context):
927 layout.use_property_split = True
928 layout.use_property_decorate = False
930 tool_settings = context.tool_settings
931 sculpt = tool_settings.sculpt
933 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
936 col.prop(sculpt, "use_threaded", text="Threaded Sculpt")
938 col.prop(sculpt, "show_low_resolution")
940 col.prop(sculpt, "use_deform_only")
942 col.prop(sculpt, "show_diffuse_color")
944 col.prop(sculpt, "show_mask")
947 class VIEW3D_PT_sculpt_options_unified(Panel, View3DPaintPanel):
948 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
949 bl_parent_id = "VIEW3D_PT_sculpt_options"
950 bl_label = "Unified Brush"
953 def poll(cls, context):
954 return (context.sculpt_object and context.tool_settings.sculpt)
956 def draw(self, context):
958 layout.use_property_split = True
959 layout.use_property_decorate = False
961 self.unified_paint_settings(layout, context)
964 class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel):
965 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
966 bl_parent_id = "VIEW3D_PT_sculpt_options"
970 def poll(cls, context):
971 return (context.sculpt_object and context.tool_settings.sculpt)
973 def draw(self, context):
975 layout.use_property_split = True
976 layout.use_property_decorate = False
978 tool_settings = context.tool_settings
979 sculpt = tool_settings.sculpt
980 capabilities = sculpt.brush.sculpt_capabilities
982 col = layout.column()
983 col.active = capabilities.has_gravity
984 col.prop(sculpt, "gravity", slider=True, text="Factor")
985 col.prop(sculpt, "gravity_object")
988 # TODO, move to space_view3d.py
989 class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
990 bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
991 bl_label = "Symmetry/Lock"
992 bl_options = {'DEFAULT_CLOSED'}
995 def poll(cls, context):
996 return (context.sculpt_object and context.tool_settings.sculpt)
998 def draw(self, context):
1001 sculpt = context.tool_settings.sculpt
1003 split = layout.split()
1005 col = split.column()
1006 col.alignment = 'RIGHT'
1007 col.label(text="Mirror")
1009 col = split.column()
1011 row = col.row(align=True)
1012 row.prop(sculpt, "use_symmetry_x", text="X", toggle=True)
1013 row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True)
1014 row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True)
1016 split = layout.split()
1018 col = split.column()
1019 col.alignment = 'RIGHT'
1020 col.label(text="Lock")
1022 col = split.column()
1024 row = col.row(align=True)
1025 row.prop(sculpt, "lock_x", text="X", toggle=True)
1026 row.prop(sculpt, "lock_y", text="Y", toggle=True)
1027 row.prop(sculpt, "lock_z", text="Z", toggle=True)
1029 split = layout.split()
1031 col = split.column()
1032 col.alignment = 'RIGHT'
1033 col.label(text="Tiling")
1035 col = split.column()
1037 row = col.row(align=True)
1038 row.prop(sculpt, "tile_x", text="X", toggle=True)
1039 row.prop(sculpt, "tile_y", text="Y", toggle=True)
1040 row.prop(sculpt, "tile_z", text="Z", toggle=True)
1042 layout.use_property_split = True
1043 layout.use_property_decorate = False
1045 layout.prop(sculpt, "use_symmetry_feather", text="Feather")
1046 layout.column().prop(sculpt, "radial_symmetry", text="Radial")
1047 layout.column().prop(sculpt, "tile_offset", text="Tile Offset")
1050 # TODO, move to space_view3d.py
1051 class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
1052 bl_context = ".paint_common" # dot on purpose (access from topbar)
1053 bl_label = "Appearance"
1054 bl_parent_id = "VIEW3D_PT_tools_brush_overlay"
1055 bl_options = {'DEFAULT_CLOSED'}
1058 def poll(cls, context):
1059 settings = cls.paint_settings(context)
1060 return (settings is not None) and (not isinstance(settings, bpy.types.ParticleEdit))
1062 def draw(self, context):
1063 layout = self.layout
1065 settings = self.paint_settings(context)
1066 brush = settings.brush
1068 if brush is None: # unlikely but can happen
1069 layout.label(text="Brush Unset")
1073 class VIEW3D_PT_tools_brush_appearance_show_brush(Panel, View3DPaintPanel):
1074 bl_context = ".paint_common" # dot on purpose (access from topbar)
1075 bl_label = "Show Brush"
1076 bl_parent_id = "VIEW3D_PT_tools_brush_appearance"
1077 bl_options = {'DEFAULT_CLOSED'}
1079 def draw_header(self, context):
1080 settings = self.paint_settings(context)
1082 self.layout.prop(settings, "show_brush", text="")
1084 def draw(self, context):
1085 layout = self.layout
1087 layout.use_property_split = True
1088 layout.use_property_decorate = False
1090 settings = self.paint_settings(context)
1091 brush = settings.brush
1093 col = layout.column()
1094 col.active = settings.show_brush
1096 if context.sculpt_object and context.tool_settings.sculpt:
1097 if brush.sculpt_capabilities.has_secondary_color:
1098 col.prop(brush, "cursor_color_add", text="Add")
1099 col.prop(brush, "cursor_color_subtract", text="Subtract")
1101 col.prop(brush, "cursor_color_add", text="Color")
1103 col.prop(brush, "cursor_color_add", text="Color")
1106 class VIEW3D_PT_tools_brush_appearance_custom_icon(Panel, View3DPaintPanel):
1107 bl_context = ".paint_common" # dot on purpose (access from topbar)
1108 bl_label = "Custom Icon"
1109 bl_parent_id = "VIEW3D_PT_tools_brush_appearance"
1110 bl_options = {'DEFAULT_CLOSED'}
1112 def draw_header(self, context):
1113 settings = self.paint_settings(context)
1114 brush = settings.brush
1116 self.layout.prop(brush, "use_custom_icon", text="")
1118 def draw(self, context):
1119 layout = self.layout
1121 layout.use_property_split = True
1122 layout.use_property_decorate = False
1124 settings = self.paint_settings(context)
1125 brush = settings.brush
1127 col = layout.column()
1128 col.active = brush.use_custom_icon
1129 col.prop(brush, "icon_filepath", text="")
1131 # ********** default tools for weight-paint ****************
1134 # TODO, move to space_view3d.py
1135 class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
1136 bl_context = ".weightpaint"
1137 bl_options = {'DEFAULT_CLOSED'}
1138 bl_label = "Symmetry"
1140 def draw(self, context):
1141 layout = self.layout
1142 tool_settings = context.tool_settings
1143 wpaint = tool_settings.weight_paint
1144 draw_vpaint_symmetry(layout, wpaint)
1147 # TODO, move to space_view3d.py
1148 class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
1149 bl_context = ".weightpaint"
1150 bl_label = "Options"
1152 def draw(self, context):
1153 layout = self.layout
1155 tool_settings = context.tool_settings
1156 wpaint = tool_settings.weight_paint
1158 col = layout.column()
1159 col.prop(wpaint, "use_group_restrict")
1161 obj = context.weight_paint_object
1162 if obj.type == 'MESH':
1164 col.prop(mesh, "use_mirror_x")
1166 row.active = mesh.use_mirror_x
1167 row.prop(mesh, "use_mirror_topology")
1169 self.unified_paint_settings(col, context)
1171 # ********** default tools for vertex-paint ****************
1174 # TODO, move to space_view3d.py
1175 class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
1176 bl_context = ".vertexpaint" # dot on purpose (access from topbar)
1177 bl_label = "Options"
1179 def draw(self, context):
1180 layout = self.layout
1182 col = layout.column()
1184 self.unified_paint_settings(col, context)
1187 # TODO, move to space_view3d.py
1188 class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
1189 bl_context = ".vertexpaint" # dot on purpose (access from topbar)
1190 bl_options = {'DEFAULT_CLOSED'}
1191 bl_label = "Symmetry"
1193 def draw(self, context):
1194 layout = self.layout
1195 tool_settings = context.tool_settings
1196 vpaint = tool_settings.vertex_paint
1197 draw_vpaint_symmetry(layout, vpaint)
1200 # ********** default tools for texture-paint ****************
1203 # TODO, move to space_view3d.py
1204 class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
1205 bl_context = ".imagepaint" # dot on purpose (access from topbar)
1206 bl_label = "External"
1207 bl_options = {'DEFAULT_CLOSED'}
1209 def draw(self, context):
1210 layout = self.layout
1211 layout.use_property_split = True
1212 layout.use_property_decorate = False
1214 tool_settings = context.tool_settings
1215 ipaint = tool_settings.image_paint
1217 layout.prop(ipaint, "screen_grab_size", text="Screen Grab Size")
1221 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1223 col.operator("image.project_edit", text="Quick Edit")
1225 col.operator("image.project_apply", text="Apply")
1227 col.operator("paint.project_image", text="Apply Camera Image")
1230 # TODO, move to space_view3d.py
1231 class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
1232 bl_context = ".imagepaint" # dot on purpose (access from topbar)
1233 bl_label = "Symmetry"
1234 bl_options = {'DEFAULT_CLOSED'}
1236 def draw(self, context):
1237 layout = self.layout
1239 tool_settings = context.tool_settings
1240 ipaint = tool_settings.image_paint
1242 split = layout.split()
1244 col = split.column()
1245 col.alignment = 'RIGHT'
1246 col.label(text="Mirror")
1248 col = split.column()
1250 row = col.row(align=True)
1251 row.prop(ipaint, "use_symmetry_x", text="X", toggle=True)
1252 row.prop(ipaint, "use_symmetry_y", text="Y", toggle=True)
1253 row.prop(ipaint, "use_symmetry_z", text="Z", toggle=True)
1256 # TODO, move to space_view3d.py
1257 class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
1258 bl_context = ".imagepaint" # dot on purpose (access from topbar)
1259 bl_label = "Project Paint"
1260 bl_options = {'DEFAULT_CLOSED'}
1263 def poll(cls, context):
1264 brush = context.tool_settings.image_paint.brush
1265 return (brush is not None)
1267 def draw(self, context):
1268 layout = self.layout
1270 layout.use_property_split = True
1271 layout.use_property_decorate = False
1273 tool_settings = context.tool_settings
1274 ipaint = tool_settings.image_paint
1277 row.prop(ipaint, "use_normal_falloff")
1280 sub.active = (ipaint.use_normal_falloff)
1281 sub.prop(ipaint, "normal_angle", text="")
1283 layout.prop(ipaint, "seam_bleed")
1284 layout.prop(ipaint, "dither")
1286 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1289 col.prop(ipaint, "use_occlude")
1292 col.prop(ipaint, "use_backface_culling")
1295 class VIEW3D_PT_tools_projectpaint_unified(Panel, View3DPaintPanel):
1296 bl_context = ".imagepaint" # dot on purpose (access from topbar)
1297 bl_parent_id = "VIEW3D_PT_tools_projectpaint"
1298 bl_label = "Unified Brush"
1300 def draw(self, context):
1301 layout = self.layout
1302 layout.use_property_split = True
1303 layout.use_property_decorate = False
1305 self.unified_paint_settings(layout, context)
1308 class VIEW3D_PT_tools_projectpaint_cavity(View3DPaintPanel, Panel):
1309 bl_context = ".imagepaint" # dot on purpose (access from topbar)
1310 bl_label = "Cavity Mask"
1311 bl_parent_id = "VIEW3D_PT_tools_projectpaint"
1312 bl_options = {'DEFAULT_CLOSED'}
1314 def draw_header(self, context):
1315 tool_settings = context.tool_settings
1316 ipaint = tool_settings.image_paint
1318 self.layout.prop(ipaint, "use_cavity", text="")
1320 def draw(self, context):
1321 layout = self.layout
1323 tool_settings = context.tool_settings
1324 ipaint = tool_settings.image_paint
1326 layout.active = ipaint.use_cavity
1328 layout.template_curve_mapping(ipaint, "cavity_curve", brush=True)
1331 # TODO, move to space_view3d.py
1332 class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
1333 bl_label = "Options"
1336 def poll(cls, context):
1337 return (context.image_paint_object and context.tool_settings.image_paint)
1339 def draw(self, context):
1340 layout = self.layout
1342 col = layout.column()
1343 self.unified_paint_settings(col, context)
1346 class VIEW3D_MT_tools_projectpaint_stencil(Menu):
1347 bl_label = "Mask Layer"
1349 def draw(self, context):
1350 layout = self.layout
1351 for i, uv_layer in enumerate(context.active_object.data.uv_layers):
1352 props = layout.operator("wm.context_set_int", text=uv_layer.name, translate=False)
1353 props.data_path = "active_object.data.uv_layer_stencil_index"
1357 # TODO, move to space_view3d.py
1358 class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
1359 """Default tools for particle mode"""
1360 bl_context = ".particlemode"
1361 bl_label = "Options"
1363 def draw(self, context):
1364 layout = self.layout
1366 pe = context.tool_settings.particle_edit
1369 layout.prop(pe, "type", text="")
1373 if pe.type == 'PARTICLES':
1374 if ob.particle_systems:
1375 if len(ob.particle_systems) > 1:
1376 layout.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
1377 ob.particle_systems, "active_index", rows=2, maxrows=3)
1379 ptcache = ob.particle_systems.active.point_cache
1381 for md in ob.modifiers:
1382 if md.type == pe.type:
1383 ptcache = md.point_cache
1385 if ptcache and len(ptcache.point_caches) > 1:
1386 layout.template_list("UI_UL_list", "particles_point_caches", ptcache, "point_caches",
1387 ptcache.point_caches, "active_index", rows=2, maxrows=3)
1389 if not pe.is_editable:
1390 layout.label(text="Point cache must be baked")
1391 layout.label(text="in memory to enable editing!")
1393 col = layout.column(align=True)
1395 col.active = pe.is_editable
1396 col.prop(pe, "use_emitter_deflect", text="Deflect Emitter")
1397 sub = col.row(align=True)
1398 sub.active = pe.use_emitter_deflect
1399 sub.prop(pe, "emitter_distance", text="Distance")
1401 col = layout.column(align=True)
1402 col.active = pe.is_editable
1403 col.label(text="Keep:")
1404 col.prop(pe, "use_preserve_length", text="Lengths")
1405 col.prop(pe, "use_preserve_root", text="Root")
1407 col.label(text="Correct:")
1408 col.prop(pe, "use_auto_velocity", text="Velocity")
1409 col.prop(ob.data, "use_mirror_x")
1411 col.prop(pe, "shape_object")
1412 col.operator("particle.shape_cut")
1414 col = layout.column(align=True)
1415 col.active = pe.is_editable
1416 col.label(text="Display:")
1417 col.prop(pe, "display_step", text="Path Steps")
1419 col.prop(pe, "show_particles", text="Children")
1421 if pe.type == 'PARTICLES':
1422 col.prop(pe, "show_particles", text="Particles")
1423 col.prop(pe, "use_fade_time")
1424 sub = col.row(align=True)
1425 sub.active = pe.use_fade_time
1426 sub.prop(pe, "fade_frames", slider=True)
1429 class VIEW3D_PT_tools_normal(View3DPanel, Panel):
1431 bl_context = ".mesh_edit"
1432 bl_label = "Normals"
1433 bl_options = {'DEFAULT_CLOSED'}
1435 def draw(self, context):
1436 layout = self.layout
1437 layout.use_property_split = True
1438 layout.use_property_decorate = False # No animation.
1440 tool_settings = context.tool_settings
1442 layout.prop(tool_settings, "normal_vector", text="Normal Vector")
1443 layout.prop(tool_settings, "face_strength", text="Face Strength")
1445 # ********** grease pencil object tool panels ****************
1447 # Grease Pencil drawing brushes
1450 class VIEW3D_PT_tools_grease_pencil_brush(View3DPanel, Panel):
1451 bl_context = ".greasepencil_paint"
1455 def poll(cls, context):
1456 is_3d_view = context.space_data.type == 'VIEW_3D'
1458 if context.gpencil_data is None:
1461 gpd = context.gpencil_data
1462 return bool(gpd.is_stroke_paint_mode)
1467 def draw(self, context):
1468 layout = self.layout
1469 layout.use_property_split = True
1470 layout.use_property_decorate = False
1472 tool_settings = context.scene.tool_settings
1473 gpencil_paint = tool_settings.gpencil_paint
1477 col.template_ID_preview(gpencil_paint, "brush", new="brush.add_gpencil", rows=3, cols=8)
1480 brush = gpencil_paint.brush
1482 sub = col.column(align=True)
1483 sub.operator("gpencil.brush_presets_create", icon='HELP', text="")
1485 if brush is not None:
1486 gp_settings = brush.gpencil_settings
1488 if brush.gpencil_tool in {'DRAW', 'FILL'}:
1489 layout.row(align=True).template_ID(gp_settings, "material")
1491 if not self.is_popover:
1492 from .properties_paint_common import (
1493 brush_basic_gpencil_paint_settings,
1495 brush_basic_gpencil_paint_settings(layout, context, brush, compact=True)
1498 # Grease Pencil drawing brushes options
1499 class VIEW3D_PT_tools_grease_pencil_brush_option(View3DPanel, Panel):
1500 bl_context = ".greasepencil_paint"
1501 bl_label = "Options"
1502 bl_options = {'DEFAULT_CLOSED'}
1505 def poll(cls, context):
1506 brush = context.tool_settings.gpencil_paint.brush
1507 return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'}
1509 def draw_header_preset(self, context):
1510 VIEW3D_PT_gpencil_brush_presets.draw_panel_header(self.layout)
1513 def draw(self, context):
1514 layout = self.layout
1515 layout.use_property_split = True
1516 layout.use_property_decorate = False
1518 brush = context.tool_settings.gpencil_paint.brush
1519 gp_settings = brush.gpencil_settings
1521 if brush is not None:
1522 col = layout.column(align=True)
1523 col.prop(gp_settings, "input_samples")
1526 col.prop(gp_settings, "active_smooth_factor")
1529 col.prop(gp_settings, "angle", slider=True)
1530 col.prop(gp_settings, "angle_factor", text="Factor", slider=True)
1534 class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(View3DPanel, Panel):
1535 bl_context = ".greasepencil_paint"
1536 bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
1537 bl_label = "Stabilizer Settings"
1538 bl_options = {'DEFAULT_CLOSED'}
1541 def poll(cls, context):
1542 brush = context.tool_settings.gpencil_paint.brush
1543 return brush is not None and brush.gpencil_tool == 'DRAW'
1545 def draw_header(self, context):
1546 brush = context.tool_settings.gpencil_paint.brush
1547 gp_settings = brush.gpencil_settings
1548 self.layout.prop(gp_settings, "use_settings_stabilizer", text="")
1551 def draw(self, context):
1552 layout = self.layout
1553 layout.use_property_split = True
1554 layout.use_property_decorate = False
1556 brush = context.tool_settings.gpencil_paint.brush
1557 gp_settings = brush.gpencil_settings
1558 layout.active = gp_settings.use_settings_stabilizer
1560 layout.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
1561 layout.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
1564 class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel):
1565 bl_context = ".greasepencil_paint"
1566 bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
1567 bl_label = "Post-processing Settings"
1568 bl_options = {'DEFAULT_CLOSED'}
1571 def poll(cls, context):
1572 brush = context.tool_settings.gpencil_paint.brush
1573 return brush is not None and brush.gpencil_tool != 'ERASE'
1575 def draw_header(self, context):
1576 brush = context.tool_settings.gpencil_paint.brush
1577 gp_settings = brush.gpencil_settings
1578 self.layout.prop(gp_settings, "use_settings_postprocess", text="")
1581 def draw(self, context):
1582 layout = self.layout
1583 layout.use_property_split = True
1584 layout.use_property_decorate = False
1586 brush = context.tool_settings.gpencil_paint.brush
1587 gp_settings = brush.gpencil_settings
1588 layout.active = gp_settings.use_settings_postprocess
1590 col = layout.column(align=True)
1591 col.prop(gp_settings, "pen_smooth_factor")
1592 col.prop(gp_settings, "pen_smooth_steps")
1594 col = layout.column(align=True)
1595 col.prop(gp_settings, "pen_thick_smooth_factor")
1596 col.prop(gp_settings, "pen_thick_smooth_steps", text="Iterations")
1598 col = layout.column(align=True)
1599 col.prop(gp_settings, "pen_subdivision_steps")
1600 col.prop(gp_settings, "random_subdiv", text="Randomness", slider=True)
1603 class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
1604 bl_context = ".greasepencil_paint"
1605 bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
1606 bl_label = "Random Settings"
1607 bl_options = {'DEFAULT_CLOSED'}
1610 def poll(cls, context):
1611 brush = context.tool_settings.gpencil_paint.brush
1612 return brush is not None and brush.gpencil_tool != 'ERASE'
1614 def draw_header(self, context):
1615 brush = context.tool_settings.gpencil_paint.brush
1616 gp_settings = brush.gpencil_settings
1617 self.layout.prop(gp_settings, "use_settings_random", text="")
1620 def draw(self, context):
1621 layout = self.layout
1622 layout.use_property_split = True
1623 layout.use_property_decorate = False
1625 brush = context.tool_settings.gpencil_paint.brush
1626 gp_settings = brush.gpencil_settings
1627 layout.active = gp_settings.use_settings_random
1629 layout.prop(gp_settings, "random_pressure", text="Pressure", slider=True)
1630 layout.prop(gp_settings, "random_strength", text="Strength", slider=True)
1631 layout.prop(gp_settings, "uv_random", text="UV", slider=True)
1633 row = layout.row(align=True)
1634 row.prop(gp_settings, "pen_jitter", slider=True)
1635 row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
1638 # Grease Pencil drawingcurves
1639 class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel):
1640 bl_context = ".greasepencil_paint"
1642 bl_options = {'DEFAULT_CLOSED'}
1645 def poll(cls, context):
1646 brush = context.tool_settings.gpencil_paint.brush
1647 return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL'}
1650 def draw(self, context):
1651 layout = self.layout
1654 class VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity(View3DPanel, Panel):
1655 bl_context = ".greasepencil_paint"
1656 bl_label = "Sensitivity"
1657 bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves"
1660 def draw(self, context):
1661 layout = self.layout
1662 layout.use_property_split = True
1664 brush = context.tool_settings.gpencil_paint.brush
1665 gp_settings = brush.gpencil_settings
1667 layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True)
1670 class VIEW3D_PT_tools_grease_pencil_brushcurves_strength(View3DPanel, Panel):
1671 bl_context = ".greasepencil_paint"
1672 bl_label = "Strength"
1673 bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves"
1676 def draw(self, context):
1677 layout = self.layout
1678 layout.use_property_split = True
1680 brush = context.tool_settings.gpencil_paint.brush
1681 gp_settings = brush.gpencil_settings
1683 layout.template_curve_mapping(gp_settings, "curve_strength", brush=True)
1686 class VIEW3D_PT_tools_grease_pencil_brushcurves_jitter(View3DPanel, Panel):
1687 bl_context = ".greasepencil_paint"
1689 bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves"
1692 def draw(self, context):
1693 layout = self.layout
1694 layout.use_property_split = True
1696 brush = context.tool_settings.gpencil_paint.brush
1697 gp_settings = brush.gpencil_settings
1699 layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True)
1702 # Grease Pencil stroke editing tools
1703 class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
1704 bl_space_type = 'VIEW_3D'
1707 # Grease Pencil stroke interpolation tools
1708 class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
1709 bl_space_type = 'VIEW_3D'
1710 bl_region_type = 'HEADER'
1711 bl_label = "Interpolate"
1714 def poll(cls, context):
1715 if context.gpencil_data is None:
1718 gpd = context.gpencil_data
1719 return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
1722 def draw(self, context):
1723 layout = self.layout
1724 settings = context.tool_settings.gpencil_interpolate
1726 col = layout.column(align=True)
1727 col.label(text="Interpolate Strokes")
1728 col.operator("gpencil.interpolate", text="Interpolate")
1729 col.operator("gpencil.interpolate_sequence", text="Sequence")
1730 col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
1732 col = layout.column(align=True)
1733 col.label(text="Options:")
1734 col.prop(settings, "interpolate_all_layers")
1735 col.prop(settings, "interpolate_selected_only")
1737 col = layout.column(align=True)
1738 col.label(text="Sequence Options:")
1739 col.prop(settings, "type")
1740 if settings.type == 'CUSTOM':
1741 # TODO: Options for loading/saving curve presets?
1742 col.template_curve_mapping(settings, "interpolation_curve", brush=True)
1743 elif settings.type != 'LINEAR':
1744 col.prop(settings, "easing")
1746 if settings.type == 'BACK':
1747 layout.prop(settings, "back")
1748 elif setting.type == 'ELASTIC':
1749 sub = layout.column(align=True)
1750 sub.prop(settings, "amplitude")
1751 sub.prop(settings, "period")
1754 # Grease Pencil stroke sculpting tools
1755 class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, View3DPanel, Panel):
1756 bl_context = ".greasepencil_sculpt"
1757 bl_category = "Tools"
1761 # Grease Pencil weight painting tools
1762 class VIEW3D_PT_tools_grease_pencil_weight_paint(View3DPanel, Panel):
1763 bl_context = ".greasepencil_weight"
1764 bl_category = "Tools"
1768 def draw(self, context):
1769 layout = self.layout
1770 layout.use_property_split = True
1771 layout.use_property_decorate = False
1773 settings = context.tool_settings.gpencil_sculpt
1774 brush = settings.brush
1776 layout.template_icon_view(settings, "weight_tool", show_labels=True)
1778 col = layout.column()
1780 if not self.is_popover:
1781 from .properties_paint_common import (
1782 brush_basic_gpencil_weight_settings,
1784 brush_basic_gpencil_weight_settings(col, context, brush)
1787 # Grease Pencil Brush Appeareance (one for each mode)
1788 class VIEW3D_PT_tools_grease_pencil_paint_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
1789 bl_context = ".greasepencil_paint"
1790 bl_label = "Appearance"
1793 class VIEW3D_PT_tools_grease_pencil_sculpt_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
1794 bl_context = ".greasepencil_sculpt"
1795 bl_label = "Appearance"
1798 class VIEW3D_PT_tools_grease_pencil_sculpt_options(GreasePencilSculptOptionsPanel, View3DPanel, Panel):
1799 bl_context = ".greasepencil_sculpt"
1800 bl_label = "Sculpt Strokes"
1801 bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_sculpt'
1804 class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
1805 bl_context = ".greasepencil_weight"
1806 bl_label = "Appearance"
1809 class VIEW3D_PT_gpencil_brush_presets(PresetMenu):
1810 """Brush settings"""
1811 bl_label = "Brush Presets"
1812 preset_subdir = "gpencil_brush"
1813 preset_operator = "script.execute_preset"
1814 preset_add_operator = "scene.gpencil_brush_preset_add"
1818 VIEW3D_PT_tools_meshedit_options,
1819 VIEW3D_PT_tools_curveedit_options_stroke,
1820 VIEW3D_PT_tools_armatureedit_options,
1821 VIEW3D_PT_tools_posemode_options,
1822 VIEW3D_PT_slots_projectpaint,
1823 VIEW3D_PT_tools_brush,
1824 TEXTURE_UL_texpaintslots,
1825 VIEW3D_MT_tools_projectpaint_uvlayer,
1826 VIEW3D_PT_stencil_projectpaint,
1827 VIEW3D_PT_tools_brush_overlay,
1828 VIEW3D_PT_tools_brush_texture,
1829 VIEW3D_PT_tools_mask_texture,
1830 VIEW3D_PT_tools_brush_stroke,
1831 VIEW3D_PT_tools_brush_stroke_smooth_stroke,
1832 VIEW3D_PT_tools_brush_curve,
1833 VIEW3D_PT_sculpt_dyntopo,
1834 VIEW3D_PT_sculpt_dyntopo_remesh,
1835 VIEW3D_PT_sculpt_options,
1836 VIEW3D_PT_sculpt_options_unified,
1837 VIEW3D_PT_sculpt_options_gravity,
1838 VIEW3D_PT_sculpt_symmetry,
1839 VIEW3D_PT_tools_brush_appearance,
1840 VIEW3D_PT_tools_brush_appearance_show_brush,
1841 VIEW3D_PT_tools_brush_appearance_custom_icon,
1842 VIEW3D_PT_tools_weightpaint_symmetry,
1843 VIEW3D_PT_tools_weightpaint_options,
1844 VIEW3D_PT_tools_vertexpaint,
1845 VIEW3D_PT_tools_vertexpaint_symmetry,
1846 VIEW3D_PT_tools_imagepaint_external,
1847 VIEW3D_PT_tools_imagepaint_symmetry,
1848 VIEW3D_PT_tools_projectpaint,
1849 VIEW3D_PT_tools_projectpaint_unified,
1850 VIEW3D_PT_tools_projectpaint_cavity,
1851 VIEW3D_MT_tools_projectpaint_stencil,
1852 VIEW3D_PT_tools_particlemode,
1854 VIEW3D_PT_gpencil_brush_presets,
1855 VIEW3D_PT_tools_grease_pencil_brush,
1856 VIEW3D_PT_tools_grease_pencil_brush_option,
1857 VIEW3D_PT_tools_grease_pencil_brush_settings,
1858 VIEW3D_PT_tools_grease_pencil_brush_stabilizer,
1859 VIEW3D_PT_tools_grease_pencil_brush_random,
1860 VIEW3D_PT_tools_grease_pencil_brushcurves,
1861 VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity,
1862 VIEW3D_PT_tools_grease_pencil_brushcurves_strength,
1863 VIEW3D_PT_tools_grease_pencil_brushcurves_jitter,
1864 VIEW3D_PT_tools_grease_pencil_sculpt,
1865 VIEW3D_PT_tools_grease_pencil_weight_paint,
1866 VIEW3D_PT_tools_grease_pencil_paint_appearance,
1867 VIEW3D_PT_tools_grease_pencil_sculpt_options,
1868 VIEW3D_PT_tools_grease_pencil_sculpt_appearance,
1869 VIEW3D_PT_tools_grease_pencil_weight_appearance,
1870 VIEW3D_PT_tools_grease_pencil_interpolate,
1871 VIEW3D_PT_tools_normal,
1874 if __name__ == "__main__": # only for live edit.
1875 from bpy.utils import register_class