diff options
author | YimingWu <xp8110@outlook.com> | 2020-02-01 05:35:40 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2020-02-01 05:35:40 +0300 |
commit | f7770cb97bb9d19d0806f67da9377129fd4d09b0 (patch) | |
tree | 2cd22d612ffba3a509d5548332c9cc8a06a1a638 /release/scripts | |
parent | b47883a990ee68e659a8a8b44729be9b8e0d002f (diff) | |
parent | dc3f073d1c5255e79763dfff3ef17f6216f1b391 (diff) |
Merge remote-tracking branch 'origin/master' into temp-lanpr-review
Diffstat (limited to 'release/scripts')
40 files changed, 690 insertions, 464 deletions
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py index 4aaa30a0508..2034b2ac55c 100644 --- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py +++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py @@ -599,8 +599,8 @@ def dump_py_messages_from_files(msgs, reports, files, settings): # We manually add funcs from bpy.app.translations for func_id, func_ids in pgettext_variants: func_translate_args[func_id] = pgettext_variants_args - for func_id in func_ids: - func_translate_args[func_id] = pgettext_variants_args + for sub_func_id in func_ids: + func_translate_args[sub_func_id] = pgettext_variants_args # print(func_translate_args) # Break recursive nodes look up on some kind of nodes. diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 2cca4171193..7c22a86d687 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -1413,8 +1413,8 @@ class I18n: "# and edit the translations by hand.", "# Just carefully respect the format of the tuple!", "", - "# Tuple of tuples " - "((msgctxt, msgid), (sources, gen_comments), (lang, translation, (is_fuzzy, comments)), ...)", + "# Tuple of tuples:", + "# ((msgctxt, msgid), (sources, gen_comments), (lang, translation, (is_fuzzy, comments)), ...)", "translations_tuple = (", ] # First gather all keys (msgctxt, msgid) - theoretically, all translations should share the same, but... diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py index abe33b0e8ea..3d36f3eb510 100644 --- a/release/scripts/modules/bpy/utils/__init__.py +++ b/release/scripts/modules/bpy/utils/__init__.py @@ -409,26 +409,17 @@ def app_template_paths(subdir=None): :return: app template paths. :rtype: generator """ - # Note: keep in sync with: Blender's BKE_appdir_app_template_any - - subdir_tuple = (subdir,) if subdir is not None else () - - # Avoid adding 'bl_app_templates_system' twice. - # Either we have a portable build or an installed system build. - for resource_type, module_name in ( - ('USER', "bl_app_templates_user"), - ('LOCAL', "bl_app_templates_system"), - ('SYSTEM', "bl_app_templates_system"), + subdir_args = (subdir,) if subdir is not None else () + # Note: keep in sync with: Blender's 'BKE_appdir_app_template_any'. + # Uses 'BLENDER_USER_SCRIPTS', 'BLENDER_SYSTEM_SCRIPTS' + # ... in this case 'system' accounts for 'local' too. + for resource_fn, module_name in ( + (_user_resource, "bl_app_templates_user"), + (system_resource, "bl_app_templates_system"), ): - path = resource_path(resource_type) - if path: - path = _os.path.join( - *(path, "scripts", "startup", module_name, *subdir_tuple)) - if _os.path.isdir(path): - yield path - # Only load LOCAL or SYSTEM (never both). - if resource_type == 'LOCAL': - break + path = resource_fn('SCRIPTS', _os.path.join("startup", module_name, *subdir_args)) + if path and _os.path.isdir(path): + yield path def preset_paths(subdir): @@ -486,7 +477,10 @@ def is_path_builtin(path): ): return True except FileNotFoundError: - #The path we tried to look up doesn't exist + # The path we tried to look up doesn't exist. + pass + except ValueError: + # Happens on Windows when paths don't have the same drive. pass return False diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index e402c9cb53c..c67134ac3f6 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -249,11 +249,17 @@ def bake_action_iter( if action is None: action = bpy.data.actions.new("Action") - # Leave tweak mode before trying to modify the action (T48397) - if atd.use_tweak_mode: - atd.use_tweak_mode = False + # Only leave tweak mode if we actually need to modify the action (T57159) + if action != atd.action: + # Leave tweak mode before trying to modify the action (T48397) + if atd.use_tweak_mode: + atd.use_tweak_mode = False - atd.action = action + atd.action = action + + # Baking the action only makes sense in Replace mode, so force it (T69105) + if not atd.use_tweak_mode: + atd.action_blend_type = 'REPLACE' # ------------------------------------------------------------------------- # Apply transformations to action diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 1f01523534f..2e78f18b78e 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -197,7 +197,6 @@ url_manual_mapping = ( ("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"), ("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"), ("bpy.types.compositornodesplitviewer*", "compositing/types/output/split_viewer.html#bpy-types-compositornodesplitviewer"), - ("bpy.types.curve.use_uv_as_generated*", "editors/uv/generated_uvs.html#bpy-types-curve-use-uv-as-generated"), ("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"), ("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-flip"), ("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-mode"), diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 202fd865723..8dda8c90f85 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -277,14 +277,15 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: val_draw = val - row = flow.row(align=True) + row = layout.row(align=True) box = row.box() if use_edit: split = box.split(factor=0.75) row = split.row(align=True) else: - row = box.row(align=True) + split = box.split(factor=1.00) + row = split.row(align=True) row.alignment = 'RIGHT' diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index 95196cb83fa..d9fc09e7d18 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -100,7 +100,7 @@ def rna2xml( elif val_type == bool: return "TRUE" if val else "FALSE" else: - raise NotImplemented("this type is not a number %s" % val_type) + raise NotImplementedError("this type is not a number %s" % val_type) def rna2xml_node(ident, value, parent): ident_next = ident + ident_val diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index 8b4e224efe4..656e2b3bd54 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -172,6 +172,13 @@ def write_sysinfo(filepath): else: output.write("Blender was built without Alembic support\n") + usd = bpy.app.usd + output.write("USD: ") + if usd.supported: + output.write("%s\n" % usd.version_string) + else: + output.write("Blender was built without USD support\n") + if not bpy.app.build_options.sdl: output.write("SDL: Blender was built without SDL support\n") diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/blender.py index 596b17d734f..11cd76335f1 100644 --- a/release/scripts/presets/keyconfig/blender.py +++ b/release/scripts/presets/keyconfig/blender.py @@ -70,6 +70,7 @@ class Prefs(bpy.types.KeyConfigPreferences): ('DRAG', "Drag", "Drag allows click events to pass through to the tool, adding a small delay"), ), description="Activation event for gizmos that support drag motion", + default='DRAG', update=update_fn, ) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 173e7e5f332..629bc24abb3 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -290,12 +290,14 @@ def _template_items_proportional_editing(*, connected=False): # Tool System Templates -def _template_items_tool_select(params, operator, cursor_operator): +def _template_items_tool_select(params, operator, cursor_operator, *, extend): if params.select_mouse == 'LEFTMOUSE': # Immediate select without quick delay. return [ (operator, {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("deselect_all", True)]}), + (operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [(extend, True)]}), ] else: # For right mouse, set the cursor. @@ -940,6 +942,7 @@ def km_view3d(params): # Visibility. ("view3d.localview", {"type": 'NUMPAD_SLASH', "value": 'PRESS'}, None), ("view3d.localview", {"type": 'SLASH', "value": 'PRESS'}, None), + ("view3d.localview", {"type": 'MOUSESMARTZOOM', "value": 'ANY'}, None), ("view3d.localview_remove_from", {"type": 'M', "value": 'PRESS'}, None), # Navigation. ("view3d.rotate", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), @@ -1526,7 +1529,7 @@ def km_image_generic(_params): ("image.reload", {"type": 'R', "value": 'PRESS', "alt": True}, None), ("image.read_viewlayers", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("image.save", {"type": 'S', "value": 'PRESS', "alt": True}, None), - ("image.save_as", {"type": 'S', "value": 'PRESS', "shift": True}, None), + ("image.save_as", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS'}, None), ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS', "alt": True}, {"properties": [("reverse", True)]}), @@ -2032,6 +2035,7 @@ def km_dopesheet(params): op_menu_pie("VIEW3D_MT_proportional_editing_falloff_pie", {"type": 'O', "value": 'PRESS', "shift": True}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), + ("marker.camera_bind", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), *_template_items_context_menu("DOPESHEET_MT_context_menu", params.context_menu_event), ]) @@ -2333,6 +2337,7 @@ def km_sequencercommon(_params): items.extend([ *_template_space_region_type_toggle( + toolbar_key={"type": 'T', "value": 'PRESS'}, sidebar_key={"type": 'N', "value": 'PRESS'}, ), ("wm.context_toggle", {"type": 'O', "value": 'PRESS', "shift": True}, @@ -2340,6 +2345,13 @@ def km_sequencercommon(_params): ("sequencer.view_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None), ]) + if _params.select_mouse == 'LEFTMOUSE' and not _params.legacy: + # Quick switch to select tool, since left select can't easily + # select with any tool active. + items.extend([ + op_tool_cycle("builtin.select_box", {"type": 'W', "value": 'PRESS'}), + ]) + return keymap @@ -2918,6 +2930,10 @@ def km_animation_channels(params): *_template_items_select_actions(params, "anim.channels_select_all"), ("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None), ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), + ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True,}, + {"properties": [("extend", True)]}), + ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True,}, + {"properties": [("deselect", True)]}), # Delete. ("anim.channels_delete", {"type": 'X', "value": 'PRESS'}, None), ("anim.channels_delete", {"type": 'DEL', "value": 'PRESS'}, None), @@ -3589,7 +3605,7 @@ def km_curve(params): ) items.extend([ - op_menu("VIEW3D_MT_curve_add", {"type": 'A', "value": 'PRESS', "shift": True}), + op_menu("TOPBAR_MT_edit_curve_add", {"type": 'A', "value": 'PRESS', "shift": True}), ("curve.handle_type_set", {"type": 'V', "value": 'PRESS'}, None), ("curve.vertex_add", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None), *_template_items_select_actions(params, "curve.select_all"), @@ -5055,7 +5071,7 @@ def km_image_editor_tool_uv_select(params): return ( "Image Editor Tool: Uv, Tweak", {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select(params, "uv.select", "uv.cursor_set")}, + {"items": _template_items_tool_select(params, "uv.select", "uv.cursor_set", extend="extend")}, ) @@ -5206,7 +5222,7 @@ def km_3d_view_tool_select(params): return ( "3D View Tool: Tweak", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select(params, "view3d.select", "view3d.cursor3d")}, + {"items": _template_items_tool_select(params, "view3d.select", "view3d.cursor3d", extend="toggle")}, ) @@ -5280,6 +5296,26 @@ def km_3d_view_tool_scale(params): ) +def km_3d_view_tool_shear(params): + return ( + "3D View Tool: Shear", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("transform.shear", + {"type": params.tool_tweak, "value": 'NORTH'}, + {"properties": [("release_confirm", True), ("orient_axis_ortho", 'Y')]}), + ("transform.shear", + {"type": params.tool_tweak, "value": 'SOUTH'}, + {"properties": [("release_confirm", True), ("orient_axis_ortho", 'Y')]}), + + # Use as fallback to catch diagonals too. + ("transform.shear", + {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [("release_confirm", True), ("orient_axis_ortho", 'X')]}), + ]}, + ) + + def km_3d_view_tool_measure(params): return ( "3D View Tool: Measure", @@ -5535,7 +5571,7 @@ def km_3d_view_tool_edit_mesh_smooth(params): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("mesh.vertices_smooth", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("factor", 0.0), ("wait_for_input", False)]}), + {"properties": [("wait_for_input", False)]}), ]}, ) @@ -5546,7 +5582,7 @@ def km_3d_view_tool_edit_mesh_randomize(params): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("transform.vertex_random", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("offset", 0.0), ("wait_for_input", False)]}), + {"properties": [("wait_for_input", False)]}), ]}, ) @@ -5595,26 +5631,6 @@ def km_3d_view_tool_edit_mesh_push_pull(params): ) -def km_3d_view_tool_edit_mesh_shear(params): - return ( - "3D View Tool: Edit Mesh, Shear", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.shear", - {"type": params.tool_tweak, "value": 'NORTH'}, - {"properties": [("release_confirm", True), ("orient_axis_ortho", 'Y')]}), - ("transform.shear", - {"type": params.tool_tweak, "value": 'SOUTH'}, - {"properties": [("release_confirm", True), ("orient_axis_ortho", 'Y')]}), - - # Use as fallback to catch diagonals too. - ("transform.shear", - {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("release_confirm", True), ("orient_axis_ortho", 'X')]}), - ]}, - ) - - def km_3d_view_tool_edit_mesh_to_sphere(params): return ( "3D View Tool: Edit Mesh, To Sphere", @@ -5686,7 +5702,7 @@ def km_3d_view_tool_edit_curve_randomize(params): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("transform.vertex_random", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("offset", 0.0), ("wait_for_input", False)]}), + {"properties": [("wait_for_input", False)]}), ]}, ) @@ -5913,7 +5929,7 @@ def km_3d_view_tool_edit_gpencil_select(params): return ( "3D View Tool: Edit Gpencil, Tweak", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d")}, + {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", extend="toggle")}, ) @@ -5960,7 +5976,7 @@ def km_3d_view_tool_edit_gpencil_radius(params): {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ ("transform.transform", {"type": params.tool_tweak, "value": 'ANY'}, - {"properties": [("mode", 'CURVE_SHRINKFATTEN'), ("release_confirm", True)]}), + {"properties": [("mode", 'GPENCIL_SHRINKFATTEN'), ("release_confirm", True)]}), ]}, ) @@ -6018,7 +6034,7 @@ def km_3d_view_tool_sculpt_gpencil_select(params): return ( "3D View Tool: Sculpt Gpencil, Tweak", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d")}, + {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", extend="toggle")}, ) @@ -6049,6 +6065,39 @@ def km_3d_view_tool_sculpt_gpencil_select_lasso(params): ) +def km_sequencer_editor_tool_select(params): + return ( + "Sequencer Tool: Select", + {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, + {"items": [ + ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'}, + {"properties": [("extend", False), ("deselect_all", not params.legacy)]}), + ]}, + ) + + +def km_sequencer_editor_tool_select_box(params): + return ( + "Sequencer Tool: Select Box", + {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, + {"items": _template_items_tool_select_actions_simple( + "sequencer.select_box", type=params.tool_tweak, value='ANY', + properties=[("tweak", True)], + )}, + ) + + +def km_sequencer_editor_tool_cut(params): + return ( + "Sequencer Tool: Cut", + {"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'}, + {"items":[ + ("sequencer.cut", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("type", 'SOFT'), ("side", 'NO_CHANGE'), ("use_cursor_position", True), ("ignore_selection", True)]}), + ]}, + ) + + # ------------------------------------------------------------------------------ # Full Configuration @@ -6194,6 +6243,7 @@ def generate_keymaps(params=None): km_3d_view_tool_move(params), km_3d_view_tool_rotate(params), km_3d_view_tool_scale(params), + km_3d_view_tool_shear(params), km_3d_view_tool_measure(params), km_3d_view_tool_pose_breakdowner(params), km_3d_view_tool_pose_push(params), @@ -6223,7 +6273,6 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_mesh_vertex_slide(params), km_3d_view_tool_edit_mesh_shrink_fatten(params), km_3d_view_tool_edit_mesh_push_pull(params), - km_3d_view_tool_edit_mesh_shear(params), km_3d_view_tool_edit_mesh_to_sphere(params), km_3d_view_tool_edit_mesh_rip_region(params), km_3d_view_tool_edit_mesh_rip_edge(params), @@ -6262,6 +6311,9 @@ def generate_keymaps(params=None): km_3d_view_tool_sculpt_gpencil_select_box(params), km_3d_view_tool_sculpt_gpencil_select_circle(params), km_3d_view_tool_sculpt_gpencil_select_lasso(params), + km_sequencer_editor_tool_select(params), + km_sequencer_editor_tool_select_box(params), + km_sequencer_editor_tool_cut(params), ] # ------------------------------------------------------------------------------ diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index e6d68510312..0bffd316f30 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -39,6 +39,9 @@ class Params: use_mouse_emulate_3_button=False, ): self.tool_mouse = 'LEFTMOUSE' + self.select_mouse = 'LEFTMOUSE' + self.select_mouse_value = 'CLICK' + self.select_tweak = 'EVT_TWEAK_L' self.tool_tweak = 'EVT_TWEAK_L' self.action_tweak = 'EVT_TWEAK_R' self.use_mouse_emulate_3_button = use_mouse_emulate_3_button @@ -114,20 +117,6 @@ def _template_items_animation(): ] -# Gizmos - -def _template_items_gizmo_tweak_value(): - return [ - ("gizmogroup.gizmo_tweak", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), - ] - - -def _template_items_gizmo_tweak_value_click_drag(): - return [ - ("gizmogroup.gizmo_tweak", {"type": 'LEFTMOUSE', "value": 'CLICK'}, None), - ("gizmogroup.gizmo_tweak", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), - ] - def _template_items_gizmo_tweak_value_drag(): return [ @@ -149,8 +138,13 @@ def _template_items_basic_tools(*, connected=False): op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}), ] -def _template_items_tool_select(params, operator, cursor_operator): - return [(operator, {"type": 'LEFTMOUSE', "value": 'PRESS'}, None)] +def _template_items_tool_select(params, operator, *, extend): + return [ + (operator, {"type": 'LEFTMOUSE', "value": 'PRESS'}, + {"properties": [("deselect_all", True)]}), + (operator, {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, + {"properties": [(extend, True)]}), + ] def _template_items_tool_select_actions(operator, *, type, value): @@ -180,6 +174,19 @@ def _template_items_tool_select_actions_simple(operator, *, type, value, propert ] +def _template_items_editmode_mesh_select_mode(params): + return [ + ( + "mesh.select_mode", + {"type": k, "value": 'PRESS', **key_expand, **key_extend}, + {"properties": [*prop_extend, *prop_expand, ("type", e)]} + ) + for key_expand, prop_expand in (({}, ()), ({"ctrl": True}, (("use_expand", True),))) + for key_extend, prop_extend in (({}, ()), ({"shift": True}, (("use_extend", True),))) + for k, e in (('ONE', 'VERT'), ('TWO', 'EDGE'), ('THREE', 'FACE')) + ] + + # ------------------------------------------------------------------------------ # Window, Screen, Areas, Regions @@ -541,6 +548,7 @@ def km_uv_editor(params): op_panel("TOPBAR_PT_name", {"type": 'RET', "value": 'PRESS'}, [("keep_open", False)]), ("wm.search_menu", {"type": 'TAB', "value": 'PRESS'}, None), # Selection modes. + *_template_items_editmode_mesh_select_mode(params), ("wm.context_set_enum", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'VERTEX')]}), ("wm.context_set_enum", {"type": 'TWO', "value": 'PRESS'}, @@ -554,6 +562,7 @@ def km_uv_editor(params): {"properties": [("extend", False), ("deselect_all", True)]}), ("uv.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True}, {"properties": [("extend", True), ("deselect_all", False)]}), + ("transform.translate", {"type": "EVT_TWEAK_L", "value": 'ANY'}, None), ("uv.select_loop", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "shift": True}, {"properties": [("extend", True)]}), @@ -621,6 +630,7 @@ def km_view3d(params): ("wm.search_menu", {"type": 'TAB', "value": 'PRESS'}, None), # Visibility. ("view3d.localview", {"type": 'I', "value": 'PRESS', "shift": True}, None), + ("view3d.localview", {"type": 'MOUSESMARTZOOM', "value": 'ANY'}, None), op_menu_pie("VIEW3D_MT_view_pie", {"type": 'V', "value": 'PRESS'}), # Navigation. ("view3d.rotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, None), @@ -755,7 +765,6 @@ def km_mask_editing(params): ("mask.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("mask.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("mask.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - #*_template_items_select_actions(params, "mask.select_all"), ("mask.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("mask.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), @@ -946,7 +955,7 @@ def km_image_generic(params): ("image.reload", {"type": 'R', "value": 'PRESS', "alt": True}, None), ("image.read_viewlayers", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("image.save", {"type": 'S', "value": 'PRESS', "alt": True}, None), - ("image.save_as", {"type": 'S', "value": 'PRESS', "shift": True}, None), + ("image.save_as", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), ]) return keymap @@ -1004,14 +1013,6 @@ def km_image(params): {"properties": [("point", 'BLACK_POINT')]}), ("image.curves_point_set", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("point", 'WHITE_POINT')]}), - ("object.mode_set", {"type": 'ONE', "value": 'PRESS'}, - {"properties": [("mode", 'EDIT')]}), - ("object.mode_set", {"type": 'TWO', "value": 'PRESS'}, - {"properties": [("mode", 'OBJECT')]}), - ("object.mode_set", {"type": 'THREE', "value": 'PRESS'}, - {"properties": [("mode", 'OBJECT')]}), - ("object.mode_set", {"type": 'FOUR', "value": 'PRESS'}, - {"properties": [("mode", 'OBJECT')]}), op_menu_pie("IMAGE_MT_pivot_pie", {"type": 'PERIOD', "value": 'PRESS'}), # Tools op_tool_cycle("builtin.select_box", {"type": 'Q', "value": 'PRESS'}), @@ -2190,8 +2191,11 @@ def km_animation_channels(params): ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("anim.channels_select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None), ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), + ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True,}, + {"properties": [("extend", True)]}), + ("anim.channels_select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True,}, + {"properties": [("deselect", True)]}), # Delete. ("anim.channels_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), ("anim.channels_delete", {"type": 'DEL', "value": 'PRESS'}, None), @@ -2249,10 +2253,12 @@ def km_grease_pencil(_params): def _grease_pencil_selection(params): return [ - # Select all - ("gpencil.select_box", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("gpencil.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("extend", True), ("toggle", True)]}), + # Select all + ("gpencil.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), + ("gpencil.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("gpencil.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), # Select linked ("gpencil.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), # Select alternate @@ -2265,14 +2271,6 @@ def _grease_pencil_selection(params): ] -def _grease_pencil_display(): - return [ - ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, - {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), - ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, - {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), - ] - def km_grease_pencil_stroke_edit_mode(params): items = [] @@ -2283,18 +2281,13 @@ def km_grease_pencil_stroke_edit_mode(params): ) items.extend([ - # Interpolation - ("gpencil.interpolate", {"type": 'E', "value": 'PRESS', "ctrl": True, "alt": True}, None), - ("gpencil.interpolate_sequence", {"type": 'E', "value": 'PRESS', "shift": True, "ctrl": True}, None), # Normal select - ("gpencil.select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, + ("gpencil.select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, {"properties": [("deselect_all", True)]}), # Selection *_grease_pencil_selection(params), # Duplicate and move selected points ("gpencil.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), - # Extrude and move selected points - ("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, None), # Delete op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}), op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'DEL', "value": 'PRESS'}), @@ -2314,20 +2307,13 @@ def km_grease_pencil_stroke_edit_mode(params): ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("gpencil.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), # Snap - op_menu("GPENCIL_MT_snap", {"type": 'S', "value": 'PRESS', "shift": True}), + op_menu("GPENCIL_MT_snap", {"type": 'X', "value": 'PRESS', "shift": True}), # Show/hide ("gpencil.reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("gpencil.hide", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("unselected", False)]}), - ("gpencil.hide", {"type": 'H', "value": 'PRESS', "shift": True}, - {"properties": [("unselected", True)]}), - ("gpencil.selection_opacity_toggle", {"type": 'H', "value": 'PRESS', "ctrl": True}, None), - # Display - *_grease_pencil_display(), # Isolate layer ("gpencil.layer_isolate", {"type": 'NUMPAD_ASTERIX', "value": 'PRESS'}, None), - # Move to layer - ("gpencil.move_to_layer", {"type": 'G', "value": 'PRESS'}, None), # Transform tools ("transform.translate", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("wm.context_toggle", {"type": 'B', "value": 'PRESS'}, @@ -2343,6 +2329,9 @@ def km_grease_pencil_stroke_edit_mode(params): {"properties": [("mode", 2)]}), # Tools *_template_items_basic_tools(), + op_tool_cycle("builtin.extrude", {"type": 'E', "value": 'PRESS', "ctrl": True}), + op_tool_cycle("builtin.radius", {"type": 'R', "value": 'PRESS', "ctrl": True}), + op_tool_cycle("builtin.bend", {"type": 'B', "value": 'PRESS', "ctrl": True}), ]) @@ -2507,8 +2496,6 @@ def km_grease_pencil_stroke_sculpt_mode(params): {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.brush.size')]}), # Context menu *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), - # Display - *_grease_pencil_display(), ]) return keymap @@ -2536,8 +2523,6 @@ def km_grease_pencil_stroke_weight_mode(params): # Brush size. ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt.weight_brush.size')]}), - # Display - *_grease_pencil_display(), ]) return keymap @@ -3122,6 +3107,9 @@ def km_mesh(params): ("mesh.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), ("mesh.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), ("mesh.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), + + *_template_items_editmode_mesh_select_mode(params), + # Hide/reveal. ("mesh.hide", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("unselected", False)]}), @@ -3584,34 +3572,35 @@ def km_transform_modal_map(_params): # ------------------------------------------------------------------------------ -# Gizmos +# Tool System Keymaps +# +# Named are auto-generated based on the tool name and it's toolbar. -# Fallback for gizmos that don't have custom a custom key-map. -def km_generic_gizmo(_params): - keymap = ( - "Generic Gizmo", - {"space_type": 'EMPTY', "region_type": 'WINDOW'}, - {"items": _template_items_gizmo_tweak_value()}, - ) - return keymap +def km_3d_view_tool_select(params): + return ( + "3D View Tool: Tweak", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": _template_items_tool_select(params, "view3d.select", extend="toggle")}, + ) -def km_generic_gizmo_drag(_params): - keymap = ( - "Generic Gizmo Drag", - {"space_type": 'EMPTY', "region_type": 'WINDOW'}, - {"items": _template_items_gizmo_tweak_value_drag()}, +def km_image_editor_tool_uv_select(params): + return ( + "Image Editor Tool: Uv, Tweak", + {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'}, + {"items": _template_items_tool_select(params, "uv.select", extend="extend")}, ) - return keymap + +# Fallback for gizmos that don't have custom a custom key-map. -def km_generic_gizmo_click_drag(_params): +def km_generic_gizmo_drag(_params): keymap = ( - "Generic Gizmo Click Drag", + "Generic Gizmo Drag", {"space_type": 'EMPTY', "region_type": 'WINDOW'}, - {"items": _template_items_gizmo_tweak_value_click_drag()}, + {"items": _template_items_gizmo_tweak_value_drag()}, ) return keymap @@ -3630,131 +3619,9 @@ def km_generic_gizmo_maybe_drag(params): # ------------------------------------------------------------------------------ -# Tool System Keymaps - - -def km_3d_view_tool_transform(params): - return ( - "3D View Tool: Transform", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.from_gizmo", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_move(params): - return ( - "3D View Tool: Move", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.translate", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_rotate(params): - return ( - "3D View Tool: Rotate", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.rotate", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_scale(params): - return ( - "3D View Tool: Scale", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.resize", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_mesh_extrude_region(params): - return ( - "3D View Tool: Edit Mesh, Extrude Region", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("mesh.extrude_context_move", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("TRANSFORM_OT_translate", [("release_confirm", True)])]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_mesh_shear(params): - return ( - "3D View Tool: Edit Mesh, Shear", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("transform.shear", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("release_confirm", True)]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_mesh_spin(params): - return ( - "3D View Tool: Edit Mesh, Spin", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("mesh.spin", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_mesh_spin_duplicate(params): - return ( - "3D View Tool: Edit Mesh, Spin Duplicates", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("mesh.spin", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("dupli", True)]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_curve_extrude(params): - return ( - "3D View Tool: Edit Curve, Extrude", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("curve.extrude_move", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("TRANSFORM_OT_translate", [("release_confirm", True)])]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -def km_3d_view_tool_edit_armature_extrude(params): - return ( - "3D View Tool: Edit Armature, Extrude", - {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, - {"items": [ - ("armature.extrude_move", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, - {"properties": [("TRANSFORM_OT_translate", [("release_confirm", True)])]}), - *_template_items_tool_select_actions("view3d.select_box", type=params.tool_tweak, value='ANY'), - ]}, - ) - - -# ------------------------------------------------------------------------------ # Full Configuration -def generate_keymaps(params=None): +def generate_keymaps_impl(params=None): if params is None: params = Params() return [ @@ -3840,20 +3707,57 @@ def generate_keymaps(params=None): km_transform_modal_map(params), # Gizmos. - km_generic_gizmo(params), km_generic_gizmo_drag(params), km_generic_gizmo_maybe_drag(params), - km_generic_gizmo_click_drag(params), # Tool System. - km_3d_view_tool_transform(params), - km_3d_view_tool_move(params), - km_3d_view_tool_rotate(params), - km_3d_view_tool_scale(params), - km_3d_view_tool_edit_mesh_extrude_region(params), - km_3d_view_tool_edit_mesh_shear(params), - km_3d_view_tool_edit_mesh_spin(params), - km_3d_view_tool_edit_mesh_spin_duplicate(params), - km_3d_view_tool_edit_curve_extrude(params), - km_3d_view_tool_edit_armature_extrude(params), + km_3d_view_tool_select(params), + km_image_editor_tool_uv_select(params), ] + + +def keymap_transform_tool_mmb(keymap): + import re + # Any tool besides fallback tools. + re_fallback_tool = re.compile( + r".*\bTool:\s(?!" + r".*\bSelect Box$|" + r".*\bSelect Circle$|" + r".*\bSelect Lasso$|" + r".*\bTweak$)", + ) + for km_name, km_args, km_content in keymap: + if re_fallback_tool.match(km_name): + km_items = km_content["items"] + km_items_new = [] + for kmi in km_items: + ty = kmi[1]["type"] + if ty == 'LEFTMOUSE': + kmi = (kmi[0], kmi[1].copy(), kmi[2]) + kmi[1]["type"] = 'MIDDLEMOUSE' + km_items_new.append(kmi) + elif ty == 'EVT_TWEAK_L': + kmi = (kmi[0], kmi[1].copy(), kmi[2]) + kmi[1]["type"] = 'EVT_TWEAK_M' + km_items_new.append(kmi) + km_items.extend(km_items_new) + + +def generate_keymaps(params=None): + import os + from bpy.utils import execfile + keymap = generate_keymaps_impl(params) + + # Combine the key-map to support manipulating it, so we don't need to manually + # define key-map here just to manipulate them. + blender_default = execfile( + os.path.join(os.path.dirname(__file__), "blender_default.py"), + ).generate_keymaps() + + keymap_existing_names = {km[0] for km in keymap} + keymap.extend([km for km in blender_default if km[0] not in keymap_existing_names]) + + # Manipulate the key-map. + keymap_transform_tool_mmb(keymap) + + return keymap diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index c42d5970ed9..12d7984b3b2 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -743,7 +743,9 @@ class TransformsToDeltas(Operator): def transfer_rotation(self, obj): # TODO: add transforms together... if obj.rotation_mode == 'QUATERNION': - obj.delta_rotation_quaternion += obj.rotation_quaternion + delta = obj.delta_rotation_quaternion.copy() + obj.delta_rotation_quaternion = obj.rotation_quaternion + obj.delta_rotation_quaternion.rotate(delta) if self.reset_values: obj.rotation_quaternion.identity() diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index e49ca0320c7..71153ba8b74 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -466,6 +466,13 @@ class QuickLiquid(Operator): self.report({'ERROR'}, "Select at least one mesh object") return {'CANCELLED'} + # set shading type to wireframe so that liquid particles are visible + for area in bpy.context.screen.areas: + if area.type == 'VIEW_3D': + for space in area.spaces: + if space.type == 'VIEW_3D': + space.shading.type = 'WIREFRAME' + for obj in mesh_objects: fake_context["object"] = obj # make each selected object a liquid flow @@ -499,7 +506,6 @@ class QuickLiquid(Operator): # setup liquid domain bpy.ops.object.modifier_add(type='FLUID') obj.modifiers[-1].fluid_type = 'DOMAIN' - obj.modifiers[-1].domain_settings.domain_type = 'LIQUID' # set all domain borders to obstacle obj.modifiers[-1].domain_settings.use_collision_border_front = True obj.modifiers[-1].domain_settings.use_collision_border_back = True @@ -511,8 +517,8 @@ class QuickLiquid(Operator): # set correct cache file format for liquid obj.modifiers[-1].domain_settings.cache_mesh_format = 'BOBJECT' - # allocate and show particle system for FLIP - obj.modifiers[-1].domain_settings.use_flip_particles = True + # change domain type, will also allocate and show particle system for FLIP + obj.modifiers[-1].domain_settings.domain_type = 'LIQUID' # make the domain smooth so it renders nicely bpy.ops.object.shade_smooth() diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index c811f542a3a..6a21f7db654 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -501,7 +501,7 @@ class AddPresetTrackingSettings(AddPresetBase, Operator): "settings.use_default_mask", "settings.use_default_red_channel", "settings.use_default_green_channel", - "settings.use_default_blue_channel" + "settings.use_default_blue_channel", "settings.default_weight" ] diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 756d2ff1eeb..3900fc3f2c2 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -85,12 +85,13 @@ class PlayRenderedAnim(Operator): fps_final = rd.fps / rd.fps_base preset = prefs.filepaths.animation_player_preset - player_path = prefs.filepaths.animation_player # file_path = bpy.path.abspath(rd.filepath) # UNUSED is_movie = rd.is_movie_format # try and guess a command line if it doesn't exist - if player_path == "": + if preset == 'CUSTOM': + player_path = prefs.filepaths.animation_player + else: player_path = guess_player_path(preset) if is_movie is False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}: diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 4c5c269955a..4cb6ddd3fa3 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -49,6 +49,44 @@ def module_filesystem_remove(path_base, module_name): else: os.remove(f_full) +# This duplicates shutil.copytree from Python 3.8, with the new dirs_exist_ok +# argument that we need. Once we upgrade to 3.8 we can remove this. +def _preferences_copytree(entries, src, dst): + import shutil + import os + os.makedirs(dst, exist_ok=True) + errors = [] + + for srcentry in entries: + srcname = os.path.join(src, srcentry.name) + dstname = os.path.join(dst, srcentry.name) + srcobj = srcentry + try: + if srcentry.is_symlink(): + linkto = os.readlink(srcname) + os.symlink(linkto, dstname) + shutil.copystat(srcobj, dstname, follow_symlinks=False) + elif srcentry.is_dir(): + preferences_copytree(srcobj, dstname) + else: + shutil.copy2(srcentry, dstname) + except Error as err: + errors.extend(err.args[0]) + except OSError as why: + errors.append((srcname, dstname, str(why))) + try: + shutil.copystat(src, dst) + except OSError as why: + if getattr(why, 'winerror', None) is None: + errors.append((src, dst, str(why))) + if errors: + raise Error(errors) + return dst + +def preferences_copytree(src, dst): + import os + with os.scandir(src) as entries: + return _preferences_copytree(entries=entries, src=src, dst=dst) class PREFERENCES_OT_keyconfig_activate(Operator): bl_idname = "preferences.keyconfig_activate" @@ -110,9 +148,10 @@ class PREFERENCES_OT_copy_prev(Operator): return os.path.isfile(old_userpref) and not os.path.isfile(new_userpref) def execute(self, _context): - import shutil - - shutil.copytree(self._old_path(), self._new_path(), symlinks=True) + # Use this instead once we upgrade to Python 3.8 with dirs_exist_ok. + # import shutil + # shutil.copytree(self._old_path(), self._new_path(), dirs_exist_ok=True) + preferences_copytree(self._old_path(), self._new_path()) # reload preferences and recent-files.txt bpy.ops.wm.read_userpref() diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py index 39d792bd557..a249599b5d7 100644 --- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py +++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py @@ -37,6 +37,20 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, from math import acos import array + # We simulate the accumulation of dirt in the creases of geometric surfaces + # by comparing the vertex normal to the average direction of all vertices + # connected to that vertex. We can also simulate surfaces being buffed or + # worn by testing protruding surfaces. + # + # So if the angle between the normal and geometric direction is: + # < 90 - dirt has accumulated in the crease + # > 90 - surface has been worn or buffed + # ~ 90 - surface is flat and is generally unworn and clean + # + # This method is limited by the complexity or lack there of in the geometry. + # + # Original code and method by Keith "Wahooney" Boshoff. + vert_tone = array.array("f", [0.0]) * len(me.vertices) # create lookup table for each vertex's connected vertices (via edges) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index a677d9932b6..335a2a633cd 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1804,9 +1804,6 @@ class WM_OT_toolbar_fallback_pie(Operator): return context.space_data is not None def invoke(self, context, event): - if not context.preferences.experimental.use_tool_fallback: - return {'PASS_THROUGH'} - from bl_ui.space_toolsystem_common import ToolSelectPanelHelper space_type = context.space_data.type cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py index b75d67b5350..3fc54ff6d12 100644 --- a/release/scripts/startup/bl_ui/properties_constraint.py +++ b/release/scripts/startup/bl_ui/properties_constraint.py @@ -492,6 +492,8 @@ class ConstraintButtonsPanel: col.prop(con, "frame_start", text="Start") col.prop(con, "frame_end", text="End") + layout.prop(con, "mix_mode", text="Mix") + def LOCKED_TRACK(self, _context, layout, con): self.target_template(layout, con) diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 5d654d33a2d..957b119e9ba 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -501,6 +501,7 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel): col = layout.column() col.prop(safe_data, "title_center", slider=True) + col.prop(safe_data, "action_center", slider=True) class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index d1975919d7e..b694062dfc5 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -144,7 +144,6 @@ class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): curve = context.curve col = layout.column() - col.prop(curve, "use_uv_as_generated") col.prop(curve, "use_auto_texspace") col = layout.column() diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index 4ce87b85410..88fdaae0433 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -37,7 +37,6 @@ class DATA_PT_empty(DataButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False ob = context.object @@ -45,12 +44,6 @@ class DATA_PT_empty(DataButtonsPanel, Panel): layout.prop(ob, "empty_display_size", text="Size") if ob.empty_display_type == 'IMAGE': - layout.prop(ob, "use_empty_image_alpha") - - col = layout.column() - col.active = ob.use_empty_image_alpha - col.prop(ob, "color", text="Transparency", index=3, slider=True) - col = layout.column(align=True) col.prop(ob, "empty_image_offset", text="Offset X", index=0) col.prop(ob, "empty_image_offset", text="Y", index=1) @@ -63,6 +56,30 @@ class DATA_PT_empty(DataButtonsPanel, Panel): col.prop(ob, "show_empty_image_only_axis_aligned") +class DATA_PT_empty_alpha(DataButtonsPanel, Panel): + bl_label = "Transparency" + bl_parent_id = "DATA_PT_empty" + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'EMPTY' and ob.empty_display_type == 'IMAGE') + + def draw_header(self, context): + ob = context.object + + self.layout.prop(ob, "use_empty_image_alpha", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + + layout.active = ob.use_empty_image_alpha + layout.prop(ob, "color", text="Opacity", index=3, slider=True) + + class DATA_PT_empty_image(DataButtonsPanel, Panel): bl_label = "Image" @@ -81,6 +98,7 @@ class DATA_PT_empty_image(DataButtonsPanel, Panel): classes = ( DATA_PT_empty, + DATA_PT_empty_alpha, DATA_PT_empty_image, ) diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index 6f730cf3307..cf894b48e1e 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -134,17 +134,15 @@ class DATA_PT_EEVEE_light_distance(DataButtonsPanel, Panel): light = context.light layout = self.layout - layout.active = light.use_shadow layout.prop(light, "use_custom_distance", text="") def draw(self, context): layout = self.layout light = context.light + layout.active = light.use_custom_distance layout.use_property_split = True - col = layout.column() - - col.prop(light, "cutoff_distance", text="Distance") + layout.prop(light, "cutoff_distance", text="Distance") class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel): @@ -311,7 +309,8 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): def draw(self, context): light = context.light - self.layout.template_curve_mapping(light, "falloff_curve", use_negative_slope=True) + self.layout.template_curve_mapping( + light, "falloff_curve", use_negative_slope=True) class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index d4b2c39bd5e..197566f16f3 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -293,7 +293,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.label(text="Vertex Group:") - col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') col = split.column() col.label(text="Control Object:") col.prop(md, "object", text="") diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 5de133f184a..10645bdd214 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -45,12 +45,10 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): speaker = context.speaker space = context.space_data - split = layout.split(factor=0.65) - if ob: - split.template_ID(ob, "data") + layout.template_ID(ob, "data") elif speaker: - split.template_ID(space, "pin_id") + layout.template_ID(space, "pin_id") class DATA_PT_speaker(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 45cb10bb3bd..2001f46820f 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -581,9 +581,9 @@ class AnnotationDataPanel: def poll(cls, context): # Show this panel as long as someone that might own this exists # AND the owner isn't an object (e.g. GP Object) - if context.gpencil_data_owner is None: + if context.annotation_data_owner is None: return False - elif type(context.gpencil_data_owner) is bpy.types.Object: + elif type(context.annotation_data_owner) is bpy.types.Object: return False else: return True @@ -597,14 +597,14 @@ class AnnotationDataPanel: layout.use_property_decorate = False # Grease Pencil owner. - gpd_owner = context.gpencil_data_owner - gpd = context.gpencil_data + gpd_owner = context.annotation_data_owner + gpd = context.annotation_data # Owner selector. if context.space_data.type == 'CLIP_EDITOR': layout.row().prop(context.space_data, "grease_pencil_source", expand=True) - layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink") + layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.annotation_add", unlink="gpencil.data_unlink") # List of layers/notes. if gpd and gpd.layers: @@ -624,17 +624,17 @@ class AnnotationDataPanel: col = row.column() sub = col.column(align=True) - sub.operator("gpencil.layer_add", icon='ADD', text="") - sub.operator("gpencil.layer_remove", icon='REMOVE', text="") + sub.operator("gpencil.layer_annotation_add", icon='ADD', text="") + sub.operator("gpencil.layer_annotation_remove", icon='REMOVE', text="") - gpl = context.active_gpencil_layer + gpl = context.active_annotation_layer if gpl: if len(gpd.layers) > 1: col.separator() sub = col.column(align=True) - sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' - sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + sub.operator("gpencil.layer_annotation_move", icon='TRIA_UP', text="").type = 'UP' + sub.operator("gpencil.layer_annotation_move", icon='TRIA_DOWN', text="").type = 'DOWN' tool_settings = context.tool_settings if gpd and gpl: @@ -653,7 +653,7 @@ class AnnotationDataPanel: else: lock_label = iface_("Lock Frame") row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED') - row.operator("gpencil.active_frame_delete", text="", icon='X') + row.operator("gpencil.annotation_active_frame_delete", text="", icon='X') class AnnotationOnionSkin: @@ -665,26 +665,26 @@ class AnnotationOnionSkin: def poll(cls, context): # Show this panel as long as someone that might own this exists # AND the owner isn't an object (e.g. GP Object) - if context.gpencil_data_owner is None: + if context.annotation_data_owner is None: return False - elif type(context.gpencil_data_owner) is bpy.types.Object: + elif type(context.annotation_data_owner) is bpy.types.Object: return False else: - gpl = context.active_gpencil_layer + gpl = context.active_annotation_layer if gpl is None: return False return True def draw_header(self, context): - gpl = context.active_gpencil_layer + gpl = context.active_annotation_layer self.layout.prop(gpl, "use_annotation_onion_skinning", text="") def draw(self, context): layout = self.layout layout.use_property_decorate = False - gpl = context.active_gpencil_layer + gpl = context.active_annotation_layer col = layout.column() split = col.split(factor=0.5) split.active = gpl.use_annotation_onion_skinning diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 327df079d3b..a9e8cae3c8b 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -121,7 +121,7 @@ class UnifiedPaintPanel: if unified_name and not header: # NOTE: We don't draw UnifiedPaintSettings in the header to reduce clutter. D5928#136281 - row.prop(ups, unified_name, text="", icon="WORLD") + row.prop(ups, unified_name, text="", icon="BRUSHES_ALL") return row @@ -438,7 +438,7 @@ class FalloffPanel(BrushPanel): row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' - if mode in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT'}: + if mode in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT'} and brush.sculpt_tool != 'POSE': col.separator() row = col.row(align=True) row.use_property_split = True @@ -616,9 +616,12 @@ def brush_settings(layout, context, brush, popover=False): layout.separator() if brush.sculpt_tool == 'POSE': - row = layout.row() - row.prop(brush, "pose_offset") - + layout.separator() + layout.prop(brush, "pose_offset") + layout.prop(brush, "pose_smooth_iterations") + layout.prop(brush, "pose_ik_segments") + layout.separator() + if brush.sculpt_tool == 'SCRAPE': row = layout.row() row.prop(brush, "invert_to_scrape_fill", text="Invert to Fill") diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 21abf8bb34c..3384032e332 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -582,7 +582,10 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): else: part = context.space_data.pin_id - self.layout.prop(part, "use_rotations", text="") + layout = self.layout + layout.prop(part, "use_rotations", text="") + layout.enabled = particle_panel_enabled(context, psys) + def draw(self, context): layout = self.layout @@ -1961,7 +1964,7 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): layout.prop(part, "shape", text="Strand Shape") col = layout.column(align=True) - col.prop(part, "root_radius", text="Radius Root") + col.prop(part, "root_radius", text="Diameter Root") col.prop(part, "tip_radius", text="Tip") col = layout.column() diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 6b0dd7ac36f..28c9895f53b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -95,6 +95,26 @@ class PhysicButtonsPanel: md = context.fluid return md and (md.fluid_type == 'FLOW') + @staticmethod + def poll_fluid_flow_outflow(context): + if not PhysicButtonsPanel.poll_fluid_flow(context): + return False + + md = context.fluid + flow = md.flow_settings + if (flow.flow_behavior == 'OUTFLOW'): + return True + + @staticmethod + def poll_fluid_flow_liquid(context): + if not PhysicButtonsPanel.poll_fluid_flow(context): + return False + + md = context.fluid + flow = md.flow_settings + if (flow.flow_type == 'LIQUID'): + return True + class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): bl_label = "Fluid" @@ -313,9 +333,9 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) flow.enabled = not is_baking_any and not has_baked_data - col = flow.column() - col.prop(domain, "alpha") - col.prop(domain, "beta", text="Temperature Diff.") + col = flow.column(align=True) + col.prop(domain, "alpha", text="Buoyancy Density") + col.prop(domain, "beta", text="Heat") col = flow.column() col.prop(domain, "vorticity") @@ -389,14 +409,12 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): col = flow.column() col.prop(domain, "burning_rate", text="Reaction Speed") - col = flow.column() + col = flow.column(align=True) col.prop(domain, "flame_smoke", text="Flame Smoke") - col = flow.column() - col.prop(domain, "flame_vorticity", text="Flame Vorticity") - col = flow.column() - col.prop(domain, "flame_ignition", text="Temperature Ignition") - col = flow.column() - col.prop(domain, "flame_max_temp", text="Maximum Temperature") + col.prop(domain, "flame_vorticity", text="Vorticity") + col = flow.column(align=True) + col.prop(domain, "flame_max_temp", text="Temperature Maximum") + col.prop(domain, "flame_ignition", text="Minimum") col = flow.column() col.prop(domain, "flame_smoke_color", text="Flame Color") @@ -485,10 +503,10 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): col = grid.column() if flow.flow_source == 'MESH': col.prop(flow, "use_plane_init", text="Is Planar") - col.prop(flow, "surface_distance", text="Surface Thickness") + col.prop(flow, "surface_distance", text="Surface Emission") if flow.flow_type in {'SMOKE', 'BOTH', 'FIRE'}: col = grid.column() - col.prop(flow, "volume_density", text="Volume Density") + col.prop(flow, "volume_density", text="Volume Emission") if flow.flow_source == 'PARTICLES': col.prop(flow, "use_particle_size", text="Set Size") @@ -507,6 +525,9 @@ class PHYSICS_PT_flow_initial_velocity(PhysicButtonsPanel, Panel): if not PhysicButtonsPanel.poll_fluid_flow(context): return False + if PhysicButtonsPanel.poll_fluid_flow_outflow(context): + return False + return (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -546,6 +567,12 @@ class PHYSICS_PT_flow_texture(PhysicButtonsPanel, Panel): if not PhysicButtonsPanel.poll_fluid_flow(context): return False + if PhysicButtonsPanel.poll_fluid_flow_outflow(context): + return False + + if PhysicButtonsPanel.poll_fluid_flow_liquid(context): + return False + return (context.engine in cls.COMPAT_ENGINES) def draw_header(self, context): @@ -1088,13 +1115,7 @@ class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): col.separator() split = layout.split() - bake_incomplete = (domain.cache_frame_pause_data < domain.cache_frame_end) - if domain.has_cache_baked_data and not domain.is_cache_baking_data and bake_incomplete: - col = split.column() - col.operator("fluid.bake_all", text="Resume") - col = split.column() - col.operator("fluid.free_all", text="Free") - elif domain.is_cache_baking_data and not domain.has_cache_baked_data: + if domain.is_cache_baking_data and not domain.has_cache_baked_data: split.enabled = False split.operator("fluid.pause_bake", text="Baking All - ESC to pause") elif not domain.has_cache_baked_data and not domain.is_cache_baking_data: diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 5a73ff094a2..a09e263fd87 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -542,8 +542,8 @@ class DOPESHEET_MT_gpencil_channel(Menu): # layout.operator("anim.channels_expand") # layout.operator("anim.channels_collapse") - # layout.separator() - #layout.operator_menu_enum("anim.channels_move", "direction", text="Move...") + layout.separator() + layout.operator_menu_enum("anim.channels_move", "direction", text="Move...") class DOPESHEET_MT_gpencil_frame(Menu): diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 82ed701aa4c..cd65980fc0d 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -92,7 +92,7 @@ class INFO_MT_area(Menu): layout.separator() - layout.operator("screen.area_dupli", icon='DUPLICATE') + layout.operator("screen.area_dupli", icon='WINDOW') layout.separator() diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index 28b67c93666..4ecc4e7fdd9 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -167,6 +167,7 @@ class NLA_MT_edit(Menu): layout.operator("nla.duplicate", text="Linked Duplicate").linked = True layout.operator("nla.split") layout.operator("nla.delete") + layout.operator("nla.tracks_delete") layout.separator() layout.operator("nla.mute_toggle") diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 097564444d0..af0c23e7892 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -30,6 +30,9 @@ from bpy.app.translations import ( from bl_ui.properties_grease_pencil_common import ( AnnotationDataPanel, ) +from bl_ui.space_toolsystem_common import ( + ToolActivePanelHelper, +) from rna_prop_ui import PropertyPanel @@ -89,6 +92,35 @@ def draw_color_balance(layout, color_balance): split.template_color_picker(color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True) +class SEQUENCER_PT_active_tool(ToolActivePanelHelper, Panel): + bl_space_type = 'SEQUENCE_EDITOR' + bl_region_type = 'UI' + bl_category = "Tool" + + +class SEQUENCER_HT_tool_header(Header): + bl_space_type = 'SEQUENCE_EDITOR' + bl_region_type = 'TOOL_HEADER' + + def draw(self, context): + layout = self.layout + + layout.template_header() + + self.draw_tool_settings(context) + + # TODO: options popover. + + def draw_tool_settings(self, context): + layout = self.layout + + # Active Tool + # ----------- + from bl_ui.space_toolsystem_common import ToolSelectPanelHelper + tool = ToolSelectPanelHelper.draw_active_tool_header(context, layout) + tool_mode = context.mode if tool is None else tool.mode + + class SEQUENCER_HT_header(Header): bl_space_type = 'SEQUENCE_EDITOR' @@ -97,7 +129,10 @@ class SEQUENCER_HT_header(Header): st = context.space_data - layout.template_header() + show_region_tool_header = st.show_region_tool_header + + if not show_region_tool_header: + layout.template_header() layout.prop(st, "view_type", text="") @@ -226,8 +261,12 @@ class SEQUENCER_MT_view(Menu): # wm_keymap_item_find_props() (see #32595). layout.operator_context = 'INVOKE_REGION_PREVIEW' layout.prop(st, "show_region_ui") + layout.prop(st, "show_region_toolbar") layout.operator_context = 'INVOKE_DEFAULT' + if is_sequencer_view: + layout.prop(st, "show_region_hud") + if st.view_type == 'SEQUENCER': layout.prop(st, "show_backdrop", text="Preview as Backdrop") @@ -268,6 +307,7 @@ class SEQUENCER_MT_view(Menu): layout.operator_context = 'INVOKE_DEFAULT' layout.prop(st, "show_seconds") + layout.prop(st, "show_locked_time") layout.prop(st, "show_strip_offset") layout.separator() layout.prop(st, "show_markers") @@ -2128,6 +2168,7 @@ class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): classes = ( SEQUENCER_MT_change, + SEQUENCER_HT_tool_header, SEQUENCER_HT_header, SEQUENCER_MT_editor_menus, SEQUENCER_MT_range, @@ -2153,7 +2194,7 @@ classes = ( SEQUENCER_MT_strip_input, SEQUENCER_MT_strip_lock_mute, SEQUENCER_MT_context_menu, - + SEQUENCER_PT_active_tool, SEQUENCER_PT_strip, SEQUENCER_PT_effect, diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index 81ccc9216a1..b7c5dcd5437 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -30,7 +30,7 @@ class TEXT_HT_header(Header): st = context.space_data text = st.text - + is_syntax_highlight_supported = st.is_syntax_highlight_supported() layout.template_header() TEXT_MT_editor_menus.draw_collapsible(context, layout) @@ -43,7 +43,18 @@ class TEXT_HT_header(Header): layout.separator_spacer() row = layout.row(align=True) - row.template_ID(st, "text", new="text.new", unlink="text.unlink", open="text.open") + row.template_ID(st, "text", new="text.new", + unlink="text.unlink", open="text.open") + + if text: + is_osl = text.name.endswith((".osl", ".osl")) + if is_osl: + row.operator("node.shader_script_update", + text="", icon='FILE_REFRESH') + else: + row = layout.row() + row.active = is_syntax_highlight_supported + row.operator("text.run_script", text="", icon='PLAY') layout.separator_spacer() @@ -51,28 +62,10 @@ class TEXT_HT_header(Header): row.prop(st, "show_line_numbers", text="") row.prop(st, "show_word_wrap", text="") - is_syntax_highlight_supported = st.is_syntax_highlight_supported() syntax = row.row(align=True) syntax.active = is_syntax_highlight_supported syntax.prop(st, "show_syntax_highlight", text="") - if text: - text_name = text.name - is_osl = text_name.endswith((".osl", ".oso")) - - row = layout.row() - if is_osl: - row = layout.row() - row.operator("node.shader_script_update") - else: - row = layout.row() - row.active = text_name.endswith(".py") - row.prop(text, "use_module") - - row = layout.row() - row.active = is_syntax_highlight_supported - row.operator("text.run_script") - class TEXT_HT_footer(Header): bl_space_type = 'TEXT_EDITOR' diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 7b0a769ae62..4dc724299f0 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -354,6 +354,16 @@ class ToolSelectPanelHelper: i += 1 return None, -1 + @classmethod + def _tool_group_active_set_by_id(cls, context, idname_group, idname): + item_group = cls._tool_get_group_by_id(context, idname_group, coerce=True) + if item_group: + for i, item in enumerate(item_group): + if item and item.idname == idname: + cls._tool_group_active[item_group[0].idname] = i + return True + return False + @staticmethod def _tool_active_from_context(context, space_type, mode=None, create=False): if space_type in {'VIEW_3D', 'PROPERTIES'}: @@ -380,6 +390,14 @@ class ToolSelectPanelHelper: if tool is not None: tool.refresh_from_context() return tool + elif space_type == 'SEQUENCE_EDITOR': + space_data = context.space_data + if mode is None: + mode = space_data.view_type + tool = context.workspace.tools.from_space_sequencer(mode, create=create) + if tool is not None: + tool.refresh_from_context() + return tool return None @staticmethod @@ -646,6 +664,8 @@ class ToolSelectPanelHelper: return space_type, space_data.mode elif space_type == 'NODE_EDITOR': return space_type, None + elif space_type == 'SEQUENCE_EDITOR': + return space_type, context.space_data.view_type else: return None, None @@ -660,10 +680,10 @@ class ToolSelectPanelHelper: *, is_horizontal_layout=False, ): - tool_fallback = tool.tool_fallback + idname_fallback = tool.idname_fallback space_type = tool.space_type cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) - item_fallback, _index = cls._tool_get_by_id(context, tool_fallback) + item_fallback, _index = cls._tool_get_by_id(context, idname_fallback) if item_fallback is not None: draw_settings = item_fallback.draw_settings if draw_settings is not None: @@ -699,12 +719,8 @@ class ToolSelectPanelHelper: if draw_settings is not None: draw_settings(context, layout, tool) - if context.preferences.experimental.use_tool_fallback: - tool_fallback = tool.tool_fallback - else: - tool_fallback = None - - if tool_fallback and tool_fallback != item.idname: + idname_fallback = tool.idname_fallback + if idname_fallback and idname_fallback != item.idname: tool_settings = context.tool_settings # Show popover which looks like an enum but isn't one. @@ -862,6 +878,7 @@ class WM_MT_toolsystem_submenu(Menu): def _activate_by_item(context, space_type, item, index, *, as_fallback=False): cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True) tool_fallback_id = cls.tool_fallback_id if as_fallback: @@ -889,6 +906,12 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False): # Done, now get the current tool to replace the item & index. tool_active = ToolSelectPanelHelper._tool_active_from_context(context, space_type) item, index = cls._tool_get_by_id(context, getattr(tool_active, "idname", None)) + else: + # Ensure the active fallback tool is read from saved state (even if the fallback tool is not in use). + stored_idname_fallback = tool.idname_fallback + if stored_idname_fallback: + cls._tool_group_active_set_by_id(context, tool_fallback_id, stored_idname_fallback) + del stored_idname_fallback # Find fallback keymap. item_fallback = None @@ -897,7 +920,6 @@ def _activate_by_item(context, space_type, item, index, *, as_fallback=False): item_fallback, _index = cls._tool_get_active_by_index(context, select_index) # End calculating fallback. - tool = ToolSelectPanelHelper._tool_active_from_context(context, space_type, create=True) tool.setup( idname=item.idname, keymap=item.keymap[0] if item.keymap is not None else "", diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 5f017e61db7..c1ad196b555 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -134,6 +134,7 @@ class _defs_view3d_generic: idname="builtin.measure", label="Measure", description=description, + cursor='CROSSHAIR', icon="ops.view3d.ruler", widget="VIEW3D_GGT_ruler", keymap="3D View Tool: Measure", @@ -292,16 +293,29 @@ class _defs_transform: ) @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 transform(): def draw_settings(context, layout, tool): if layout.use_property_split: layout.label(text="Gizmos:") show_drag = True - if context.preferences.experimental.use_tool_fallback: - tool_settings = context.tool_settings - if tool_settings.workspace_tool_type == 'FALLBACK': - show_drag = False + 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") @@ -362,6 +376,7 @@ class _defs_view3d_select: label="Select Lasso", icon="ops.generic.select_lasso", widget=None, + cursor='DEFAULT', keymap="3D View Tool: Select Lasso", draw_settings=draw_settings, ) @@ -386,6 +401,7 @@ class _defs_view3d_select: label="Select Circle", icon="ops.generic.select_circle", widget=None, + cursor='DEFAULT', keymap="3D View Tool: Select Circle", draw_settings=draw_settings, draw_cursor=draw_cursor, @@ -764,20 +780,6 @@ class _defs_edit_mesh: ) @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=(), - draw_settings=draw_settings, - ) - - @ToolDef.from_fn def tosphere(): return dict( idname="builtin.to_sphere", @@ -1708,6 +1710,51 @@ class _defs_node_edit: keymap="Node Tool: Links Cut", ) +class _defs_sequencer_generic: + + @ToolDef.from_fn + def cut(): + def draw_settings(_context, layout, tool): + props = tool.operator_properties("sequencer.cut") + row = layout.row() + row.use_property_split = False + row.prop(props, "type", expand=True) + return dict( + idname="builtin.cut", + label="Cut", + icon="ops.mesh.knife_tool", + widget=None, + keymap="Sequencer Tool: Cut", + draw_settings=draw_settings, + ) + +class _defs_sequencer_select: + @ToolDef.from_fn + def select(): + return dict( + idname="builtin.select", + label="Select", + icon="ops.generic.select", + widget=None, + keymap="Sequencer Tool: Select", + ) + @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) + pass + 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, + ) + class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): bl_space_type = 'IMAGE_EDITOR' @@ -1961,6 +2008,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_edit_armature.extrude, _defs_edit_armature.extrude_cursor, ), + _defs_transform.shear, ], 'EDIT_MESH': [ *_tools_default, @@ -1999,7 +2047,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_edit_mesh.push_pull, ), ( - _defs_edit_mesh.shear, + _defs_transform.shear, _defs_edit_mesh.tosphere, ), ( @@ -2019,16 +2067,23 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_edit_curve.curve_radius, _defs_edit_curve.tilt, None, + _defs_transform.shear, _defs_edit_curve.curve_vertex_randomize, ], '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_view3d_generic.cursor, @@ -2116,6 +2171,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_gpencil_paint.curve, _defs_gpencil_paint.box, _defs_gpencil_paint.circle, + None, + *_tools_annotate, ], 'EDIT_GPENCIL': [ *_tools_gpencil_select, @@ -2130,11 +2187,13 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_gpencil_edit.shear, _defs_gpencil_edit.tosphere, ), - + 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) @@ -2143,14 +2202,75 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'WEIGHT_GPENCIL': [ _defs_gpencil_weight.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() + + _tools_select = ( + ( + _defs_sequencer_select.select, + _defs_sequencer_select.box, + ), + ) + _tools_annotate = ( + ( + _defs_annotate.scribble, + _defs_annotate.line, + _defs_annotate.poly, + _defs_annotate.eraser, + ), + ) + + _tools = { + None: [ + ], + 'PREVIEW': [ + *_tools_annotate, + ], + 'SEQUENCER': [ + *_tools_select, + _defs_sequencer_generic.cut, + ], + 'SEQUENCER_PREVIEW': [ + *_tools_select, + *_tools_annotate, + _defs_sequencer_generic.cut, + ], + } classes = ( IMAGE_PT_tools_active, NODE_PT_tools_active, VIEW3D_PT_tools_active, + SEQUENCER_PT_tools_active, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 7dbf49d01e3..fd46bd53cd2 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -471,7 +471,7 @@ class TOPBAR_MT_file_export(Menu): text="Collada (Default) (.dae)") if bpy.app.build_options.alembic: self.layout.operator("wm.alembic_export", text="Alembic (.abc)") - if bpy.app.build_options.usd and context.preferences.experimental.use_usd_exporter: + if bpy.app.build_options.usd: self.layout.operator( "wm.usd_export", text="Universal Scene Description (.usd, .usdc, .usda)") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 9527c7f4de8..ad5e7b5442c 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -997,6 +997,7 @@ class PreferenceThemeSpacePanel: "freestyle_face_mark", "split_normal", "bone_solid", + "bone_locked_weight", "paint_curve_pivot", }, 'GRAPH_EDITOR': { @@ -2003,7 +2004,7 @@ class USERPREF_PT_studiolight_matcaps(StudioLightPanel, StudioLightPanelMixin, P class USERPREF_PT_studiolight_world(StudioLightPanel, StudioLightPanelMixin, Panel): - bl_label = "LookDev HDRIs" + bl_label = "HDRIs" sl_type = 'WORLD' def draw_header_preset(self, _context): @@ -2087,26 +2088,6 @@ class ExperimentalPanel: url_prefix = "https://developer.blender.org/" - -class USERPREF_PT_experimental_ui(ExperimentalPanel, Panel): - bl_label = "User Interface" - - def draw(self, context): - prefs = context.preferences - experimental = prefs.experimental - - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - - task = "T66304" - split = layout.split(factor=0.66) - col = split.column() - col.prop(experimental, "use_tool_fallback", text="Use Tool Fallback") - col = split.column() - col.operator("wm.url_open", text=task, icon='URL').url = self.url_prefix + task - - """ # Example panel, leave it here so we always have a template to follow even # after the features are gone from the experimental panel. @@ -2114,10 +2095,14 @@ class USERPREF_PT_experimental_ui(ExperimentalPanel, Panel): class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): bl_label = "Virtual Reality" - def draw_centered(self, context, layout): + def draw(self, context): prefs = context.preferences experimental = prefs.experimental + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + task = "T71347" split = layout.split(factor=0.66) col = split.split() @@ -2134,30 +2119,6 @@ class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): """ -class USERPREF_PT_experimental_usd(ExperimentalPanel, Panel): - bl_label = "Universal Scene Description" - - @classmethod - def poll(cls, context): - # Only show the panel if Blender was actually built with USD support. - return getattr(bpy.app.build_options, "usd", False) - - def draw(self, context): - prefs = context.preferences - experimental = prefs.experimental - - layout = self.layout - layout.use_property_split = True - layout.use_property_decorate = False - - split = layout.split(factor=0.66) - col = split.split() - col.prop(experimental, "use_usd_exporter", text="USD Exporter") - col = split.split() - url = "https://devtalk.blender.org/t/universal-scene-description-usd-exporter-feedback/10920" - col.operator("wm.url_open", text='Give Feedback', icon='URL').url = url - - # ----------------------------------------------------------------------------- # Class Registration @@ -2242,9 +2203,6 @@ classes = ( USERPREF_PT_studiolight_matcaps, USERPREF_PT_studiolight_world, - USERPREF_PT_experimental_ui, - USERPREF_PT_experimental_usd, - # Popovers. USERPREF_PT_ndof_settings, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 48e40554cfb..aa8f343e1a0 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -621,15 +621,19 @@ class VIEW3D_HT_header(Header): tool_settings = context.tool_settings view = context.space_data shading = view.shading - # mode_string = context.mode - obj = context.active_object show_region_tool_header = view.show_region_tool_header if not show_region_tool_header: layout.row(align=True).template_header() row = layout.row(align=True) + obj = context.active_object + # mode_string = context.mode object_mode = 'OBJECT' if obj is None else obj.mode + has_pose_mode = ( + (object_mode == 'POSE') or + (object_mode == 'WEIGHT_PAINT' and context.pose_object is not None) + ) # Note: This is actually deadly in case enum_items have to be dynamically generated # (because internal RNA array iterator will free everything immediately...). @@ -780,10 +784,13 @@ class VIEW3D_HT_header(Header): "view3d.toggle_xray", text="", icon='XRAY', - depress=getattr( - shading, - "show_xray_wireframe" if shading.type == 'WIREFRAME' else - "show_xray" + depress=( + overlay.show_xray_bone if has_pose_mode else + getattr( + shading, + "show_xray_wireframe" if shading.type == 'WIREFRAME' else + "show_xray" + ) ), ) @@ -918,7 +925,7 @@ class VIEW3D_MT_transform_base(Menu): if context.mode != 'OBJECT': layout.operator("transform.vertex_warp", text="Warp") layout.operator_context = 'EXEC_DEFAULT' - layout.operator("transform.vertex_random", text="Randomize") + layout.operator("transform.vertex_random", text="Randomize").offset = 0.1 layout.operator_context = 'INVOKE_REGION_WIN' @@ -3530,8 +3537,8 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu): col.operator("transform.shear", text="Shear") col.operator("transform.vert_slide", text="Slide Vertices") col.operator_context = 'EXEC_DEFAULT' - col.operator("transform.vertex_random", text="Randomize Vertices") - col.operator("mesh.vertices_smooth", text="Smooth Vertices") + col.operator("transform.vertex_random", text="Randomize Vertices").offset = 0.1 + col.operator("mesh.vertices_smooth", text="Smooth Vertices").factor = 0.5 col.operator_context = 'INVOKE_REGION_WIN' col.operator("mesh.vertices_smooth_laplacian", text="Smooth Laplacian") @@ -3747,7 +3754,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("transform.vert_slide", text="Slide Vertices") layout.operator_context = 'EXEC_DEFAULT' - layout.operator("mesh.vertices_smooth", text="Smooth Vertices") + layout.operator("mesh.vertices_smooth", text="Smooth Vertices").factor = 0.5 layout.operator_context = 'INVOKE_REGION_WIN' layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index f0c4aaa9344..19d5e3da309 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -313,7 +313,7 @@ class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel): layout.prop(pose, "use_auto_ik") layout.prop(pose, "use_mirror_x") col = layout.column() - col.active = pose.use_mirror_x + col.active = pose.use_mirror_x and not pose.use_auto_ik col.prop(pose, "use_mirror_relative") layout.label(text="Affect Only") @@ -560,12 +560,23 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel): layout.operator("image.save_all_modified", text="Save All Images", icon='FILE_TICK') +class VIEW3D_PT_mask(View3DPanel, Panel): + bl_category = "Tool" + bl_context = ".imagepaint" # dot on purpose (access from topbar) + bl_label = "Masking" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + pass + + # TODO, move to space_view3d.py class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel): bl_category = "Tool" bl_context = ".imagepaint" # dot on purpose (access from topbar) - bl_label = "Mask" + bl_label = "Stencil Mask" bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = "VIEW3D_PT_mask" bl_ui_units_x = 14 @classmethod @@ -1192,6 +1203,7 @@ class VIEW3D_PT_tools_imagepaint_options_cavity(View3DPaintPanel, Panel): bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_label = "Cavity Mask" bl_parent_id = "VIEW3D_PT_tools_imagepaint_options" + bl_parent_id = "VIEW3D_PT_mask" bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -1876,7 +1888,7 @@ classes = ( VIEW3D_PT_tools_curveedit_options_stroke, VIEW3D_PT_tools_armatureedit_options, VIEW3D_PT_tools_posemode_options, - + VIEW3D_PT_slots_projectpaint, VIEW3D_PT_tools_brush_select, VIEW3D_PT_tools_brush_settings, @@ -1886,7 +1898,6 @@ classes = ( VIEW3D_PT_tools_brush_clone, TEXTURE_UL_texpaintslots, VIEW3D_MT_tools_projectpaint_uvlayer, - VIEW3D_PT_stencil_projectpaint, VIEW3D_PT_tools_brush_texture, VIEW3D_PT_tools_mask_texture, VIEW3D_PT_tools_brush_stroke, @@ -1912,9 +1923,13 @@ classes = ( VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar, VIEW3D_PT_tools_vertexpaint_options, + VIEW3D_PT_mask, + VIEW3D_PT_stencil_projectpaint, + VIEW3D_PT_tools_imagepaint_options_cavity, + VIEW3D_PT_tools_imagepaint_symmetry, VIEW3D_PT_tools_imagepaint_options, - VIEW3D_PT_tools_imagepaint_options_cavity, + VIEW3D_PT_tools_imagepaint_options_external, VIEW3D_MT_tools_projectpaint_stencil, |