Files
test2/scripts/startup/bl_ui/space_toolsystem_toolbar.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

3345 lines
105 KiB
Python
Raw Normal View History

# SPDX-FileCopyrightText: 2017-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
# For documentation on tool definitions: see "bl_ui.space_toolsystem_common.ToolDef"
# where there are comments for each field and their use.
# For now group all tools together
# we may want to move these into per space-type files.
#
# For now keep this in a single file since it's an area that may change,
# so avoid making changes all over the place.
import bpy
from bpy.types import Panel
from bl_ui.space_toolsystem_common import (
ToolSelectPanelHelper,
ToolDef,
)
from bpy.app.translations import pgettext_tip as tip_
def kmi_to_string_or_none(kmi):
return kmi.to_string() if kmi else "<none>"
def generate_from_enum_ex(
_context, *,
idname_prefix,
icon_prefix,
type,
attr,
cursor='DEFAULT',
tooldef_keywords=None,
icon_map=None,
use_separators=True,
):
if tooldef_keywords is None:
tooldef_keywords = {}
tool_defs = []
enum_items = getattr(
type.bl_rna.properties[attr],
"enum_items_static_ui" if use_separators else
"enum_items_static",
)
for enum in enum_items:
if use_separators:
if not (name := enum.name):
# Empty string for a UI Separator.
tool_defs.append(None)
continue
if not (idname := enum.identifier):
# This is a heading, there is no purpose in showing headings here.
continue
else:
name = enum.name
idname = enum.identifier
icon = icon_prefix + idname.lower()
if icon_map is not None:
icon = icon_map.get(icon, icon)
tool_defs.append(
ToolDef.from_dict(
dict(
idname=idname_prefix + name,
label=name,
description=enum.description,
icon=icon,
cursor=cursor,
data_block=idname,
**tooldef_keywords,
),
),
)
return tuple(tool_defs)
# Use for shared widget data.
class _template_widget:
2018-11-21 09:25:55 +11:00
class VIEW3D_GGT_xform_extrude:
@staticmethod
def draw_settings(_context, layout, tool):
2018-11-21 09:25:55 +11:00
props = tool.gizmo_group_properties("VIEW3D_GGT_xform_extrude")
layout.prop(props, "axis_type", expand=True)
class VIEW3D_GGT_xform_gizmo:
@staticmethod
def draw_settings_with_index(context, layout, index):
scene = context.scene
orient_slot = scene.transform_orientation_slots[index]
layout.prop(orient_slot, "type")
class _defs_view3d_generic:
@ToolDef.from_fn
def cursor():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("view3d.cursor3d")
layout.prop(props, "use_depth")
layout.prop(props, "orientation")
return dict(
idname="builtin.cursor",
label="Cursor",
description=(
"Set the cursor location, drag to transform"
),
2018-05-07 21:38:43 +02:00
icon="ops.generic.cursor",
keymap="3D View Tool: Cursor",
draw_settings=draw_settings,
2018-05-07 21:38:43 +02:00
)
@ToolDef.from_fn
def cursor_click():
return dict(
idname="builtin.none",
label="None",
icon="ops.generic.cursor",
keymap=(),
)
@ToolDef.from_fn
def ruler():
def description(_context, _item, km):
if km is not None:
kmi_add = km.keymap_items.find_from_operator("view3d.ruler_add")
kmi_remove = km.keymap_items.find_from_operator("view3d.ruler_remove")
else:
kmi_add = None
kmi_remove = None
2019-04-09 23:16:11 +10:00
return tip_(
"Measure distance and angles.\n"
"\u2022 %s anywhere for new measurement.\n"
"\u2022 Drag ruler segment to measure an angle.\n"
"\u2022 %s to remove the active ruler.\n"
"\u2022 Ctrl while dragging to snap.\n"
"\u2022 Shift while dragging to measure surface thickness"
) % (
kmi_to_string_or_none(kmi_add),
kmi_to_string_or_none(kmi_remove),
)
return dict(
idname="builtin.measure",
label="Measure",
description=description,
2018-05-07 21:38:43 +02:00
icon="ops.view3d.ruler",
widget="VIEW3D_GGT_ruler",
keymap="3D View Tool: Measure",
2018-05-07 21:38:43 +02:00
)
2018-08-28 21:00:25 +10:00
class _defs_annotate:
def draw_settings_common(context, layout, tool):
gpd = context.annotation_data
region_type = context.region.type
if gpd is not None:
if gpd.layers.active_note is not None:
text = gpd.layers.active_note
maxw = 25
if len(text) > maxw:
text = text[:maxw - 5] + '..' + text[-3:]
else:
text = ""
gpl = context.active_annotation_layer
if gpl is not None:
if context.space_data.type in {'VIEW_3D', 'SEQUENCE_EDITOR', 'IMAGE_EDITOR', 'NODE_EDITOR'}:
layout.label(text="Annotation:")
if region_type == 'TOOL_HEADER':
sub = layout.split(align=True, factor=0.5)
sub.ui_units_x = 6.5
sub.prop(gpl, "color", text="")
else:
sub = layout.row(align=True)
sub.prop(gpl, "color", text="")
sub.popover(
panel="TOPBAR_PT_annotation_layers",
text=text,
)
elif context.space_data.type == 'PROPERTIES':
row = layout.row(align=True)
row.prop(gpl, "color", text="Annotation")
row.popover(
panel="TOPBAR_PT_annotation_layers",
text=text,
)
else:
layout.label(text="Annotation:")
layout.prop(gpl, "color", text="")
space_type = tool.space_type
tool_settings = context.tool_settings
if space_type == 'VIEW_3D':
row = layout.row(align=True)
row.prop(tool_settings, "annotation_stroke_placement_view3d", text="Placement")
if tool_settings.gpencil_stroke_placement_view3d == 'CURSOR':
row.prop(tool_settings.gpencil_sculpt, "lockaxis")
elif tool_settings.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}:
row.prop(tool_settings, "use_gpencil_stroke_endpoints")
elif space_type in {'IMAGE_EDITOR', 'NODE_EDITOR', 'SEQUENCE_EDITOR', 'CLIP_EDITOR'}:
row = layout.row(align=True)
row.prop(tool_settings, "annotation_stroke_placement_view2d", text="Placement")
if tool.idname == "builtin.annotate_line":
props = tool.operator_properties("gpencil.annotate")
if region_type == 'TOOL_HEADER':
row = layout.row()
row.ui_units_x = 15
row.prop(props, "arrowstyle_start", text="Start")
row.separator()
row.prop(props, "arrowstyle_end", text="End")
else:
col = layout.row().column(align=True)
col.prop(props, "arrowstyle_start", text="Style Start")
col.prop(props, "arrowstyle_end", text="End")
elif tool.idname == "builtin.annotate":
props = tool.operator_properties("gpencil.annotate")
if region_type == 'TOOL_HEADER':
row = layout.row()
row.prop(props, "use_stabilizer", text="Stabilize Stroke")
subrow = layout.row(align=False)
subrow.active = props.use_stabilizer
subrow.prop(props, "stabilizer_radius", text="Radius", slider=True)
subrow.prop(props, "stabilizer_factor", text="Factor", slider=True)
else:
layout.prop(props, "use_stabilizer", text="Stabilize Stroke")
col = layout.column(align=False)
col.active = props.use_stabilizer
col.prop(props, "stabilizer_radius", text="Radius", slider=True)
col.prop(props, "stabilizer_factor", text="Factor", slider=True)
@ToolDef.from_fn.with_args(draw_settings=draw_settings_common)
def scribble(*, draw_settings):
return dict(
idname="builtin.annotate",
label="Annotate",
icon="ops.gpencil.draw",
cursor='PAINT_BRUSH',
keymap="Generic Tool: Annotate",
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
@ToolDef.from_fn.with_args(draw_settings=draw_settings_common)
def line(*, draw_settings):
return dict(
idname="builtin.annotate_line",
label="Annotate Line",
icon="ops.gpencil.draw.line",
cursor='PAINT_BRUSH',
keymap="Generic Tool: Annotate Line",
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
@ToolDef.from_fn.with_args(draw_settings=draw_settings_common)
def poly(*, draw_settings):
return dict(
idname="builtin.annotate_polygon",
label="Annotate Polygon",
icon="ops.gpencil.draw.poly",
cursor='PAINT_BRUSH',
keymap="Generic Tool: Annotate Polygon",
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
2018-08-28 21:00:25 +10:00
@ToolDef.from_fn
def eraser():
def draw_settings(context, layout, _tool):
# TODO: Move this setting to tool_settings
prefs = context.preferences
layout.prop(prefs.edit, "grease_pencil_eraser_radius", text="Radius")
return dict(
idname="builtin.annotate_eraser",
label="Annotate Eraser",
icon="ops.gpencil.draw.eraser",
cursor='ERASER',
keymap="Generic Tool: Annotate Eraser",
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
class _defs_transform:
def draw_transform_sculpt_tool_settings(context, layout):
if context.mode != 'SCULPT':
return
layout.prop(context.tool_settings.sculpt, "transform_mode")
@ToolDef.from_fn
def translate():
def draw_settings(context, layout, _tool):
_defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
return dict(
idname="builtin.move",
label="Move",
# cursor='SCROLL_XY',
2018-05-07 21:38:43 +02:00
icon="ops.transform.translate",
widget="VIEW3D_GGT_xform_gizmo",
operator="transform.translate",
keymap="3D View Tool: Move",
draw_settings=draw_settings,
2018-05-07 21:38:43 +02:00
)
@ToolDef.from_fn
def rotate():
def draw_settings(context, layout, _tool):
_defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2)
return dict(
idname="builtin.rotate",
label="Rotate",
# cursor='SCROLL_XY',
icon="ops.transform.rotate",
widget="VIEW3D_GGT_xform_gizmo",
operator="transform.rotate",
keymap="3D View Tool: Rotate",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def scale():
def draw_settings(context, layout, _tool):
_defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3)
return dict(
idname="builtin.scale",
label="Scale",
# cursor='SCROLL_XY',
icon="ops.transform.resize",
widget="VIEW3D_GGT_xform_gizmo",
operator="transform.resize",
keymap="3D View Tool: Scale",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def scale_cage():
def draw_settings(context, layout, _tool):
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3)
return dict(
idname="builtin.scale_cage",
label="Scale Cage",
icon="ops.transform.resize.cage",
widget="VIEW3D_GGT_xform_cage",
operator="transform.resize",
keymap="3D View Tool: Scale",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def shear():
def draw_settings(context, layout, _tool):
# props = tool.operator_properties("transform.shear")
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2)
return dict(
idname="builtin.shear",
label="Shear",
icon="ops.transform.shear",
widget="VIEW3D_GGT_xform_shear",
keymap="3D View Tool: Shear",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def bend():
return dict(
idname="builtin.bend",
label="Bend",
icon="ops.gpencil.edit_bend",
widget=None,
keymap="3D View Tool: Bend",
)
@ToolDef.from_fn
def transform():
def draw_settings(context, layout, tool):
if layout.use_property_split:
layout.label(text="Gizmos:")
show_drag = True
tool_settings = context.tool_settings
if tool_settings.workspace_tool_type == 'FALLBACK':
show_drag = False
if show_drag:
props = tool.gizmo_group_properties("VIEW3D_GGT_xform_gizmo")
layout.prop(props, "drag_action")
_defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
return dict(
idname="builtin.transform",
label="Transform",
description=(
"Supports any combination of grab, rotate, and scale at once"
),
icon="ops.transform.transform",
widget="VIEW3D_GGT_xform_gizmo",
keymap="3D View Tool: Transform",
draw_settings=draw_settings,
)
class _defs_view3d_select:
@ToolDef.from_fn
def select():
return dict(
idname="builtin.select",
label="Tweak",
icon="ops.generic.select",
widget=None,
keymap="3D View Tool: Tweak",
)
@ToolDef.from_fn
def box():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("view3d.select_box")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
return dict(
idname="builtin.select_box",
label="Select Box",
icon="ops.generic.select_box",
widget=None,
keymap="3D View Tool: Select Box",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("view3d.select_lasso")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
return dict(
idname="builtin.select_lasso",
label="Select Lasso",
icon="ops.generic.select_lasso",
widget=None,
2018-12-14 13:21:13 +11:00
keymap="3D View Tool: Select Lasso",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("view3d.select_circle")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
layout.prop(props, "radius")
def draw_cursor(_context, tool, xy):
from gpu_extras.presets import draw_circle_2d
props = tool.operator_properties("view3d.select_circle")
radius = props.radius
PyAPI: use keyword only arguments Use keyword only arguments for the following functions. - addon_utils.module_bl_info 2nd arg `info_basis`. - addon_utils.modules 1st `module_cache`, 2nd arg `refresh`. - addon_utils.modules_refresh 1st arg `module_cache`. - bl_app_template_utils.activate 1nd arg `template_id`. - bl_app_template_utils.import_from_id 2nd arg `ignore_not_found`. - bl_app_template_utils.import_from_path 2nd arg `ignore_not_found`. - bl_keymap_utils.keymap_from_toolbar.generate 2nd & 3rd args `use_fallback_keys` & `use_reset`. - bl_keymap_utils.platform_helpers.keyconfig_data_oskey_from_ctrl 2nd arg `filter_fn`. - bl_ui_utils.bug_report_url.url_prefill_from_blender 1st arg `addon_info`. - bmesh.types.BMFace.copy 1st & 2nd args `verts`, `edges`. - bmesh.types.BMesh.calc_volume 1st arg `signed`. - bmesh.types.BMesh.from_mesh 2nd..4th args `face_normals`, `use_shape_key`, `shape_key_index`. - bmesh.types.BMesh.from_object 3rd & 4th args `cage`, `face_normals`. - bmesh.types.BMesh.transform 2nd arg `filter`. - bmesh.types.BMesh.update_edit_mesh 2nd & 3rd args `loop_triangles`, `destructive`. - bmesh.types.{BMVertSeq,BMEdgeSeq,BMFaceSeq}.sort 1st & 2nd arg `key`, `reverse`. - bmesh.utils.face_split 4th..6th args `coords`, `use_exist`, `example`. - bpy.data.libraries.load 2nd..4th args `link`, `relative`, `assets_only`. - bpy.data.user_map 1st..3rd args `subset`, `key_types, `value_types`. - bpy.msgbus.subscribe_rna 5th arg `options`. - bpy.path.abspath 2nd & 3rd args `start` & `library`. - bpy.path.clean_name 2nd arg `replace`. - bpy.path.ensure_ext 3rd arg `case_sensitive`. - bpy.path.module_names 2nd arg `recursive`. - bpy.path.relpath 2nd arg `start`. - bpy.types.EditBone.transform 2nd & 3rd arg `scale`, `roll`. - bpy.types.Operator.as_keywords 1st arg `ignore`. - bpy.types.Struct.{keyframe_insert,keyframe_delete} 2nd..5th args `index`, `frame`, `group`, `options`. - bpy.types.WindowManager.popup_menu 2nd & 3rd arg `title`, `icon`. - bpy.types.WindowManager.popup_menu_pie 3rd & 4th arg `title`, `icon`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.blend_paths 1st..3rd args `absolute`, `packed`, `local`. - bpy.utils.execfile 2nd arg `mod`. - bpy.utils.keyconfig_set 2nd arg `report`. - bpy.utils.load_scripts 1st & 2nd `reload_scripts` & `refresh_scripts`. - bpy.utils.preset_find 3rd & 4th args `display_name`, `ext`. - bpy.utils.resource_path 2nd & 3rd arg `major`, `minor`. - bpy.utils.script_paths 1st..4th args `subdir`, `user_pref`, `check_all`, `use_user`. - bpy.utils.smpte_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.smpte_from_seconds 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.system_resource 2nd arg `subdir`. - bpy.utils.time_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.time_to_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.units.to_string 4th..6th `precision`, `split_unit`, `compatible_unit`. - bpy.utils.units.to_value 4th arg `str_ref_unit`. - bpy.utils.user_resource 2nd & 3rd args `subdir`, `create` - bpy_extras.view3d_utils.location_3d_to_region_2d 4th arg `default`. - bpy_extras.view3d_utils.region_2d_to_origin_3d 4th arg `clamp`. - gpu.offscreen.unbind 1st arg `restore`. - gpu_extras.batch.batch_for_shader 4th arg `indices`. - gpu_extras.batch.presets.draw_circle_2d 4th arg `segments`. - gpu_extras.presets.draw_circle_2d 4th arg `segments`. - imbuf.types.ImBuf.resize 2nd arg `resize`. - imbuf.write 2nd arg `filepath`. - mathutils.kdtree.KDTree.find 2nd arg `filter`. - nodeitems_utils.NodeCategory 3rd & 4th arg `descriptions`, `items`. - nodeitems_utils.NodeItem 2nd..4th args `label`, `settings`, `poll`. - nodeitems_utils.NodeItemCustom 1st & 2nd arg `poll`, `draw`. - rna_prop_ui.draw 5th arg `use_edit`. - rna_prop_ui.rna_idprop_ui_get 2nd arg `create`. - rna_prop_ui.rna_idprop_ui_prop_clear 3rd arg `remove`. - rna_prop_ui.rna_idprop_ui_prop_get 3rd arg `create`. - rna_xml.xml2rna 2nd arg `root_rna`. - rna_xml.xml_file_write 4th arg `skip_typemap`.
2021-06-08 18:03:14 +10:00
draw_circle_2d(xy, (1.0,) * 4, radius, segments=32)
return dict(
idname="builtin.select_circle",
label="Select Circle",
icon="ops.generic.select_circle",
widget=None,
keymap="3D View Tool: Select Circle",
draw_settings=draw_settings,
draw_cursor=draw_cursor,
)
class _defs_view3d_add:
@staticmethod
def description_interactive_add(context, _item, _km, *, prefix):
km = context.window_manager.keyconfigs.user.keymaps["View3D Placement Modal"]
def keymap_item_from_propvalue(propvalue):
for item in km.keymap_items:
if item.propvalue == propvalue:
return item
return None
if km is not None:
kmi_snap = keymap_item_from_propvalue('SNAP_ON')
kmi_center = keymap_item_from_propvalue('PIVOT_CENTER_ON')
kmi_fixed_aspect = keymap_item_from_propvalue('FIXED_ASPECT_ON')
else:
kmi_snap = None
kmi_center = None
kmi_fixed_aspect = None
return tip_(
"%s\n"
"\u2022 %s toggles snap while dragging.\n"
"\u2022 %s toggles dragging from the center.\n"
"\u2022 %s toggles fixed aspect"
) % (
prefix,
kmi_to_string_or_none(kmi_snap),
kmi_to_string_or_none(kmi_center),
kmi_to_string_or_none(kmi_fixed_aspect),
)
# Layout tweaks here would be good to avoid,
# this shows limits in layout engine, as buttons are using a lot of space.
@staticmethod
def draw_settings_interactive_add(layout, tool_settings, tool, extra):
show_extra = False
if not extra:
row = layout.row()
row.label(text="Depth:")
row = layout.row()
row.prop(tool_settings, "plane_depth", text="")
row = layout.row()
row.label(text="Orientation:")
row = layout.row()
row.prop(tool_settings, "plane_orientation", text="")
row = layout.row()
row.prop(tool_settings, "snap_elements_tool")
region_is_header = bpy.context.region.type == 'TOOL_HEADER'
if region_is_header:
# Don't draw the "extra" popover here as we might have other settings & this should be last.
show_extra = True
else:
extra = True
if extra:
props = tool.operator_properties("view3d.interactive_add")
layout.use_property_split = True
layout.row().prop(tool_settings, "plane_axis", expand=True)
layout.row().prop(tool_settings, "plane_axis_auto")
layout.label(text="Base")
layout.row().prop(props, "plane_origin_base", expand=True)
layout.row().prop(props, "plane_aspect_base", expand=True)
layout.label(text="Height")
layout.row().prop(props, "plane_origin_depth", expand=True)
layout.row().prop(props, "plane_aspect_depth", expand=True)
return show_extra
@ToolDef.from_fn
def cube_add():
def draw_settings(context, layout, tool, *, extra=False):
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, context.tool_settings, tool, extra)
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.primitive_cube_add",
label="Add Cube",
icon="ops.mesh.primitive_cube_add_gizmo",
description=lambda *args: _defs_view3d_add.description_interactive_add(
*args, prefix=tip_("Add cube to mesh interactively"),
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def cone_add():
def draw_settings(context, layout, tool, *, extra=False):
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, context.tool_settings, tool, extra)
if extra:
return
props = tool.operator_properties("mesh.primitive_cone_add")
layout.prop(props, "vertices")
layout.prop(props, "end_fill_type")
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.primitive_cone_add",
label="Add Cone",
icon="ops.mesh.primitive_cone_add_gizmo",
description=lambda *args: _defs_view3d_add.description_interactive_add(
*args, prefix=tip_("Add cone to mesh interactively"),
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def cylinder_add():
def draw_settings(context, layout, tool, *, extra=False):
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, context.tool_settings, tool, extra)
if extra:
return
props = tool.operator_properties("mesh.primitive_cylinder_add")
layout.prop(props, "vertices")
layout.prop(props, "end_fill_type")
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.primitive_cylinder_add",
label="Add Cylinder",
icon="ops.mesh.primitive_cylinder_add_gizmo",
description=lambda *args: _defs_view3d_add.description_interactive_add(
*args, prefix=tip_("Add cylinder to mesh interactively"),
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def uv_sphere_add():
def draw_settings(context, layout, tool, *, extra=False):
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, context.tool_settings, tool, extra)
if extra:
return
props = tool.operator_properties("mesh.primitive_uv_sphere_add")
layout.prop(props, "segments")
layout.prop(props, "ring_count")
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.primitive_uv_sphere_add",
label="Add UV Sphere",
icon="ops.mesh.primitive_sphere_add_gizmo",
description=lambda *args: _defs_view3d_add.description_interactive_add(
*args, prefix=tip_("Add sphere to mesh interactively"),
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def ico_sphere_add():
def draw_settings(context, layout, tool, *, extra=False):
show_extra = _defs_view3d_add.draw_settings_interactive_add(layout, context.tool_settings, tool, extra)
if extra:
return
props = tool.operator_properties("mesh.primitive_ico_sphere_add")
layout.prop(props, "subdivisions")
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.primitive_ico_sphere_add",
label="Add Ico Sphere",
icon="ops.mesh.primitive_sphere_add_gizmo",
description=lambda *args: _defs_view3d_add.description_interactive_add(
*args, prefix=tip_("Add sphere to mesh interactively"),
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
# -----------------------------------------------------------------------------
# Object Modes (named based on context.mode)
class _defs_edit_armature:
@ToolDef.from_fn
def roll():
return dict(
idname="builtin.roll",
label="Roll",
icon="ops.armature.bone.roll",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
)
@ToolDef.from_fn
def bone_envelope():
return dict(
idname="builtin.bone_envelope",
label="Bone Envelope",
icon="ops.transform.bone_envelope",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
)
@ToolDef.from_fn
def bone_size():
return dict(
idname="builtin.bone_size",
label="Bone Size",
icon="ops.transform.bone_size",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
)
@ToolDef.from_fn
def extrude():
return dict(
idname="builtin.extrude",
label="Extrude",
icon="ops.armature.extrude_move",
2018-11-21 09:25:55 +11:00
widget="VIEW3D_GGT_xform_extrude",
keymap=(),
2018-11-21 09:25:55 +11:00
draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings,
)
@ToolDef.from_fn
def extrude_cursor():
return dict(
idname="builtin.extrude_to_cursor",
label="Extrude to Cursor",
cursor='CROSSHAIR',
icon="ops.armature.extrude_cursor",
widget=None,
keymap=(),
)
2018-05-07 21:38:43 +02:00
class _defs_edit_mesh:
@ToolDef.from_fn
def rip_region():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.rip_move")
2018-05-11 20:22:04 +02:00
props_macro = props.MESH_OT_rip
layout.prop(props_macro, "use_fill")
return dict(
idname="builtin.rip_region",
label="Rip Region",
icon="ops.mesh.rip",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
2018-05-11 20:22:04 +02:00
draw_settings=draw_settings,
)
@ToolDef.from_fn
def rip_edge():
return dict(
idname="builtin.rip_edge",
label="Rip Edge",
icon="ops.mesh.rip_edge",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
)
@ToolDef.from_fn
def poly_build():
2019-09-15 05:26:15 +10:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.polybuild_face_at_cursor_move")
props_macro = props.MESH_OT_polybuild_face_at_cursor
layout.prop(props_macro, "create_quads")
return dict(
idname="builtin.poly_build",
label="Poly Build",
icon="ops.mesh.polybuild_hover",
widget="VIEW3D_GGT_mesh_preselect_elem",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def edge_slide():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("transform.edge_slide")
layout.prop(props, "correct_uv")
return dict(
idname="builtin.edge_slide",
label="Edge Slide",
icon="ops.transform.edge_slide",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def vert_slide():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("transform.vert_slide")
layout.prop(props, "correct_uv")
return dict(
idname="builtin.vertex_slide",
label="Vertex Slide",
icon="ops.transform.vert_slide",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def spin():
def draw_settings(_context, layout, tool):
2018-09-17 14:52:54 +10:00
props = tool.operator_properties("mesh.spin")
layout.prop(props, "steps")
layout.prop(props, "dupli")
props = tool.gizmo_group_properties("MESH_GGT_spin")
layout.prop(props, "axis")
2018-09-17 14:52:54 +10:00
return dict(
idname="builtin.spin",
label="Spin",
icon="ops.mesh.spin",
widget="MESH_GGT_spin",
keymap=(),
2018-09-17 14:52:54 +10:00
draw_settings=draw_settings,
)
@ToolDef.from_fn
def inset():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.inset")
layout.prop(props, "use_outset")
layout.prop(props, "use_individual")
layout.prop(props, "use_even_offset")
layout.prop(props, "use_relative_offset")
return dict(
idname="builtin.inset_faces",
label="Inset Faces",
icon="ops.mesh.inset",
widget="VIEW3D_GGT_tool_generic_handle_free",
widget_properties=[
("radius", 75.0),
("backdrop_fill_alpha", 0.0),
],
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def bevel():
def draw_settings(context, layout, tool, *, extra=False):
2018-08-22 17:37:07 +10:00
props = tool.operator_properties("mesh.bevel")
region_is_header = context.region.type == 'TOOL_HEADER'
edge_bevel = props.affect == 'EDGES'
if not extra:
if region_is_header:
layout.prop(props, "offset_type", text="")
else:
layout.row().prop(props, "affect", expand=True)
layout.separator()
layout.prop(props, "offset_type")
layout.prop(props, "segments")
if region_is_header:
layout.prop(props, "affect", text="")
layout.prop(props, "profile", text="Shape", slider=True)
if region_is_header:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
else:
extra = True
if extra:
layout.use_property_split = True
layout.use_property_decorate = False
layout.prop(props, "material")
col = layout.column()
col.prop(props, "harden_normals")
col.prop(props, "clamp_overlap")
col.prop(props, "loop_slide")
UI: Layout changes for new checkbox layout possibilities Follow-up to previous commit. Some examples: {F8473507} {F8473508} {F8473509} {F8473510} For more screenshots, please see D7430. We use column or row headings here to bring more structure, and to give the eye visual anchors which aid eye-scanning. The left-aligned checkboxes likewise help with this. And we keep the adherence to the center line, so the alignment matches up between the various buttons and controls. * Changes the property split percentage from 50/50% to 40/60%. This is needed to give enough space for the checkboxes. But in most cases this looks better anyway - see Transform panel. In some cases it simply fills out the available space more efficently. * Fix various hacks where we previously used manually defined splits. When we did this, the alignment was never quite right, and the layout code was a mess. * Adds column headings to many places where a list of checkboxes all share a common purpose or leading text. * Add checkbox + value configurations various places where a checkbox only serves to enable the value slider * Removes most uses of grid flow layout. The grid flow layouts combine poorly with column headings, and also they would mess alignment up badly. The grid flow layouts also often made buttons and controls jump around on the screen if you would just resize editors slightly, causing visual confusion, making users lose their place. The logic for at what time the list of items would re-flow was often flawed, jumping to multiple columns too fast or too late - and frankly, the grid flow layouts would often just look bad. Maniphest Task: https://developer.blender.org/T65965 Differential Revision: https://developer.blender.org/D7430 Reviewed by: Brecht Van Lommel, Pablo Vazquez. Most work here by William Reynish, few changes by Julian Eisel.
2020-04-17 16:54:03 +02:00
col = layout.column(heading="Mark")
col.active = edge_bevel
UI: Layout changes for new checkbox layout possibilities Follow-up to previous commit. Some examples: {F8473507} {F8473508} {F8473509} {F8473510} For more screenshots, please see D7430. We use column or row headings here to bring more structure, and to give the eye visual anchors which aid eye-scanning. The left-aligned checkboxes likewise help with this. And we keep the adherence to the center line, so the alignment matches up between the various buttons and controls. * Changes the property split percentage from 50/50% to 40/60%. This is needed to give enough space for the checkboxes. But in most cases this looks better anyway - see Transform panel. In some cases it simply fills out the available space more efficently. * Fix various hacks where we previously used manually defined splits. When we did this, the alignment was never quite right, and the layout code was a mess. * Adds column headings to many places where a list of checkboxes all share a common purpose or leading text. * Add checkbox + value configurations various places where a checkbox only serves to enable the value slider * Removes most uses of grid flow layout. The grid flow layouts combine poorly with column headings, and also they would mess alignment up badly. The grid flow layouts also often made buttons and controls jump around on the screen if you would just resize editors slightly, causing visual confusion, making users lose their place. The logic for at what time the list of items would re-flow was often flawed, jumping to multiple columns too fast or too late - and frankly, the grid flow layouts would often just look bad. Maniphest Task: https://developer.blender.org/T65965 Differential Revision: https://developer.blender.org/D7430 Reviewed by: Brecht Van Lommel, Pablo Vazquez. Most work here by William Reynish, few changes by Julian Eisel.
2020-04-17 16:54:03 +02:00
col.prop(props, "mark_seam", text="Seam")
col.prop(props, "mark_sharp", text="Sharp")
col = layout.column()
col.active = edge_bevel
col.prop(props, "miter_outer", text="Miter Outer")
col.prop(props, "miter_inner", text="Inner")
if props.miter_inner == 'ARC':
col.prop(props, "spread")
layout.separator()
col = layout.column()
col.active = edge_bevel
col.prop(props, "vmesh_method", text="Intersections")
layout.prop(props, "face_strength_mode", text="Face Strength")
layout.prop(props, "profile_type")
if props.profile_type == 'CUSTOM':
tool_settings = context.tool_settings
layout.template_curveprofile(tool_settings, "custom_bevel_profile_preset")
2018-08-22 17:37:07 +10:00
return dict(
idname="builtin.bevel",
label="Bevel",
icon="ops.mesh.bevel",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
2018-08-22 17:37:07 +10:00
draw_settings=draw_settings,
)
@ToolDef.from_fn
def extrude():
return dict(
idname="builtin.extrude_region",
label="Extrude Region",
# The operator description isn't useful in this case, give our own.
description=(
"Extrude freely or along an axis"
),
icon="ops.mesh.extrude_region_move",
2018-11-21 09:25:55 +11:00
widget="VIEW3D_GGT_xform_extrude",
# Important to use same operator as 'E' key.
operator="view3d.edit_mesh_extrude_move_normal",
keymap=(),
2018-11-21 09:25:55 +11:00
draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings,
)
@ToolDef.from_fn
def extrude_manifold():
return dict(
idname="builtin.extrude_manifold",
label="Extrude Manifold",
description=(
"Extrude, dissolves edges whose faces form a flat surface and intersect new edges"
),
icon="ops.mesh.extrude_manifold",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
)
@ToolDef.from_fn
def extrude_normals():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.extrude_region_shrink_fatten")
props_macro = props.TRANSFORM_OT_shrink_fatten
layout.prop(props_macro, "use_even_offset")
return dict(
idname="builtin.extrude_along_normals",
label="Extrude Along Normals",
icon="ops.mesh.extrude_region_shrink_fatten",
widget="VIEW3D_GGT_tool_generic_handle_normal",
operator="mesh.extrude_region_shrink_fatten",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def extrude_individual():
return dict(
idname="builtin.extrude_individual",
label="Extrude Individual",
icon="ops.mesh.extrude_faces_move",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
)
@ToolDef.from_fn
def extrude_cursor():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.dupli_extrude_cursor")
layout.prop(props, "rotate_source")
return dict(
idname="builtin.extrude_to_cursor",
label="Extrude to Cursor",
cursor='CROSSHAIR',
icon="ops.mesh.dupli_extrude_cursor",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def loopcut_slide():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.loopcut_slide")
props_macro = props.MESH_OT_loopcut
layout.prop(props_macro, "number_cuts")
props_macro = props.TRANSFORM_OT_edge_slide
layout.prop(props_macro, "correct_uv")
return dict(
idname="builtin.loop_cut",
label="Loop Cut",
icon="ops.mesh.loopcut_slide",
widget="VIEW3D_GGT_mesh_preselect_edgering",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def offset_edge_loops_slide():
return dict(
idname="builtin.offset_edge_loop_cut",
label="Offset Edge Loop Cut",
icon="ops.mesh.offset_edge_loops_slide",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def vertex_smooth():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("mesh.vertices_smooth")
layout.prop(props, "repeat")
return dict(
idname="builtin.smooth",
label="Smooth",
icon="ops.mesh.vertices_smooth",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def vertex_randomize():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("transform.vertex_random")
layout.prop(props, "uniform")
layout.prop(props, "normal")
layout.prop(props, "seed")
return dict(
idname="builtin.randomize",
label="Randomize",
icon="ops.transform.vertex_random",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def tosphere():
return dict(
idname="builtin.to_sphere",
label="To Sphere",
icon="ops.transform.tosphere",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def shrink_fatten():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("transform.shrink_fatten")
layout.prop(props, "use_even_offset")
return dict(
idname="builtin.shrink_fatten",
label="Shrink/Fatten",
icon="ops.transform.shrink_fatten",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def push_pull():
return dict(
idname="builtin.push_pull",
label="Push/Pull",
icon="ops.transform.push_pull",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
)
@ToolDef.from_fn
def knife():
def draw_settings(_context, layout, tool, *, extra=False):
show_extra = False
props = tool.operator_properties("mesh.knife_tool")
if not extra:
layout.prop(props, "use_occlude_geometry")
layout.prop(props, "only_selected")
layout.prop(props, "xray")
region_is_header = bpy.context.region.type == 'TOOL_HEADER'
if region_is_header:
show_extra = True
else:
extra = True
if extra:
layout.use_property_decorate = False
layout.use_property_split = True
layout.prop(props, "visible_measurements")
layout.prop(props, "angle_snapping")
layout.label(text="Angle Snapping Increment")
layout.prop(props, "angle_snapping_increment", text="")
if show_extra:
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return dict(
idname="builtin.knife",
label="Knife",
cursor='KNIFE',
icon="ops.mesh.knife_tool",
widget=None,
keymap=(),
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
@ToolDef.from_fn
def bisect():
def draw_settings(_context, layout, tool):
2018-09-12 06:24:15 +10:00
props = tool.operator_properties("mesh.bisect")
layout.prop(props, "use_fill")
layout.prop(props, "clear_inner")
layout.prop(props, "clear_outer")
layout.prop(props, "threshold")
return dict(
idname="builtin.bisect",
label="Bisect",
icon="ops.mesh.bisect",
widget=None,
keymap=(),
2018-09-12 06:24:15 +10:00
draw_settings=draw_settings,
)
2018-05-07 21:38:43 +02:00
def curve_draw_settings(context, layout, tool, *, extra=False):
2023-12-11 15:46:55 -05:00
# Tool settings initialize operator options.
tool_settings = context.tool_settings
cps = tool_settings.curve_paint_settings
region_type = context.region.type
2018-05-11 20:25:01 +02:00
2023-12-11 15:46:55 -05:00
if region_type == 'TOOL_HEADER':
if not extra:
layout.prop(cps, "curve_type", text="")
layout.prop(cps, "depth_mode", expand=True)
layout.popover("TOPBAR_PT_tool_settings_extra", text="...")
return
2018-05-11 20:25:01 +02:00
2023-12-11 15:46:55 -05:00
layout.use_property_split = True
layout.use_property_decorate = False
2023-12-11 15:46:55 -05:00
if region_type != 'TOOL_HEADER':
layout.prop(cps, "curve_type")
layout.separator()
if cps.curve_type == 'BEZIER':
layout.prop(cps, "fit_method")
layout.prop(cps, "error_threshold")
if region_type != 'TOOL_HEADER':
2023-12-11 15:46:55 -05:00
row = layout.row(heading="Detect Corners", align=True)
else:
row = layout.row(heading="Corners", align=True)
row.prop(cps, "use_corners_detect", text="")
sub = row.row(align=True)
sub.active = cps.use_corners_detect
sub.prop(cps, "corner_angle", text="")
layout.separator()
col = layout.column(align=True)
col.prop(cps, "radius_taper_start", text="Taper Start", slider=True)
col.prop(cps, "radius_taper_end", text="End", slider=True)
col = layout.column(align=True)
col.prop(cps, "radius_min", text="Radius Min")
col.prop(cps, "radius_max", text="Max")
col.prop(cps, "use_pressure_radius")
if region_type != 'TOOL_HEADER' or cps.depth_mode == 'SURFACE':
layout.separator()
if region_type != 'TOOL_HEADER':
row = layout.row()
row.prop(cps, "depth_mode", expand=True)
if cps.depth_mode == 'SURFACE':
col = layout.column()
col.prop(cps, "surface_offset")
col.prop(cps, "use_offset_absolute")
col.prop(cps, "use_stroke_endpoints")
if cps.use_stroke_endpoints:
colsub = layout.column(align=True)
colsub.prop(cps, "surface_plane")
props = tool.operator_properties("curves.draw")
col = layout.column(align=True)
col.prop(props, "is_curve_2d", text="Curve 2D")
col.prop(props, "bezier_as_nurbs", text="As NURBS")
class _defs_edit_curve:
2018-05-11 20:25:01 +02:00
@ToolDef.from_fn
def draw():
return dict(
idname="builtin.draw",
label="Draw",
cursor='PAINT_BRUSH',
icon="ops.curve.draw",
widget=None,
keymap=(),
draw_settings=curve_draw_settings,
)
2018-08-29 15:14:41 +10:00
@ToolDef.from_fn
def extrude():
return dict(
idname="builtin.extrude",
label="Extrude",
icon="ops.curve.extrude_move",
2018-11-21 09:25:55 +11:00
widget="VIEW3D_GGT_xform_extrude",
keymap=(),
2018-11-21 09:25:55 +11:00
draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings,
2018-08-29 15:14:41 +10:00
)
@ToolDef.from_fn
def extrude_cursor():
return dict(
idname="builtin.extrude_cursor",
label="Extrude to Cursor",
cursor='CROSSHAIR',
icon="ops.curve.extrude_cursor",
widget=None,
keymap=(),
)
Curves: Curve Pen This tool can be used to rapidly edit curves. The current set of functionalities for Bezier splines are as follows: The functionalities are divided into three versions of the operator: * Left-Click * Ctrl + Left-Click * Double Click All current functionalities and their defaults are as follows: * Extrude Point: Add a point connected to an existing point. Enabled for Left-Click. * Extrude Handle Type: Type of the handles of the extruded points. Can be either Vector or Auto. Defaults to Vector. * Delete Point: Delete existing point. Enabled for Ctrl + Left-Click. * Insert Point: Insert a point into a curve segment. Enabled for Ctrl + Left-Click. * Move Segment: Move curve segment. Enabled for Left-Click. * Select Point: Select a single point or handle at a time. Enabled for Left-Click. * Move point: Move existing points or handles. Enabled for Left-Click. * Close Spline: Close spline by clicking the endpoints consecutively. Defaults to True. * Close Spline Method: The condition for Close Spline to activate. Can be one of None, On Press or On Click. Defaults to On Click for Left-Click and None for the others. * None: Functionality is turned off. * On Press: Activate on mouse down. This makes it possible to move the handles by dragging immediately after closing the spline. * On Click: Activate on mouse release. This makes it possible to avoid triggering the Close Spline functionality by dragging afterward. * Toggle Vector: Toggle handle between Vector and Auto handle types. Enabled for Double Click on a handle. * Cycle Handle Type: Cycle between all four handle types. Enabled for Double Click on the middle point of a Bezier point. The keybindings for the following functionalities can be adjusted from the modal keymap * Free-Align Toggle: Toggle between Free and Align handle types. Defaults to Left Shift. Activated on hold. * Move Adjacent Handle: Move the closer handle of the adjacent vertex. Defaults to Left Ctrl. Activated on hold. * Move Entire: Move the entire point by moving by grabbing on the handle Defaults to Spacebar. Activated on hold. * Link Handles: Mirror the movement of one handle onto the other. Defaults to Right Ctrl. Activated on press. * Lock Handle Angle: Move the handle along its current angle. Defaults to Left Alt. Activated on hold. All the above functionalities, except for Move Segment and those that work with handles, work similarly in the case of Poly and NURBS splines. Reviewed By: HooglyBoogly, weasel, campbellbarton Differential Revision: http://developer.blender.org/D12155
2022-04-03 22:37:22 +05:30
@ToolDef.from_fn
def pen():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("curve.pen")
layout.prop(props, "close_spline")
layout.prop(props, "extrude_handle")
return dict(
idname="builtin.pen",
label="Curve Pen",
cursor='CROSSHAIR',
Curves: Curve Pen This tool can be used to rapidly edit curves. The current set of functionalities for Bezier splines are as follows: The functionalities are divided into three versions of the operator: * Left-Click * Ctrl + Left-Click * Double Click All current functionalities and their defaults are as follows: * Extrude Point: Add a point connected to an existing point. Enabled for Left-Click. * Extrude Handle Type: Type of the handles of the extruded points. Can be either Vector or Auto. Defaults to Vector. * Delete Point: Delete existing point. Enabled for Ctrl + Left-Click. * Insert Point: Insert a point into a curve segment. Enabled for Ctrl + Left-Click. * Move Segment: Move curve segment. Enabled for Left-Click. * Select Point: Select a single point or handle at a time. Enabled for Left-Click. * Move point: Move existing points or handles. Enabled for Left-Click. * Close Spline: Close spline by clicking the endpoints consecutively. Defaults to True. * Close Spline Method: The condition for Close Spline to activate. Can be one of None, On Press or On Click. Defaults to On Click for Left-Click and None for the others. * None: Functionality is turned off. * On Press: Activate on mouse down. This makes it possible to move the handles by dragging immediately after closing the spline. * On Click: Activate on mouse release. This makes it possible to avoid triggering the Close Spline functionality by dragging afterward. * Toggle Vector: Toggle handle between Vector and Auto handle types. Enabled for Double Click on a handle. * Cycle Handle Type: Cycle between all four handle types. Enabled for Double Click on the middle point of a Bezier point. The keybindings for the following functionalities can be adjusted from the modal keymap * Free-Align Toggle: Toggle between Free and Align handle types. Defaults to Left Shift. Activated on hold. * Move Adjacent Handle: Move the closer handle of the adjacent vertex. Defaults to Left Ctrl. Activated on hold. * Move Entire: Move the entire point by moving by grabbing on the handle Defaults to Spacebar. Activated on hold. * Link Handles: Mirror the movement of one handle onto the other. Defaults to Right Ctrl. Activated on press. * Lock Handle Angle: Move the handle along its current angle. Defaults to Left Alt. Activated on hold. All the above functionalities, except for Move Segment and those that work with handles, work similarly in the case of Poly and NURBS splines. Reviewed By: HooglyBoogly, weasel, campbellbarton Differential Revision: http://developer.blender.org/D12155
2022-04-03 22:37:22 +05:30
icon="ops.curve.pen",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
2018-11-15 22:27:02 +11:00
@ToolDef.from_fn
def tilt():
return dict(
idname="builtin.tilt",
label="Tilt",
2018-11-15 22:27:02 +11:00
icon="ops.transform.tilt",
widget="VIEW3D_GGT_tool_generic_handle_free",
2018-11-15 22:27:02 +11:00
keymap=(),
)
@ToolDef.from_fn
def curve_radius():
return dict(
idname="builtin.radius",
label="Radius",
description=(
"Expand or contract the radius of the selected curve points"
),
icon="ops.curve.radius",
widget="VIEW3D_GGT_tool_generic_handle_free",
keymap=(),
)
2018-05-07 21:38:43 +02:00
@ToolDef.from_fn
def curve_vertex_randomize():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("transform.vertex_random")
layout.prop(props, "uniform")
layout.prop(props, "normal")
layout.prop(props, "seed")
return dict(
idname="builtin.randomize",
label="Randomize",
icon="ops.curve.vertex_random",
widget="VIEW3D_GGT_tool_generic_handle_normal",
keymap=(),
draw_settings=draw_settings,
)
2023-12-11 15:46:55 -05:00
class _defs_edit_curves:
@ToolDef.from_fn
def draw():
def curve_draw(context, layout, tool, *, extra=False):
curve_draw_settings(context, layout, tool, extra=extra)
return dict(
idname="builtin.draw",
label="Draw",
cursor='PAINT_BRUSH',
icon="ops.curve.draw",
widget=None,
keymap=(),
draw_settings=curve_draw,
)
2023-12-11 15:46:55 -05:00
class _defs_edit_text:
@ToolDef.from_fn
def select_text():
return dict(
idname="builtin.select_text",
label="Select Text",
cursor='TEXT',
icon="ops.generic.select_box",
widget=None,
keymap=(),
)
class _defs_pose:
@ToolDef.from_fn
def breakdown():
return dict(
idname="builtin.breakdowner",
label="Breakdowner",
icon="ops.pose.breakdowner",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def push():
return dict(
idname="builtin.push",
label="Push",
icon="ops.pose.push",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def relax():
return dict(
idname="builtin.relax",
label="Relax",
icon="ops.pose.relax",
widget=None,
keymap=(),
)
class _defs_particle:
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.particle.",
type=bpy.types.ParticleEdit,
attr="tool",
)
class _defs_sculpt:
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.sculpt.",
type=bpy.types.Brush,
attr="sculpt_tool",
# TODO(@ideasman42): we may want to enable this,
# it causes awkward grouping with 2x column button layout.
use_separators=False,
)
@ToolDef.from_fn
def hide_border():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.hide_show")
layout.prop(props, "area", expand=False)
return dict(
idname="builtin.box_hide",
label="Box Hide",
icon="ops.sculpt.border_hide",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def hide_lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.hide_show_lasso_gesture")
layout.prop(props, "area", expand=False)
return dict(
idname="builtin.lasso_hide",
label="Lasso Hide",
icon="ops.sculpt.lasso_hide",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mask_border():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.mask_box_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
return dict(
idname="builtin.box_mask",
label="Box Mask",
icon="ops.sculpt.border_mask",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mask_lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.mask_lasso_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
return dict(
idname="builtin.lasso_mask",
label="Lasso Mask",
icon="ops.sculpt.lasso_mask",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mask_line():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.mask_line_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
layout.prop(props, "use_limit_to_segment", expand=False)
return dict(
idname="builtin.line_mask",
label="Line Mask",
icon="ops.sculpt.line_mask",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def face_set_box():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.face_set_box_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
return dict(
idname="builtin.box_face_set",
label="Box Face Set",
icon="ops.sculpt.border_face_set",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def face_set_lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.face_set_lasso_gesture")
layout.prop(props, "use_front_faces_only", expand=False)
return dict(
idname="builtin.lasso_face_set",
label="Lasso Face Set",
icon="ops.sculpt.lasso_face_set",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def trim_box():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.trim_box_gesture")
layout.prop(props, "trim_solver", expand=False)
layout.prop(props, "trim_mode", expand=False)
layout.prop(props, "trim_orientation", expand=False)
layout.prop(props, "trim_extrude_mode", expand=False)
layout.prop(props, "use_cursor_depth", expand=False)
return dict(
idname="builtin.box_trim",
label="Box Trim",
icon="ops.sculpt.box_trim",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def trim_lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.trim_lasso_gesture")
layout.prop(props, "trim_solver", expand=False)
layout.prop(props, "trim_mode", expand=False)
layout.prop(props, "trim_orientation", expand=False)
layout.prop(props, "trim_extrude_mode", expand=False)
layout.prop(props, "use_cursor_depth", expand=False)
return dict(
idname="builtin.lasso_trim",
label="Lasso Trim",
icon="ops.sculpt.lasso_trim",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def project_line():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.project_line_gesture")
layout.prop(props, "use_limit_to_segment", expand=False)
return dict(
idname="builtin.line_project",
label="Line Project",
icon="ops.sculpt.line_project",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mesh_filter():
2019-09-15 05:26:15 +10:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.mesh_filter")
layout.prop(props, "type", expand=False)
layout.prop(props, "strength")
row = layout.row(align=True)
row.prop(props, "deform_axis")
layout.prop(props, "orientation", expand=False)
if props.type == 'SURFACE_SMOOTH':
layout.prop(props, "surface_smooth_shape_preservation", expand=False)
layout.prop(props, "surface_smooth_current_vertex", expand=False)
elif props.type == 'SHARPEN':
layout.prop(props, "sharpen_smooth_ratio", expand=False)
layout.prop(props, "sharpen_intensify_detail_strength", expand=False)
layout.prop(props, "sharpen_curvature_smooth_iterations", expand=False)
return dict(
idname="builtin.mesh_filter",
label="Mesh Filter",
icon="ops.sculpt.mesh_filter",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
2018-08-28 21:00:25 +10:00
@ToolDef.from_fn
def cloth_filter():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.cloth_filter")
layout.prop(props, "type", expand=False)
layout.prop(props, "strength")
row = layout.row(align=True)
row.prop(props, "force_axis")
layout.prop(props, "orientation", expand=False)
layout.prop(props, "cloth_mass")
layout.prop(props, "cloth_damping")
layout.prop(props, "use_face_sets")
layout.prop(props, "use_collisions")
return dict(
idname="builtin.cloth_filter",
label="Cloth Filter",
icon="ops.sculpt.cloth_filter",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def color_filter():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.color_filter")
layout.prop(props, "type", expand=False)
if props.type == 'FILL':
layout.prop(props, "fill_color", expand=False)
layout.prop(props, "strength")
return dict(
idname="builtin.color_filter",
label="Color Filter",
icon="ops.sculpt.color_filter",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mask_by_color():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.mask_by_color")
layout.prop(props, "threshold")
layout.prop(props, "contiguous")
layout.prop(props, "invert")
layout.prop(props, "preserve_previous_mask")
return dict(
idname="builtin.mask_by_color",
label="Mask by Color",
icon="ops.sculpt.mask_by_color",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def face_set_edit():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sculpt.face_set_edit")
layout.prop(props, "mode", expand=False)
layout.prop(props, "modify_hidden")
return dict(
idname="builtin.face_set_edit",
label="Edit Face Set",
icon="ops.sculpt.face_set_edit",
widget=None,
keymap="3D View Tool: Sculpt, Face Set Edit",
draw_settings=draw_settings,
)
class _defs_vertex_paint:
@staticmethod
def poll_select_mask(context):
if context is None:
return True
ob = context.active_object
return (ob and ob.type == 'MESH' and
(ob.data.use_paint_mask or
ob.data.use_paint_mask_vertex))
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.paint_vertex.",
type=bpy.types.Brush,
attr="vertex_tool",
)
2018-12-20 13:01:40 +11:00
class _defs_texture_paint:
@staticmethod
def poll_select_mask(context):
if context is None:
return True
ob = context.active_object
return (ob and ob.type == 'MESH' and
(ob.data.use_paint_mask))
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.paint_texture.",
type=bpy.types.Brush,
attr="image_tool",
cursor='PAINT_CROSS',
)
class _defs_weight_paint:
@staticmethod
Fix #44834: Add bone selection icon next to face and vertex selection in weight paint mode Currently, in weight paint mode, there is an icon for face and vertex selection mode, but there isn't one for the default mode where the user can select a bone in any tool by alt clicking. This lack of indication might lead to confusion for the users when they are not able to select a bone by alt clicking during weight painting. By adding a bone selection icon when there is a pose mode armature, we can communicate to the user that: 1. they can select a bone while the bone selection icon is active. (when they are not in face or vertex selection mode) 2. they have forgot to select an armature when entering weight paint mode by not showing the bone selection icon at all when there is no pose mode armature. When the bone selection icon is inactive, the user can't select a bone. (alt clicking selects face and vertex mode's respective element) When no armature is selected when entering weight paint mode, the bone selection icon doesn't show up indicating that the user has forgot to select an armature. (The user is also unable to select a bone by alt clicking.) ## Selection tool for bone selection mode Currently, while selection tools exist for face and vertex selection mode, one doesn't exist for the default mode (bone selection mode). As the default mode will be getting a clear indicator that it will function as a bone selection mode, I added a selection tool entry for the bone selection mode. Face and vertex selection modes has the shortcut 1 and 2, so it seemed natural to give bone selection mode the shortcut of 3. Pull Request: https://projects.blender.org/blender/blender/pulls/115409
2023-12-01 13:38:58 +01:00
def poll_select_tools(context):
if context is None:
Fix #44834: Add bone selection icon next to face and vertex selection in weight paint mode Currently, in weight paint mode, there is an icon for face and vertex selection mode, but there isn't one for the default mode where the user can select a bone in any tool by alt clicking. This lack of indication might lead to confusion for the users when they are not able to select a bone by alt clicking during weight painting. By adding a bone selection icon when there is a pose mode armature, we can communicate to the user that: 1. they can select a bone while the bone selection icon is active. (when they are not in face or vertex selection mode) 2. they have forgot to select an armature when entering weight paint mode by not showing the bone selection icon at all when there is no pose mode armature. When the bone selection icon is inactive, the user can't select a bone. (alt clicking selects face and vertex mode's respective element) When no armature is selected when entering weight paint mode, the bone selection icon doesn't show up indicating that the user has forgot to select an armature. (The user is also unable to select a bone by alt clicking.) ## Selection tool for bone selection mode Currently, while selection tools exist for face and vertex selection mode, one doesn't exist for the default mode (bone selection mode). As the default mode will be getting a clear indicator that it will function as a bone selection mode, I added a selection tool entry for the bone selection mode. Face and vertex selection modes has the shortcut 1 and 2, so it seemed natural to give bone selection mode the shortcut of 3. Pull Request: https://projects.blender.org/blender/blender/pulls/115409
2023-12-01 13:38:58 +01:00
return VIEW3D_PT_tools_active._tools_select
ob = context.active_object
Fix #44834: Add bone selection icon next to face and vertex selection in weight paint mode Currently, in weight paint mode, there is an icon for face and vertex selection mode, but there isn't one for the default mode where the user can select a bone in any tool by alt clicking. This lack of indication might lead to confusion for the users when they are not able to select a bone by alt clicking during weight painting. By adding a bone selection icon when there is a pose mode armature, we can communicate to the user that: 1. they can select a bone while the bone selection icon is active. (when they are not in face or vertex selection mode) 2. they have forgot to select an armature when entering weight paint mode by not showing the bone selection icon at all when there is no pose mode armature. When the bone selection icon is inactive, the user can't select a bone. (alt clicking selects face and vertex mode's respective element) When no armature is selected when entering weight paint mode, the bone selection icon doesn't show up indicating that the user has forgot to select an armature. (The user is also unable to select a bone by alt clicking.) ## Selection tool for bone selection mode Currently, while selection tools exist for face and vertex selection mode, one doesn't exist for the default mode (bone selection mode). As the default mode will be getting a clear indicator that it will function as a bone selection mode, I added a selection tool entry for the bone selection mode. Face and vertex selection modes has the shortcut 1 and 2, so it seemed natural to give bone selection mode the shortcut of 3. Pull Request: https://projects.blender.org/blender/blender/pulls/115409
2023-12-01 13:38:58 +01:00
if (ob and ob.type == 'MESH' and
(ob.data.use_paint_mask or
ob.data.use_paint_mask_vertex)):
return VIEW3D_PT_tools_active._tools_select
elif context.pose_object:
return VIEW3D_PT_tools_active._tools_select
Fix #44834: Add bone selection icon next to face and vertex selection in weight paint mode Currently, in weight paint mode, there is an icon for face and vertex selection mode, but there isn't one for the default mode where the user can select a bone in any tool by alt clicking. This lack of indication might lead to confusion for the users when they are not able to select a bone by alt clicking during weight painting. By adding a bone selection icon when there is a pose mode armature, we can communicate to the user that: 1. they can select a bone while the bone selection icon is active. (when they are not in face or vertex selection mode) 2. they have forgot to select an armature when entering weight paint mode by not showing the bone selection icon at all when there is no pose mode armature. When the bone selection icon is inactive, the user can't select a bone. (alt clicking selects face and vertex mode's respective element) When no armature is selected when entering weight paint mode, the bone selection icon doesn't show up indicating that the user has forgot to select an armature. (The user is also unable to select a bone by alt clicking.) ## Selection tool for bone selection mode Currently, while selection tools exist for face and vertex selection mode, one doesn't exist for the default mode (bone selection mode). As the default mode will be getting a clear indicator that it will function as a bone selection mode, I added a selection tool entry for the bone selection mode. Face and vertex selection modes has the shortcut 1 and 2, so it seemed natural to give bone selection mode the shortcut of 3. Pull Request: https://projects.blender.org/blender/blender/pulls/115409
2023-12-01 13:38:58 +01:00
return ()
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.paint_weight.",
type=bpy.types.Brush,
attr="weight_tool",
)
@ToolDef.from_fn
def sample_weight():
2021-03-06 18:21:17 +11:00
def draw_settings(context, layout, _tool):
if context.tool_settings.unified_paint_settings.use_unified_weight:
weight = context.tool_settings.unified_paint_settings.weight
elif context.tool_settings.weight_paint.brush:
weight = context.tool_settings.weight_paint.brush.weight
else:
return
layout.label(text="Weight: %.3f" % weight)
return dict(
idname="builtin.sample_weight",
label="Sample Weight",
icon="ops.paint.weight_sample",
cursor='EYEDROPPER',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def sample_weight_group():
return dict(
idname="builtin.sample_vertex_group",
label="Sample Vertex Group",
icon="ops.paint.weight_sample_group",
cursor='EYEDROPPER',
widget=None,
keymap=(),
)
@ToolDef.from_fn
def gradient():
def draw_settings(context, layout, tool):
brush = context.tool_settings.weight_paint.brush
if brush is not None:
from bl_ui.properties_paint_common import UnifiedPaintPanel
UnifiedPaintPanel.prop_unified(
layout,
context,
brush,
"weight",
unified_name="use_unified_weight",
slider=True,
header=True,
)
UnifiedPaintPanel.prop_unified(
layout,
context,
brush,
"strength",
unified_name="use_unified_strength",
header=True,
)
props = tool.operator_properties("paint.weight_gradient")
UI: Brush Settings overhaul This makes a number of changes to the tool settings brush UI: - All brush-related controls are now grouped together, so you can see which items are brush settings are which are not. Previously it was all jumbled together. - The brush picker is in a separate panel, so that you can switch brushes without worrying about the settings, or vice versa. - Custom Icon settings moved from the Display settings(now known as Cursor) to the Brushes panel. - UnifiedPaintSettings panels are removed and the contained options are now next to their relevant setting with a globe icon toggle. This is not displayed in the header. - 2D Falloff and Absolute Jitter toggles were changed into enums, to make it clearer what happens when they are on or off. - Adjust Strength for Spacing option was in the Options panel in some modes, but in the Stroke panel in others. It is now always under Stroke. - Display (now Cursor) panel was reorganized, settings renamed. - 2-option enums are annoying as a drop-down menu, so they are now drawn with expand=True. - Smooth Stroke and Stabilizer options in grease pencil and other paint modes are now both called "Stabilize Stroke", for consistency and clarity. - De-duplicated some drawing code between various painting modes' brush options. I tried to keep de-duplication reasonable and easy to follow. - A few more tweaks - see D5928 for the extensive list. Most of the patch is written by Demeter Dzadik, with some additions by myself Differential Revision: https://developer.blender.org/D5928 Reviewers: Pablo Dobarro, Bastien Montagne, Matias Mendiola
2019-12-14 18:48:18 +01:00
layout.prop(props, "type", expand=True)
Weightpaint Gradient tool: expose falloff to the UI By default, we'll always get a falloff like this from the tool: {F10559413} But in the context of using vertexgroups in modifiers/modeling, a choice on how the gradient falloff of the Weightpaint Gradient tool is shaped would be desirable: "real" linear: {F10559416} Custom: {F10559421} {F10559428} The way the Weightpaint gradient tool works is a bit outside the usual tools that use brushes [even though it creates a brush on the fly in `WPGradient_userData`]. However, it does not have an entry in `eBrushWeightPaintTool` and adding one there does not play nice for the same reasons (not "really" being integrated in the brush-based tools). So in order to expose the brush curve in the UI, we would have to do one of the following: - [1] try to use `VIEW3D_PT_tools_brush_falloff`, for this to work: -- make all kinds of exception in python super classes [`FalloffPanel`, `BrushPanel`, `UnifiedPaintPanel`, ... -- including making real entries in `eBrushWeightPaintTool`] to get a proper tool mode and... -- .. to also make sure Falloff Shape and Front-Face Falloff are not available [which the tool seems to just not support in its current form] - [2] just have a simple, contained panel for this tool alone This patch implements [2] and adds it as part of the ToolDef (could also be done in `VIEW3D_HT_tool_header`, but again, I think this is nice to keep separate from the usual tools) {F10559482} {F10559485} Testfile: {F10559442} Fixes T91636 Maniphest Tasks: T91636 Differential Revision: https://developer.blender.org/D12614
2021-09-23 15:48:32 +02:00
layout.popover("VIEW3D_PT_tools_weight_gradient")
return dict(
idname="builtin.gradient",
label="Gradient",
icon="ops.paint.weight_gradient",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
class _defs_paint_grease_pencil:
# FIXME: Replace brush tools with code below once they are all implemented:
#
# @staticmethod
# def generate_from_brushes(context):
# return generate_from_enum_ex(
# context,
# idname_prefix="builtin_brush.",
# icon_prefix="brush.gpencil_draw.",
# type=bpy.types.Brush,
# attr="gpencil_tool",
# cursor='DOT',
# )
@ToolDef.from_fn
def draw():
return dict(
idname="builtin_brush.Draw",
label="Draw",
icon="brush.gpencil_draw.draw",
data_block='DRAW',
)
2023-07-21 14:23:49 +02:00
@ToolDef.from_fn
def erase():
return dict(
idname="builtin_brush.Erase",
label="Erase",
icon="brush.gpencil_draw.erase",
data_block='ERASE',
)
class _defs_image_generic:
@staticmethod
def poll_uvedit(context):
if context is None:
return True
ob = context.edit_object
if ob is not None:
data = ob.data
if data is not None:
return bool(getattr(data, "uv_layers", False))
return False
@ToolDef.from_fn
def cursor():
return dict(
idname="builtin.cursor",
label="Cursor",
description=(
"Set the cursor location, drag to transform"
),
icon="ops.generic.cursor",
keymap=(),
)
# Currently a place holder so we can switch away from the annotation tool.
# Falls back to default image editor action.
@ToolDef.from_fn
def sample():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("image.sample")
layout.prop(props, "size")
return dict(
idname="builtin.sample",
label="Sample",
description=(
"Sample pixel values under the cursor"
),
icon="ops.paint.weight_sample", # XXX, needs own icon.
keymap="Image Editor Tool: Sample",
draw_settings=draw_settings,
)
class _defs_image_uv_transform:
2019-06-26 01:39:58 +10:00
@ToolDef.from_fn
def translate():
return dict(
idname="builtin.move",
label="Move",
icon="ops.transform.translate",
widget="IMAGE_GGT_gizmo2d_translate",
2019-06-26 01:39:58 +10:00
operator="transform.translate",
keymap="Image Editor Tool: Uv, Move",
2019-06-26 01:39:58 +10:00
)
@ToolDef.from_fn
def rotate():
return dict(
idname="builtin.rotate",
label="Rotate",
icon="ops.transform.rotate",
widget="IMAGE_GGT_gizmo2d_rotate",
2019-06-26 01:39:58 +10:00
operator="transform.rotate",
keymap="Image Editor Tool: Uv, Rotate",
2019-06-26 01:39:58 +10:00
)
@ToolDef.from_fn
def scale():
return dict(
idname="builtin.scale",
label="Scale",
icon="ops.transform.resize",
widget="IMAGE_GGT_gizmo2d_resize",
2019-06-26 01:39:58 +10:00
operator="transform.resize",
keymap="Image Editor Tool: Uv, Scale",
2019-06-26 01:39:58 +10:00
)
@ToolDef.from_fn
def transform():
return dict(
idname="builtin.transform",
label="Transform",
description=(
"Supports any combination of grab, rotate, and scale at once"
),
icon="ops.transform.transform",
widget="IMAGE_GGT_gizmo2d",
# No keymap default action, only for gizmo!
)
class _defs_image_uv_select:
@ToolDef.from_fn
def select():
return dict(
idname="builtin.select",
label="Tweak",
icon="ops.generic.select",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def box():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("uv.select_box")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
return dict(
idname="builtin.select_box",
label="Select Box",
icon="ops.generic.select_box",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def lasso():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("uv.select_lasso")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
return dict(
idname="builtin.select_lasso",
label="Select Lasso",
icon="ops.generic.select_lasso",
widget=None,
2018-12-14 13:21:13 +11:00
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("uv.select_circle")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
layout.prop(props, "radius")
def draw_cursor(_context, tool, xy):
from gpu_extras.presets import draw_circle_2d
props = tool.operator_properties("uv.select_circle")
radius = props.radius
PyAPI: use keyword only arguments Use keyword only arguments for the following functions. - addon_utils.module_bl_info 2nd arg `info_basis`. - addon_utils.modules 1st `module_cache`, 2nd arg `refresh`. - addon_utils.modules_refresh 1st arg `module_cache`. - bl_app_template_utils.activate 1nd arg `template_id`. - bl_app_template_utils.import_from_id 2nd arg `ignore_not_found`. - bl_app_template_utils.import_from_path 2nd arg `ignore_not_found`. - bl_keymap_utils.keymap_from_toolbar.generate 2nd & 3rd args `use_fallback_keys` & `use_reset`. - bl_keymap_utils.platform_helpers.keyconfig_data_oskey_from_ctrl 2nd arg `filter_fn`. - bl_ui_utils.bug_report_url.url_prefill_from_blender 1st arg `addon_info`. - bmesh.types.BMFace.copy 1st & 2nd args `verts`, `edges`. - bmesh.types.BMesh.calc_volume 1st arg `signed`. - bmesh.types.BMesh.from_mesh 2nd..4th args `face_normals`, `use_shape_key`, `shape_key_index`. - bmesh.types.BMesh.from_object 3rd & 4th args `cage`, `face_normals`. - bmesh.types.BMesh.transform 2nd arg `filter`. - bmesh.types.BMesh.update_edit_mesh 2nd & 3rd args `loop_triangles`, `destructive`. - bmesh.types.{BMVertSeq,BMEdgeSeq,BMFaceSeq}.sort 1st & 2nd arg `key`, `reverse`. - bmesh.utils.face_split 4th..6th args `coords`, `use_exist`, `example`. - bpy.data.libraries.load 2nd..4th args `link`, `relative`, `assets_only`. - bpy.data.user_map 1st..3rd args `subset`, `key_types, `value_types`. - bpy.msgbus.subscribe_rna 5th arg `options`. - bpy.path.abspath 2nd & 3rd args `start` & `library`. - bpy.path.clean_name 2nd arg `replace`. - bpy.path.ensure_ext 3rd arg `case_sensitive`. - bpy.path.module_names 2nd arg `recursive`. - bpy.path.relpath 2nd arg `start`. - bpy.types.EditBone.transform 2nd & 3rd arg `scale`, `roll`. - bpy.types.Operator.as_keywords 1st arg `ignore`. - bpy.types.Struct.{keyframe_insert,keyframe_delete} 2nd..5th args `index`, `frame`, `group`, `options`. - bpy.types.WindowManager.popup_menu 2nd & 3rd arg `title`, `icon`. - bpy.types.WindowManager.popup_menu_pie 3rd & 4th arg `title`, `icon`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.blend_paths 1st..3rd args `absolute`, `packed`, `local`. - bpy.utils.execfile 2nd arg `mod`. - bpy.utils.keyconfig_set 2nd arg `report`. - bpy.utils.load_scripts 1st & 2nd `reload_scripts` & `refresh_scripts`. - bpy.utils.preset_find 3rd & 4th args `display_name`, `ext`. - bpy.utils.resource_path 2nd & 3rd arg `major`, `minor`. - bpy.utils.script_paths 1st..4th args `subdir`, `user_pref`, `check_all`, `use_user`. - bpy.utils.smpte_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.smpte_from_seconds 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.system_resource 2nd arg `subdir`. - bpy.utils.time_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.time_to_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.units.to_string 4th..6th `precision`, `split_unit`, `compatible_unit`. - bpy.utils.units.to_value 4th arg `str_ref_unit`. - bpy.utils.user_resource 2nd & 3rd args `subdir`, `create` - bpy_extras.view3d_utils.location_3d_to_region_2d 4th arg `default`. - bpy_extras.view3d_utils.region_2d_to_origin_3d 4th arg `clamp`. - gpu.offscreen.unbind 1st arg `restore`. - gpu_extras.batch.batch_for_shader 4th arg `indices`. - gpu_extras.batch.presets.draw_circle_2d 4th arg `segments`. - gpu_extras.presets.draw_circle_2d 4th arg `segments`. - imbuf.types.ImBuf.resize 2nd arg `resize`. - imbuf.write 2nd arg `filepath`. - mathutils.kdtree.KDTree.find 2nd arg `filter`. - nodeitems_utils.NodeCategory 3rd & 4th arg `descriptions`, `items`. - nodeitems_utils.NodeItem 2nd..4th args `label`, `settings`, `poll`. - nodeitems_utils.NodeItemCustom 1st & 2nd arg `poll`, `draw`. - rna_prop_ui.draw 5th arg `use_edit`. - rna_prop_ui.rna_idprop_ui_get 2nd arg `create`. - rna_prop_ui.rna_idprop_ui_prop_clear 3rd arg `remove`. - rna_prop_ui.rna_idprop_ui_prop_get 3rd arg `create`. - rna_xml.xml2rna 2nd arg `root_rna`. - rna_xml.xml_file_write 4th arg `skip_typemap`.
2021-06-08 18:03:14 +10:00
draw_circle_2d(xy, (1.0,) * 4, radius, segments=32)
return dict(
idname="builtin.select_circle",
label="Select Circle",
icon="ops.generic.select_circle",
widget=None,
keymap=(),
draw_settings=draw_settings,
draw_cursor=draw_cursor,
)
2018-07-31 21:06:08 +10:00
2020-07-06 21:14:12 +10:00
class _defs_image_uv_edit:
2020-07-06 21:14:12 +10:00
@ToolDef.from_fn
def rip_region():
return dict(
idname="builtin.rip_region",
label="Rip Region",
icon="ops.mesh.rip",
# TODO: generic operator (UV version of `VIEW3D_GGT_tool_generic_handle_free`).
widget=None,
keymap=(),
options={'KEYMAP_FALLBACK'},
2020-07-06 21:14:12 +10:00
)
class _defs_image_uv_sculpt:
@staticmethod
def generate_from_brushes(context):
def draw_cursor(context, _tool, xy):
from gpu_extras.presets import draw_circle_2d
tool_settings = context.tool_settings
uv_sculpt = tool_settings.uv_sculpt
if not uv_sculpt.show_brush:
return
ups = tool_settings.unified_paint_settings
if ups.use_unified_size:
radius = ups.size
else:
brush = tool_settings.uv_sculpt.brush
if brush is None:
return
radius = brush.size
draw_circle_2d(xy, (1.0,) * 4, radius)
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.uv_sculpt.",
type=bpy.types.Brush,
attr="uv_sculpt_tool",
tooldef_keywords=dict(
operator="sculpt.uv_sculpt_stroke",
keymap="Image Editor Tool: Uv, Sculpt Stroke",
draw_cursor=draw_cursor,
options={'KEYMAP_FALLBACK'},
),
)
class _defs_gpencil_paint:
@staticmethod
2021-03-06 18:21:17 +11:00
def gpencil_primitive_toolbar(context, layout, _tool, props):
paint = context.tool_settings.gpencil_paint
brush = paint.brush
if brush is None:
return False
gp_settings = brush.gpencil_settings
row = layout.row(align=True)
tool_settings = context.scene.tool_settings
settings = tool_settings.gpencil_paint
row.template_ID_preview(settings, "brush", rows=3, cols=8, hide_buttons=True)
from bl_ui.properties_paint_common import (
brush_basic_gpencil_paint_settings,
brush_basic__draw_color_selector,
)
brush_basic__draw_color_selector(context, layout, brush, gp_settings, props)
brush_basic_gpencil_paint_settings(layout, context, brush, compact=True)
return True
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.gpencil_draw.",
type=bpy.types.Brush,
attr="gpencil_tool",
cursor='DOT',
tooldef_keywords=dict(
operator="gpencil.draw",
),
)
@ToolDef.from_fn
def cutter():
2021-03-06 18:21:17 +11:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("gpencil.stroke_cutter")
row = layout.row()
row.use_property_split = False
row.prop(props, "flat_caps")
return dict(
idname="builtin.cutter",
label="Cutter",
icon="ops.gpencil.stroke_cutter",
cursor='KNIFE',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def line():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_line")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.line",
label="Line",
icon="ops.gpencil.primitive_line",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def polyline():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_polyline")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.polyline",
label="Polyline",
icon="ops.gpencil.primitive_polyline",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
2019-10-23 01:03:31 +11:00
)
@ToolDef.from_fn
def box():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_box")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.box",
label="Box",
icon="ops.gpencil.primitive_box",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_circle")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.circle",
label="Circle",
icon="ops.gpencil.primitive_circle",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def arc():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_curve")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.arc",
label="Arc",
icon="ops.gpencil.primitive_arc",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def curve():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.primitive_curve")
_defs_gpencil_paint.gpencil_primitive_toolbar(context, layout, tool, props)
return dict(
idname="builtin.curve",
label="Curve",
icon="ops.gpencil.primitive_curve",
cursor='CROSSHAIR',
widget=None,
keymap=(),
draw_settings=draw_settings,
2019-10-23 01:03:31 +11:00
)
@ToolDef.from_fn
def eyedropper():
2021-03-06 18:21:17 +11:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("ui.eyedropper_gpencil_color")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", expand=True)
return dict(
idname="builtin.eyedropper",
label="Eyedropper",
icon="ops.paint.eyedropper_add",
cursor='EYEDROPPER',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def interpolate():
2021-03-06 18:21:17 +11:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("gpencil.interpolate")
layout.prop(props, "layers")
layout.prop(props, "exclude_breakdowns")
layout.prop(props, "flip")
layout.prop(props, "smooth_factor")
layout.prop(props, "smooth_steps")
return dict(
idname="builtin.interpolate",
label="Interpolate",
icon="ops.pose.breakdowner",
cursor='DEFAULT',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
2019-10-12 10:22:09 +11:00
class _defs_gpencil_edit:
def is_segment(context):
tool_settings = context.scene.tool_settings
if context.mode == 'EDIT_GPENCIL':
return tool_settings.gpencil_selectmode_edit == 'SEGMENT'
elif context.mode == 'SCULPT_GPENCIL':
return tool_settings.use_gpencil_select_mask_segment
elif context.mode == 'VERTEX_GPENCIL':
return tool_settings.use_gpencil_vertex_select_mask_segment
else:
return False
@ToolDef.from_fn
def bend():
return dict(
idname="builtin.bend",
label="Bend",
icon="ops.gpencil.edit_bend",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def select():
def draw_settings(context, layout, _tool):
if _defs_gpencil_edit.is_segment(context):
layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold")
return dict(
idname="builtin.select",
label="Tweak",
icon="ops.generic.select",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def box_select():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.select_box")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
if _defs_gpencil_edit.is_segment(context):
layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold")
return dict(
idname="builtin.select_box",
label="Select Box",
icon="ops.generic.select_box",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def lasso_select():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.select_lasso")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
if _defs_gpencil_edit.is_segment(context):
layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold")
return dict(
idname="builtin.select_lasso",
label="Select Lasso",
icon="ops.generic.select_lasso",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle_select():
def draw_settings(context, layout, tool):
props = tool.operator_properties("gpencil.select_circle")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
layout.prop(props, "radius")
if _defs_gpencil_edit.is_segment(context):
layout.prop(context.tool_settings.gpencil_sculpt, "intersection_threshold")
def draw_cursor(_context, tool, xy):
from gpu_extras.presets import draw_circle_2d
props = tool.operator_properties("gpencil.select_circle")
radius = props.radius
PyAPI: use keyword only arguments Use keyword only arguments for the following functions. - addon_utils.module_bl_info 2nd arg `info_basis`. - addon_utils.modules 1st `module_cache`, 2nd arg `refresh`. - addon_utils.modules_refresh 1st arg `module_cache`. - bl_app_template_utils.activate 1nd arg `template_id`. - bl_app_template_utils.import_from_id 2nd arg `ignore_not_found`. - bl_app_template_utils.import_from_path 2nd arg `ignore_not_found`. - bl_keymap_utils.keymap_from_toolbar.generate 2nd & 3rd args `use_fallback_keys` & `use_reset`. - bl_keymap_utils.platform_helpers.keyconfig_data_oskey_from_ctrl 2nd arg `filter_fn`. - bl_ui_utils.bug_report_url.url_prefill_from_blender 1st arg `addon_info`. - bmesh.types.BMFace.copy 1st & 2nd args `verts`, `edges`. - bmesh.types.BMesh.calc_volume 1st arg `signed`. - bmesh.types.BMesh.from_mesh 2nd..4th args `face_normals`, `use_shape_key`, `shape_key_index`. - bmesh.types.BMesh.from_object 3rd & 4th args `cage`, `face_normals`. - bmesh.types.BMesh.transform 2nd arg `filter`. - bmesh.types.BMesh.update_edit_mesh 2nd & 3rd args `loop_triangles`, `destructive`. - bmesh.types.{BMVertSeq,BMEdgeSeq,BMFaceSeq}.sort 1st & 2nd arg `key`, `reverse`. - bmesh.utils.face_split 4th..6th args `coords`, `use_exist`, `example`. - bpy.data.libraries.load 2nd..4th args `link`, `relative`, `assets_only`. - bpy.data.user_map 1st..3rd args `subset`, `key_types, `value_types`. - bpy.msgbus.subscribe_rna 5th arg `options`. - bpy.path.abspath 2nd & 3rd args `start` & `library`. - bpy.path.clean_name 2nd arg `replace`. - bpy.path.ensure_ext 3rd arg `case_sensitive`. - bpy.path.module_names 2nd arg `recursive`. - bpy.path.relpath 2nd arg `start`. - bpy.types.EditBone.transform 2nd & 3rd arg `scale`, `roll`. - bpy.types.Operator.as_keywords 1st arg `ignore`. - bpy.types.Struct.{keyframe_insert,keyframe_delete} 2nd..5th args `index`, `frame`, `group`, `options`. - bpy.types.WindowManager.popup_menu 2nd & 3rd arg `title`, `icon`. - bpy.types.WindowManager.popup_menu_pie 3rd & 4th arg `title`, `icon`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.blend_paths 1st..3rd args `absolute`, `packed`, `local`. - bpy.utils.execfile 2nd arg `mod`. - bpy.utils.keyconfig_set 2nd arg `report`. - bpy.utils.load_scripts 1st & 2nd `reload_scripts` & `refresh_scripts`. - bpy.utils.preset_find 3rd & 4th args `display_name`, `ext`. - bpy.utils.resource_path 2nd & 3rd arg `major`, `minor`. - bpy.utils.script_paths 1st..4th args `subdir`, `user_pref`, `check_all`, `use_user`. - bpy.utils.smpte_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.smpte_from_seconds 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.system_resource 2nd arg `subdir`. - bpy.utils.time_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.time_to_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.units.to_string 4th..6th `precision`, `split_unit`, `compatible_unit`. - bpy.utils.units.to_value 4th arg `str_ref_unit`. - bpy.utils.user_resource 2nd & 3rd args `subdir`, `create` - bpy_extras.view3d_utils.location_3d_to_region_2d 4th arg `default`. - bpy_extras.view3d_utils.region_2d_to_origin_3d 4th arg `clamp`. - gpu.offscreen.unbind 1st arg `restore`. - gpu_extras.batch.batch_for_shader 4th arg `indices`. - gpu_extras.batch.presets.draw_circle_2d 4th arg `segments`. - gpu_extras.presets.draw_circle_2d 4th arg `segments`. - imbuf.types.ImBuf.resize 2nd arg `resize`. - imbuf.write 2nd arg `filepath`. - mathutils.kdtree.KDTree.find 2nd arg `filter`. - nodeitems_utils.NodeCategory 3rd & 4th arg `descriptions`, `items`. - nodeitems_utils.NodeItem 2nd..4th args `label`, `settings`, `poll`. - nodeitems_utils.NodeItemCustom 1st & 2nd arg `poll`, `draw`. - rna_prop_ui.draw 5th arg `use_edit`. - rna_prop_ui.rna_idprop_ui_get 2nd arg `create`. - rna_prop_ui.rna_idprop_ui_prop_clear 3rd arg `remove`. - rna_prop_ui.rna_idprop_ui_prop_get 3rd arg `create`. - rna_xml.xml2rna 2nd arg `root_rna`. - rna_xml.xml_file_write 4th arg `skip_typemap`.
2021-06-08 18:03:14 +10:00
draw_circle_2d(xy, (1.0,) * 4, radius, segments=32)
return dict(
idname="builtin.select_circle",
label="Select Circle",
icon="ops.generic.select_circle",
widget=None,
2018-11-15 13:34:47 +11:00
keymap=(),
draw_settings=draw_settings,
draw_cursor=draw_cursor,
)
@ToolDef.from_fn
def radius():
return dict(
idname="builtin.radius",
label="Radius",
description=(
"Expand or contract the radius of the selected points"
),
icon="ops.gpencil.radius",
widget=None,
keymap=(),
)
@ToolDef.from_fn
def shear():
return dict(
idname="builtin.shear",
label="Shear",
icon="ops.gpencil.edit_shear",
widget=None,
2018-11-15 13:34:47 +11:00
keymap=(),
)
@ToolDef.from_fn
def tosphere():
return dict(
idname="builtin.to_sphere",
label="To Sphere",
icon="ops.transform.tosphere",
widget=None,
2018-11-15 13:34:47 +11:00
keymap=(),
)
@ToolDef.from_fn
def extrude():
return dict(
idname="builtin.extrude",
label="Extrude",
icon="ops.gpencil.extrude_move",
widget="VIEW3D_GGT_xform_extrude",
keymap=(),
draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings,
)
@ToolDef.from_fn
def transform_fill():
2021-03-06 18:21:17 +11:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("gpencil.transform_fill")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", expand=True)
return dict(
idname="builtin.transform_fill",
label="Transform Fill",
icon="ops.gpencil.transform_fill",
cursor='DEFAULT',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def interpolate():
2021-03-06 18:21:17 +11:00
def draw_settings(_context, layout, tool):
props = tool.operator_properties("gpencil.interpolate")
layout.prop(props, "layers")
layout.prop(props, "interpolate_selected_only")
layout.prop(props, "exclude_breakdowns")
layout.prop(props, "flip")
layout.prop(props, "smooth_factor")
layout.prop(props, "smooth_steps")
return dict(
idname="builtin.interpolate",
label="Interpolate",
icon="ops.pose.breakdowner",
cursor='DEFAULT',
widget=None,
keymap=(),
draw_settings=draw_settings,
)
class _defs_gpencil_sculpt:
@staticmethod
def poll_select_mask(context):
if context is None:
return True
ob = context.active_object
tool_settings = context.scene.tool_settings
return (
ob is not None and
ob.type == 'GPENCIL' and (
tool_settings.use_gpencil_select_mask_point or
tool_settings.use_gpencil_select_mask_stroke or
tool_settings.use_gpencil_select_mask_segment
)
)
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="ops.gpencil.sculpt_",
type=bpy.types.Brush,
attr="gpencil_sculpt_tool",
tooldef_keywords=dict(
operator="gpencil.sculpt_paint",
),
)
class _defs_gpencil_weight:
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="ops.gpencil.sculpt_",
type=bpy.types.Brush,
attr="gpencil_weight_tool",
tooldef_keywords=dict(
operator="gpencil.weight_paint",
),
)
class _defs_curves_sculpt:
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="ops.curves.sculpt_",
type=bpy.types.Brush,
attr="curves_sculpt_tool",
icon_map={
# Use the generic icon for selection painting.
"ops.curves.sculpt_selection_paint": "ops.generic.select_paint",
},
)
class _defs_gpencil_vertex:
@staticmethod
def poll_select_mask(context):
if context is None:
return True
ob = context.active_object
tool_settings = context.scene.tool_settings
return (
ob is not None and
ob.type == 'GPENCIL' and (
tool_settings.use_gpencil_vertex_select_mask_point or
tool_settings.use_gpencil_vertex_select_mask_stroke or
tool_settings.use_gpencil_vertex_select_mask_segment
)
)
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="brush.paint_vertex.",
type=bpy.types.Brush,
attr="gpencil_vertex_tool",
cursor='DOT',
tooldef_keywords=dict(
operator="gpencil.vertex_paint",
),
)
2018-11-27 18:39:29 +11:00
class _defs_node_select:
2018-11-27 18:39:29 +11:00
@ToolDef.from_fn
def select():
return dict(
idname="builtin.select",
label="Tweak",
2018-11-27 18:39:29 +11:00
icon="ops.generic.select",
widget=None,
keymap="Node Tool: Tweak",
2018-11-27 18:39:29 +11:00
)
@ToolDef.from_fn
def box():
def draw_settings(_context, layout, tool):
2018-11-27 18:39:29 +11:00
props = tool.operator_properties("node.select_box")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
2018-11-27 18:39:29 +11:00
return dict(
idname="builtin.select_box",
label="Select Box",
2018-11-27 18:39:29 +11:00
icon="ops.generic.select_box",
widget=None,
keymap="Node Tool: Select Box",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def lasso():
def draw_settings(_context, layout, tool):
2018-11-27 18:39:29 +11:00
props = tool.operator_properties("node.select_lasso")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
2018-11-27 18:39:29 +11:00
return dict(
idname="builtin.select_lasso",
label="Select Lasso",
2018-11-27 18:39:29 +11:00
icon="ops.generic.select_lasso",
widget=None,
keymap="Node Tool: Select Lasso",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def circle():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("node.select_circle")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
layout.prop(props, "radius")
def draw_cursor(_context, tool, xy):
from gpu_extras.presets import draw_circle_2d
props = tool.operator_properties("node.select_circle")
radius = props.radius
PyAPI: use keyword only arguments Use keyword only arguments for the following functions. - addon_utils.module_bl_info 2nd arg `info_basis`. - addon_utils.modules 1st `module_cache`, 2nd arg `refresh`. - addon_utils.modules_refresh 1st arg `module_cache`. - bl_app_template_utils.activate 1nd arg `template_id`. - bl_app_template_utils.import_from_id 2nd arg `ignore_not_found`. - bl_app_template_utils.import_from_path 2nd arg `ignore_not_found`. - bl_keymap_utils.keymap_from_toolbar.generate 2nd & 3rd args `use_fallback_keys` & `use_reset`. - bl_keymap_utils.platform_helpers.keyconfig_data_oskey_from_ctrl 2nd arg `filter_fn`. - bl_ui_utils.bug_report_url.url_prefill_from_blender 1st arg `addon_info`. - bmesh.types.BMFace.copy 1st & 2nd args `verts`, `edges`. - bmesh.types.BMesh.calc_volume 1st arg `signed`. - bmesh.types.BMesh.from_mesh 2nd..4th args `face_normals`, `use_shape_key`, `shape_key_index`. - bmesh.types.BMesh.from_object 3rd & 4th args `cage`, `face_normals`. - bmesh.types.BMesh.transform 2nd arg `filter`. - bmesh.types.BMesh.update_edit_mesh 2nd & 3rd args `loop_triangles`, `destructive`. - bmesh.types.{BMVertSeq,BMEdgeSeq,BMFaceSeq}.sort 1st & 2nd arg `key`, `reverse`. - bmesh.utils.face_split 4th..6th args `coords`, `use_exist`, `example`. - bpy.data.libraries.load 2nd..4th args `link`, `relative`, `assets_only`. - bpy.data.user_map 1st..3rd args `subset`, `key_types, `value_types`. - bpy.msgbus.subscribe_rna 5th arg `options`. - bpy.path.abspath 2nd & 3rd args `start` & `library`. - bpy.path.clean_name 2nd arg `replace`. - bpy.path.ensure_ext 3rd arg `case_sensitive`. - bpy.path.module_names 2nd arg `recursive`. - bpy.path.relpath 2nd arg `start`. - bpy.types.EditBone.transform 2nd & 3rd arg `scale`, `roll`. - bpy.types.Operator.as_keywords 1st arg `ignore`. - bpy.types.Struct.{keyframe_insert,keyframe_delete} 2nd..5th args `index`, `frame`, `group`, `options`. - bpy.types.WindowManager.popup_menu 2nd & 3rd arg `title`, `icon`. - bpy.types.WindowManager.popup_menu_pie 3rd & 4th arg `title`, `icon`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.app_template_paths 1st arg `subdir`. - bpy.utils.blend_paths 1st..3rd args `absolute`, `packed`, `local`. - bpy.utils.execfile 2nd arg `mod`. - bpy.utils.keyconfig_set 2nd arg `report`. - bpy.utils.load_scripts 1st & 2nd `reload_scripts` & `refresh_scripts`. - bpy.utils.preset_find 3rd & 4th args `display_name`, `ext`. - bpy.utils.resource_path 2nd & 3rd arg `major`, `minor`. - bpy.utils.script_paths 1st..4th args `subdir`, `user_pref`, `check_all`, `use_user`. - bpy.utils.smpte_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.smpte_from_seconds 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.system_resource 2nd arg `subdir`. - bpy.utils.time_from_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.time_to_frame 2nd & 3rd args `fps`, `fps_base`. - bpy.utils.units.to_string 4th..6th `precision`, `split_unit`, `compatible_unit`. - bpy.utils.units.to_value 4th arg `str_ref_unit`. - bpy.utils.user_resource 2nd & 3rd args `subdir`, `create` - bpy_extras.view3d_utils.location_3d_to_region_2d 4th arg `default`. - bpy_extras.view3d_utils.region_2d_to_origin_3d 4th arg `clamp`. - gpu.offscreen.unbind 1st arg `restore`. - gpu_extras.batch.batch_for_shader 4th arg `indices`. - gpu_extras.batch.presets.draw_circle_2d 4th arg `segments`. - gpu_extras.presets.draw_circle_2d 4th arg `segments`. - imbuf.types.ImBuf.resize 2nd arg `resize`. - imbuf.write 2nd arg `filepath`. - mathutils.kdtree.KDTree.find 2nd arg `filter`. - nodeitems_utils.NodeCategory 3rd & 4th arg `descriptions`, `items`. - nodeitems_utils.NodeItem 2nd..4th args `label`, `settings`, `poll`. - nodeitems_utils.NodeItemCustom 1st & 2nd arg `poll`, `draw`. - rna_prop_ui.draw 5th arg `use_edit`. - rna_prop_ui.rna_idprop_ui_get 2nd arg `create`. - rna_prop_ui.rna_idprop_ui_prop_clear 3rd arg `remove`. - rna_prop_ui.rna_idprop_ui_prop_get 3rd arg `create`. - rna_xml.xml2rna 2nd arg `root_rna`. - rna_xml.xml_file_write 4th arg `skip_typemap`.
2021-06-08 18:03:14 +10:00
draw_circle_2d(xy, (1.0,) * 4, radius, segments=32)
return dict(
idname="builtin.select_circle",
label="Select Circle",
icon="ops.generic.select_circle",
widget=None,
keymap="Node Tool: Select Circle",
draw_settings=draw_settings,
draw_cursor=draw_cursor,
)
2018-11-27 18:39:29 +11:00
2018-11-28 17:37:40 +11:00
class _defs_node_edit:
2018-11-28 17:37:40 +11:00
@ToolDef.from_fn
def links_cut():
return dict(
idname="builtin.links_cut",
label="Links Cut",
icon="ops.node.links_cut",
2018-11-28 17:37:40 +11:00
widget=None,
keymap="Node Tool: Links Cut",
options={'KEYMAP_FALLBACK'},
2018-11-28 17:37:40 +11:00
)
class _defs_sequencer_generic:
@ToolDef.from_fn
def cursor():
return dict(
idname="builtin.cursor",
label="Cursor",
description=(
"Set the cursor location, drag to transform"
),
icon="ops.generic.cursor",
keymap="Sequencer Tool: Cursor",
)
@ToolDef.from_fn
def blade():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sequencer.split")
row = layout.row()
row.use_property_split = False
row.prop(props, "type", expand=True)
return dict(
idname="builtin.blade",
label="Blade",
icon="ops.sequencer.blade",
cursor='CROSSHAIR',
widget=None,
keymap="Sequencer Tool: Blade",
draw_settings=draw_settings,
options={'KEYMAP_FALLBACK'},
)
@ToolDef.from_fn
def sample():
return dict(
idname="builtin.sample",
label="Sample",
description=(
"Sample pixel values under the cursor"
),
icon="ops.paint.weight_sample", # XXX, needs own icon.
keymap="Sequencer Tool: Sample",
)
@ToolDef.from_fn
def translate():
return dict(
idname="builtin.move",
label="Move",
icon="ops.transform.translate",
widget="SEQUENCER_GGT_gizmo2d_translate",
operator="transform.translate",
keymap="Sequencer Tool: Move",
)
@ToolDef.from_fn
def rotate():
return dict(
idname="builtin.rotate",
label="Rotate",
icon="ops.transform.rotate",
widget="SEQUENCER_GGT_gizmo2d_rotate",
operator="transform.rotate",
keymap="Sequencer Tool: Rotate",
)
@ToolDef.from_fn
def scale():
return dict(
idname="builtin.scale",
label="Scale",
icon="ops.transform.resize",
widget="SEQUENCER_GGT_gizmo2d_resize",
operator="transform.resize",
keymap="Sequencer Tool: Scale",
)
@ToolDef.from_fn
def transform():
return dict(
idname="builtin.transform",
label="Transform",
description=(
"Supports any combination of grab, rotate, and scale at once"
),
icon="ops.transform.transform",
widget="SEQUENCER_GGT_gizmo2d",
# No keymap default action, only for gizmo!
)
class _defs_sequencer_select:
@ToolDef.from_fn
def select():
return dict(
idname="builtin.select",
label="Tweak",
icon="ops.generic.select",
widget=None,
keymap="Sequencer Tool: Tweak",
)
@ToolDef.from_fn
def box():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("sequencer.select_box")
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
return dict(
idname="builtin.select_box",
label="Select Box",
icon="ops.generic.select_box",
widget=None,
keymap="Sequencer Tool: Select Box",
draw_settings=draw_settings,
)
2018-11-28 17:37:40 +11:00
class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "Image Editor Tool:"
# Default group to use as a fallback.
tool_fallback_id = "builtin.select"
@classmethod
def tools_from_context(cls, context, mode=None):
if mode is None:
if context.space_data is None:
mode = 'VIEW'
else:
mode = context.space_data.mode
for tools in (cls._tools[None], cls._tools.get(mode, ())):
for item in tools:
if not (type(item) is ToolDef) and callable(item):
yield from item(context)
else:
yield item
@classmethod
def tools_all(cls):
yield from cls._tools.items()
# Private tool lists for convenient reuse in `_tools`.
_tools_transform = (
2019-06-26 01:39:58 +10:00
_defs_image_uv_transform.translate,
_defs_image_uv_transform.rotate,
_defs_image_uv_transform.scale,
_defs_image_uv_transform.transform,
)
_tools_select = (
(
_defs_image_uv_select.select,
_defs_image_uv_select.box,
_defs_image_uv_select.circle,
_defs_image_uv_select.lasso,
),
)
_tools_annotate = (
(
_defs_annotate.scribble,
_defs_annotate.line,
_defs_annotate.poly,
_defs_annotate.eraser,
),
)
# Private tools dictionary, store data to implement `tools_all` & `tools_from_context`.
# The keys match image spaces modes: `context.space_data.mode`.
# The values represent the tools, see `ToolSelectPanelHelper` for details.
_tools = {
None: [
# for all modes
],
'VIEW': [
_defs_image_generic.sample,
*_tools_annotate,
],
'UV': [
*_tools_select,
_defs_image_generic.cursor,
None,
*_tools_transform,
None,
*_tools_annotate,
None,
2020-07-06 21:14:12 +10:00
_defs_image_uv_edit.rip_region,
None,
lambda context: (
_defs_image_uv_sculpt.generate_from_brushes(context)
if _defs_image_generic.poll_uvedit(context)
else ()
),
],
'MASK': [
None,
],
'PAINT': [
_defs_texture_paint.generate_from_brushes,
None,
*_tools_annotate,
],
}
2018-11-27 18:39:29 +11:00
class NODE_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'TOOLS'
2018-11-27 18:39:29 +11:00
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
2018-11-27 18:39:29 +11:00
# Satisfy the `ToolSelectPanelHelper` API.
2018-11-27 18:39:29 +11:00
keymap_prefix = "Node Editor Tool:"
# Default group to use as a fallback.
tool_fallback_id = "builtin.select"
2018-11-27 18:39:29 +11:00
@classmethod
def tools_from_context(cls, context, mode=None):
if mode is None:
if context.space_data is None:
mode = None
else:
mode = context.space_data.tree_type
for tools in (cls._tools[None], cls._tools.get(mode, ())):
for item in tools:
if not (type(item) is ToolDef) and callable(item):
yield from item(context)
else:
yield item
@classmethod
def tools_all(cls):
yield from cls._tools.items()
# Private tool lists for convenient reuse in `_tools`.
2018-11-27 18:39:29 +11:00
_tools_select = (
(
_defs_node_select.select,
_defs_node_select.box,
_defs_node_select.lasso,
_defs_node_select.circle,
2018-11-27 18:39:29 +11:00
),
)
_tools_annotate = (
(
_defs_annotate.scribble,
_defs_annotate.line,
_defs_annotate.poly,
_defs_annotate.eraser,
),
)
# Private tools dictionary, store data to implement `tools_all` & `tools_from_context`.
# The keys is always `None` since nodes don't use use modes to access different tools.
# The values represent the tools, see `ToolSelectPanelHelper` for details.
2018-11-27 18:39:29 +11:00
_tools = {
None: [
*_tools_select,
None,
*_tools_annotate,
2018-11-28 17:37:40 +11:00
None,
_defs_node_edit.links_cut,
2018-11-27 18:39:29 +11:00
],
}
class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
2018-04-24 16:04:07 +02:00
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "3D View Tool:"
# Default group to use as a fallback.
tool_fallback_id = "builtin.select"
@classmethod
def tools_from_context(cls, context, mode=None):
if mode is None:
mode = context.mode
for tools in (cls._tools[None], cls._tools.get(mode, ())):
for item in tools:
if not (type(item) is ToolDef) and callable(item):
yield from item(context)
else:
yield item
@classmethod
def tools_all(cls):
yield from cls._tools.items()
# Private tool lists for convenient reuse in `_tools`.
_tools_transform = (
_defs_transform.translate,
_defs_transform.rotate,
2018-04-24 09:19:28 +02:00
(
_defs_transform.scale,
_defs_transform.scale_cage,
2018-04-24 09:19:28 +02:00
),
_defs_transform.transform,
)
_tools_select = (
(
_defs_view3d_select.select,
_defs_view3d_select.box,
_defs_view3d_select.circle,
_defs_view3d_select.lasso,
),
)
_tools_annotate = (
(
_defs_annotate.scribble,
_defs_annotate.line,
_defs_annotate.poly,
_defs_annotate.eraser,
),
)
2018-09-25 13:17:48 +02:00
_tools_gpencil_select = (
(
_defs_gpencil_edit.select,
_defs_gpencil_edit.box_select,
2018-09-25 13:17:48 +02:00
_defs_gpencil_edit.circle_select,
_defs_gpencil_edit.lasso_select,
),
)
_tools_view3d_add = (
_defs_view3d_add.cube_add,
_defs_view3d_add.cone_add,
_defs_view3d_add.cylinder_add,
_defs_view3d_add.uv_sphere_add,
_defs_view3d_add.ico_sphere_add,
)
_tools_default = (
*_tools_select,
_defs_view3d_generic.cursor,
None,
*_tools_transform,
None,
*_tools_annotate,
_defs_view3d_generic.ruler,
)
# Private tools dictionary, store data to implement `tools_all` & `tools_from_context`.
# The keys match object-modes from: `context.mode`.
# The values represent the tools, see `ToolSelectPanelHelper` for details.
_tools = {
None: [
# Don't use this! because of paint modes.
# _defs_view3d_generic.cursor,
2017-11-02 23:05:13 +11:00
# End group.
],
'OBJECT': [
*_tools_default,
None,
_tools_view3d_add,
],
'POSE': [
*_tools_default,
None,
(
_defs_pose.breakdown,
_defs_pose.push,
_defs_pose.relax,
),
],
'EDIT_ARMATURE': [
*_tools_default,
None,
_defs_edit_armature.roll,
(
_defs_edit_armature.bone_size,
_defs_edit_armature.bone_envelope,
),
None,
(
_defs_edit_armature.extrude,
_defs_edit_armature.extrude_cursor,
),
_defs_transform.shear,
],
'EDIT_MESH': [
*_tools_default,
None,
_tools_view3d_add,
None,
2018-04-24 15:32:11 +02:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.extrude,
_defs_edit_mesh.extrude_manifold,
_defs_edit_mesh.extrude_normals,
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.extrude_individual,
_defs_edit_mesh.extrude_cursor,
2018-04-24 15:32:11 +02:00
),
_defs_edit_mesh.inset,
_defs_edit_mesh.bevel,
(
_defs_edit_mesh.loopcut_slide,
_defs_edit_mesh.offset_edge_loops_slide,
),
2018-04-24 15:32:11 +02:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.knife,
_defs_edit_mesh.bisect,
),
_defs_edit_mesh.poly_build,
_defs_edit_mesh.spin,
2018-04-24 15:32:11 +02:00
(
_defs_edit_mesh.vertex_smooth,
_defs_edit_mesh.vertex_randomize,
2018-04-24 15:32:11 +02:00
),
2018-04-30 20:40:36 +02:00
(
_defs_edit_mesh.edge_slide,
_defs_edit_mesh.vert_slide,
),
2018-04-24 15:32:11 +02:00
(
_defs_edit_mesh.shrink_fatten,
_defs_edit_mesh.push_pull,
2018-04-24 15:32:11 +02:00
),
(
_defs_transform.shear,
_defs_edit_mesh.tosphere,
),
2017-11-02 23:05:13 +11:00
(
2018-04-30 20:40:36 +02:00
_defs_edit_mesh.rip_region,
_defs_edit_mesh.rip_edge,
),
],
'EDIT_CURVE': [
*_tools_default,
None,
_defs_edit_curve.draw,
Curves: Curve Pen This tool can be used to rapidly edit curves. The current set of functionalities for Bezier splines are as follows: The functionalities are divided into three versions of the operator: * Left-Click * Ctrl + Left-Click * Double Click All current functionalities and their defaults are as follows: * Extrude Point: Add a point connected to an existing point. Enabled for Left-Click. * Extrude Handle Type: Type of the handles of the extruded points. Can be either Vector or Auto. Defaults to Vector. * Delete Point: Delete existing point. Enabled for Ctrl + Left-Click. * Insert Point: Insert a point into a curve segment. Enabled for Ctrl + Left-Click. * Move Segment: Move curve segment. Enabled for Left-Click. * Select Point: Select a single point or handle at a time. Enabled for Left-Click. * Move point: Move existing points or handles. Enabled for Left-Click. * Close Spline: Close spline by clicking the endpoints consecutively. Defaults to True. * Close Spline Method: The condition for Close Spline to activate. Can be one of None, On Press or On Click. Defaults to On Click for Left-Click and None for the others. * None: Functionality is turned off. * On Press: Activate on mouse down. This makes it possible to move the handles by dragging immediately after closing the spline. * On Click: Activate on mouse release. This makes it possible to avoid triggering the Close Spline functionality by dragging afterward. * Toggle Vector: Toggle handle between Vector and Auto handle types. Enabled for Double Click on a handle. * Cycle Handle Type: Cycle between all four handle types. Enabled for Double Click on the middle point of a Bezier point. The keybindings for the following functionalities can be adjusted from the modal keymap * Free-Align Toggle: Toggle between Free and Align handle types. Defaults to Left Shift. Activated on hold. * Move Adjacent Handle: Move the closer handle of the adjacent vertex. Defaults to Left Ctrl. Activated on hold. * Move Entire: Move the entire point by moving by grabbing on the handle Defaults to Spacebar. Activated on hold. * Link Handles: Mirror the movement of one handle onto the other. Defaults to Right Ctrl. Activated on press. * Lock Handle Angle: Move the handle along its current angle. Defaults to Left Alt. Activated on hold. All the above functionalities, except for Move Segment and those that work with handles, work similarly in the case of Poly and NURBS splines. Reviewed By: HooglyBoogly, weasel, campbellbarton Differential Revision: http://developer.blender.org/D12155
2022-04-03 22:37:22 +05:30
_defs_edit_curve.pen,
2018-08-29 15:14:41 +10:00
(
_defs_edit_curve.extrude,
_defs_edit_curve.extrude_cursor,
2018-11-15 22:27:02 +11:00
),
None,
_defs_edit_curve.curve_radius,
_defs_edit_curve.tilt,
None,
_defs_transform.shear,
_defs_edit_curve.curve_vertex_randomize,
],
'EDIT_CURVES': [
*_tools_default,
None,
_defs_edit_curves.draw,
None,
_defs_edit_curve.curve_radius,
_defs_edit_curve.tilt,
],
'EDIT_SURFACE': [
*_tools_default,
None,
_defs_transform.shear,
],
'EDIT_METABALL': [
*_tools_default,
None,
_defs_transform.shear,
],
'EDIT_LATTICE': [
*_tools_default,
None,
_defs_transform.shear,
],
'EDIT_TEXT': [
_defs_edit_text.select_text,
_defs_view3d_generic.cursor,
None,
*_tools_annotate,
_defs_view3d_generic.ruler,
],
'EDIT_GREASE_PENCIL': [
*_tools_select,
_defs_view3d_generic.cursor,
None,
*_tools_transform,
None,
_defs_edit_curve.curve_radius,
_defs_transform.bend,
(
_defs_transform.shear,
_defs_edit_mesh.tosphere,
),
None,
*_tools_annotate,
],
'PARTICLE': [
*_tools_select,
_defs_view3d_generic.cursor,
None,
_defs_particle.generate_from_brushes,
],
'SCULPT': [
_defs_sculpt.generate_from_brushes,
None,
(
_defs_sculpt.mask_border,
_defs_sculpt.mask_lasso,
_defs_sculpt.mask_line,
),
(
_defs_sculpt.hide_border,
_defs_sculpt.hide_lasso
),
(
_defs_sculpt.face_set_box,
_defs_sculpt.face_set_lasso,
),
(
_defs_sculpt.trim_box,
_defs_sculpt.trim_lasso,
),
_defs_sculpt.project_line,
None,
_defs_sculpt.mesh_filter,
_defs_sculpt.cloth_filter,
_defs_sculpt.color_filter,
None,
_defs_sculpt.face_set_edit,
_defs_sculpt.mask_by_color,
None,
_defs_transform.translate,
_defs_transform.rotate,
_defs_transform.scale,
_defs_transform.transform,
None,
*_tools_annotate,
],
'PAINT_TEXTURE': [
_defs_texture_paint.generate_from_brushes,
None,
lambda context: (
VIEW3D_PT_tools_active._tools_select
if _defs_texture_paint.poll_select_mask(context)
else ()
),
*_tools_annotate,
],
'PAINT_VERTEX': [
_defs_vertex_paint.generate_from_brushes,
None,
lambda context: (
VIEW3D_PT_tools_active._tools_select
if _defs_vertex_paint.poll_select_mask(context)
else ()
),
*_tools_annotate,
],
'PAINT_WEIGHT': [
_defs_weight_paint.generate_from_brushes,
_defs_weight_paint.gradient,
None,
(
2019-03-20 10:44:13 +11:00
_defs_weight_paint.sample_weight,
_defs_weight_paint.sample_weight_group,
),
None,
lambda context: (
(
_defs_view3d_generic.cursor,
None,
*VIEW3D_PT_tools_active._tools_transform,
)
if context is None or context.pose_object
else ()
),
None,
Fix #44834: Add bone selection icon next to face and vertex selection in weight paint mode Currently, in weight paint mode, there is an icon for face and vertex selection mode, but there isn't one for the default mode where the user can select a bone in any tool by alt clicking. This lack of indication might lead to confusion for the users when they are not able to select a bone by alt clicking during weight painting. By adding a bone selection icon when there is a pose mode armature, we can communicate to the user that: 1. they can select a bone while the bone selection icon is active. (when they are not in face or vertex selection mode) 2. they have forgot to select an armature when entering weight paint mode by not showing the bone selection icon at all when there is no pose mode armature. When the bone selection icon is inactive, the user can't select a bone. (alt clicking selects face and vertex mode's respective element) When no armature is selected when entering weight paint mode, the bone selection icon doesn't show up indicating that the user has forgot to select an armature. (The user is also unable to select a bone by alt clicking.) ## Selection tool for bone selection mode Currently, while selection tools exist for face and vertex selection mode, one doesn't exist for the default mode (bone selection mode). As the default mode will be getting a clear indicator that it will function as a bone selection mode, I added a selection tool entry for the bone selection mode. Face and vertex selection modes has the shortcut 1 and 2, so it seemed natural to give bone selection mode the shortcut of 3. Pull Request: https://projects.blender.org/blender/blender/pulls/115409
2023-12-01 13:38:58 +01:00
_defs_weight_paint.poll_select_tools,
*_tools_annotate,
],
'PAINT_GREASE_PENCIL': [
_defs_view3d_generic.cursor,
None,
_defs_paint_grease_pencil.draw,
_defs_paint_grease_pencil.erase,
],
'PAINT_GPENCIL': [
_defs_view3d_generic.cursor,
None,
_defs_gpencil_paint.generate_from_brushes,
_defs_gpencil_paint.cutter,
None,
_defs_gpencil_paint.eyedropper,
None,
_defs_gpencil_paint.line,
_defs_gpencil_paint.polyline,
_defs_gpencil_paint.arc,
_defs_gpencil_paint.curve,
_defs_gpencil_paint.box,
_defs_gpencil_paint.circle,
None,
_defs_gpencil_paint.interpolate,
None,
*_tools_annotate,
],
'EDIT_GPENCIL': [
*_tools_gpencil_select,
_defs_view3d_generic.cursor,
None,
2018-10-23 13:03:25 +02:00
*_tools_transform,
None,
_defs_gpencil_edit.extrude,
_defs_gpencil_edit.radius,
_defs_gpencil_edit.bend,
(
_defs_gpencil_edit.shear,
_defs_gpencil_edit.tosphere,
),
_defs_gpencil_edit.transform_fill,
None,
_defs_gpencil_edit.interpolate,
None,
*_tools_annotate,
],
'SCULPT_GPENCIL': [
_defs_gpencil_sculpt.generate_from_brushes,
None,
*_tools_annotate,
lambda context: (
VIEW3D_PT_tools_active._tools_gpencil_select
if _defs_gpencil_sculpt.poll_select_mask(context)
else ()
),
],
'WEIGHT_GPENCIL': [
_defs_gpencil_weight.generate_from_brushes,
None,
*_tools_annotate,
],
'VERTEX_GPENCIL': [
_defs_gpencil_vertex.generate_from_brushes,
None,
*_tools_annotate,
None,
lambda context: (
VIEW3D_PT_tools_active._tools_gpencil_select
if _defs_gpencil_vertex.poll_select_mask(context)
else ()
),
],
'SCULPT_CURVES': [
_defs_curves_sculpt.generate_from_brushes,
None,
*_tools_annotate,
],
}
class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel):
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Tools" # not visible
bl_options = {'HIDE_HEADER'}
# Satisfy the `ToolSelectPanelHelper` API.
keymap_prefix = "Sequence Editor Tool:"
# Default group to use as a fallback.
tool_fallback_id = "builtin.select"
@classmethod
def tools_from_context(cls, context, mode=None):
if mode is None:
if context.space_data:
mode = context.space_data.view_type
for tools in (cls._tools[None], cls._tools.get(mode, ())):
for item in tools:
if not (type(item) is ToolDef) and callable(item):
yield from item(context)
else:
yield item
@classmethod
def tools_all(cls):
yield from cls._tools.items()
# Private tool lists for convenient reuse in `_tools`.
_tools_select = (
(
_defs_sequencer_select.select,
_defs_sequencer_select.box,
),
)
_tools_annotate = (
(
_defs_annotate.scribble,
_defs_annotate.line,
_defs_annotate.poly,
_defs_annotate.eraser,
),
)
# Private tools dictionary, store data to implement `tools_all` & `tools_from_context`.
# The keys match sequence editors view type: `context.space_data.view_type`.
# The values represent the tools, see `ToolSelectPanelHelper` for details.
_tools = {
None: [
],
'PREVIEW': [
*_tools_select,
_defs_sequencer_generic.cursor,
None,
_defs_sequencer_generic.translate,
_defs_sequencer_generic.rotate,
_defs_sequencer_generic.scale,
_defs_sequencer_generic.transform,
None,
_defs_sequencer_generic.sample,
*_tools_annotate,
],
'SEQUENCER': [
*_tools_select,
_defs_sequencer_generic.blade,
],
'SEQUENCER_PREVIEW': [
*_tools_select,
None,
*_tools_annotate,
None,
_defs_sequencer_generic.blade,
],
}
classes = (
IMAGE_PT_tools_active,
2018-11-27 18:39:29 +11:00
NODE_PT_tools_active,
VIEW3D_PT_tools_active,
SEQUENCER_PT_tools_active,
)
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
for cls in classes:
register_class(cls)