diff options
Diffstat (limited to 'release')
47 files changed, 388 insertions, 306 deletions
diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject f7b706dd6434db2d752f47c4b8c3148b2990fd7 +Subproject 5ab29b1331d2103dae634b987f121c4599459d7 diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 70a68ce6847..babb3e30c6d 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/scripts/addons b/release/scripts/addons -Subproject af6356139616749c952ff5dfc6bf6dfa668e332 +Subproject 4fcdbfe7c20edfc1204c0aa46c98ea25354abcd diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib -Subproject 8970953d4a8a4ea3bf77c66370c817ed0cf1308 +Subproject 7d78c8a63f2f4b146f9327ddc0d567a5921b94e diff --git a/release/scripts/freestyle/styles/ignore_small_occlusions.py b/release/scripts/freestyle/styles/ignore_small_occlusions.py index efa228f4663..a5fb4671917 100644 --- a/release/scripts/freestyle/styles/ignore_small_occlusions.py +++ b/release/scripts/freestyle/styles/ignore_small_occlusions.py @@ -16,7 +16,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# Filename : ignore_small_oclusions.py +# Filename : ignore_small_occlusions.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : The strokes are drawn through small occlusions diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 387691f9f05..1e308dc9602 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -543,22 +543,6 @@ def module_bl_info(mod, info_basis=None): if not addon_info["name"]: addon_info["name"] = mod.__name__ - # Replace 'wiki_url' with 'doc_url'. - doc_url = addon_info.pop("wiki_url", None) - if doc_url is not None: - # Unlikely, but possible that both are set. - if not addon_info["doc_url"]: - addon_info["doc_url"] = doc_url - if _bpy.app.debug: - print( - "Warning: add-on \"%s\": 'wiki_url' in 'bl_info' " - "is deprecated please use 'doc_url' instead!\n" - " %s" % ( - addon_info['name'], - getattr(mod, "__file__", None), - ) - ) - doc_url = addon_info["doc_url"] if doc_url: doc_url_prefix = "{BLENDER_MANUAL_URL}" diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py index 979b47f7a14..51ea53c0eba 100644 --- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -37,6 +37,9 @@ OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'} def ids_nolib(bids): return (bid for bid in bids if not bid.library) +def ids_nolib_with_preview(bids): + return (bid for bid in bids if (not bid.library and bid.preview)) + def rna_backup_gen(data, include_props=None, exclude_props=None, root=()): # only writable properties... @@ -313,8 +316,9 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): image = bpy.data.images[render_context.image, None] item = getattr(bpy.data, item_container)[item_name, None] image.reload() - item.preview.image_size = (RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE) - item.preview.image_pixels_float[:] = image.pixels + preview = item.preview_ensure() + preview.image_size = (RENDER_PREVIEW_SIZE, RENDER_PREVIEW_SIZE) + preview.image_pixels_float[:] = image.pixels # And now, main code! do_save = True @@ -451,15 +455,15 @@ def do_clear_previews(do_objects, do_collections, do_scenes, do_data_intern): bpy.ops.wm.previews_clear(id_type={'SHADING'}) if do_objects: - for ob in ids_nolib(bpy.data.objects): + for ob in ids_nolib_with_preview(bpy.data.objects): ob.preview.image_size = (0, 0) if do_collections: - for grp in ids_nolib(bpy.data.collections): + for grp in ids_nolib_with_preview(bpy.data.collections): grp.preview.image_size = (0, 0) if do_scenes: - for scene in ids_nolib(bpy.data.scenes): + for scene in ids_nolib_with_preview(bpy.data.scenes): scene.preview.image_size = (0, 0) print("Saving %s..." % bpy.data.filepath) diff --git a/release/scripts/modules/bl_ui_utils/bug_report_url.py b/release/scripts/modules/bl_ui_utils/bug_report_url.py index 5676e0d6815..3fc57467dac 100644 --- a/release/scripts/modules/bl_ui_utils/bug_report_url.py +++ b/release/scripts/modules/bl_ui_utils/bug_report_url.py @@ -21,7 +21,7 @@ def url_prefill_from_blender(addon_info=None): import bpy - import bgl + import gpu import struct import platform import urllib.parse @@ -38,9 +38,9 @@ def url_prefill_from_blender(addon_info=None): ) fh.write( "Graphics card: %s %s %s\n" % ( - bgl.glGetString(bgl.GL_RENDERER), - bgl.glGetString(bgl.GL_VENDOR), - bgl.glGetString(bgl.GL_VERSION), + gpu.platform.renderer_get(), + gpu.platform.vendor_get(), + gpu.platform.version_get(), ) ) fh.write( diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index fad52eae84a..e9e9671cc35 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -370,7 +370,7 @@ def module_names(path, recursive=False): def basename(path): """ - Equivalent to os.path.basename, but skips a "//" prefix. + Equivalent to ``os.path.basename``, but skips a "//" prefix. Use for Windows compatibility. """ diff --git a/release/scripts/modules/bpy_extras/asset_utils.py b/release/scripts/modules/bpy_extras/asset_utils.py index db982e119d4..1656c21a137 100644 --- a/release/scripts/modules/bpy_extras/asset_utils.py +++ b/release/scripts/modules/bpy_extras/asset_utils.py @@ -34,7 +34,7 @@ __all__ = ( class SpaceAssetInfo: @classmethod def is_asset_browser(cls, space_data: bpy.types.Space): - return space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'ASSETS' + return space_data and space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'ASSETS' @classmethod def is_asset_browser_poll(cls, context: Context): diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 4ea8c88e8d9..aa540eeb23b 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -657,16 +657,14 @@ class Gizmo(StructRNA): use_blend = color[3] < 1.0 if use_blend: - # TODO: wrap GPU_blend from GPU state. - from bgl import glEnable, glDisable, GL_BLEND - glEnable(GL_BLEND) + gpu.state.blend_set('ALPHA') with gpu.matrix.push_pop(): gpu.matrix.multiply_matrix(matrix) batch.draw() if use_blend: - glDisable(GL_BLEND) + gpu.state.blend_set('NONE') @staticmethod def new_custom_shape(type, verts): diff --git a/release/scripts/modules/gpu_extras/presets.py b/release/scripts/modules/gpu_extras/presets.py index 81d515904a1..f490e1e74ba 100644 --- a/release/scripts/modules/gpu_extras/presets.py +++ b/release/scripts/modules/gpu_extras/presets.py @@ -57,12 +57,12 @@ def draw_circle_2d(position, color, radius, segments=32): batch.draw() -def draw_texture_2d(texture_id, position, width, height): +def draw_texture_2d(texture, position, width, height): """ Draw a 2d texture. - :arg texture_id: OpenGL id of the texture (e.g. :class:`bpy.types.Image.bindcode`). - :type texture_id: int + :arg texture: GPUTexture to draw (e.g. gpu.texture.from_image(image) for :class:`bpy.types.Image`). + :type texture: :class:`gpu.types.GPUTexture` :arg position: Position of the lower left corner. :type position: 2D Vector :arg width: Width of the image when drawn (not necessarily @@ -72,7 +72,6 @@ def draw_texture_2d(texture_id, position, width, height): :type height: float """ import gpu - import bgl from . batch import batch_for_shader coords = ((0, 0), (1, 0), (1, 1), (0, 1)) @@ -83,14 +82,20 @@ def draw_texture_2d(texture_id, position, width, height): {"pos": coords, "texCoord": coords}, ) - bgl.glActiveTexture(bgl.GL_TEXTURE0) - bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id) - with gpu.matrix.push_pop(): gpu.matrix.translate(position) gpu.matrix.scale((width, height)) shader = gpu.shader.from_builtin('2D_IMAGE') shader.bind() - shader.uniform_int("image", 0) + + if isinstance(texture, int): + # Call the legacy bgl to not break the existing API + import bgl + bgl.glActiveTexture(bgl.GL_TEXTURE0) + bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture) + shader.uniform_int("image", 0) + else: + shader.uniform_sampler("image", texture) + batch.draw(shader) diff --git a/release/scripts/modules/keyingsets_utils.py b/release/scripts/modules/keyingsets_utils.py index 190f0282339..b7a15bbbc19 100644 --- a/release/scripts/modules/keyingsets_utils.py +++ b/release/scripts/modules/keyingsets_utils.py @@ -219,6 +219,40 @@ def RKS_GEN_scaling(_ksi, _context, ks, data): else: ks.paths.add(id_block, path) + +# Custom Properties +def RKS_GEN_custom_props(_ksi, _context, ks, data): + # get id-block and path info + id_block, base_path, grouping = get_transform_generators_base_info(data) + + # Only some RNA types can be animated. + prop_type_compat = {bpy.types.BoolProperty, + bpy.types.IntProperty, + bpy.types.FloatProperty} + + # When working with a pose, 'id_block' is the armature object (which should + # get the animation data), whereas 'data' is the bone being keyed. + for cprop_name in data.keys(): + # ignore special "_RNA_UI" used for UI editing + if cprop_name == "_RNA_UI": + continue + + prop_path = '["%s"]' % bpy.utils.escape_identifier(cprop_name) + try: + rna_property = data.path_resolve(prop_path, False) + except ValueError as ex: + # This happens when a custom property is set to None. In that case it cannot + # be converted to an FCurve-compatible value, so we can't keyframe it anyway. + continue + if rna_property.rna_type not in prop_type_compat: + continue + + path = "%s%s" % (base_path, prop_path) + if grouping: + ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping) + else: + ks.paths.add(id_block, path) + # ------ diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py index 6076bf00063..365d6c0087f 100644 --- a/release/scripts/modules/rna_keymap_ui.py +++ b/release/scripts/modules/rna_keymap_ui.py @@ -421,7 +421,7 @@ def draw_keymaps(context, layout): rowsubsub.prop(spref, "filter_text", text="", icon='VIEWZOOM') if not filter_text: - # When the keyconfig defines it's own preferences. + # When the keyconfig defines its own preferences. kc_prefs = kc_active.preferences if kc_prefs is not None: box = col.box() diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 6d345e87d93..552f7eeb4f3 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -1187,6 +1187,7 @@ url_manual_mapping = ( ("bpy.ops.clip.set_scene_frames*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-scene-frames"), ("bpy.ops.curve.handle_type_set*", "modeling/curves/editing/control_points.html#bpy-ops-curve-handle-type-set"), ("bpy.ops.curve.spline_type_set*", "modeling/curves/editing/curve.html#bpy-ops-curve-spline-type-set"), + ("bpy.ops.file.unpack_libraries*", "files/blend/packed_data.html#bpy-ops-file-unpack-libraries"), ("bpy.ops.gpencil.move_to_layer*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-move-to-layer"), ("bpy.ops.gpencil.stroke_sample*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-sample"), ("bpy.ops.gpencil.stroke_smooth*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-smooth"), @@ -1297,6 +1298,7 @@ url_manual_mapping = ( ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), ("bpy.ops.curve.duplicate_move*", "modeling/curves/editing/curve.html#bpy-ops-curve-duplicate-move"), + ("bpy.ops.file.autopack_toggle*", "files/blend/packed_data.html#bpy-ops-file-autopack-toggle"), ("bpy.ops.fluid.bake_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-bake-particles"), ("bpy.ops.fluid.free_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-free-particles"), ("bpy.ops.gpencil.extrude_move*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-extrude-move"), @@ -1339,6 +1341,7 @@ url_manual_mapping = ( ("bpy.types.alphaundersequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"), ("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"), ("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"), + ("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"), ("bpy.types.compositornodecomb*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodecomb"), ("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"), ("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"), @@ -1401,6 +1404,7 @@ url_manual_mapping = ( ("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"), ("bpy.ops.curve.smooth_radius*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-radius"), ("bpy.ops.curve.smooth_weight*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-weight"), + ("bpy.ops.file.pack_libraries*", "files/blend/packed_data.html#bpy-ops-file-pack-libraries"), ("bpy.ops.font.change_spacing*", "modeling/texts/editing.html#bpy-ops-font-change-spacing"), ("bpy.ops.gpencil.stroke_flip*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-flip"), ("bpy.ops.gpencil.stroke_join*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-join"), @@ -1746,6 +1750,7 @@ url_manual_mapping = ( ("bpy.ops.clip.set_origin*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-origin"), ("bpy.ops.curve.subdivide*", "modeling/curves/editing/segments.html#bpy-ops-curve-subdivide"), ("bpy.ops.ed.undo_history*", "interface/undo_redo.html#bpy-ops-ed-undo-history"), + ("bpy.ops.file.unpack_all*", "files/blend/packed_data.html#bpy-ops-file-unpack-all"), ("bpy.ops.fluid.bake_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-bake-data"), ("bpy.ops.fluid.bake_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-bake-mesh"), ("bpy.ops.fluid.free_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-free-data"), @@ -1902,6 +1907,7 @@ url_manual_mapping = ( ("bpy.types.wipesequence*", "video_editing/sequencer/strips/transitions/wipe.html#bpy-types-wipesequence"), ("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"), ("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"), + ("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"), ("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"), ("bpy.ops.image.project*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-ops-image-project"), ("bpy.ops.image.replace*", "editors/image/editing.html#bpy-ops-image-replace"), diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index e3158118146..54cde1e1c04 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -235,7 +235,7 @@ def draw(layout, context, context_member, property_type, use_edit=True): assert(isinstance(rna_item, property_type)) - items = rna_item.items() + items = list(rna_item.items()) items.sort() # TODO: Allow/support adding new custom props to overrides. diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py index cb80529f0f3..192fc1a201f 100644 --- a/release/scripts/modules/sys_info.py +++ b/release/scripts/modules/sys_info.py @@ -23,11 +23,12 @@ def write_sysinfo(filepath): import sys + import platform import subprocess import bpy - import bgl + import gpu # pretty repr def prepr(v): @@ -63,7 +64,7 @@ def write_sysinfo(filepath): )) output.write("build date: %s, %s\n" % (prepr(bpy.app.build_date), prepr(bpy.app.build_time))) - output.write("platform: %s\n" % prepr(bpy.app.build_platform)) + output.write("platform: %s\n" % prepr(platform.platform())) output.write("binary path: %s\n" % prepr(bpy.app.binary_path)) output.write("build cflags: %s\n" % prepr(bpy.app.build_cflags)) output.write("build cxxflags: %s\n" % prepr(bpy.app.build_cxxflags)) @@ -189,46 +190,29 @@ def write_sysinfo(filepath): if bpy.app.background: output.write("\nOpenGL: missing, background mode\n") else: - output.write(title("OpenGL")) - version = bgl.glGetString(bgl.GL_RENDERER) - output.write("renderer:\t%r\n" % version) - output.write("vendor:\t\t%r\n" % (bgl.glGetString(bgl.GL_VENDOR))) - output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION))) + output.write(title("GPU")) + output.write("renderer:\t%r\n" % gpu.platform.renderer_get()) + output.write("vendor:\t\t%r\n" % gpu.platform.vendor_get()) + output.write("version:\t%r\n" % gpu.platform.version_get()) output.write("extensions:\n") - limit = bgl.Buffer(bgl.GL_INT, 1) - bgl.glGetIntegerv(bgl.GL_NUM_EXTENSIONS, limit) - - glext = [] - for i in range(limit[0]): - glext.append(bgl.glGetStringi(bgl.GL_EXTENSIONS, i)) - - glext = sorted(glext) + glext = sorted(gpu.capabilities.extensions_get()) for l in glext: output.write("\t%s\n" % l) - output.write(title("Implementation Dependent OpenGL Limits")) - bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_VERTICES, limit) - output.write("Maximum DrawElements Vertices:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_ELEMENTS_INDICES, limit) - output.write("Maximum DrawElements Indices:\t%d\n" % limit[0]) + output.write(title("Implementation Dependent GPU Limits")) + output.write("Maximum Batch Vertices:\t%d\n" % gpu.capabilities.max_batch_vertices_get()) + output.write("Maximum Batch Indices:\t%d\n" % gpu.capabilities.max_batch_indices_get()) output.write("\nGLSL:\n") - bgl.glGetIntegerv(bgl.GL_MAX_VARYING_FLOATS, limit) - output.write("Maximum Varying Floats:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_ATTRIBS, limit) - output.write("Maximum Vertex Attributes:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_UNIFORM_COMPONENTS, limit) - output.write("Maximum Vertex Uniform Components:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, limit) - output.write("Maximum Fragment Uniform Components:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, limit) - output.write("Maximum Vertex Image Units:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_TEXTURE_IMAGE_UNITS, limit) - output.write("Maximum Fragment Image Units:\t%d\n" % limit[0]) - bgl.glGetIntegerv(bgl.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, limit) - output.write("Maximum Pipeline Image Units:\t%d\n" % limit[0]) + output.write("Maximum Varying Floats:\t%d\n" % gpu.capabilities.max_varying_floats_get()) + output.write("Maximum Vertex Attributes:\t%d\n" % gpu.capabilities.max_vertex_attribs_get()) + output.write("Maximum Vertex Uniform Components:\t%d\n" % gpu.capabilities.max_uniforms_vert_get()) + output.write("Maximum Fragment Uniform Components:\t%d\n" % gpu.capabilities.max_uniforms_frag_get()) + output.write("Maximum Vertex Image Units:\t%d\n" % gpu.capabilities.max_textures_vert_get()) + output.write("Maximum Fragment Image Units:\t%d\n" % gpu.capabilities.max_textures_frag_get()) + output.write("Maximum Pipeline Image Units:\t%d\n" % gpu.capabilities.max_textures_get()) if bpy.app.build_options.cycles: import cycles diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 9404bfe327a..d63ae7a2745 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -278,15 +278,11 @@ def _template_items_uv_select_mode(params): else: return [ *_template_items_editmode_mesh_select_mode(params), + # Hack to prevent fall-through, when sync select isn't enabled (and the island button isn't visible). ("mesh.select_mode", {"type": 'FOUR', "value": 'PRESS'}, None), - ("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'}, - {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'EDGE')]}), - ("wm.context_set_enum", {"type": 'THREE', "value": 'PRESS'}, - {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'FACE')]}), - ("wm.context_set_enum", {"type": 'FOUR', "value": 'PRESS'}, - {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", 'ISLAND')]}), + *(("wm.context_set_enum", {"type": NUMBERS_1[i], "value": 'PRESS'}, + {"properties": [("data_path", 'tool_settings.uv_select_mode'), ("value", ty)]}) + for i, ty in enumerate(('VERTEX', 'EDGE', 'FACE', 'ISLAND'))) ] @@ -2009,8 +2005,7 @@ def km_file_browser_main(params): ) items.extend([ - ("file.execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, - {"properties": [("need_active", True)]}), + ("file.mouse_execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), # Both .execute and .select are needed here. The former only works if # there's a file operator (i.e. not in regular editor mode) but is # needed to load files. The latter makes selection work if there's no @@ -3382,6 +3377,11 @@ def km_grease_pencil_stroke_paint_mode(params): # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_paint.brush.size')]}), + # Increase/Decrease brush size + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 0.9)]}), + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 1.0 / 0.9)]}), # Draw delete menu op_menu("GPENCIL_MT_gpencil_draw_delete", {"type": 'X', "value": 'PRESS'}), # Animation menu @@ -3549,6 +3549,11 @@ def km_grease_pencil_stroke_sculpt_mode(params): # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_sculpt_paint.brush.size')]}), + # Increase/Decrease brush size + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 0.9)]}), + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 1.0 / 0.9)]}), # Copy ("gpencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), # Display @@ -3763,6 +3768,11 @@ def km_grease_pencil_stroke_weight_mode(params): # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.size')]}), + # Increase/Decrease brush size + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 0.9)]}), + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 1.0 / 0.9)]}), # Display *_grease_pencil_display(), # Keyframe menu @@ -3820,6 +3830,11 @@ def km_grease_pencil_stroke_vertex_mode(params): # Brush size ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_vertex_paint.brush.size')]}), + # Increase/Decrease brush size + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 0.9)]}), + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, + {"properties": [("scalar", 1.0 / 0.9)]}), # Display *_grease_pencil_display(), # Tools @@ -4470,8 +4485,7 @@ def km_sculpt(params): items.extend([ # Transfer Sculpt Mode (release to avoid conflict with grease pencil drawing). - ("object.transfer_mode", {"type": 'D', "value": 'RELEASE'}, - {"properties": [("use_eyedropper", False)]}), + ("object.transfer_mode", {"type": 'D', "value": 'RELEASE'}, None), # Brush strokes ("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'}, {"properties": [("mode", 'NORMAL')]}), @@ -5011,32 +5025,30 @@ def km_object_non_modal(params): {"properties": [("mode", 'VERTEX_PAINT'), ("toggle", True)]}), ("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, {"properties": [("mode", 'WEIGHT_PAINT'), ("toggle", True)]}), - ]) - elif params.use_pie_click_drag: - items.extend([ - ("object.mode_set", {"type": 'TAB', "value": 'CLICK'}, - {"properties": [("mode", 'EDIT'), ("toggle", True)]}), - op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'CLICK_DRAG'}), - ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None), - ]) - elif not params.use_v3d_tab_menu: - items.extend([ - ("object.mode_set", {"type": 'TAB', "value": 'PRESS'}, - {"properties": [("mode", 'EDIT'), ("toggle", True)]}), - ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None), - ]) - else: - # Swap Tab/Ctrl-Tab - items.extend([ - ("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, - {"properties": [("mode", 'EDIT'), ("toggle", True)]}), - op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'PRESS'}), - ]) - if params.legacy: - items.extend([ ("object.origin_set", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), ]) + else: + if params.use_pie_click_drag: + items.extend([ + ("object.mode_set", {"type": 'TAB', "value": 'CLICK'}, + {"properties": [("mode", 'EDIT'), ("toggle", True)]}), + op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'CLICK_DRAG'}), + ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None), + ]) + elif params.use_v3d_tab_menu: + # Swap Tab/Ctrl-Tab + items.extend([ + ("object.mode_set", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, + {"properties": [("mode", 'EDIT'), ("toggle", True)]}), + op_menu_pie("VIEW3D_MT_object_mode_pie", {"type": 'TAB', "value": 'PRESS'}), + ]) + else: + items.extend([ + ("object.mode_set", {"type": 'TAB', "value": 'PRESS'}, + {"properties": [("mode", 'EDIT'), ("toggle", True)]}), + ("view3d.object_mode_pie_or_toggle", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, None), + ]) return keymap 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 2880d56a005..dbf583149e3 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -1263,8 +1263,7 @@ def km_file_browser_main(params): ) items.extend([ - ("file.execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, - {"properties": [("need_active", True)]}), + ("file.mouse_execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("file.refresh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("file.select", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), ("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 0470f542c63..45d1ea98a8a 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -206,8 +206,8 @@ class CLIP_OT_filter_tracks(Operator): @classmethod def poll(cls, context): - space = context.space_data - return (space.type == 'CLIP_EDITOR') and space.clip + sc = context.space_data + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def execute(self, context): num_tracks = self._filter_values(context, self.track_threshold) @@ -221,8 +221,8 @@ class CLIP_OT_set_active_clip(Operator): @classmethod def poll(cls, context): - space = context.space_data - return space.type == 'CLIP_EDITOR' and space.clip + sc = context.space_data + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def execute(self, context): clip = context.space_data.clip @@ -268,8 +268,8 @@ class CLIP_OT_track_to_empty(Operator): @classmethod def poll(cls, context): - space = context.space_data - return space.type == 'CLIP_EDITOR' and space.clip + sc = context.space_data + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def execute(self, context): sc = context.space_data @@ -293,7 +293,7 @@ class CLIP_OT_bundles_to_mesh(Operator): @classmethod def poll(cls, context): sc = context.space_data - return (sc.type == 'CLIP_EDITOR') and sc.clip + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def execute(self, context): from bpy_extras.io_utils import unpack_list @@ -341,12 +341,8 @@ class CLIP_OT_delete_proxy(Operator): @classmethod def poll(cls, context): - if context.space_data.type != 'CLIP_EDITOR': - return False - sc = context.space_data - - return sc.clip + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def invoke(self, context, event): wm = context.window_manager @@ -424,12 +420,8 @@ class CLIP_OT_set_viewport_background(Operator): @classmethod def poll(cls, context): - if context.space_data.type != 'CLIP_EDITOR': - return False - sc = context.space_data - - return sc.clip + return sc and (sc.type == 'CLIP_EDITOR') and sc.clip def execute(self, context): sc = context.space_data @@ -563,13 +555,11 @@ class CLIP_OT_setup_tracking_scene(Operator): @classmethod def poll(cls, context): sc = context.space_data - - if sc.type != 'CLIP_EDITOR': - return False - - clip = sc.clip - - return clip and clip.tracking.reconstruction.is_valid + if sc and sc.type == 'CLIP_EDITOR': + clip = sc.clip + if clip and clip.tracking.reconstruction.is_valid: + return True + return False @staticmethod def _setupScene(context): @@ -1018,13 +1008,11 @@ class CLIP_OT_track_settings_as_default(Operator): @classmethod def poll(cls, context): sc = context.space_data - - if sc.type != 'CLIP_EDITOR': - return False - - clip = sc.clip - - return clip and clip.tracking.tracks.active + if sc and sc.type == 'CLIP_EDITOR': + clip = sc.clip + if clip and clip.tracking.tracks.active: + return True + return False def execute(self, context): sc = context.space_data @@ -1068,11 +1056,12 @@ class CLIP_OT_track_settings_to_track(Operator): @classmethod def poll(cls, context): - space = context.space_data - if space.type != 'CLIP_EDITOR': - return False - clip = space.clip - return clip and clip.tracking.tracks.active + sc = context.space_data + if sc and sc.type == 'CLIP_EDITOR': + clip = sc.clip + if clip and clip.tracking.tracks.active: + return True + return False def execute(self, context): space = context.space_data diff --git a/release/scripts/startup/bl_operators/constraint.py b/release/scripts/startup/bl_operators/constraint.py index 49fc6a04112..f18f3bb3a49 100644 --- a/release/scripts/startup/bl_operators/constraint.py +++ b/release/scripts/startup/bl_operators/constraint.py @@ -33,6 +33,11 @@ class CONSTRAINT_OT_add_target(Operator): bl_label = "Add Target" bl_options = {'UNDO', 'INTERNAL'} + @classmethod + def poll(cls, context): + constraint = getattr(context, "constraint", None) + return constraint + def execute(self, context): context.constraint.targets.new() return {'FINISHED'} @@ -46,6 +51,11 @@ class CONSTRAINT_OT_remove_target(Operator): index: IntProperty() + @classmethod + def poll(cls, context): + constraint = getattr(context, "constraint", None) + return constraint + def execute(self, context): tgts = context.constraint.targets tgts.remove(tgts[self.index]) @@ -58,6 +68,11 @@ class CONSTRAINT_OT_normalize_target_weights(Operator): bl_label = "Normalize Weights" bl_options = {'UNDO', 'INTERNAL'} + @classmethod + def poll(cls, context): + constraint = getattr(context, "constraint", None) + return constraint + def execute(self, context): tgts = context.constraint.targets total = sum(t.weight for t in tgts) diff --git a/release/scripts/startup/bl_operators/geometry_nodes.py b/release/scripts/startup/bl_operators/geometry_nodes.py index 0c7a2a01b7a..71ef89a066b 100644 --- a/release/scripts/startup/bl_operators/geometry_nodes.py +++ b/release/scripts/startup/bl_operators/geometry_nodes.py @@ -42,8 +42,8 @@ def geometry_node_group_empty_new(): def geometry_modifier_poll(context): ob = context.object - # Test object support for geometry node modifier (No volume, curve, or hair object support yet) - if not ob or ob.type not in {'MESH', 'POINTCLOUD'}: + # Test object support for geometry node modifier (No curve, or hair object support yet) + if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME'}: return False return True diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index e0d0fc1e145..6150789ea10 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -120,7 +120,7 @@ class NodeAddOperator: def poll(cls, context): space = context.space_data # needs active node editor and a tree to add nodes to - return ((space.type == 'NODE_EDITOR') and + return (space and (space.type == 'NODE_EDITOR') and space.edit_tree and not space.edit_tree.library) # Default execute simply adds a node @@ -265,7 +265,7 @@ class NODE_OT_collapse_hide_unused_toggle(Operator): def poll(cls, context): space = context.space_data # needs active node editor and a tree - return ((space.type == 'NODE_EDITOR') and + return (space and (space.type == 'NODE_EDITOR') and (space.edit_tree and not space.edit_tree.library)) def execute(self, context): @@ -296,7 +296,7 @@ class NODE_OT_tree_path_parent(Operator): def poll(cls, context): space = context.space_data # needs active node editor and a tree - return (space.type == 'NODE_EDITOR' and len(space.path) > 1) + return (space and (space.type == 'NODE_EDITOR') and len(space.path) > 1) def execute(self, context): space = context.space_data @@ -315,6 +315,8 @@ class NODE_OT_active_preview_toggle(Operator): @classmethod def poll(cls, context): space = context.space_data + if space is None: + return False if space.type != 'NODE_EDITOR': return False if space.edit_tree is None: diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 564a7b69957..dd84dfa2df8 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -99,6 +99,15 @@ class PREFERENCES_OT_copy_prev(Operator): version = bpy.app.version version_new = ((version[0] * 100) + version[1]) version_old = ((version[0] * 100) + version[1]) - 1 + + # Special case, remove when the version is > 3.0. + if version_new == 300: + version_new = 294 + version_old = 293 + else: + print("TODO: remove exception!") + # End special case. + # Ensure we only try to copy files from a point release. # The check below ensures the second numbers match. while (version_new % 100) // 10 == (version_old % 100) // 10: @@ -581,7 +590,7 @@ class PREFERENCES_OT_addon_install(Operator): name="Target Path", items=( ('DEFAULT', "Default", ""), - ('PREFS', "User Prefs", ""), + ('PREFS', "Preferences", ""), ), ) diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 29c17711c2a..6ba8750e9df 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -628,7 +628,7 @@ class LightMapPack(Operator): name="New Image", description=( "Assign new images for every mesh (only one if " - "shared tex space enabled)" + "Share Texture Space is enabled)" ), default=False, ) diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index ff5bcdb034f..0fa82e36d20 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -208,7 +208,8 @@ class VIEW3D_OT_transform_gizmo_set(Operator): @classmethod def poll(cls, context): - return context.area.type == 'VIEW_3D' + area = context.area + return area and (area.type == 'VIEW_3D') def execute(self, context): space_data = context.space_data diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index f3e116ca321..6452ad8465b 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -292,10 +292,15 @@ class BONE_PT_display_custom_shape(BoneButtonsPanel, Panel): sub = col.column() sub.active = bool(pchan and pchan.custom_shape) sub.separator() - sub.prop(pchan, "custom_shape_scale", text="Scale") + + sub.prop(pchan, "custom_shape_scale_xyz", text="Scale") + sub.prop(pchan, "custom_shape_translation", text="Translation") + sub.prop(pchan, "custom_shape_rotation_euler", text="Rotation") + sub.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="Override Transform") sub.prop(pchan, "use_custom_shape_bone_size") + sub.separator() sub.prop(bone, "show_wire", text="Wireframe") diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index 69720a6c54b..e71ea2f31a4 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -113,7 +113,8 @@ class GPENCIL_MT_layer_context_menu(Menu): layout.operator("gpencil.layer_merge", icon='SORT_ASC', text="Merge Down") layout.separator() - layout.menu("VIEW3D_MT_gpencil_copy_layer") + layout.operator("gpencil.layer_duplicate_object", text="Copy Layer to Selected").only_active=True + layout.operator("gpencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active=False class DATA_PT_gpencil_layers(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 766b82f8ba4..2e89ddcb1d4 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -407,7 +407,7 @@ class AnnotationDataPanel: bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): - if context.space_data.type not in {'VIEW_3D', 'TOPBAR'}: + if context.space_data.type not in {'VIEW_3D', 'TOPBAR', 'SEQUENCE_EDITOR'}: self.layout.prop(context.space_data, "show_annotation", text="") def draw(self, context): @@ -821,6 +821,12 @@ class GreasePencilLayerMasksPanel: col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="") col2.operator("gpencil.layer_mask_remove", icon='REMOVE', text="") + col2.separator() + + sub = col2.column(align=True) + sub.operator("gpencil.layer_mask_move", icon='TRIA_UP', text="").type = 'UP' + sub.operator("gpencil.layer_mask_move", icon='TRIA_DOWN', text="").type = 'DOWN' + class GreasePencilLayerRelationsPanel: @@ -851,6 +857,10 @@ class GreasePencilLayerRelationsPanel: col = layout.row(align=True) col.prop_search(gpl, "viewlayer_render", scene, "view_layers", text="View Layer") + col = layout.row(align=True) + # Only enable this property when a view layer is selected. + col.enabled = bool(gpl.viewlayer_render) + col.prop(gpl, "use_viewlayer_masks") class GreasePencilLayerDisplayPanel: diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index aca7ba3c5ad..217ec248764 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -286,19 +286,17 @@ class MATERIAL_PT_lineart(MaterialButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True mat = context.material lineart = mat.lineart layout.prop(lineart, "use_transparency") - if lineart.use_transparency: - - layout.label(text="Transparency Masks:") - - row = layout.row(align=True) - for i in range(8): - row.prop(lineart, "use_transparency_mask", text=str(i), index=i, toggle=True) + row = layout.row(align=True, heading="Masks") + row.active = lineart.use_transparency + for i in range(8): + row.prop(lineart, "use_transparency_mask", text=str(i), index=i, toggle=True) classes = ( diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 6a5c000116f..9d099ff2231 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -46,13 +46,19 @@ class GPENCIL_MT_material_context_menu(Menu): layout.separator() - layout.operator("object.material_slot_remove_unused") - layout.operator("gpencil.stroke_merge_material", text="Merge Similar") - - layout.separator() layout.operator("gpencil.material_to_vertex_color", text="Convert Materials to Vertex Color") layout.operator("gpencil.extract_palette_vertex", text="Extract Palette from Vertex Color") + layout.separator() + + layout.operator("gpencil.materials_copy_to_object", text="Copy Material to Selected").only_active = True + layout.operator("gpencil.materials_copy_to_object", text="Copy All Materials to Selected").only_active = False + + layout.separator() + + layout.operator("gpencil.stroke_merge_material", text="Merge Similar") + layout.operator("object.material_slot_remove_unused") + class GPENCIL_UL_matslots(UIList): def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 033e6196323..4ea1ec26738 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -329,7 +329,9 @@ class OBJECT_PT_lineart(ObjectButtonsPanel, Panel): row = layout.row(heading="Override Crease") row.prop(lineart, "use_crease_override", text="") - row.prop(lineart, "crease_threshold", slider=True, text="") + subrow = row.row() + subrow.active = lineart.use_crease_override + subrow.prop(lineart, "crease_threshold", slider=True, text="") class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 22ef0fe77dd..f3462dfb35d 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1225,7 +1225,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row = layout.row(align=True) row.prop(gp_settings, "fill_factor") row = layout.row(align=True) - row.prop(gp_settings, "fill_leak", text="Leak Size") + row.prop(gp_settings, "dilate") row = layout.row(align=True) row.prop(brush, "size", text="Thickness") layout.use_property_split = use_property_split_prev diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index a9f040db9b5..ae15fda2c69 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -1803,9 +1803,10 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): part = particle_get_settings(context) - col = layout.column() - col.prop(part.force_field_1, "type", text="Type 1") - basic_force_field_settings_ui(self, part.force_field_1) + if part.force_field_1: + col = layout.column() + col.prop(part.force_field_1, "type", text="Type 1") + basic_force_field_settings_ui(self, part.force_field_1) class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): @@ -1819,9 +1820,10 @@ class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): part = particle_get_settings(context) - col = layout.column() - col.prop(part.force_field_2, "type", text="Type 2") - basic_force_field_settings_ui(self, part.force_field_2) + if part.force_field_2: + col = layout.column() + col.prop(part.force_field_2, "type", text="Type 2") + basic_force_field_settings_ui(self, part.force_field_2) class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): @@ -1836,7 +1838,8 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): part = particle_get_settings(context) - basic_force_field_falloff_ui(self, part.force_field_1) + if part.force_field_1: + basic_force_field_falloff_ui(self, part.force_field_1) class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): @@ -1851,7 +1854,8 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): part = particle_get_settings(context) - basic_force_field_falloff_ui(self, part.force_field_2) + if part.force_field_2: + basic_force_field_falloff_ui(self, part.force_field_2) class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 7f55e4888cf..f13a808e324 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -79,7 +79,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): col = flow.column() - if obj.field.type == 'NONE': + if not obj.field or obj.field.type == 'NONE': col.operator("object.forcefield_toggle", text="Force Field", icon='FORCE_FORCE') else: col.operator("object.forcefield_toggle", text="Force Field", icon='X') diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index cd65980fc0d..3a97b104271 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -92,16 +92,15 @@ class INFO_MT_area(Menu): layout.separator() - layout.operator("screen.area_dupli", icon='WINDOW') - - layout.separator() - layout.operator("screen.screen_full_area") layout.operator( "screen.screen_full_area", - text="Toggle Fullscreen Area", - icon='FULLSCREEN_ENTER', - ).use_hide_panels = True + text="Toggle Fullscreen Area").use_hide_panels = True + layout.operator("screen.area_dupli") + + layout.separator() + + layout.operator("screen.area_close") class INFO_MT_context_menu(Menu): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index f6a03b4769c..e9bfe6cd4e2 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1398,8 +1398,8 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): box.template_image_stereo_3d(strip.stereo_3d_format) # Resolution. - col = layout.column(align=True) - col = col.box() + col = layout.box() + col = col.column(align=True) split = col.split(factor=0.5, align=False) split.alignment = 'RIGHT' split.label(text="Resolution") @@ -1409,6 +1409,14 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): split.label(text="%dx%d" % size, translate=False) else: split.label(text="None") + #FPS + if elem.orig_fps: + split = col.split(factor=0.5, align=False) + split.alignment = 'RIGHT' + split.label(text="FPS") + split.alignment = 'LEFT' + split.label(text="%.2f" % elem.orig_fps, translate=False) + class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): @@ -1453,7 +1461,7 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): if strip.scene_input == 'CAMERA': layout = layout.column(heading="Show") - layout.prop(strip, "use_grease_pencil", text="Grease Pencil") + layout.prop(strip, "use_annotations", text="Annotations") if scene: # Warning, this is not a good convention to follow. # Expose here because setting the alpha from the 'Render' menu is very inconvenient. diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 1e52142c85c..ce1c401b14b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -164,7 +164,7 @@ class _defs_annotate: gpl = context.active_annotation_layer if gpl is not None: layout.label(text="Annotation:") - if context.space_data.type == 'VIEW_3D': + if context.space_data.type in {'VIEW_3D', 'SEQUENCE_EDITOR'}: if region_type == 'TOOL_HEADER': sub = layout.split(align=True, factor=0.5) sub.ui_units_x = 6.5 @@ -206,14 +206,22 @@ class _defs_annotate: 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" and region_type != 'TOOL_HEADER': - layout.separator() + elif tool.idname == "builtin.annotate": props = tool.operator_properties("gpencil.annotate") - 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) + 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.separator() + 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): diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index adab0b0c88a..5e68896a2a7 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -504,8 +504,6 @@ class TOPBAR_MT_file_external_data(Menu): icon = 'CHECKBOX_HLT' if bpy.data.use_autopack else 'CHECKBOX_DEHLT' layout.operator("file.autopack_toggle", icon=icon) - layout.separator() - pack_all = layout.row() pack_all.operator("file.pack_all") pack_all.active = not bpy.data.use_autopack @@ -516,8 +514,16 @@ class TOPBAR_MT_file_external_data(Menu): layout.separator() + layout.operator("file.pack_libraries") + layout.operator("file.unpack_libraries") + + layout.separator() + layout.operator("file.make_paths_relative") layout.operator("file.make_paths_absolute") + + layout.separator() + layout.operator("file.report_missing_files") layout.operator("file.find_missing_files") diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 04b7a11bde1..de78b88c0f6 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -570,7 +570,7 @@ class USERPREF_PT_system_sound(SystemPanel, CenterAlignMixIn, Panel): layout.prop(system, "audio_device", expand=False) sub = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) - sub.active = system.audio_device not in {'NONE', 'Null'} + sub.active = system.audio_device not in {'NONE', 'None'} sub.prop(system, "audio_channels", text="Channels") sub.prop(system, "audio_mixing_buffer", text="Mixing Buffer") sub.prop(system, "audio_sample_rate", text="Sample Rate") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index bdc924e3197..ae18fc4fb76 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2314,6 +2314,7 @@ class VIEW3D_MT_object_animation(Menu): layout.operator("nla.bake", text="Bake Action...") layout.operator("gpencil.bake_mesh_animation", text="Bake Mesh to Grease Pencil...") + layout.operator("gpencil.bake_grease_pencil_animation", text="Bake Object Transform to Grease Pencil...") class VIEW3D_MT_object_rigid_body(Menu): @@ -4956,28 +4957,6 @@ class VIEW3D_MT_assign_material(Menu): icon='LAYER_ACTIVE' if mat == mat_active else 'BLANK1').material = mat.name -class VIEW3D_MT_gpencil_copy_layer(Menu): - bl_label = "Copy Layer to Object" - - def draw(self, context): - layout = self.layout - view_layer = context.view_layer - obact = context.active_object - gpl = context.active_gpencil_layer - - done = False - if gpl is not None: - for ob in view_layer.objects: - if ob.type == 'GPENCIL' and ob != obact: - layout.operator("gpencil.layer_duplicate_object", text=ob.name).object = ob.name - done = True - - if done is False: - layout.label(text="No destination object", icon='ERROR') - else: - layout.label(text="No layer to copy", icon='ERROR') - - class VIEW3D_MT_edit_gpencil(Menu): bl_label = "Grease Pencil" @@ -6191,6 +6170,12 @@ class VIEW3D_PT_overlay_geometry(Panel): sub.prop(overlay, "wireframe_opacity", text="Opacity") row = col.row(align=True) + + # These properties should be always available in the UI for all modes + # other than Object. + # Even when the Fade Inactive Geometry overlay is not affecting the + # current active object depending on its mode, it will always affect + # the rest of the scene. if context.mode != 'OBJECT': row.prop(overlay, "show_fade_inactive", text="") sub = row.row() @@ -7642,7 +7627,6 @@ classes = ( VIEW3D_MT_weight_gpencil, VIEW3D_MT_gpencil_animation, VIEW3D_MT_gpencil_simplify, - VIEW3D_MT_gpencil_copy_layer, VIEW3D_MT_gpencil_autoweights, VIEW3D_MT_gpencil_edit_context_menu, VIEW3D_MT_edit_curve, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index ab012a6f2ef..08d581bfa24 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1468,6 +1468,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel): row.prop(gp_settings, "show_fill_extend", text="", icon='GRID') col.separator() + col.prop(gp_settings, "fill_leak", text="Leak Size") + + col.separator() col.prop(gp_settings, "fill_simplify_level", text="Simplify") if gp_settings.fill_draw_mode != 'STROKE': col = layout.column(align=False, heading="Ignore Transparent") diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index 012febc7cc7..83151a3480c 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -44,6 +44,7 @@ ANIM_KS_LOCATION_ID = "Location" ANIM_KS_ROTATION_ID = "Rotation" ANIM_KS_SCALING_ID = "Scaling" ANIM_KS_LOC_ROT_SCALE_ID = "LocRotScale" +ANIM_KS_LOC_ROT_SCALE_CPROP_ID = "LocRotScaleCProp" ANIM_KS_AVAILABLE_ID = "Available" ANIM_KS_WHOLE_CHARACTER_ID = "WholeCharacter" ANIM_KS_WHOLE_CHARACTER_SELECTED_ID = "WholeCharacterSelected" @@ -159,6 +160,22 @@ class BUILTIN_KSI_LocRotScale(KeyingSetInfo): keyingsets_utils.RKS_GEN_scaling(self, context, ks, data) +# LocRotScaleCProp +class BUILTIN_KSI_LocRotScaleCProp(KeyingSetInfo): + """Key location/rotation/scale as well as custom properties""" + bl_idname = ANIM_KS_LOC_ROT_SCALE_CPROP_ID + bl_label = "Location, Rotation, Scale & Custom Properties" + + poll = keyingsets_utils.RKS_POLL_selected_items + iterator = keyingsets_utils.RKS_ITER_selected_item + + def generate(self, context, ks, data): + keyingsets_utils.RKS_GEN_location(self, context, ks, data) + keyingsets_utils.RKS_GEN_rotation(self, context, ks, data) + keyingsets_utils.RKS_GEN_scaling(self, context, ks, data) + keyingsets_utils.RKS_GEN_custom_props(self, context, ks, data) + + # RotScale class BUILTIN_KSI_RotScale(KeyingSetInfo): """Insert a keyframe on each of the rotation and scale channels""" @@ -350,7 +367,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo): bl_label = "Available" # poll - selected objects or selected object with animation data - def poll(ksi, context): + def poll(self, context): ob = context.active_object if ob: # TODO: this fails if one animation-less object is active, but many others are selected @@ -366,14 +383,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo): ############################### - -# All properties that are likely to get animated in a character rig -class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): - """Insert a keyframe for all properties that are likely to get animated in a character rig """ \ - """(useful when blocking out a shot)""" - bl_idname = ANIM_KS_WHOLE_CHARACTER_ID - bl_label = "Whole Character" - +class WholeCharacterMixin: # these prefixes should be avoided, as they are not really bones # that animators should be touching (or need to touch) badBonePrefixes = ( @@ -387,38 +397,37 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): ) # poll - pose-mode on active object only - def poll(ksi, context): + def poll(self, context): return ((context.active_object) and (context.active_object.pose) and (context.active_object.mode == 'POSE')) # iterator - all bones regardless of selection - def iterator(ksi, context, ks): + def iterator(self, context, ks): for bone in context.active_object.pose.bones: - if not bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes): - ksi.generate(context, ks, bone) + if not bone.name.startswith(self.badBonePrefixes): + self.generate(context, ks, bone) # generator - all unlocked bone transforms + custom properties - def generate(ksi, context, ks, bone): + def generate(self, context, ks, bone): # loc, rot, scale - only include unlocked ones if not bone.bone.use_connect: - ksi.doLoc(ks, bone) + self.doLoc(ks, bone) if bone.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}: - ksi.doRot4d(ks, bone) + self.doRot4d(ks, bone) else: - ksi.doRot3d(ks, bone) - ksi.doScale(ks, bone) + self.doRot3d(ks, bone) + self.doScale(ks, bone) # bbone properties? - ksi.doBBone(context, ks, bone) + self.doBBone(context, ks, bone) # custom props? - ksi.doCustomProps(ks, bone) - + self.doCustomProps(ks, bone) # ---------------- # helper to add some bone's property to the Keying Set - def addProp(ksi, ks, bone, prop, index=-1, use_groups=True): + def addProp(self, ks, bone, prop, index=-1, use_groups=True): # add the property name to the base path id_path = bone.path_from_id() id_block = bone.id_data @@ -439,16 +448,16 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # ---------------- # location properties - def doLoc(ksi, ks, bone): + def doLoc(self, ks, bone): if bone.lock_location == (False, False, False): - ksi.addProp(ks, bone, "location") + self.addProp(ks, bone, "location") else: for i in range(3): if not bone.lock_location[i]: - ksi.addProp(ks, bone, "location", i) + self.addProp(ks, bone, "location", i) # rotation properties - def doRot4d(ksi, ks, bone): + def doRot4d(self, ks, bone): # rotation mode affects the property used if bone.rotation_mode == 'QUATERNION': prop = "rotation_quaternion" @@ -459,40 +468,40 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): if bone.lock_rotations_4d: # can check individually if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w is False): - ksi.addProp(ks, bone, prop) + self.addProp(ks, bone, prop) else: if bone.lock_rotation_w is False: - ksi.addProp(ks, bone, prop, 0) # w = 0 + self.addProp(ks, bone, prop, 0) # w = 0 for i in range(3): if not bone.lock_rotation[i]: - ksi.addProp(ks, bone, prop, i + 1) # i + 1, since here x/y/z = 1,2,3, and w=0 + self.addProp(ks, bone, prop, i + 1) # i + 1, since here x/y/z = 1,2,3, and w=0 elif True not in bone.lock_rotation: # if axis-angle rotations get locked as eulers, then it's too messy to allow anything # other than all open unless we keyframe the whole lot - ksi.addProp(ks, bone, prop) + self.addProp(ks, bone, prop) - def doRot3d(ksi, ks, bone): + def doRot3d(self, ks, bone): if bone.lock_rotation == (False, False, False): - ksi.addProp(ks, bone, "rotation_euler") + self.addProp(ks, bone, "rotation_euler") else: for i in range(3): if not bone.lock_rotation[i]: - ksi.addProp(ks, bone, "rotation_euler", i) + self.addProp(ks, bone, "rotation_euler", i) # scale properties - def doScale(ksi, ks, bone): + def doScale(self, ks, bone): if bone.lock_scale == (0, 0, 0): - ksi.addProp(ks, bone, "scale") + self.addProp(ks, bone, "scale") else: for i in range(3): if not bone.lock_scale[i]: - ksi.addProp(ks, bone, "scale", i) + self.addProp(ks, bone, "scale", i) # ---------------- # bendy bone properties - def doBBone(ksi, context, ks, pchan): + def doBBone(self, context, ks, pchan): bone = pchan.bone # This check is crude, but is the best we can do for now @@ -500,12 +509,12 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # (and the bone is a control bone). This may lead to some # false positives... if bone.bbone_segments > 1: - keyingsets_utils.RKS_GEN_bendy_bones(ksi, context, ks, pchan) + keyingsets_utils.RKS_GEN_bendy_bones(self, context, ks, pchan) # ---------------- # custom properties - def doCustomProps(ksi, ks, bone): + def doCustomProps(self, ks, bone): prop_type_compat = {bpy.types.BoolProperty, bpy.types.IntProperty, @@ -528,39 +537,34 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # be converted to an FCurve-compatible value, so we can't keyframe it anyway. continue if rna_property.rna_type in prop_type_compat: - ksi.addProp(ks, bone, prop_path) + self.addProp(ks, bone, prop_path) elif prop_rna.is_animatable: - ksi.addProp(ks, bone, prop) + self.addProp(ks, bone, prop) -# All properties that are likely to get animated in a character rig, only selected bones. + +class BUILTIN_KSI_WholeCharacter(WholeCharacterMixin, KeyingSetInfo): + """Insert a keyframe for all properties that are likely to get animated in a character rig """ \ + """(useful when blocking out a shot)""" + bl_idname = ANIM_KS_WHOLE_CHARACTER_ID + bl_label = "Whole Character" -class BUILTIN_KSI_WholeCharacterSelected(KeyingSetInfo): +class BUILTIN_KSI_WholeCharacterSelected(WholeCharacterMixin, KeyingSetInfo): """Insert a keyframe for all properties that are likely to get animated in a character rig """ \ """(only selected bones)""" bl_idname = ANIM_KS_WHOLE_CHARACTER_SELECTED_ID bl_label = "Whole Character (Selected Bones Only)" # iterator - all bones regardless of selection - def iterator(ksi, context, ks): + def iterator(self, context, ks): # Use either the selected bones, or all of them if none are selected. bones = context.selected_pose_bones_from_active_object or context.active_object.pose.bones for bone in bones: - if bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes): + if bone.name.startswith(self.badBonePrefixes): continue - ksi.generate(context, ks, bone) - - # Poor man's subclassing. Blender breaks when we actually subclass BUILTIN_KSI_WholeCharacter. - poll = BUILTIN_KSI_WholeCharacter.poll - generate = BUILTIN_KSI_WholeCharacter.generate - addProp = BUILTIN_KSI_WholeCharacter.addProp - doLoc = BUILTIN_KSI_WholeCharacter.doLoc - doRot4d = BUILTIN_KSI_WholeCharacter.doRot4d - doRot3d = BUILTIN_KSI_WholeCharacter.doRot3d - doScale = BUILTIN_KSI_WholeCharacter.doScale - doBBone = BUILTIN_KSI_WholeCharacter.doBBone - doCustomProps = BUILTIN_KSI_WholeCharacter.doCustomProps + self.generate(context, ks, bone) + ############################### @@ -578,7 +582,7 @@ class BUILTIN_KSI_DeltaLocation(KeyingSetInfo): iterator = keyingsets_utils.RKS_ITER_selected_objects # generator - delta location channels only - def generate(ksi, context, ks, data): + def generate(self, context, ks, data): # get id-block and path info id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data) @@ -604,7 +608,7 @@ class BUILTIN_KSI_DeltaRotation(KeyingSetInfo): iterator = keyingsets_utils.RKS_ITER_selected_objects # generator - delta location channels only - def generate(ksi, context, ks, data): + def generate(self, context, ks, data): # get id-block and path info id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data) @@ -638,7 +642,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo): iterator = keyingsets_utils.RKS_ITER_selected_objects # generator - delta location channels only - def generate(ksi, context, ks, data): + def generate(self, context, ks, data): # get id-block and path info id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data) @@ -664,6 +668,7 @@ classes = ( BUILTIN_KSI_Scaling, BUILTIN_KSI_LocRot, BUILTIN_KSI_LocRotScale, + BUILTIN_KSI_LocRotScaleCProp, BUILTIN_KSI_LocScale, BUILTIN_KSI_RotScale, BUILTIN_KSI_DeltaLocation, diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index ab4d9353e1b..05c7ef756c7 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -472,14 +472,6 @@ texture_node_categories = [ ]), ] - -def not_implemented_node(idname): - NodeType = getattr(bpy.types, idname) - name = NodeType.bl_rna.name - label = "%s (mockup)" % name - return NodeItem(idname, label=label) - - geometry_node_categories = [ # Geometry Nodes GeometryNodeCategory("GEO_ATTRIBUTE", "Attribute", items=[ @@ -488,22 +480,31 @@ geometry_node_categories = [ NodeItem("GeometryNodeAttributeClamp"), NodeItem("GeometryNodeAttributeCompare"), NodeItem("GeometryNodeAttributeConvert"), + NodeItem("GeometryNodeAttributeCurveMap"), NodeItem("GeometryNodeAttributeFill"), NodeItem("GeometryNodeAttributeMix"), NodeItem("GeometryNodeAttributeProximity"), NodeItem("GeometryNodeAttributeColorRamp"), NodeItem("GeometryNodeAttributeVectorMath"), + NodeItem("GeometryNodeAttributeVectorRotate"), NodeItem("GeometryNodeAttributeSampleTexture"), NodeItem("GeometryNodeAttributeCombineXYZ"), NodeItem("GeometryNodeAttributeSeparateXYZ"), NodeItem("GeometryNodeAttributeRemove"), NodeItem("GeometryNodeAttributeMapRange"), + NodeItem("GeometryNodeAttributeTransfer"), ]), GeometryNodeCategory("GEO_COLOR", "Color", items=[ + NodeItem("ShaderNodeRGBCurve"), NodeItem("ShaderNodeValToRGB"), NodeItem("ShaderNodeSeparateRGB"), NodeItem("ShaderNodeCombineRGB"), ]), + GeometryNodeCategory("GEO_CURVE", "Curve", items=[ + NodeItem("GeometryNodeCurveToMesh"), + NodeItem("GeometryNodeCurveResample"), + NodeItem("GeometryNodeMeshToCurve"), + ]), GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[ NodeItem("GeometryNodeBoundBox"), NodeItem("GeometryNodeTransform"), @@ -516,8 +517,13 @@ geometry_node_categories = [ NodeItem("ShaderNodeValue"), NodeItem("FunctionNodeInputString"), NodeItem("FunctionNodeInputVector"), + NodeItem("GeometryNodeInputMaterial"), NodeItem("GeometryNodeIsViewport"), ]), + GeometryNodeCategory("GEO_MATERIAL", "Material", items=[ + NodeItem("GeometryNodeMaterialAssign"), + NodeItem("GeometryNodeMaterialReplace"), + ]), GeometryNodeCategory("GEO_MESH", "Mesh", items=[ NodeItem("GeometryNodeBoolean"), NodeItem("GeometryNodeTriangulate"), @@ -550,8 +556,10 @@ geometry_node_categories = [ NodeItem("ShaderNodeMath"), NodeItem("FunctionNodeBooleanMath"), NodeItem("FunctionNodeFloatCompare"), + NodeItem("GeometryNodeSwitch"), ]), GeometryNodeCategory("GEO_VECTOR", "Vector", items=[ + NodeItem("ShaderNodeVectorCurve"), NodeItem("ShaderNodeSeparateXYZ"), NodeItem("ShaderNodeCombineXYZ"), NodeItem("ShaderNodeVectorMath"), diff --git a/release/scripts/templates_py/gizmo_custom_geometry.py b/release/scripts/templates_py/gizmo_custom_geometry.py index 4105a99c633..701b1ac48ba 100644 --- a/release/scripts/templates_py/gizmo_custom_geometry.py +++ b/release/scripts/templates_py/gizmo_custom_geometry.py @@ -1,4 +1,4 @@ -# Example of a custom widget that defines it's own geometry. +# Example of a custom widget that defines its own geometry. # # Usage: Select a light in the 3D view and drag the arrow at it's rear # to change it's energy value. diff --git a/release/scripts/templates_py/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py index 1e185ecfe2b..16c6f6dbe22 100644 --- a/release/scripts/templates_py/operator_modal_draw.py +++ b/release/scripts/templates_py/operator_modal_draw.py @@ -1,5 +1,4 @@ import bpy -import bgl import blf import gpu from gpu_extras.batch import batch_for_shader @@ -17,16 +16,16 @@ def draw_callback_px(self, context): # 50% alpha, 2 pixel width line shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') - bgl.glEnable(bgl.GL_BLEND) - bgl.glLineWidth(2) + gpu.state.blend_set('ALPHA') + gpu.state.line_width_set(2.0) batch = batch_for_shader(shader, 'LINE_STRIP', {"pos": self.mouse_path}) shader.bind() shader.uniform_float("color", (0.0, 0.0, 0.0, 0.5)) batch.draw(shader) # restore opengl defaults - bgl.glLineWidth(1) - bgl.glDisable(bgl.GL_BLEND) + gpu.state.line_width_set(1.0) + gpu.state.blend_set('NONE') class ModalDrawOperator(bpy.types.Operator): diff --git a/release/windows/manifest/blender.exe.manifest.in b/release/windows/manifest/blender.exe.manifest.in index e73ddf3267b..b516efe24cb 100644 --- a/release/windows/manifest/blender.exe.manifest.in +++ b/release/windows/manifest/blender.exe.manifest.in @@ -13,12 +13,6 @@ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <!-- Windows 8 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <!-- Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!-- Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> </application> </compatibility> <dependency> |