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; 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 ffcef4f22e5..dd63ab55a62 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -6046,6 +6046,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" @@ -8960,6 +8977,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, 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 {