diff options
Diffstat (limited to 'release')
32 files changed, 255 insertions, 204 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/lts/create_download_urls.py b/release/lts/create_download_urls.py index 0d0b2554d2a..db6c3479f83 100755 --- a/release/lts/create_download_urls.py +++ b/release/lts/create_download_urls.py @@ -29,10 +29,10 @@ class Version: def get_download_file_names(version: Version): - yield f"blender-{version}-linux64.tar.xz" - yield f"blender-{version}-macOS.dmg" - yield f"blender-{version}-windows64.msi" - yield f"blender-{version}-windows64.zip" + yield f"blender-{version}-linux-x86_64.tar.xz" + yield f"blender-{version}-darwin-x86_64.dmg" + yield f"blender-{version}-windows-amd64.msi" + yield f"blender-{version}-windows-amd64.zip" def get_download_url(version: Version, file_name: str) -> str: diff --git a/release/scripts/addons b/release/scripts/addons -Subproject af6356139616749c952ff5dfc6bf6dfa668e332 +Subproject bb16aba5bd3873794eefe167497118b6063b9a8 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib -Subproject 8970953d4a8a4ea3bf77c66370c817ed0cf1308 +Subproject 7d78c8a63f2f4b146f9327ddc0d567a5921b94e 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_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_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_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index b6fda8911cc..7e2d09efcd4 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -305,7 +305,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodealignrotationtovector*", "modeling/geometry_nodes/point/align_rotation_to_vector.html#bpy-types-geometrynodealignrotationtovector"), ("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"), ("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"), - ("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/lineart.html#bpy-types-objectlineart-use-crease-override"), + ("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-crease-override"), ("bpy.types.rendersettings.preview_pixel_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-preview-pixel-size"), ("bpy.types.rendersettings.use_crop_to_border*", "render/output/properties/dimensions.html#bpy-types-rendersettings-use-crop-to-border"), ("bpy.types.rendersettings.use_file_extension*", "render/output/properties/output.html#bpy-types-rendersettings-use-file-extension"), @@ -449,7 +449,7 @@ url_manual_mapping = ( ("bpy.types.nodesocketinterface*.max_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-max-value"), ("bpy.types.nodesocketinterface*.min_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-min-value"), ("bpy.types.nodesocketinterface.hide_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-hide-value"), - ("bpy.types.objectlineart.crease_threshold*", "scene_layout/object/properties/lineart.html#bpy-types-objectlineart-crease-threshold"), + ("bpy.types.objectlineart.crease_threshold*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-crease-threshold"), ("bpy.types.rendersettings.use_compositing*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-compositing"), ("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"), ("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"), @@ -487,6 +487,7 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), + ("bpy.types.geometrynodeattributemaprange*", "modeling/geometry_nodes/attribute/attribute_map_range.html#bpy-types-geometrynodeattributemaprange"), ("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"), ("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"), ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), @@ -947,7 +948,7 @@ url_manual_mapping = ( ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), ("bpy.types.imagesequence.use_flip*", "video_editing/sequencer/sidebar/strip.html#bpy-types-imagesequence-use-flip"), ("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"), - ("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/lineart.html#bpy-types-lineartgpencilmodifier"), + ("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier"), ("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"), ("bpy.types.objectsolverconstraint*", "animation/constraints/motion_tracking/object_solver.html#bpy-types-objectsolverconstraint"), ("bpy.types.opacitygpencilmodifier*", "grease_pencil/modifiers/color/opacity.html#bpy-types-opacitygpencilmodifier"), @@ -1110,6 +1111,7 @@ url_manual_mapping = ( ("bpy.types.ffmpegsettings.audio*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio"), ("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"), ("bpy.types.gaussianblursequence*", "video_editing/sequencer/strips/effects/blur.html#bpy-types-gaussianblursequence"), + ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/bounding_box.html#bpy-types-geometrynodeboundbox"), ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh_primitives/cone.html#bpy-types-geometrynodemeshcone"), ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh_primitives/cube.html#bpy-types-geometrynodemeshcube"), ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh_primitives/grid.html#bpy-types-geometrynodemeshgrid"), @@ -1152,6 +1154,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"), @@ -1219,7 +1222,7 @@ url_manual_mapping = ( ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"), ("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera"), ("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"), - ("bpy.types.objectlineart.usage*", "scene_layout/object/properties/lineart.html#bpy-types-objectlineart-usage"), + ("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"), ("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"), ("bpy.types.poseboneconstraints*", "animation/armatures/posing/bone_constraints/index.html#bpy-types-poseboneconstraints"), ("bpy.types.rigidbodyconstraint*", "physics/rigid_body/constraints/index.html#bpy-types-rigidbodyconstraint"), @@ -1260,6 +1263,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"), @@ -1297,6 +1301,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"), @@ -1358,6 +1363,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"), @@ -1453,7 +1459,7 @@ url_manual_mapping = ( ("bpy.types.viewlayer.use_sky*", "render/layers/introduction.html#bpy-types-viewlayer-use-sky"), ("bpy.types.wireframemodifier*", "modeling/modifiers/generate/wireframe.html#bpy-types-wireframemodifier"), ("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"), - ("bpy.ops.anim.channels_move*", "editors/nla/editing.html#bpy-ops-anim-channels-move"), + ("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"), ("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"), ("bpy.ops.clip.filter_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-filter-tracks"), ("bpy.ops.clip.select_circle*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-circle"), @@ -1691,6 +1697,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"), @@ -1749,7 +1756,7 @@ url_manual_mapping = ( ("bpy.types.nlastrip.name*", "editors/nla/sidebar.html#bpy-types-nlastrip-name"), ("bpy.types.nodesmodifier*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier"), ("bpy.types.object.parent*", "scene_layout/object/editing/parent.html#bpy-types-object-parent"), - ("bpy.types.objectlineart*", "scene_layout/object/properties/lineart.html#bpy-types-objectlineart"), + ("bpy.types.objectlineart*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart"), ("bpy.types.oceanmodifier*", "modeling/modifiers/physics/ocean.html#bpy-types-oceanmodifier"), ("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"), ("bpy.types.scene.gravity*", "physics/forces/gravity.html#bpy-types-scene-gravity"), @@ -1845,6 +1852,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.material.copy*", "render/materials/assignment.html#bpy-ops-material-copy"), 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..9bccc69d41f 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 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/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 7547184dc04..3969386bad7 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_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 c1d60a127d2..3064b33c7f7 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -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: 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/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_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..df004b21077 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -4956,28 +4956,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" @@ -7642,7 +7620,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..96c825c5285 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -488,22 +488,29 @@ 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("ShaderNodeValToRGB"), NodeItem("ShaderNodeSeparateRGB"), NodeItem("ShaderNodeCombineRGB"), ]), + GeometryNodeCategory("GEO_CURVE", "Curve", items=[ + NodeItem("GeometryNodeCurveToMesh"), + NodeItem("GeometryNodeCurveResample"), + ]), GeometryNodeCategory("GEO_GEOMETRY", "Geometry", items=[ NodeItem("GeometryNodeBoundBox"), NodeItem("GeometryNodeTransform"), @@ -550,6 +557,7 @@ geometry_node_categories = [ NodeItem("ShaderNodeMath"), NodeItem("FunctionNodeBooleanMath"), NodeItem("FunctionNodeFloatCompare"), + NodeItem("GeometryNodeSwitch"), ]), GeometryNodeCategory("GEO_VECTOR", "Vector", items=[ NodeItem("ShaderNodeSeparateXYZ"), 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): |