From 5ad56c52ff3473756e687bbd052c5db73a4945c6 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 15 Oct 2024 11:02:22 +0200 Subject: [PATCH 1/3] Fix #128861: crash with Index Switch node when sliced virtual arrays are used It looks like this specific case never really worked. This wasn't found before, because in the large majority of cases, execution uses a more optimized code path instead of this general one. Pull Request: https://projects.blender.org/blender/blender/pulls/128993 --- source/blender/blenlib/intern/generic_virtual_array.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc index 64d4f52a3ed..ed9a78b820f 100644 --- a/source/blender/blenlib/intern/generic_virtual_array.cc +++ b/source/blender/blenlib/intern/generic_virtual_array.cc @@ -515,13 +515,15 @@ class GVArrayImpl_For_SlicedGVArray : public GVArrayImpl { { IndexMaskMemory memory; const IndexMask shifted_mask = mask.shift(offset_, memory); - varray_.materialize(shifted_mask, dst); + void *shifted_dst = POINTER_OFFSET(dst, -offset_ * type_->size()); + varray_.materialize(shifted_mask, shifted_dst); } void materialize_to_uninitialized(const IndexMask &mask, void *dst) const final { IndexMaskMemory memory; const IndexMask shifted_mask = mask.shift(offset_, memory); - varray_.materialize_to_uninitialized(shifted_mask, dst); + void *shifted_dst = POINTER_OFFSET(dst, -offset_ * type_->size()); + varray_.materialize_to_uninitialized(shifted_mask, shifted_dst); } void materialize_compressed(const IndexMask &mask, void *dst) const final { From f909bf2b132dd4719185089a05461ab747bddd68 Mon Sep 17 00:00:00 2001 From: Nika Kutsniashvili Date: Tue, 15 Oct 2024 11:35:57 +0200 Subject: [PATCH 2/3] Fix: GPv3: Add missing keymaps Adds missing keymaps in Grease Pencil modes. Two menus are also added which are needed to be called by keymaps to match GPv2. **Paint Mode** | Keymap | Operator | | -------- | -------- | | Shift I | Insert Blank Keyframe | | Alt I | Delete Animation (menu) | | Shift Delete | Delete Active Keyframes (all layers) | | Shift Ctrl M | Merge Layers | **Edit Mode** | Keymap | Operator | | -------- | -------- | | Shift I | Insert Blank Keyframe | | Alt I | Delete Animation (menu) | | Shift Ctrl M | Merge Layers | | Shift Q | Edit Lines (overlay toggle) | | Shift Alt Q | Edit Lines Multi-Frame (overlay toggle) | | Shift G | Vertex Groups | **Sculpt Mode** | Keymap | Operator | | -------- | -------- | | I | Animation (menu) | | Shift I | Insert Blank Keyframe | | Alt I | Delete Animation (menu) | | Shift Delete | Delete Active Keyframes (all layers) | | Shift Ctrl M | Merge Layers | | Shift Q | Edit Lines (overlay toggle) | | Shift Alt Q | Edit Lines Multi-Frame (overlay toggle) | | Y | Active Layer | | U | Active Material | | Ctrl C | Copy Strokes | | Ctrl V | Paste Strokes | | Shift Ctrl V | Paste Strokes (back) | | Shift Alt A | Automasking (menu) | **Weight Paint and Vertex Paint Modes** | Keymap | Operator | | -------- | -------- | | I | Animation (menu) | | Shift I | Insert Blank Keyframe | | Alt I | Delete Animation (menu) | | Shift Delete | Delete Active Keyframes (all layers) | | Shift Ctrl M | Merge Layers | | Shift Q | Edit Lines (overlay toggle) | | Shift Alt Q | Edit Lines Multi-Frame (overlay toggle) | | Y | Active Layer | Pull Request: https://projects.blender.org/blender/blender/pulls/128705 --- .../keyconfig/keymap_data/blender_default.py | 122 ++++++++++++++++++ .../bl_ui/properties_grease_pencil_common.py | 19 +++ scripts/startup/bl_ui/space_view3d.py | 18 +++ 3 files changed, 159 insertions(+) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index 82d50b5585c..dd8d13942ee 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -3726,6 +3726,8 @@ def km_grease_pencil_selection(params): # Select more/less ("grease_pencil.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("grease_pencil.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + # Select Similar + ("grease_pencil.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), ]) return keymap @@ -3757,6 +3759,19 @@ def km_grease_pencil_paint_mode(params): # Keyframe Menu op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}), + # Insert Blank Keyframe + ("grease_pencil.insert_blank_frame", {"type": 'I', "value": 'PRESS', "shift": True}, None), + + # Delete all active frames + ("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True}, + {"properties": [("type", "ALL_FRAMES")]}), + + # Delete Animation menu + op_menu("GREASE_PENCIL_MT_draw_delete", {"type": 'I', "value": 'PRESS', "alt": True}), + + # Merge Down + ("grease_pencil.layer_merge", {"type": 'M', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("mode", 'ACTIVE')]}), + op_tool_optional( ("grease_pencil.interpolate", {"type": 'E', "value": 'PRESS', "ctrl": True}, None), (op_tool_cycle, "builtin.interpolate"), params), @@ -3834,6 +3849,12 @@ def km_grease_pencil_edit_mode(params): # Keyframe Menu op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}), + # Insert Blank Keyframe + ("grease_pencil.insert_blank_frame", {"type": 'I', "value": 'PRESS', "shift": True}, None), + + # Delete Animation menu + op_menu("GREASE_PENCIL_MT_draw_delete", {"type": 'I', "value": 'PRESS', "alt": True}), + # Show/hide *_template_items_hide_reveal_actions("grease_pencil.layer_hide", "grease_pencil.layer_reveal"), @@ -3871,9 +3892,21 @@ def km_grease_pencil_edit_mode(params): # Move to layer op_menu("GREASE_PENCIL_MT_move_to_layer", {"type": 'M', "value": 'PRESS'}), + # Merge Down + ("grease_pencil.layer_merge", {"type": 'M', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("mode", 'ACTIVE')]}), + + # Edit Lines overlay + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), + # Context menu *_template_items_context_menu("VIEW3D_MT_greasepencil_edit_context_menu", params.context_menu_event), + # Vertex Groups + op_menu("VIEW3D_MT_greasepencil_vertex_group", {"type": 'G', "value": 'PRESS', "ctrl": True}), + # Reorder ("grease_pencil.reorder", {"type": 'UP_ARROW', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("direction", "TOP")]}), @@ -3931,6 +3964,44 @@ def km_grease_pencil_sculpt_mode(params): {"properties": [("data_path", "scene.tool_settings.use_gpencil_select_mask_stroke")]}), ("wm.context_toggle", {"type": 'THREE', "value": 'PRESS'}, {"properties": [("data_path", "scene.tool_settings.use_gpencil_select_mask_segment")]}), + + # Edit Lines overlay + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), + + # Keyframe Menu + op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}), + + # Insert Blank Keyframe + ("grease_pencil.insert_blank_frame", {"type": 'I', "value": 'PRESS', "shift": True}, None), + + # Delete Animation menu + op_menu("GREASE_PENCIL_MT_draw_delete", {"type": 'I', "value": 'PRESS', "alt": True}), + + # Delete all active frames + ("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True}, + {"properties": [("type", "ALL_FRAMES")]}), + + # Merge Down + ("grease_pencil.layer_merge", {"type": 'M', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("mode", 'ACTIVE')]}), + + # Copy/paste + ("grease_pencil.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), + ("grease_pencil.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("grease_pencil.paste", {"type": 'V', "value": 'PRESS', "shift": True, "ctrl": True}, + {"properties": [("paste_back", True)]}), + + # Active material + op_menu("VIEW3D_MT_greasepencil_material_active", {"type": 'U', "value": 'PRESS'}), + + # Active layer + op_menu("GREASE_PENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + + # Automasking menu + op_menu_pie("VIEW3D_MT_grease_pencil_sculpt_automasking_pie", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True}), + *_template_paint_radial_control("gpencil_sculpt_paint"), op_asset_shelf_popup( "VIEW3D_AST_brush_gpencil_sculpt", @@ -3969,6 +4040,32 @@ def km_grease_pencil_weight_paint(params): radial_control_properties("gpencil_weight_paint", "weight", "use_unified_weight")), # Toggle Add/Subtract for weight draw tool ("grease_pencil.weight_toggle_direction", {"type": 'D', "value": 'PRESS'}, None), + + # Edit Lines overlay + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), + + # Active layer + op_menu("GREASE_PENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + + # Merge Down + ("grease_pencil.layer_merge", {"type": 'M', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("mode", 'ACTIVE')]}), + + # Keyframe Menu + op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}), + + # Insert Blank Keyframe + ("grease_pencil.insert_blank_frame", {"type": 'I', "value": 'PRESS', "shift": True}, None), + + # Delete Animation menu + op_menu("GREASE_PENCIL_MT_draw_delete", {"type": 'I', "value": 'PRESS', "alt": True}), + + # Delete all active frames + ("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True}, + {"properties": [("type", "ALL_FRAMES")]}), + # Sample weight ("grease_pencil.weight_sample", {"type": 'X', "value": 'PRESS', "shift": True}, None), # Context menu @@ -4027,6 +4124,31 @@ def km_grease_pencil_vertex_paint(params): # Flip primary and secondary color ("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None), + # Edit Lines overlay + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_edit_lines')]}), + ("wm.context_toggle", {"type": 'Q', "value": 'PRESS', "shift": True, "alt": True}, + {"properties": [("data_path", 'space_data.overlay.use_gpencil_multiedit_line_only')]}), + + # Active layer + op_menu("GREASE_PENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + + # Merge Down + ("grease_pencil.layer_merge", {"type": 'M', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("mode", 'ACTIVE')]}), + + # Keyframe Menu + op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}), + + # Insert Blank Keyframe + ("grease_pencil.insert_blank_frame", {"type": 'I', "value": 'PRESS', "shift": True}, None), + + # Delete Animation menu + op_menu("GREASE_PENCIL_MT_draw_delete", {"type": 'I', "value": 'PRESS', "alt": True}), + + # Delete all active frames + ("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True}, + {"properties": [("type", "ALL_FRAMES")]}), + # Radial controls *_template_paint_radial_control("gpencil_vertex_paint"), # Context menu diff --git a/scripts/startup/bl_ui/properties_grease_pencil_common.py b/scripts/startup/bl_ui/properties_grease_pencil_common.py index ed6ba382948..06a015743da 100644 --- a/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -803,6 +803,23 @@ class GREASE_PENCIL_MT_snap_pie(Menu): pie.separator() +class GREASE_PENCIL_MT_draw_delete(Menu): + bl_label = "Delete" + + def draw(self, _context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.operator( + "grease_pencil.delete_frame", + text="Delete Active Keyframe (Active Layer)", + ).type = 'ACTIVE_FRAME' + layout.operator( + "grease_pencil.delete_frame", + text="Delete Active Keyframes (All Layers)", + ).type = 'ALL_FRAMES' + + classes = ( GPENCIL_UL_annotation_layer, GPENCIL_UL_layer, @@ -814,6 +831,8 @@ classes = ( GREASE_PENCIL_MT_snap, GREASE_PENCIL_MT_snap_pie, + GREASE_PENCIL_MT_draw_delete, + GreasePencilFlipTintColors, ) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index e9f253c1d75..0c63bd840d0 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -6043,6 +6043,23 @@ class VIEW3D_MT_sculpt_automasking_pie(Menu): pie.prop(sculpt, "use_automasking_view_normal", text="View Normal") +class VIEW3D_MT_grease_pencil_sculpt_automasking_pie(Menu): + bl_label = "Automasking" + + def draw(self, context): + layout = self.layout + pie = layout.menu_pie() + + tool_settings = context.tool_settings + sculpt = tool_settings.gpencil_sculpt + + pie.prop(sculpt, "use_automasking_stroke", text="Stroke") + pie.prop(sculpt, "use_automasking_layer_stroke", text="Layer") + pie.prop(sculpt, "use_automasking_material_stroke", text="Material") + pie.prop(sculpt, "use_automasking_layer_active", text="Active Layer") + pie.prop(sculpt, "use_automasking_material_active", text="Active Material") + + class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): bl_label = "Face Sets Edit" @@ -8934,6 +8951,7 @@ classes = ( VIEW3D_MT_proportional_editing_falloff_pie, VIEW3D_MT_sculpt_mask_edit_pie, VIEW3D_MT_sculpt_automasking_pie, + VIEW3D_MT_grease_pencil_sculpt_automasking_pie, VIEW3D_MT_wpaint_vgroup_lock_pie, VIEW3D_MT_sculpt_face_sets_edit_pie, VIEW3D_MT_sculpt_curves, From dfc58d282b62819e8b60e26bd1ff80102bf172ad Mon Sep 17 00:00:00 2001 From: Mark Stead Date: Tue, 15 Oct 2024 11:42:11 +0200 Subject: [PATCH 3/3] Fix #69731: Cycles: Vector Pass ignores animated FOV This PR fixes the motion vector values when using animation of the (perspective) camera focal length (and therefore changing the fov). Pull Request: https://projects.blender.org/blender/blender/pulls/127442 --- intern/cycles/scene/camera.cpp | 21 +++++++++++++-------- intern/cycles/scene/camera.h | 1 - 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index cae46786cee..ae95c9ad278 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -275,7 +275,6 @@ void Camera::update(Scene *scene) rastertocamera = screentocamera * rastertoscreen; full_rastertocamera = screentocamera * full_rastertoscreen; - cameratoraster = screentoraster * cameratoscreen; cameratoworld = matrix; screentoworld = cameratoworld * screentocamera; @@ -354,7 +353,6 @@ void Camera::update(Scene *scene) } if (need_motion == Scene::MOTION_PASS) { - /* TODO(sergey): Support perspective (zoom, fov) motion. */ if (camera_type == CAMERA_PANORAMA) { if (have_motion) { kcam->motion_pass_pre = transform_inverse(motion[0]); @@ -366,9 +364,19 @@ void Camera::update(Scene *scene) } } else { - if (have_motion) { - kcam->perspective_pre = cameratoraster * transform_inverse(motion[0]); - kcam->perspective_post = cameratoraster * transform_inverse(motion[motion.size() - 1]); + if (have_motion || fov != fov_pre || fov != fov_post) { + /* Note the values for perspective_pre/perspective_post calculated for MOTION_PASS are + * different to those calculated for MOTION_BLUR below, so the code has not been combined. + */ + ProjectionTransform cameratoscreen_pre = projection_perspective( + fov_pre, nearclip, farclip); + ProjectionTransform cameratoscreen_post = projection_perspective( + fov_post, nearclip, farclip); + ProjectionTransform cameratoraster_pre = screentoraster * cameratoscreen_pre; + ProjectionTransform cameratoraster_post = screentoraster * cameratoscreen_post; + kcam->perspective_pre = cameratoraster_pre * transform_inverse(motion[0]); + kcam->perspective_post = cameratoraster_post * + transform_inverse(motion[motion.size() - 1]); } else { kcam->perspective_pre = worldtoraster; @@ -385,9 +393,6 @@ void Camera::update(Scene *scene) /* TODO(sergey): Support other types of camera. */ if (use_perspective_motion && camera_type == CAMERA_PERSPECTIVE) { - /* TODO(sergey): Move to an utility function and de-duplicate with - * calculation above. - */ ProjectionTransform screentocamera_pre = projection_inverse( projection_perspective(fov_pre, nearclip, farclip)); ProjectionTransform screentocamera_post = projection_inverse( diff --git a/intern/cycles/scene/camera.h b/intern/cycles/scene/camera.h index 358ff798f3a..6343ff9bd4a 100644 --- a/intern/cycles/scene/camera.h +++ b/intern/cycles/scene/camera.h @@ -159,7 +159,6 @@ class Camera : public Node { Transform worldtocamera; ProjectionTransform rastertocamera; - ProjectionTransform cameratoraster; ProjectionTransform full_rastertocamera;