From e8684eff301d09e25b4e7ef6221a5289661da2e3 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Mon, 30 Aug 2021 17:04:02 +0200 Subject: Fix T91056: GPencil merge layers doesn't preseve Keyframe type. Now if the frame does not exist in destination layer, the frame type of merge layer is used. For existing frames in destination layer, the existing type is not changed. --- source/blender/editors/gpencil/gpencil_data.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 8baac26bed3..a77d3bee025 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1347,6 +1347,8 @@ static int gpencil_merge_layer_exec(bContext *C, wmOperator *op) bGPDframe *gpf_dst = BLI_ghash_lookup(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum)); if (!gpf_dst) { gpf_dst = BKE_gpencil_layer_frame_get(gpl_dst, gpf_src->framenum, GP_GETFRAME_ADD_COPY); + /* Use same frame type. */ + gpf_dst->key_type = gpf_src->key_type; BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum), gpf_dst); } } -- cgit v1.2.3 From 0a8f53a7b847d9c8bdcefc025de70fd2608012b7 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 30 Aug 2021 20:56:37 +1000 Subject: Context: add "active_sequence_strip" context member This is an alternative to context.scene.sequence_editor.active_strip which could be verbose, especially with additional None checks. Part of fix for T90723, extracted from D12297. --- source/blender/editors/screen/screen_context.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index b0181de96a0..390d1bdf428 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -56,6 +56,7 @@ #include "ED_armature.h" #include "ED_gpencil.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" #include "UI_interface.h" @@ -91,6 +92,7 @@ const char *screen_context_dir[] = { "image_paint_object", "particle_edit_object", "pose_object", + "active_sequence_strip", "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ @@ -603,6 +605,18 @@ static eContextResult screen_ctx_pose_object(const bContext *C, bContextDataResu } return CTX_RESULT_OK; } +static eContextResult screen_ctx_active_sequence_strip(const bContext *C, + bContextDataResult *result) +{ + wmWindow *win = CTX_wm_window(C); + Scene *scene = WM_window_get_active_scene(win); + Sequence *seq = SEQ_select_active_get(scene); + if (seq) { + CTX_data_pointer_set(result, &scene->id, &RNA_Sequence, seq); + return CTX_RESULT_OK; + } + return CTX_RESULT_NO_DATA; +} static eContextResult screen_ctx_sequences(const bContext *C, bContextDataResult *result) { wmWindow *win = CTX_wm_window(C); @@ -1097,6 +1111,7 @@ static void ensure_ed_screen_context_functions(void) register_context_function("image_paint_object", screen_ctx_image_paint_object); register_context_function("particle_edit_object", screen_ctx_particle_edit_object); register_context_function("pose_object", screen_ctx_pose_object); + register_context_function("active_sequence_strip", screen_ctx_active_sequence_strip); register_context_function("sequences", screen_ctx_sequences); register_context_function("selected_sequences", screen_ctx_selected_sequences); register_context_function("selected_editable_sequences", screen_ctx_selected_editable_sequences); -- cgit v1.2.3 From aabe6e3b457f1d4f1b860ed510bf2630a818465e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 11:46:46 +1000 Subject: Context: add "active_nla_track" & "active_nla_strip" context members Selection was already accessible but not active. Add utility functions: - ANIM_nla_context_track to access the active track, following the convention of ANIM_nla_context_strip. - ANIM_nla_context_*_ptr versions of these functions, needed to for creating context members to access the ID pointer. Part of fix for T90723. --- source/blender/editors/include/ED_anim_api.h | 5 +++++ source/blender/editors/screen/screen_context.c | 24 +++++++++++++++++++++++- source/blender/editors/space_nla/nla_buttons.c | 23 ++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 75c02082bd3..8b954b0fe69 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -678,6 +678,11 @@ void ANIM_draw_framerange(struct Scene *scene, struct View2D *v2d); /* ------------- UI Panel Drawing -------------- */ + +bool ANIM_nla_context_track_ptr(const struct bContext *C, struct PointerRNA *r_ptr); +bool ANIM_nla_context_strip_ptr(const struct bContext *C, struct PointerRNA *r_ptr); + +struct NlaTrack *ANIM_nla_context_track(const struct bContext *C); struct NlaStrip *ANIM_nla_context_strip(const struct bContext *C); struct FCurve *ANIM_graph_context_fcurve(const struct bContext *C); diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 390d1bdf428..6eb404cb801 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -96,7 +96,9 @@ const char *screen_context_dir[] = { "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ - "selected_nla_strips", /* nla editor */ + "active_nla_track", + "active_nla_strip", + "selected_nla_strips", /* nla editor */ "gpencil_data", "gpencil_data_owner", /* grease pencil data */ "annotation_data", @@ -664,6 +666,24 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, } return CTX_RESULT_NO_DATA; } +static eContextResult screen_ctx_active_nla_track(const bContext *C, bContextDataResult *result) +{ + PointerRNA ptr; + if (ANIM_nla_context_track_ptr(C, &ptr)) { + CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + return CTX_RESULT_OK; + } + return CTX_RESULT_NO_DATA; +} +static eContextResult screen_ctx_active_nla_strip(const bContext *C, bContextDataResult *result) +{ + PointerRNA ptr; + if (ANIM_nla_context_strip_ptr(C, &ptr)) { + CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + return CTX_RESULT_OK; + } + return CTX_RESULT_NO_DATA; +} static eContextResult screen_ctx_selected_nla_strips(const bContext *C, bContextDataResult *result) { bAnimContext ac; @@ -1115,6 +1135,8 @@ static void ensure_ed_screen_context_functions(void) register_context_function("sequences", screen_ctx_sequences); register_context_function("selected_sequences", screen_ctx_selected_sequences); register_context_function("selected_editable_sequences", screen_ctx_selected_editable_sequences); + register_context_function("active_nla_track", screen_ctx_active_nla_track); + register_context_function("active_nla_strip", screen_ctx_active_nla_strip); register_context_function("selected_nla_strips", screen_ctx_selected_nla_strips); register_context_function("gpencil_data", screen_ctx_gpencil_data); register_context_function("gpencil_data_owner", screen_ctx_gpencil_data_owner); diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index d019573bf93..215e865d194 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -185,10 +185,31 @@ bool nla_panel_context(const bContext *C, return (found != 0); } +bool ANIM_nla_context_track_ptr(const bContext *C, PointerRNA *r_ptr) +{ + return nla_panel_context(C, NULL, r_ptr, NULL); +} + +bool ANIM_nla_context_strip_ptr(const bContext *C, PointerRNA *r_ptr) +{ + return nla_panel_context(C, NULL, NULL, r_ptr); +} + +NlaTrack *ANIM_nla_context_track(const bContext *C) +{ + PointerRNA track_ptr; + if (!ANIM_nla_context_track_ptr(C, &track_ptr)) { + return NULL; + } + NlaTrack *track = track_ptr.data; + + return track; +} + NlaStrip *ANIM_nla_context_strip(const bContext *C) { PointerRNA strip_ptr; - if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) { + if (!ANIM_nla_context_strip_ptr(C, &strip_ptr)) { return NULL; } NlaStrip *strip = strip_ptr.data; -- cgit v1.2.3 From 3e4d720ae4836783db978b0a378e97b47dcaca87 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 11:46:47 +1000 Subject: Fix logical error resolving RNA paths Only append RNA_path_from_ID_to_struct to context attributes if those paths resolve to ID types. Also simplify creating RNA paths by adding utility functions: - WM_context_path_resolve_property_full - WM_context_path_resolve_full Part of fix for T90723. --- .../editors/interface/interface_context_menu.c | 70 ++++++++-------------- 1 file changed, 25 insertions(+), 45 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index b953d88c896..e89b8dc7bd7 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -70,26 +70,12 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but) /* If this returns null, we won't be able to bind shortcuts to these RNA properties. * Support can be added at #wm_context_member_from_ptr. */ - const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin); - if (member_id == NULL) { + char *final_data_path = WM_context_path_resolve_property_full( + C, &but->rnapoin, but->rnaprop, -1); + if (final_data_path == NULL) { return NULL; } - const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin); - const char *member_id_data_path = member_id; - - if (data_path) { - member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path); - MEM_freeN((void *)data_path); - } - - const char *prop_id = RNA_property_identifier(but->rnaprop); - const char *final_data_path = BLI_sprintfN("%s.%s", member_id_data_path, prop_id); - - if (member_id != member_id_data_path) { - MEM_freeN((void *)member_id_data_path); - } - /* Create ID property of data path, to pass to the operator. */ const IDPropertyTemplate val = {0}; IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__); @@ -329,10 +315,24 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but) { - return (but->optype || - (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) && - (WM_context_member_from_ptr(C, &but->rnapoin) != NULL)) || - UI_but_menutype_get(but)); + bool result = false; + if (but->optype) { + result = true; + } + else if (but->rnaprop) { + if (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) { + char *data_path = WM_context_path_resolve_full(C, &but->rnapoin); + if (data_path != NULL) { + MEM_freeN(data_path); + result = true; + } + } + } + else if (UI_but_menutype_get(but)) { + result = true; + } + + return result; } static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um) @@ -343,21 +343,11 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu * &um->items, but->optype, prop, but->opcontext); } if (but->rnaprop) { - const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin); - const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin); - const char *member_id_data_path = member_id; - if (data_path) { - member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path); - } + char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); const char *prop_id = RNA_property_identifier(but->rnaprop); bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop( &um->items, member_id_data_path, prop_id, but->rnaindex); - if (data_path) { - MEM_freeN((void *)data_path); - } - if (member_id != member_id_data_path) { - MEM_freeN((void *)member_id_data_path); - } + MEM_freeN(member_id_data_path); return umi; } @@ -412,21 +402,11 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um) } else if (but->rnaprop) { /* NOTE: 'member_id' may be a path. */ - const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin); - const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin); - const char *member_id_data_path = member_id; - if (data_path) { - member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path); - } + char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin); const char *prop_id = RNA_property_identifier(but->rnaprop); /* NOTE: ignore 'drawstr', use property idname always. */ ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex); - if (data_path) { - MEM_freeN((void *)data_path); - } - if (member_id != member_id_data_path) { - MEM_freeN((void *)member_id_data_path); - } + MEM_freeN(member_id_data_path); } else if ((mt = UI_but_menutype_get(but))) { ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt); -- cgit v1.2.3 From ea575744b8c9badb7f9b56fba625adb059ff3b5c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 12:30:45 +1000 Subject: Fix assigning shortcuts that include array indices Assigning a shortcut to bone layers for example, raised a Python exception when used. --- source/blender/editors/interface/interface_context_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index e89b8dc7bd7..bb9e813ea50 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -71,7 +71,7 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but) /* If this returns null, we won't be able to bind shortcuts to these RNA properties. * Support can be added at #wm_context_member_from_ptr. */ char *final_data_path = WM_context_path_resolve_property_full( - C, &but->rnapoin, but->rnaprop, -1); + C, &but->rnapoin, but->rnaprop, but->rnaindex); if (final_data_path == NULL) { return NULL; } -- cgit v1.2.3 From c758b87c5e1dbad174779d69340ad1983a94198c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 12:45:45 +1000 Subject: Cleanup: add CTX_data_pointer_set_ptr & CTX_data_list_add_ptr Many callers expanded a PointerRNA argument, so add a version of these functions that takes a PointerRNA. --- source/blender/editors/include/ED_anim_api.h | 1 - source/blender/editors/screen/screen_context.c | 8 ++++---- source/blender/editors/space_buttons/buttons_context.c | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 8b954b0fe69..6a0a42ee77b 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -678,7 +678,6 @@ void ANIM_draw_framerange(struct Scene *scene, struct View2D *v2d); /* ------------- UI Panel Drawing -------------- */ - bool ANIM_nla_context_track_ptr(const struct bContext *C, struct PointerRNA *r_ptr); bool ANIM_nla_context_strip_ptr(const struct bContext *C, struct PointerRNA *r_ptr); diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 6eb404cb801..13c338efdec 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -670,7 +670,7 @@ static eContextResult screen_ctx_active_nla_track(const bContext *C, bContextDat { PointerRNA ptr; if (ANIM_nla_context_track_ptr(C, &ptr)) { - CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + CTX_data_pointer_set_ptr(result, &ptr); return CTX_RESULT_OK; } return CTX_RESULT_NO_DATA; @@ -679,7 +679,7 @@ static eContextResult screen_ctx_active_nla_strip(const bContext *C, bContextDat { PointerRNA ptr; if (ANIM_nla_context_strip_ptr(C, &ptr)) { - CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + CTX_data_pointer_set_ptr(result, &ptr); return CTX_RESULT_OK; } return CTX_RESULT_NO_DATA; @@ -741,7 +741,7 @@ static eContextResult screen_ctx_gpencil_data_owner(const bContext *C, bContextD bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(area, obact, &ptr); if (gpd_ptr) { - CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + CTX_data_pointer_set_ptr(result, &ptr); return CTX_RESULT_OK; } return CTX_RESULT_NO_DATA; @@ -773,7 +773,7 @@ static eContextResult screen_ctx_annotation_data_owner(const bContext *C, bGPdata **gpd_ptr = ED_annotation_data_get_pointers_direct((ID *)screen, area, scene, &ptr); if (gpd_ptr) { - CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); + CTX_data_pointer_set_ptr(result, &ptr); return CTX_RESULT_OK; } return CTX_RESULT_NO_DATA; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index bf855db07e9..91b0677ebaa 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -72,7 +72,7 @@ static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, S PointerRNA *ptr = &path->ptr[i]; if (RNA_struct_is_a(ptr->type, type)) { - CTX_data_pointer_set(result, ptr->owner_id, ptr->type, ptr->data); + CTX_data_pointer_set_ptr(result, ptr); return CTX_RESULT_OK; } } @@ -1003,7 +1003,7 @@ int /*eContextResult*/ buttons_context(const bContext *C, if (ct->user && ct->user->ptr.data) { ButsTextureUser *user = ct->user; - CTX_data_pointer_set(result, user->ptr.owner_id, user->ptr.type, user->ptr.data); + CTX_data_pointer_set_ptr(result, &user->ptr); } return CTX_RESULT_OK; @@ -1092,7 +1092,7 @@ int /*eContextResult*/ buttons_context(const bContext *C, PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSettings); if (ptr && ptr->data) { - CTX_data_pointer_set(result, ptr->owner_id, &RNA_ParticleSettings, ptr->data); + CTX_data_pointer_set_ptr(result, ptr); return CTX_RESULT_OK; } -- cgit v1.2.3 From fa4f9292e16ce6a9253164ea731870c6d0161848 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 16:29:59 +1000 Subject: Transform: avoid passing the context to extended orientation functions This makes it possible to calculate orientation from functions that don't have the context. --- source/blender/editors/include/ED_transform.h | 15 ++++--- source/blender/editors/mesh/editmesh_select.c | 11 ++++- source/blender/editors/space_view3d/view3d_edit.c | 3 +- .../blender/editors/transform/transform_gizmo_3d.c | 2 +- source/blender/editors/transform/transform_mode.c | 12 +++++- .../editors/transform/transform_orientations.c | 50 +++++++++++----------- .../editors/transform/transform_orientations.h | 3 +- 7 files changed, 57 insertions(+), 39 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 69ac48d842f..bedd0e2fa35 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -109,7 +109,8 @@ bool BIF_createTransformOrientation(struct bContext *C, const bool overwrite); void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *target); -void ED_getTransformOrientationMatrix(const struct bContext *C, +void ED_getTransformOrientationMatrix(struct ViewLayer *view_layer, + const struct View3D *v3d, struct Object *ob, struct Object *obedit, const short around, @@ -145,15 +146,15 @@ void Transform_Properties(struct wmOperatorType *ot, int flags); /* *** transform_orientations.c *** */ void ED_transform_calc_orientation_from_type(const struct bContext *C, float r_mat[3][3]); -short ED_transform_calc_orientation_from_type_ex(const struct bContext *C, - float r_mat[3][3], - /* extra args */ - struct Scene *scene, - struct RegionView3D *rv3d, +short ED_transform_calc_orientation_from_type_ex(const struct Scene *scene, + struct ViewLayer *view_layer, + const struct View3D *v3d, + const struct RegionView3D *rv3d, struct Object *ob, struct Object *obedit, const short orientation_index, - const int pivot_point); + const int pivot_point, + float r_mat[3][3]); /* transform gizmos */ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 8e38d41f971..2fcf8fa6f8f 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -4871,8 +4871,15 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op) float axis_mat[3][3]; /* 3D view variables may be NULL, (no need to check in poll function). */ - ED_transform_calc_orientation_from_type_ex( - C, axis_mat, scene, CTX_wm_region_view3d(C), obedit, obedit, orientation, V3D_AROUND_ACTIVE); + ED_transform_calc_orientation_from_type_ex(scene, + view_layer, + CTX_wm_view3d(C), + CTX_wm_region_view3d(C), + obedit, + obedit, + orientation, + V3D_AROUND_ACTIVE, + axis_mat); const float *axis_vector = axis_mat[axis]; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 466820353b9..8ed134c7fd1 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3961,9 +3961,10 @@ static int view_axis_exec(bContext *C, wmOperator *op) Object *obact = CTX_data_active_object(C); if (obact != NULL) { float twmat[3][3]; + ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); /* same as transform gizmo when normal is set */ - ED_getTransformOrientationMatrix(C, obact, obedit, V3D_AROUND_ACTIVE, twmat); + ED_getTransformOrientationMatrix(view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat); align_quat = align_quat_buf; mat3_to_quat(align_quat, twmat); invert_qt_normalized(align_quat); diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 279dca9731d..8dc4f107837 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -674,7 +674,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, if (ob) { float mat[3][3]; ED_transform_calc_orientation_from_type_ex( - C, mat, scene, rv3d, ob, obedit, orient_index, pivot_point); + scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, mat); copy_m4_m3(rv3d->twmat, mat); } diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index 8df95222fa1..b9fb8a86752 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -1232,14 +1232,24 @@ void transform_mode_default_modal_orientation_set(TransInfo *t, int type) return; } + View3D *v3d = NULL; RegionView3D *rv3d = NULL; if ((type == V3D_ORIENT_VIEW) && (t->spacetype == SPACE_VIEW3D) && t->region && (t->region->regiontype == RGN_TYPE_WINDOW)) { + v3d = t->view; rv3d = t->region->regiondata; } t->orient[O_DEFAULT].type = ED_transform_calc_orientation_from_type_ex( - NULL, t->orient[O_DEFAULT].matrix, NULL, rv3d, NULL, NULL, type, 0); + t->scene, + t->view_layer, + v3d, + rv3d, + NULL, + NULL, + type, + V3D_AROUND_CENTER_BOUNDS, + t->orient[O_DEFAULT].matrix); if (t->orient_curr == O_DEFAULT) { /* Update Orientation. */ diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 33f4b06eb0e..1e3acdf1071 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -490,13 +490,14 @@ void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3 Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); + View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = region->regiondata; Object *ob = OBACT(view_layer); const short orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT); const int pivot_point = scene->toolsettings->transform_pivot_point; ED_transform_calc_orientation_from_type_ex( - C, r_mat, scene, rv3d, ob, obedit, orient_index, pivot_point); + scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, r_mat); } /** @@ -508,15 +509,15 @@ void ED_transform_calc_orientation_from_type(const bContext *C, float r_mat[3][3 * - #V3D_ORIENT_LOCAL may contain shear from non-uniform scale in parent/child relationships. * - #V3D_ORIENT_CUSTOM may have been created from #V3D_ORIENT_LOCAL. */ -short ED_transform_calc_orientation_from_type_ex(const bContext *C, - float r_mat[3][3], - /* extra args (can be accessed from context) */ - Scene *scene, - RegionView3D *rv3d, +short ED_transform_calc_orientation_from_type_ex(const Scene *scene, + ViewLayer *view_layer, + const View3D *v3d, + const RegionView3D *rv3d, Object *ob, Object *obedit, const short orientation_index, - const int pivot_point) + const int pivot_point, + float r_mat[3][3]) { switch (orientation_index) { case V3D_ORIENT_GIMBAL: { @@ -528,7 +529,7 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C, } case V3D_ORIENT_NORMAL: { if (obedit || (ob && ob->mode & OB_MODE_POSE)) { - ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat); + ED_getTransformOrientationMatrix(view_layer, v3d, ob, obedit, pivot_point, r_mat); break; } /* No break we define 'normal' as 'local' in Object mode. */ @@ -541,7 +542,7 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C, * use the active pones axis for display T33575, this works as expected on a single * bone and users who select many bones will understand what's going on and what local * means when they start transforming. */ - ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat); + ED_getTransformOrientationMatrix(view_layer, v3d, ob, obedit, pivot_point, r_mat); } else { transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat)); @@ -604,9 +605,11 @@ short transform_orientation_matrix_get(bContext *C, Object *ob = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); Scene *scene = t->scene; + View3D *v3d = NULL; RegionView3D *rv3d = NULL; if ((t->spacetype == SPACE_VIEW3D) && t->region && (t->region->regiontype == RGN_TYPE_WINDOW)) { + v3d = t->view; rv3d = t->region->regiondata; if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) { @@ -619,15 +622,7 @@ short transform_orientation_matrix_get(bContext *C, } short r_orient_index = ED_transform_calc_orientation_from_type_ex( - C, - r_spacemtx, - /* extra args (can be accessed from context) */ - scene, - rv3d, - ob, - obedit, - orient_index, - t->around); + scene, t->view_layer, v3d, rv3d, ob, obedit, orient_index, t->around, r_spacemtx); if (rv3d && (t->options & CTX_PAINT_CURVE)) { /* Screen space in the 3d region. */ @@ -757,15 +752,14 @@ static uint bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const uint n) } #endif -int getTransformOrientation_ex(const bContext *C, +int getTransformOrientation_ex(ViewLayer *view_layer, + const View3D *v3d, struct Object *ob, struct Object *obedit, float normal[3], float plane[3], const short around) { - ViewLayer *view_layer = CTX_data_view_layer(C); - View3D *v3d = CTX_wm_view3d(C); int result = ORIENTATION_NONE; const bool activeOnly = (around == V3D_AROUND_ACTIVE); @@ -1296,12 +1290,16 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3]) /* dummy value, not V3D_AROUND_ACTIVE and not V3D_AROUND_LOCAL_ORIGINS */ short around = V3D_AROUND_CENTER_BOUNDS; - return getTransformOrientation_ex(C, obact, obedit, normal, plane, around); + ViewLayer *view_layer = CTX_data_view_layer(C); + View3D *v3d = CTX_wm_view3d(C); + + return getTransformOrientation_ex(view_layer, v3d, obact, obedit, normal, plane, around); } -void ED_getTransformOrientationMatrix(const bContext *C, - struct Object *ob, - struct Object *obedit, +void ED_getTransformOrientationMatrix(ViewLayer *view_layer, + const View3D *v3d, + Object *ob, + Object *obedit, const short around, float r_orientation_mat[3][3]) { @@ -1310,7 +1308,7 @@ void ED_getTransformOrientationMatrix(const bContext *C, int type; - type = getTransformOrientation_ex(C, ob, obedit, normal, plane, around); + type = getTransformOrientation_ex(view_layer, v3d, ob, obedit, normal, plane, around); /* Fallback, when the plane can't be calculated. */ if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) { diff --git a/source/blender/editors/transform/transform_orientations.h b/source/blender/editors/transform/transform_orientations.h index de8c9b165c1..1da369c8307 100644 --- a/source/blender/editors/transform/transform_orientations.h +++ b/source/blender/editors/transform/transform_orientations.h @@ -58,7 +58,8 @@ enum { }; #define ORIENTATION_USE_PLANE(ty) ELEM(ty, ORIENTATION_NORMAL, ORIENTATION_EDGE, ORIENTATION_FACE) -int getTransformOrientation_ex(const struct bContext *C, +int getTransformOrientation_ex(ViewLayer *view_layer, + const View3D *v3d, struct Object *ob, struct Object *obedit, float normal[3], -- cgit v1.2.3 From fa4a35d4c4eea7cd0c4a9a8bf448afd27c273695 Mon Sep 17 00:00:00 2001 From: Eric Abrahamsson Date: Tue, 31 Aug 2021 17:14:32 +1000 Subject: Measure tool: Add support to restrict dimension to one axis Support axis constraints for the measure tool. Press X, Y or Z to restrict the dimension to that axis, it's also possible to toggle between orientations matching transform. Reviewed By: campbellbarton Ref D10872 --- .../editors/space_view3d/view3d_gizmo_ruler.c | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index edc34d0d883..f8278edbcae 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -33,6 +33,7 @@ #include "BKE_material.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_unit.h" #include "DNA_gpencil_types.h" @@ -44,6 +45,7 @@ #include "ED_gizmo_utils.h" #include "ED_gpencil.h" #include "ED_screen.h" +#include "ED_transform.h" #include "ED_transform_snap_object_context.h" #include "ED_view3d.h" @@ -69,6 +71,12 @@ #include "BLF_api.h" +/** + * Supporting transform features could be removed if the actual transform system is used. + * Keep the option open since each transform feature is duplicating logic. + */ +#define USE_AXIS_CONSTRAINTS + static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler"; #define MVAL_MAX_PX_DIST 12.0f @@ -98,6 +106,24 @@ enum { RULER_STATE_DRAG, }; +#ifdef USE_AXIS_CONSTRAINTS +/* Constrain axes */ +enum { + CONSTRAIN_AXIS_NONE = -1, + CONSTRAIN_AXIS_X = 0, + CONSTRAIN_AXIS_Y = 1, + CONSTRAIN_AXIS_Z = 2, +}; + +/* Constraining modes. + Off / Scene orientation / Global (or Local if Scene orientation is Global) */ +enum { + CONSTRAIN_MODE_OFF = 0, + CONSTRAIN_MODE_1 = 1, + CONSTRAIN_MODE_2 = 2, +}; +#endif /* USE_AXIS_CONSTRAINTS */ + struct RulerItem; typedef struct RulerInfo { @@ -106,6 +132,10 @@ typedef struct RulerInfo { int snap_flag; int state; +#ifdef USE_AXIS_CONSTRAINTS + short constrain_axis, constrain_mode; +#endif + /* wm state */ wmWindowManager *wm; wmWindow *win; @@ -394,6 +424,44 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph, if (ED_gizmotypes_snap_3d_is_enabled(snap_gizmo)) { ED_gizmotypes_snap_3d_data_get(snap_gizmo, co, NULL, NULL, NULL); } + +#ifdef USE_AXIS_CONSTRAINTS + if (!(ruler_item->flag & RULERITEM_USE_ANGLE) && + ruler_info->constrain_mode != CONSTRAIN_MODE_OFF) { + + Scene *scene = DEG_get_input_scene(depsgraph); + ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); + RegionView3D *rv3d = ruler_info->region->regiondata; + Object *ob = OBACT(view_layer); + Object *obedit = OBEDIT_FROM_OBACT(ob); + + short orient_index = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT); + + if (ruler_info->constrain_mode == CONSTRAIN_MODE_2) { + orient_index = (orient_index == V3D_ORIENT_GLOBAL) ? V3D_ORIENT_LOCAL : + V3D_ORIENT_GLOBAL; + } + + const int pivot_point = scene->toolsettings->transform_pivot_point; + float mat[3][3]; + + ED_transform_calc_orientation_from_type_ex( + scene, view_layer, v3d, rv3d, ob, obedit, orient_index, pivot_point, mat); + + invert_m3(mat); + mul_m3_m3_pre(ruler_item->co, mat); + + /* Loop through the axes and constrain the dragged point to the current constrained axis. + */ + for (int i = 0; i <= 2; i++) { + if (ruler_info->constrain_axis != i) { + ruler_item->co[inter->co_index][i] = ruler_item->co[(inter->co_index == 0) ? 2 : 0][i]; + } + } + invert_m3(mat); + mul_m3_m3_pre(ruler_item->co, mat); + } +#endif } return true; } @@ -940,6 +1008,35 @@ static int gizmo_ruler_modal(bContext *C, ruler_info->region = region; +#ifdef USE_AXIS_CONSTRAINTS + if ((event->val == KM_PRESS) && ELEM(event->type, EVT_XKEY, EVT_YKEY, EVT_ZKEY)) { + /* Go to Mode 1 if a new axis is selected. */ + if (event->type == EVT_XKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_X) { + ruler_info->constrain_axis = CONSTRAIN_AXIS_X; + ruler_info->constrain_mode = CONSTRAIN_MODE_1; + } + else if (event->type == EVT_YKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_Y) { + ruler_info->constrain_axis = CONSTRAIN_AXIS_Y; + ruler_info->constrain_mode = CONSTRAIN_MODE_1; + } + else if (event->type == EVT_ZKEY && ruler_info->constrain_axis != CONSTRAIN_AXIS_Z) { + ruler_info->constrain_axis = CONSTRAIN_AXIS_Z; + ruler_info->constrain_mode = CONSTRAIN_MODE_1; + } + else { + /* Cycle to the next mode if the same key is pressed again. */ + if (ruler_info->constrain_mode != CONSTRAIN_MODE_2) { + ruler_info->constrain_mode++; + } + else { + ruler_info->constrain_mode = CONSTRAIN_MODE_OFF; + ruler_info->constrain_axis = CONSTRAIN_AXIS_NONE; + } + } + do_cursor_update = true; + } +#endif + #ifndef USE_SNAP_DETECT_FROM_KEYMAP_HACK const bool do_snap = !(tweak_flag & WM_GIZMO_TWEAK_SNAP); #endif @@ -986,6 +1083,11 @@ static int gizmo_ruler_invoke(bContext *C, wmGizmo *gz, const wmEvent *event) const float mval_fl[2] = {UNPACK2(event->mval)}; +#ifdef USE_AXIS_CONSTRAINTS + ruler_info->constrain_axis = CONSTRAIN_AXIS_NONE; + ruler_info->constrain_mode = CONSTRAIN_MODE_OFF; +#endif + /* select and drag */ if (gz->highlight_part == PART_LINE) { if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { -- cgit v1.2.3 From 1f0d63b9a1e3d11885a8acf8e55b36e3f7fb737b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Aug 2021 18:25:43 +1000 Subject: Cleanup: remove unnecessary obedit argument from ED_space_image_set This was left over from when changing the image set the faces texture. --- source/blender/editors/include/ED_image.h | 1 - source/blender/editors/sculpt_paint/paint_image.c | 2 +- source/blender/editors/space_image/image_edit.c | 6 +----- source/blender/editors/space_image/image_ops.c | 9 +++------ 4 files changed, 5 insertions(+), 13 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index ec525806b81..6b0b9f4a27c 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -46,7 +46,6 @@ struct wmWindowManager; struct Image *ED_space_image(struct SpaceImage *sima); void ED_space_image_set(struct Main *bmain, struct SpaceImage *sima, - struct Object *obedit, struct Image *ima, bool automatic); void ED_space_image_auto_set(const struct bContext *C, struct SpaceImage *sima); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 39d776e0054..b5113681955 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -1153,7 +1153,7 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob SpaceImage *sima = (SpaceImage *)sl; if (!sima->pin) { - ED_space_image_set(bmain, sima, NULL, ima, true); + ED_space_image_set(bmain, sima, ima, true); } } } diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index a95189a303f..2174a4b9dc1 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -57,7 +57,7 @@ Image *ED_space_image(SpaceImage *sima) return sima->image; } -void ED_space_image_set(Main *bmain, SpaceImage *sima, Object *obedit, Image *ima, bool automatic) +void ED_space_image_set(Main *bmain, SpaceImage *sima, Image *ima, bool automatic) { /* Automatically pin image when manually assigned, otherwise it follows object. */ if (!automatic && sima->image != ima && sima->mode == SI_MODE_UV) { @@ -78,10 +78,6 @@ void ED_space_image_set(Main *bmain, SpaceImage *sima, Object *obedit, Image *im id_us_ensure_real((ID *)sima->image); - if (obedit) { - WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); - } - WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 11efd3e33ef..94d44e047a4 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1311,7 +1311,6 @@ static int image_open_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); ScrArea *area = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); - Object *obedit = CTX_data_edit_object(C); ImageUser *iuser = NULL; Image *ima = NULL; int frame_seq_len = 0; @@ -1364,7 +1363,7 @@ static int image_open_exec(bContext *C, wmOperator *op) } else if (area && area->spacetype == SPACE_IMAGE) { SpaceImage *sima = area->spacedata.first; - ED_space_image_set(bmain, sima, obedit, ima, false); + ED_space_image_set(bmain, sima, ima, false); iuser = &sima->iuser; } else { @@ -2519,7 +2518,6 @@ static void image_new_free(wmOperator *op) static int image_new_exec(bContext *C, wmOperator *op) { SpaceImage *sima; - Object *obedit; Image *ima; Main *bmain; PropertyRNA *prop; @@ -2531,7 +2529,6 @@ static int image_new_exec(bContext *C, wmOperator *op) /* retrieve state */ sima = CTX_wm_space_image(C); - obedit = CTX_data_edit_object(C); bmain = CTX_data_main(C); prop = RNA_struct_find_property(op->ptr, "name"); @@ -2587,7 +2584,7 @@ static int image_new_exec(bContext *C, wmOperator *op) RNA_property_update(C, &data->pprop.ptr, data->pprop.prop); } else if (sima) { - ED_space_image_set(bmain, sima, obedit, ima, false); + ED_space_image_set(bmain, sima, ima, false); } BKE_image_signal(bmain, ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE); @@ -3705,7 +3702,7 @@ static int image_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op)) ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"); if (sima->image == NULL) { - ED_space_image_set(bmain, sima, NULL, ima, false); + ED_space_image_set(bmain, sima, ima, false); } RE_ReadRenderResult(scene, scene); -- cgit v1.2.3 From 3b2a01edf698fb27d9984fe12eb210df5246f16c Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 4 Jun 2021 10:24:01 +0200 Subject: Texture Paint: sync changing active texture in the node editor to the active paint slot When changing to another texture paint slot, the texture displayed in the viewport changes accordingly (as well as the image displayed in the Image Editor). When changing the active texture in the Node Editor though, only the texture displayed in the viewport changes. This _can_ be confusing because you can end up painting on a texture that you are not looking at in the viewport (so you dont have any feedback whatsoever). Not 100% sure this is desired in all scenarios, but this change makes it so that the active paint slot changes to the one that uses the texture we chaged to in the Node Editor (keeping them in sync). If this is not desired in all cases, this could be made an option. ref T88788 ref D11496 Maniphest Tasks: T88788 Differential Revision: https://developer.blender.org/D11497 --- source/blender/editors/space_node/node_edit.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 5b1b737751c..fd907d41a62 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -719,11 +719,22 @@ void ED_node_set_active( ED_node_tag_update_nodetree(bmain, ntree, node); } - /* if active texture changed, free glsl materials */ if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { + /* If active texture changed, free glsl materials. */ LISTBASE_FOREACH (Material *, ma, &bmain->materials) { if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { GPU_material_free(&ma->gpumaterial); + + /* Sync to active texpaint slot, otherwise we can end up painting on a different slot + * than we are looking at. */ + if (ma->texpaintslot) { + Image *image = (Image *)node->id; + for (int i = 0; i < ma->tot_slots; i++) { + if (ma->texpaintslot[i].ima == image) { + ma->paint_active_slot = i; + } + } + } } } -- cgit v1.2.3 From b0cb0a78547582848f5f18f5d5cc85c69f3dbe30 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 4 Jun 2021 10:37:00 +0200 Subject: Texture Paint: sync changing active texture in the Node Editor to the Image Editor When changing to another texture paint slot, the texture displayed in the viewport changes accordingly (as well as the image displayed in the Image Editor). When changing the active texture in the Node Editor though, only the texture displayed in the viewport changes. This was mentioned in T88788 and I am not 100% sure this is desired in all scenarios (or at all), it should be seen in tandem of D11497. This change makes it so that the Image Editor changes to the image we changed to in the Node Editor (keeping them in sync). If this is not desired in all cases, this could be made an option. ref T88788 ref D11496 ref D11497 Maniphest Tasks: T88788 Differential Revision: https://developer.blender.org/D11498 --- source/blender/editors/space_node/node_edit.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index fd907d41a62..030d1672a08 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -52,6 +52,7 @@ #include "RE_engine.h" #include "RE_pipeline.h" +#include "ED_image.h" #include "ED_node.h" /* own include */ #include "ED_render.h" #include "ED_screen.h" @@ -744,6 +745,23 @@ void ED_node_set_active( } } + /* Sync to Image Editor. */ + Image *image = (Image *)node->id; + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + const bScreen *screen = WM_window_get_active_screen(win); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)sl; + if (!sima->pin) { + ED_space_image_set(bmain, sima, image, true); + } + } + } + } + } + if (r_active_texture_changed) { *r_active_texture_changed = true; } -- cgit v1.2.3 From 90dac47717b12f33d5dd738da12a337cfe4f2f14 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Sep 2021 15:23:56 +1000 Subject: Cleanup: remove redundant strstr calls Rely on BLI_str_quoted_substrN to detect if the prefix exists since this function exists early there is no need to check before calling. --- source/blender/editors/animation/anim_deps.c | 11 ++-- source/blender/editors/animation/anim_filter.c | 62 ++++++++++------------ source/blender/editors/animation/keyframing.c | 17 +++--- source/blender/editors/armature/pose_select.c | 26 +++++---- .../editors/transform/transform_convert_armature.c | 34 ++++++------ 5 files changed, 67 insertions(+), 83 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 42fdb714127..2cc0f6ad288 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -207,19 +207,14 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) Scene *scene = (Scene *)owner_id; FCurve *fcu = (FCurve *)ale->data; - /* only affect if F-Curve involves sequence_editor.sequences */ - if (!strstr(fcu->rna_path, "sequences_all")) { - return; - } - - Editing *ed = SEQ_editing_get(scene, false); - - /* get strip name, and check if this strip is selected */ + /* Only affect if F-Curve involves sequence_editor.sequences. */ char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); if (seq_name == NULL) { return; } + /* Check if this strip is selected. */ + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 020518b5813..2252fc4fcbc 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1061,20 +1061,16 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id if (GS(owner_id->name) == ID_OB) { Object *ob = (Object *)owner_id; + char *bone_name; - /* only consider if F-Curve involves pose.bones */ - if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) { - - /* get bone-name, and check if this bone is selected */ - bPoseChannel *pchan = NULL; - char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - if (bone_name) { - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); - } + /* Only consider if F-Curve involves `pose.bones`. */ + if (fcu->rna_path && (bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["))) { + /* Get bone-name, and check if this bone is selected. */ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + MEM_freeN(bone_name); /* check whether to continue or skip */ - if ((pchan) && (pchan->bone)) { + if (pchan && pchan->bone) { /* If only visible channels, * skip if bone not visible unless user wants channels from hidden data too. */ if (skip_hidden) { @@ -1101,22 +1097,19 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id } else if (GS(owner_id->name) == ID_SCE) { Scene *scene = (Scene *)owner_id; + char *seq_name; - /* only consider if F-Curve involves sequence_editor.sequences */ - if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { - Editing *ed = SEQ_editing_get(scene, false); + /* Only consider if F-Curve involves `sequence_editor.sequences`. */ + if (fcu->rna_path && (seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["))) { + /* Get strip name, and check if this strip is selected. */ Sequence *seq = NULL; - + Editing *ed = SEQ_editing_get(scene, false); if (ed) { - /* get strip name, and check if this strip is selected */ - char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); - if (seq_name) { - seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); - MEM_freeN(seq_name); - } + seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); } + MEM_freeN(seq_name); - /* can only add this F-Curve if it is selected */ + /* Can only add this F-Curve if it is selected. */ if (ads->filterflag & ADS_FILTER_ONLYSEL) { if ((seq == NULL) || (seq->flag & SELECT) == 0) { return true; @@ -1126,22 +1119,21 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id } else if (GS(owner_id->name) == ID_NT) { bNodeTree *ntree = (bNodeTree *)owner_id; + char *node_name; - /* check for selected nodes */ - if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) { + /* Check for selected nodes. */ + if (fcu->rna_path && (node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["))) { bNode *node = NULL; + /* Get strip name, and check if this strip is selected. */ + node = nodeFindNodebyName(ntree, node_name); + MEM_freeN(node_name); - /* get strip name, and check if this strip is selected */ - char *node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["); - if (node_name) { - node = nodeFindNodebyName(ntree, node_name); - MEM_freeN(node_name); - } - - /* can only add this F-Curve if it is selected */ - if (ads->filterflag & ADS_FILTER_ONLYSEL) { - if ((node) && (node->flag & NODE_SELECT) == 0) { - return true; + /* Can only add this F-Curve if it is selected. */ + if (node) { + if (ads->filterflag & ADS_FILTER_ONLYSEL) { + if ((node->flag & NODE_SELECT) == 0) { + return true; + } } } } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 0a499232ba9..292d665caca 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2216,9 +2216,8 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ if (ob->mode & OB_MODE_POSE) { - if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { - - /* get bone-name, and check if this bone is selected */ + if (fcu->rna_path) { + /* Get bone-name, and check if this bone is selected. */ char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); if (bone_name) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); @@ -2320,16 +2319,18 @@ static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op) * NOTE: This is only done in pose mode. * In object mode, we're dealing with the entire object. */ - if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) { + if (ob->mode & OB_MODE_POSE) { bPoseChannel *pchan = NULL; - /* get bone-name, and check if this bone is selected */ + /* Get bone-name, and check if this bone is selected. */ char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - if (bone_name) { - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); + if (bone_name == NULL) { + continue; } + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + MEM_freeN(bone_name); + /* skip if bone is not selected */ if ((pchan) && (pchan->bone)) { /* bones are only selected/editable if visible... */ diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 1dbb859fd6c..4db8569a7d2 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -1106,20 +1106,18 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex for (ksp = ks->paths.first; ksp; ksp = ksp->next) { /* only items related to this object will be relevant */ if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) { - if (strstr(ksp->rna_path, "bones")) { - char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones["); - - if (boneName) { - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName); - MEM_freeN(boneName); - - if (pchan) { - /* select if bone is visible and can be affected */ - if (PBONE_SELECTABLE(arm, pchan->bone)) { - pchan->bone->flag |= BONE_SELECTED; - changed = true; - } - } + char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones["); + if (boneName == NULL) { + continue; + } + bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName); + MEM_freeN(boneName); + + if (pchan) { + /* select if bone is visible and can be affected */ + if (PBONE_SELECTABLE(arm, pchan->bone)) { + pchan->bone->flag |= BONE_SELECTED; + changed = true; } } } diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 5627a910ab4..98e00c20170 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -145,31 +145,29 @@ static void autokeyframe_pose( if (act) { for (fcu = act->curves.first; fcu; fcu = fcu->next) { /* only insert keyframes for this F-Curve if it affects the current bone */ - if (strstr(fcu->rna_path, "bones") == NULL) { + char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones["); + if (pchanName == NULL) { continue; } - char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones["); /* only if bone name matches too... * NOTE: this will do constraints too, but those are ok to do here too? */ - if (pchanName) { - if (STREQ(pchanName, pchan->name)) { - insert_keyframe(bmain, - reports, - id, - act, - ((fcu->grp) ? (fcu->grp->name) : (NULL)), - fcu->rna_path, - fcu->array_index, - &anim_eval_context, - ts->keyframe_type, - &nla_cache, - flag); - } - - MEM_freeN(pchanName); + if (STREQ(pchanName, pchan->name)) { + insert_keyframe(bmain, + reports, + id, + act, + ((fcu->grp) ? (fcu->grp->name) : (NULL)), + fcu->rna_path, + fcu->array_index, + &anim_eval_context, + ts->keyframe_type, + &nla_cache, + flag); } + + MEM_freeN(pchanName); } } } -- cgit v1.2.3 From 2914ec571e34733ed89a64f182cf4045be49a28f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Sep 2021 15:23:59 +1000 Subject: Fix errors pasting flipped names in the action editor Use BLI_str_quoted_substr_range instead of in-line quote extraction to resolve: - Bone names containing quotes caused flip to fail. - Missing NULL check if a matching quote could not be found. --- .../blender/editors/animation/keyframes_general.c | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 75ce62d5e27..9f3fe239113 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -824,31 +824,35 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data) return 0; } -static void flip_names(tAnimCopybufItem *aci, char **name) +static void flip_names(tAnimCopybufItem *aci, char **r_name) { if (aci->is_bone) { - char *str_start; - if ((str_start = strstr(aci->rna_path, "pose.bones["))) { - /* ninja coding, try to change the name */ + int ofs_start; + int ofs_end; + + if (BLI_str_quoted_substr_range(aci->rna_path, "pose.bones[", &ofs_start, &ofs_end)) { + char *str_start = aci->rna_path + ofs_start; + const char *str_end = aci->rna_path + ofs_end; + + /* Swap out the name. + * Note that there is no need to un-escape the string to flip it. */ char bname_new[MAX_VGROUP_NAME]; - char *str_iter, *str_end; + char *str_iter; int length, prefix_l, postfix_l; - str_start += 12; prefix_l = str_start - aci->rna_path; - str_end = strchr(str_start, '\"'); - length = str_end - str_start; postfix_l = strlen(str_end); - /* more ninja stuff, temporary substitute with NULL terminator */ + /* Temporary substitute with NULL terminator. */ + BLI_assert(str_start[length] == '\"'); str_start[length] = 0; BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new)); str_start[length] = '\"'; - str_iter = *name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1), - "flipped_path"); + str_iter = *r_name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1), + "flipped_path"); BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1); str_iter += prefix_l; -- cgit v1.2.3 From 7ec839adfa99b049f84c2d75834a4e6d20c4a7b7 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 1 Sep 2021 15:13:18 +0200 Subject: File Browser/BPY: Expose list of selected files in context Since recently it's possible to query the active file (as object, not just the name), but it's quite useful for scripting to have access to all selected files. This introduces `bpy.context.selected_files`, returning a list of file objects representing files in the File Browser. --- source/blender/editors/space_file/space_file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 7deaa2fec60..daf522273a9 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -873,6 +873,7 @@ static void file_space_subtype_item_extend(bContext *UNUSED(C), static const char *file_context_dir[] = { "active_file", + "selected_files", "asset_library_ref", "id", NULL, @@ -907,6 +908,20 @@ static int /*eContextResult*/ file_context(const bContext *C, CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file); return CTX_RESULT_OK; } + if (CTX_data_equals(member, "selected_files")) { + const int num_files_filtered = filelist_files_ensure(sfile->files); + + for (int file_index = 0; file_index < num_files_filtered; file_index++) { + if (filelist_entry_is_selected(sfile->files, file_index)) { + FileDirEntry *entry = filelist_file(sfile->files, file_index); + CTX_data_list_add(result, &screen->id, &RNA_FileSelectEntry, entry); + } + } + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return CTX_RESULT_OK; + } + if (CTX_data_equals(member, "asset_library_ref")) { FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); if (!asset_params) { -- cgit v1.2.3 From f62eb8ac16c1bd7abe0925b8b70fb47b613fbdd8 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 1 Sep 2021 16:27:29 +0200 Subject: BPY-Docs: Add missing file context members documentation Context members of the file space would not be shown in the context API docs. --- source/blender/editors/space_file/file_intern.h | 3 +++ source/blender/editors/space_file/space_file.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 17749d36418..905c0aeb8e0 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -92,6 +92,9 @@ void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct Sp void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op); +/* space_file.c */ +extern const char *file_context_dir[]; /* doc access */ + /* filesel.c */ void fileselect_refresh_params(struct SpaceFile *sfile); void fileselect_file_set(SpaceFile *sfile, const int index); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index daf522273a9..a4f36c2a6ee 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -871,7 +871,7 @@ static void file_space_subtype_item_extend(bContext *UNUSED(C), RNA_enum_items_add(item, totitem, rna_enum_space_file_browse_mode_items); } -static const char *file_context_dir[] = { +const char *file_context_dir[] = { "active_file", "selected_files", "asset_library_ref", -- cgit v1.2.3 From f8dd0d0dba748035706382f0c5700bb23e5a9048 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Sep 2021 21:41:23 +1000 Subject: Cleanup: spelling in comments --- source/blender/editors/gpencil/annotate_paint.c | 2 +- source/blender/editors/gpencil/gpencil_paint.c | 2 +- source/blender/editors/object/object_modifier.c | 2 +- source/blender/editors/screen/workspace_layout_edit.c | 2 +- source/blender/editors/space_action/space_action.c | 4 ++-- source/blender/editors/space_graph/space_graph.c | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index bf47704746b..65c5b8ee573 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -2423,7 +2423,7 @@ static void annotation_add_missing_events(bContext *C, static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) { tGPsdata *p = op->customdata; - /* default exit state - pass through to support MMB view nav, etc. */ + /* Default exit state - pass through to support MMB view navigation, etc. */ int estate = OPERATOR_PASS_THROUGH; /* NOTE(mike erwin): Not quite what I was looking for, but a good start! diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index d2dbf6ab2a6..28a22633742 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -3568,7 +3568,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) // ToolSettings *ts = CTX_data_tool_settings(C); GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide; - /* default exit state - pass through to support MMB view nav, etc. */ + /* Default exit state - pass through to support MMB view navigation, etc. */ int estate = OPERATOR_PASS_THROUGH; /* NOTE(mike erwin): Not quite what I was looking for, but a good start! diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index e1e0a0600be..2a1a6696493 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -3100,7 +3100,7 @@ void OBJECT_OT_ocean_bake(wmOperatorType *ot) /** \} */ /* ------------------------------------------------------------------- */ -/** \name Laplaciandeform Bind Operator +/** \name Laplacian-Deform Bind Operator * \{ */ static bool laplaciandeform_poll(bContext *C) diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c index 31ca11bb847..0ec32da0404 100644 --- a/source/blender/editors/screen/workspace_layout_edit.c +++ b/source/blender/editors/screen/workspace_layout_edit.c @@ -140,7 +140,7 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol BLI_assert(BLI_findindex(&workspace->layouts, layout_old) != -1); - /* don't allow deleting temp fullscreens for now */ + /* Don't allow deleting temp full-screens for now. */ if (BKE_screen_is_fullscreen_area(screen_old)) { return false; } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 5e5143723a6..f59429ba981 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -536,9 +536,9 @@ static void action_listener(const wmSpaceTypeListenerParams *params) saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; ED_area_tag_refresh(area); } - /* autocolor only really needs to change when channels are added/removed, + /* Auto-color only really needs to change when channels are added/removed, * or previously hidden stuff appears - * (assume for now that if just adding these works, that will be fine) + * (assume for now that if just adding these works, that will be fine). */ else if (((wmn->data == ND_KEYFRAME) && ELEM(wmn->action, NA_ADDED, NA_REMOVED)) || ((wmn->data == ND_ANIMCHAN) && (wmn->action != NA_SELECTED))) { diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 49966e880d3..720d69eaf4f 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -556,8 +556,8 @@ static void graph_listener(const wmSpaceTypeListenerParams *params) /* context changes */ switch (wmn->category) { case NC_ANIMATION: - /* for selection changes of animation data, we can just redraw... - * otherwise autocolor might need to be done again */ + /* For selection changes of animation data, we can just redraw... + * otherwise auto-color might need to be done again. */ if (ELEM(wmn->data, ND_KEYFRAME, ND_ANIMCHAN) && (wmn->action == NA_SELECTED)) { ED_area_tag_redraw(area); } -- cgit v1.2.3 From baee000001f6a840f7aa15ad3834afc6639ef0f2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Sep 2021 21:44:32 +1000 Subject: Fix T90798: calc_loop_triangles is not updated after joining objects --- source/blender/editors/mesh/meshtools.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 27fb21e1dfb..1b720f2c14d 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -424,6 +424,11 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) /* remove tessface to ensure we don't hold references to invalid faces */ BKE_mesh_tessface_clear(me); + /* Clear any run-time data. + * Even though this mesh wont typically have run-time data, the Python API can for e.g. + * create loop-triangle cache here, which is confusing when left in the mesh, see: T90798. */ + BKE_mesh_runtime_clear_geometry(me); + /* new material indices and material array */ if (totmat) { matar = MEM_callocN(sizeof(*matar) * totmat, "join_mesh matar"); -- cgit v1.2.3 From 6c177838f30a171c6b69b66d885cdefd01669a33 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Sep 2021 11:29:32 +1000 Subject: Cleanup: remove redundant alloc argument to SEQ_editing_get Callers that require lazy initialization can use SEQ_editing_ensure. --- source/blender/editors/animation/anim_deps.c | 2 +- source/blender/editors/animation/anim_filter.c | 2 +- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/screen/screen_context.c | 6 +- .../editors/space_outliner/outliner_select.c | 4 +- .../editors/space_outliner/outliner_tools.c | 2 +- .../space_outliner/tree/tree_display_sequencer.cc | 2 +- .../editors/space_sequencer/sequencer_add.c | 24 +++---- .../editors/space_sequencer/sequencer_draw.c | 8 +-- .../editors/space_sequencer/sequencer_edit.c | 84 +++++++++++----------- .../editors/space_sequencer/sequencer_modifier.c | 2 +- .../editors/space_sequencer/sequencer_proxy.c | 6 +- .../editors/space_sequencer/sequencer_select.c | 26 +++---- .../editors/space_sequencer/sequencer_view.c | 4 +- .../transform/transform_convert_sequencer.c | 8 +-- .../editors/transform/transform_snap_sequencer.c | 4 +- source/blender/editors/util/ed_util_imbuf.c | 2 +- 17 files changed, 94 insertions(+), 94 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 2cc0f6ad288..916d4232f03 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -214,7 +214,7 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) } /* Check if this strip is selected. */ - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 2252fc4fcbc..7e3e3f363c2 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1103,7 +1103,7 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id if (fcu->rna_path && (seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["))) { /* Get strip name, and check if this strip is selected. */ Sequence *seq = NULL; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); } diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 6f3277397c5..450d7cd100e 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -105,7 +105,7 @@ static void seq_frame_snap_update_best(const int position, static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene, false)); + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); SeqCollection *strips = SEQ_query_all_strips(seqbase); int best_frame = 0; diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 13c338efdec..2ccefb993c7 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -623,7 +623,7 @@ static eContextResult screen_ctx_sequences(const bContext *C, bContextDataResult { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); @@ -637,7 +637,7 @@ static eContextResult screen_ctx_selected_sequences(const bContext *C, bContextD { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT) { @@ -654,7 +654,7 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 1feecc04ead..581892ebb3a 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -673,7 +673,7 @@ static void tree_element_sequence_activate(bContext *C, const eOLSetState set) { Sequence *seq = (Sequence *)te->directdata; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (BLI_findindex(ed->seqbasep, seq) != -1) { if (set == OL_SETSEL_EXTEND) { @@ -695,7 +695,7 @@ static void tree_element_sequence_activate(bContext *C, static void tree_element_sequence_dup_activate(Scene *scene, TreeElement *UNUSED(te)) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); #if 0 select_single_seq(seq, 1); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index d88ae82cc9a..7709c6bb053 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1286,7 +1286,7 @@ static void sequence_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem { Sequence *seq = (Sequence *)te->directdata; Scene *scene = (Scene *)scene_ptr; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (BLI_findindex(ed->seqbasep, seq) != -1) { if (event == OL_DOP_SELECT) { ED_sequencer_select_sequence_single(scene, seq, true); diff --git a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc index 40f329d72c3..02af6a13cb3 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc @@ -43,7 +43,7 @@ ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data) { ListBase tree = {nullptr}; - Editing *ed = SEQ_editing_get(source_data.scene, false); + Editing *ed = SEQ_editing_get(source_data.scene); if (ed == nullptr) { return tree; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 16b690dd6e4..081f0241e94 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -185,7 +185,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) Sequence *tgt = NULL; Sequence *seq; Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); + Editing *ed = SEQ_editing_ensure(scene); int timeline_frame = (int)CFRA; int proximity = INT_MAX; @@ -314,7 +314,7 @@ static void load_data_init_from_operator(SeqLoadData *load_data, bContext *C, wm static void seq_load_apply_generic_options(bContext *C, wmOperator *op, Sequence *seq) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (seq == NULL) { return; @@ -356,7 +356,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, true); + const Editing *ed = SEQ_editing_ensure(scene); Scene *sce_seq = BLI_findlink(&bmain->scenes, RNA_enum_get(op->ptr, "scene")); if (sce_seq == NULL) { @@ -384,7 +384,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) static void sequencer_disable_one_time_properties(bContext *C, wmOperator *op) { - Editing *ed = SEQ_editing_get(CTX_data_scene(C), false); + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); /* Disable following properties if there are any existing strips, unless overridden by user. */ if (ed && ed->seqbasep && ed->seqbasep->first) { if (RNA_struct_find_property(op->ptr, "use_framerate")) { @@ -435,7 +435,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, true); + const Editing *ed = SEQ_editing_ensure(scene); MovieClip *clip = BLI_findlink(&bmain->movieclips, RNA_enum_get(op->ptr, "clip")); if (clip == NULL) { @@ -499,7 +499,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, true); + const Editing *ed = SEQ_editing_ensure(scene); Mask *mask = BLI_findlink(&bmain->masks, RNA_enum_get(op->ptr, "mask")); if (mask == NULL) { @@ -632,7 +632,7 @@ static void sequencer_add_movie_multiple_strips(bContext *C, { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, true); + const Editing *ed = SEQ_editing_ensure(scene); RNA_BEGIN (op->ptr, itemptr, "files") { char dir_only[FILE_MAX]; @@ -668,7 +668,7 @@ static bool sequencer_add_movie_single_strip(bContext *C, wmOperator *op, SeqLoa { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, true); + const Editing *ed = SEQ_editing_ensure(scene); Sequence *seq_movie = NULL; Sequence *seq_sound = NULL; @@ -817,7 +817,7 @@ static void sequencer_add_sound_multiple_strips(bContext *C, { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); + Editing *ed = SEQ_editing_ensure(scene); RNA_BEGIN (op->ptr, itemptr, "files") { char dir_only[FILE_MAX]; @@ -842,7 +842,7 @@ static bool sequencer_add_sound_single_strip(bContext *C, wmOperator *op, SeqLoa { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); + Editing *ed = SEQ_editing_ensure(scene); Sequence *seq = SEQ_add_sound_strip(bmain, scene, ed->seqbasep, load_data, 0.0f); if (seq == NULL) { @@ -1035,7 +1035,7 @@ static void sequencer_add_image_strip_load_files( static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); + Editing *ed = SEQ_editing_ensure(scene); SeqLoadData load_data; load_data_init_from_operator(&load_data, C, op); @@ -1141,7 +1141,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); + Editing *ed = SEQ_editing_ensure(scene); const char *error_msg; SeqLoadData load_data; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index fe3ff469e50..b56ad48cec2 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2275,9 +2275,9 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) } } -static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) +static void seq_draw_sfra_efra(const Scene *scene, View2D *v2d) { - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); const int frame_sta = scene->r.sfra; const int frame_end = scene->r.efra + 1; @@ -2312,7 +2312,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) /* While in meta strip, draw a checkerboard overlay outside of frame range. */ if (ed && !BLI_listbase_is_empty(&ed->metastack)) { - MetaStack *ms = ed->metastack.last; + const MetaStack *ms = ed->metastack.last; immUnbindProgram(); immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); @@ -2586,7 +2586,7 @@ static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D void draw_timeline_seq(const bContext *C, ARegion *region) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); SpaceSeq *sseq = CTX_wm_space_seq(C); View2D *v2d = ®ion->v2d; short cfra_flag = 0; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 935bc97d0b2..b95b7fa0620 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -190,14 +190,14 @@ bool ED_space_sequencer_has_playback_animation(const struct SpaceSeq *sseq, /* Operator functions. */ bool sequencer_edit_poll(bContext *C) { - return (SEQ_editing_get(CTX_data_scene(C), false) != NULL); + return (SEQ_editing_get(CTX_data_scene(C)) != NULL); } #if 0 /* UNUSED */ bool sequencer_strip_poll(bContext *C) { Editing *ed; - return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && + return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && (ed->act_seq != NULL)); } #endif @@ -206,14 +206,14 @@ bool sequencer_strip_has_path_poll(bContext *C) { Editing *ed; Sequence *seq; - return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && - ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq))); + return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && ((seq = ed->act_seq) != NULL) && + (SEQ_HAS_PATH(seq))); } bool sequencer_view_preview_poll(bContext *C) { SpaceSeq *sseq = CTX_wm_space_seq(C); - Editing *ed = SEQ_editing_get(CTX_data_scene(C), false); + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF)) { return 1; } @@ -241,7 +241,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); const bool do_all = RNA_boolean_get(op->ptr, "all"); - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); SEQ_edit_remove_gaps(scene, ed->seqbasep, CFRA, do_all); @@ -281,7 +281,7 @@ static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); const int frames = RNA_int_get(op->ptr, "frames"); - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); SEQ_transform_offset_after_frame(scene, ed->seqbasep, frames, CFRA); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -327,7 +327,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; int snap_frame; @@ -531,7 +531,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve { SlipData *data; Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); float mouseloc[2]; int num_seq; View2D *v2d = UI_view2d_fromcontext(C); @@ -579,7 +579,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) { /* Only data types supported for now. */ - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); bool changed = false; /* Iterate in reverse so meta-strips are iterated after their children. */ @@ -663,7 +663,7 @@ static void sequencer_slip_apply_limits(SlipData *data, int *offset) static int sequencer_slip_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); int offset = RNA_int_get(op->ptr, "offset"); bool success = false; @@ -798,7 +798,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even case EVT_ESCKEY: case RIGHTMOUSE: { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); for (int i = 0; i < data->num_seq; i++) { transseq_restore(data->ts + i, data->seq_array[i]); @@ -900,7 +900,7 @@ void SEQUENCER_OT_slip(struct wmOperatorType *ot) static int sequencer_mute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; bool selected; @@ -956,7 +956,7 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot) static int sequencer_unmute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; bool selected; @@ -1012,7 +1012,7 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot) static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -1050,7 +1050,7 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot) static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -1089,7 +1089,7 @@ static int sequencer_reload_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length"); @@ -1152,7 +1152,7 @@ static bool sequencer_refresh_all_poll(bContext *C) static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); SEQ_relations_free_imbuf(scene, &ed->seqbase, false); @@ -1187,7 +1187,7 @@ int seq_effect_find_selected(Scene *scene, Sequence **r_selseq3, const char **r_error_str) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq; *r_error_str = NULL; @@ -1316,7 +1316,7 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) static bool sequencer_effect_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { Sequence *last_seq = SEQ_select_active_get(scene); @@ -1423,7 +1423,7 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); bool changed = false; bool seq_selected = false; @@ -1628,7 +1628,7 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return OPERATOR_CANCELLED; @@ -1688,7 +1688,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); SEQ_prefetch_stop(scene); @@ -1747,7 +1747,7 @@ void SEQUENCER_OT_delete(wmOperatorType *ot) static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; /* For effects, try to find a replacement input. */ @@ -1802,7 +1802,7 @@ void SEQUENCER_OT_offset_clear(wmOperatorType *ot) static int sequencer_separate_images_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq, *seq_new; Strip *strip_new; @@ -1908,7 +1908,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *active_seq = SEQ_select_active_get(scene); if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) { @@ -1959,7 +1959,7 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) static int sequencer_meta_make_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *active_seq = SEQ_select_active_get(scene); ListBase *active_seqbase = SEQ_active_seqbase_get(ed); @@ -2027,7 +2027,7 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot) static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *active_seq = SEQ_select_active_get(scene); if (active_seq == NULL || active_seq->type != SEQ_TYPE_META) { @@ -2181,7 +2181,7 @@ static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, i { /* sel: 0==unselected, 1==selected, -1==don't care. */ Sequence *seq, *best_seq = NULL; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); int dist, best_dist; best_dist = MAXFRAME * 2; @@ -2231,7 +2231,7 @@ static bool seq_is_parent(Sequence *par, Sequence *seq) static int sequencer_swap_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *active_seq = SEQ_select_active_get(scene); Sequence *seq, *iseq; int side = RNA_enum_get(op->ptr, "side"); @@ -2399,7 +2399,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); SEQ_clipboard_free(); @@ -2456,7 +2456,7 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) void ED_sequencer_deselect_all(Scene *scene) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return; @@ -2471,7 +2471,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, true); /* Create if needed. */ + Editing *ed = SEQ_editing_ensure(scene); /* Create if needed. */ ListBase nseqbase = {NULL, NULL}; int ofs; Sequence *iseq, *iseq_first; @@ -2640,7 +2640,7 @@ static const EnumPropertyItem prop_change_effect_input_types[] = { static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_select_active_get(scene); Sequence **seq_1, **seq_2; @@ -2724,7 +2724,7 @@ EnumPropertyItem sequencer_prop_effect_types[] = { static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_select_active_get(scene); const int new_type = RNA_enum_get(op->ptr, "type"); @@ -2790,7 +2790,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq = SEQ_select_active_get(scene); const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); @@ -3000,7 +3000,7 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Sequence *seq, *seq_next; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); ListBase text_seq = {0}; int iter = 0; FILE *file; @@ -3077,8 +3077,8 @@ static bool sequencer_strip_is_text_poll(bContext *C) { Editing *ed; Sequence *seq; - return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && - ((seq = ed->act_seq) != NULL) && (seq->type == SEQ_TYPE_TEXT)); + return (((ed = SEQ_editing_get(CTX_data_scene(C))) != NULL) && ((seq = ed->act_seq) != NULL) && + (seq->type == SEQ_TYPE_TEXT)); } void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) @@ -3114,7 +3114,7 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; int sfra = MAXFRAME; @@ -3199,7 +3199,7 @@ static const EnumPropertyItem transform_reset_properties[] = { static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); Sequence *seq; const int property = RNA_enum_get(op->ptr, "property"); @@ -3272,7 +3272,7 @@ static const EnumPropertyItem scale_fit_methods[] = { static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); Sequence *seq; const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method"); diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index 9b3ecacceb9..dd8595622f8 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -48,7 +48,7 @@ static bool strip_modifier_active_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed) { Sequence *seq = SEQ_select_active_get(scene); diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c index 16d14b5fa72..0a8eb7cb88f 100644 --- a/source/blender/editors/space_sequencer/sequencer_proxy.c +++ b/source/blender/editors/space_sequencer/sequencer_proxy.c @@ -56,7 +56,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); ScrArea *area = CTX_wm_area(C); if (ed == NULL) { @@ -121,7 +121,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); GSet *file_list; if (ed == NULL) { @@ -184,7 +184,7 @@ static int sequencer_enable_proxies_invoke(bContext *C, static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25"); bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50"); bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75"); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 333edd0ed5f..4c938a412d2 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -202,7 +202,7 @@ void select_surround_from_last(Scene *scene) void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (deselect_all) { ED_sequencer_deselect_all(scene); @@ -236,7 +236,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se { /* sel: 0==unselected, 1==selected, -1==don't care. */ Sequence *seq; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return NULL; @@ -270,7 +270,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2]) { Sequence *seq; - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); float x, y; float pixelx; float handsize; @@ -396,7 +396,7 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) int action = RNA_enum_get(op->ptr, "action"); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; if (action == SEL_TOGGLE) { @@ -463,7 +463,7 @@ void SEQUENCER_OT_select_all(struct wmOperatorType *ot) static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -508,7 +508,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) { View2D *v2d = UI_view2d_fromcontext(C); Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); const bool extend = RNA_boolean_get(op->ptr, "extend"); const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all"); const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle"); @@ -799,7 +799,7 @@ void SEQUENCER_OT_select(wmOperatorType *ot) /* Run recursively to select linked. */ static bool select_linked_internal(Scene *scene) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return false; @@ -832,7 +832,7 @@ static bool select_linked_internal(Scene *scene) /* Select only one linked strip on each side. */ static bool select_more_less_seq__internal(Scene *scene, bool select_more) { - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return false; @@ -1070,7 +1070,7 @@ static const EnumPropertyItem prop_select_handles_side_types[] = { static int sequencer_select_handles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; int sel_side = RNA_enum_get(op->ptr, "side"); @@ -1169,7 +1169,7 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot) static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); const bool extend = RNA_boolean_get(op->ptr, "extend"); const int side = RNA_enum_get(op->ptr, "side"); @@ -1244,7 +1244,7 @@ void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) static int sequencer_select_side_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); const int sel_side = RNA_enum_get(op->ptr, "side"); const int frame_init = sel_side == SEQ_SIDE_LEFT ? INT_MIN : INT_MAX; @@ -1315,7 +1315,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); View2D *v2d = UI_view2d_fromcontext(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); if (ed == NULL) { return OPERATOR_CANCELLED; @@ -1679,7 +1679,7 @@ static bool select_grouped_effect_link(Editing *ed, static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *actseq = SEQ_select_active_get(scene); if (actseq == NULL) { diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index a0a9cdd96b1..981f793c896 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -90,7 +90,7 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); Scene *scene = CTX_data_scene(C); - const Editing *ed = SEQ_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene); SEQ_timeline_boundbox(scene, SEQ_active_seqbase_get(ed), &box); UI_view2d_smooth_view(C, region, &box, smooth_viewtx); @@ -274,7 +274,7 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View2D *v2d = UI_view2d_fromcontext(C); ARegion *region = CTX_wm_region(C); - Editing *ed = SEQ_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene); Sequence *seq; rctf cur_new = v2d->cur; diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 9548498f0b8..a2698b342d0 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -265,7 +265,7 @@ static void free_transform_custom_data(TransCustomData *custom_data) /* Canceled, need to update the strips display. */ static void seq_transform_cancel(TransInfo *t, SeqCollection *transformed_strips) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false)); + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene)); Sequence *seq; SEQ_ITERATOR_FOREACH (seq, transformed_strips) { @@ -346,7 +346,7 @@ static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips) static ListBase *seqbase_active_get(const TransInfo *t) { - Editing *ed = SEQ_editing_get(t->scene, false); + Editing *ed = SEQ_editing_get(t->scene); return SEQ_active_seqbase_get(ed); } @@ -589,7 +589,7 @@ static SeqCollection *seq_transform_collection_from_transdata(TransDataContainer static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data) { - Editing *ed = SEQ_editing_get(t->scene, false); + Editing *ed = SEQ_editing_get(t->scene); if (ed == NULL) { free_transform_custom_data(custom_data); return; @@ -622,7 +622,7 @@ void createTransSeqData(TransInfo *t) #define XXX_DURIAN_ANIM_TX_HACK Scene *scene = t->scene; - Editing *ed = SEQ_editing_get(t->scene, false); + Editing *ed = SEQ_editing_get(t->scene); TransData *td = NULL; TransData2D *td2d = NULL; TransDataSeq *tdsq = NULL; diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index 6e926f36fba..a54149912a9 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -137,7 +137,7 @@ static SeqCollection *seq_collection_extract_effects(SeqCollection *collection) static SeqCollection *query_snap_targets(const TransInfo *t, SeqCollection *snap_sources) { - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false)); + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene)); const short snap_flag = SEQ_tool_settings_snap_flag_get(t->scene); SeqCollection *snap_targets = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { @@ -255,7 +255,7 @@ static int seq_snap_threshold_get_frame_distance(const TransInfo *t) TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t) { TransSeqSnapData *snap_data = MEM_callocN(sizeof(TransSeqSnapData), __func__); - ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene, false)); + ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene)); SeqCollection *snap_sources = SEQ_query_selected_strips(seqbase); SeqCollection *snap_targets = query_snap_targets(t, snap_sources); diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index 9e05efca3df..fcbc0807893 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -565,7 +565,7 @@ bool ED_imbuf_sample_poll(bContext *C) return false; } - return sseq && SEQ_editing_get(CTX_data_scene(C), false) != NULL; + return sseq && SEQ_editing_get(CTX_data_scene(C)) != NULL; } return false; -- cgit v1.2.3 From f77de678d89fe9e279cbb4228959955f42b007d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Sep 2021 11:42:18 +1000 Subject: EditMesh: recalculate normals after running rip Failure to calculate normals caused an assertion since face tessellation was being calculated with invalid normals. In practice the rip-drag action would recalculate normals anyway, however mesh tessellation should always be performed with valid normals. --- source/blender/editors/mesh/editmesh_rip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 5a2a090b725..0553fa077f8 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1085,7 +1085,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event) EDBM_update(obedit->data, &(const struct EDBMUpdate_Params){ .calc_looptri = true, - .calc_normals = false, + .calc_normals = true, .is_destructive = true, }); } -- cgit v1.2.3 From 809b33b69a04fc37e1535697b667158ca80f6d60 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Sep 2021 15:29:33 +1000 Subject: Docs: improve the error when undo poll fails Calling undo in from Python background-mode would raise an exception without any information about how to initialize undo. --- source/blender/editors/undo/ed_undo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 3e0029156c1..84d5d3b9aae 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -574,7 +574,12 @@ static bool ed_undo_is_init_poll(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); if (wm->undo_stack == NULL) { - CTX_wm_operator_poll_msg_set(C, "Undo disabled at startup"); + /* This message is intended for Python developers, + * it will be part of the exception when attempting to call undo in background mode. */ + CTX_wm_operator_poll_msg_set( + C, + "Undo disabled at startup in background-mode. " + "Call `ed.undo_push()` to explicitly initialize the undo-system."); return false; } return true; -- cgit v1.2.3 From 4a3243f311c75d8b15fc39ec07dd57ecb40bd32f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Sep 2021 14:37:36 +1000 Subject: Docs: add note to skip_fcurve_selected_data sequence strip check Without an explanation the sequencer logic looked wrong since other selection checks don't skip data that can't be found. --- source/blender/editors/animation/anim_filter.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 7e3e3f363c2..104540e2257 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1111,7 +1111,27 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id /* Can only add this F-Curve if it is selected. */ if (ads->filterflag & ADS_FILTER_ONLYSEL) { - if ((seq == NULL) || (seq->flag & SELECT) == 0) { + + /* NOTE(@campbellbarton): The `seq == NULL` check doesn't look right + * (compared to other checks in this function which skip data that can't be found). + * + * This is done since the search for sequence strips doesn't use a global lookup: + * - Nested meta-strips are excluded. + * - When inside a meta-strip - strips outside the meta-strip excluded. + * + * Instead, only the strips directly visible to the user are considered for selection. + * The NULL check here means everything else is considered unselected and is not shown. + * + * There is a subtle difference between nodes, pose-bones ... etc + * since data-paths that point to missing strips are not shown. + * If this is an important difference, the NULL case could perform a global lookup, + * only returning `true` if the sequence strip exists elsewhere + * (ignoring it's selection state). */ + if (seq == NULL) { + return true; + } + + if ((seq->flag & SELECT) == 0) { return true; } } -- cgit v1.2.3 From ae334532cffb2dd9074454b9a7ba095430f18735 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 3 Sep 2021 15:24:01 +0200 Subject: GPencil: Smooth thickness when joining strokes When joining two strokes in paint mode using the auto merge option, the join was very hard if the thickness was too different. This patch adds a smooth to the join in order to get better transition. Also fixed the problem to join existing strokes very far from actual stroke. Some cleanup and rename of old code is included in order to make code more readable. Reviewed By: pepeland Differential Revision: https://developer.blender.org/D12362 --- source/blender/editors/gpencil/gpencil_edit.c | 4 ++-- source/blender/editors/gpencil/gpencil_fill.c | 2 +- .../blender/editors/gpencil/gpencil_interpolate.c | 2 +- source/blender/editors/gpencil/gpencil_paint.c | 21 +++++++++++++---- source/blender/editors/gpencil/gpencil_primitive.c | 16 +++++++++++-- .../blender/editors/gpencil/gpencil_sculpt_paint.c | 2 +- source/blender/editors/gpencil/gpencil_utils.c | 27 +++++++++++++++++++++- source/blender/editors/include/ED_gpencil.h | 7 ++++++ 8 files changed, 69 insertions(+), 12 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 8d1f841da6c..aa3178ddc2c 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3618,7 +3618,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op) } elem = &strokes_list[i]; /* Join new_stroke and stroke B. */ - BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true); + BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true, false); elem->used = true; } @@ -3967,7 +3967,7 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op) /* perform smoothing */ if (smooth_position) { - BKE_gpencil_stroke_smooth(gps, i, factor); + BKE_gpencil_stroke_smooth_point(gps, i, factor); } if (smooth_strength) { BKE_gpencil_stroke_smooth_strength(gps, i, factor); diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 0c88d678ef4..f5474a7cdc3 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -1569,7 +1569,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) float smoothfac = 1.0f; for (int r = 0; r < 1; r++) { for (int i = 0; i < gps->totpoints; i++) { - BKE_gpencil_stroke_smooth(gps, i, smoothfac - reduce); + BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce); } reduce += 0.25f; /* reduce the factor */ } diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index a8bd3b11bb1..fdd9f44605e 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -333,7 +333,7 @@ static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps, float reduce = 0.0f; for (int r = 0; r < smooth_steps; r++) { for (int i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth(gps, i, smooth_factor - reduce); + BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce); BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor); } reduce += 0.25f; /* reduce the factor */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 28a22633742..9b157224178 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1209,7 +1209,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) float reduce = 0.0f; for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) { for (i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth(gps, i, brush->gpencil_settings->draw_smoothfac - reduce); + BKE_gpencil_stroke_smooth_point( + gps, i, brush->gpencil_settings->draw_smoothfac - reduce); BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac); } reduce += 0.25f; /* reduce the factor */ @@ -1221,7 +1222,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) float ifac = (float)brush->gpencil_settings->input_samples / 10.0f; float sfac = interpf(1.0f, 0.2f, ifac); for (i = 0; i < gps->totpoints - 1; i++) { - BKE_gpencil_stroke_smooth(gps, i, sfac); + BKE_gpencil_stroke_smooth_point(gps, i, sfac); BKE_gpencil_stroke_smooth_strength(gps, i, sfac); } } @@ -1288,11 +1289,23 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* Join with existing strokes. */ if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) { if (gps->prev != NULL) { + BKE_gpencil_stroke_boundingbox_calc(gps); + float diff_mat[4][4], ctrl1[2], ctrl2[2]; + BKE_gpencil_layer_transform_matrix_get(depsgraph, p->ob, gpl, diff_mat); + ED_gpencil_stroke_extremes_to2d(&p->gsc, diff_mat, gps, ctrl1, ctrl2); + int pt_index = 0; bool doit = true; while (doit && gps) { - bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends( - p->C, &p->gsc, gpl, gpl->actframe, gps, GPENCIL_MINIMUM_JOIN_DIST, &pt_index); + bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(p->C, + &p->gsc, + gpl, + gpl->actframe, + gps, + ctrl1, + ctrl2, + GPENCIL_MINIMUM_JOIN_DIST, + &pt_index); if (gps_target != NULL) { gps = ED_gpencil_stroke_join_and_trim(p->gpd, p->gpf, gps, gps_target, pt_index); } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 5ecb6d9a212..f8cfc130e35 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -1382,11 +1382,23 @@ static void gpencil_primitive_interaction_end(bContext *C, if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) { if (ELEM(tgpi->type, GP_STROKE_ARC, GP_STROKE_LINE, GP_STROKE_CURVE, GP_STROKE_POLYLINE)) { if (gps->prev != NULL) { + BKE_gpencil_stroke_boundingbox_calc(gps); + float diff_mat[4][4], ctrl1[2], ctrl2[2]; + BKE_gpencil_layer_transform_matrix_get(tgpi->depsgraph, tgpi->ob, tgpi->gpl, diff_mat); + ED_gpencil_stroke_extremes_to2d(&tgpi->gsc, diff_mat, gps, ctrl1, ctrl2); + int pt_index = 0; bool doit = true; while (doit && gps) { - bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends( - C, &tgpi->gsc, tgpi->gpl, gpf, gps, GPENCIL_MINIMUM_JOIN_DIST, &pt_index); + bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(C, + &tgpi->gsc, + tgpi->gpl, + gpf, + gps, + ctrl1, + ctrl2, + GPENCIL_MINIMUM_JOIN_DIST, + &pt_index); if (gps_target != NULL) { gps = ED_gpencil_stroke_join_and_trim(tgpi->gpd, gpf, gps, gps_target, pt_index); } diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 869254cef3b..e9a6beab798 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -337,7 +337,7 @@ static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso, /* perform smoothing */ if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) { - BKE_gpencil_stroke_smooth(gps, pt_index, inf); + BKE_gpencil_stroke_smooth_point(gps, pt_index, inf); } if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) { BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf); diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 5cc52303cd6..72d10d840fa 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3213,11 +3213,28 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps, return hit; } +/* Get extremes of stroke in 2D using current view. */ +void ED_gpencil_stroke_extremes_to2d(const GP_SpaceConversion *gsc, + const float diff_mat[4][4], + bGPDstroke *gps, + float r_ctrl1[2], + float r_ctrl2[2]) +{ + bGPDspoint pt_dummy_ps; + + gpencil_point_to_parent_space(&gps->points[0], diff_mat, &pt_dummy_ps); + gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl1[0], &r_ctrl1[1]); + gpencil_point_to_parent_space(&gps->points[gps->totpoints - 1], diff_mat, &pt_dummy_ps); + gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl2[0], &r_ctrl2[1]); +} + bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C, const GP_SpaceConversion *gsc, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, + const float ctrl1[2], + const float ctrl2[2], const float radius, int *r_index) { @@ -3267,6 +3284,14 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C, gpencil_point_to_parent_space(pt, diff_mat, &pt_parent); gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_target_end[0], &pt2d_target_end[1]); + /* If the distance to the original stroke extremes is too big, the stroke must not be joined. */ + if ((len_squared_v2v2(ctrl1, pt2d_target_start) > radius_sqr) && + (len_squared_v2v2(ctrl1, pt2d_target_end) > radius_sqr) && + (len_squared_v2v2(ctrl2, pt2d_target_start) > radius_sqr) && + (len_squared_v2v2(ctrl2, pt2d_target_end) > radius_sqr)) { + continue; + } + if ((len_squared_v2v2(pt2d_start, pt2d_target_start) > radius_sqr) && (len_squared_v2v2(pt2d_start, pt2d_target_end) > radius_sqr) && (len_squared_v2v2(pt2d_end, pt2d_target_start) > radius_sqr) && @@ -3350,7 +3375,7 @@ bGPDstroke *ED_gpencil_stroke_join_and_trim( /* Join both strokes. */ int totpoint = gps_final->totpoints; - BKE_gpencil_stroke_join(gps_final, gps, false, true); + BKE_gpencil_stroke_join(gps_final, gps, false, true, true); /* Select the join points and merge if the distance is very small. */ pt = &gps_final->points[totpoint - 1]; diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 8a8d91a570c..c760b661373 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -391,8 +391,15 @@ struct bGPDstroke *ED_gpencil_stroke_nearest_to_ends(struct bContext *C, struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps, + const float ctrl1[2], + const float ctrl2[2], const float radius, int *r_index); +void ED_gpencil_stroke_extremes_to2d(const struct GP_SpaceConversion *gsc, + const float diff_mat[4][4], + struct bGPDstroke *gps, + float r_ctrl1[2], + float r_ctrl2[2]); struct bGPDstroke *ED_gpencil_stroke_join_and_trim(struct bGPdata *gpd, struct bGPDframe *gpf, -- cgit v1.2.3 From ac97893dfc77fd77e0254a0a4692820c7dbc6967 Mon Sep 17 00:00:00 2001 From: Leon Leno Date: Fri, 3 Sep 2021 16:13:29 +0200 Subject: Fix T88411: Draw frame node text when label is empty This patch fixes the issue described in T88411, that the text in frame nodes is only shown, when the node has a label. This has been caused by rB8f04ddbbc626, because `node_draw_frame_label` not only draws the label, but also all the other text. Therefore skipping it, when the label is empty, also skips drawing the other text. This is fixed by moving the check for the empty label into `node_frame_draw_label`. **Patch:** Frame nodes show text despite not having a label. {F10286204, size = full} **Same setup in master:** {F10128099, size = full} **Test file** {F10128102} Reviewed By: #user_interface, pablovazquez Maniphest Tasks: T88411 Differential Revision: https://developer.blender.org/D11315 --- source/blender/editors/space_node/drawnode.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 0f7a911e3ce..4b859de0ac9 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -362,8 +362,12 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp float x = BLI_rctf_cent_x(rct) - (0.5f * width); float y = rct->ymax - label_height; - BLF_position(fontid, x, y, 0); - BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX); + /* label */ + const bool has_label = node->label[0] != '\0'; + if (has_label) { + BLF_position(fontid, x, y, 0); + BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX); + } /* draw text body */ if (node->id) { @@ -374,7 +378,8 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp /* 'x' doesn't need aspect correction */ x = rct->xmin + margin; - y = rct->ymax - (label_height + line_spacing); + y = rct->ymax - label_height - (has_label ? line_spacing : 0); + /* early exit */ int y_min = y + ((margin * 2) - (y - rct->ymin)); @@ -455,10 +460,8 @@ static void node_draw_frame(const bContext *C, UI_draw_roundbox_aa(rct, false, BASIS_RAD, color); } - /* label */ - if (node->label[0] != '\0') { - node_draw_frame_label(ntree, node, snode->runtime->aspect); - } + /* label and text */ + node_draw_frame_label(ntree, node, snode->runtime->aspect); UI_block_end(C, node->block); UI_block_draw(C, node->block); -- cgit v1.2.3 From e6194e735791b42feb51e810a4910a41d999d3bf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 4 Sep 2021 14:22:44 +1000 Subject: RNA: support extracting names from paths without allocating memory Support extracting identifiers RNA paths into fixed size buffer since the maximum size of the identifier is known all cases. - Add BLI_str_unescape_ex to support limiting the destination buffer. - Add BLI_str_quoted_substr to copy values into a fixed size buffer. --- source/blender/editors/animation/anim_deps.c | 7 ++--- source/blender/editors/animation/anim_filter.c | 25 +++++++++--------- source/blender/editors/animation/anim_ipo_utils.c | 30 +++++++--------------- .../blender/editors/animation/keyframes_general.c | 9 +++---- source/blender/editors/animation/keyframing.c | 16 +++++------- source/blender/editors/armature/pose_select.c | 8 +++--- .../editors/transform/transform_convert_armature.c | 8 +++--- 7 files changed, 44 insertions(+), 59 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 916d4232f03..97679723d84 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -206,16 +206,17 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) BLI_assert(GS(owner_id->name) == ID_SCE); Scene *scene = (Scene *)owner_id; FCurve *fcu = (FCurve *)ale->data; + Sequence *seq = NULL; /* Only affect if F-Curve involves sequence_editor.sequences. */ - char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); - if (seq_name == NULL) { + char seq_name[sizeof(seq->name)]; + if (!BLI_str_quoted_substr(fcu->rna_path, "sequences_all[", seq_name, sizeof(seq_name))) { return; } /* Check if this strip is selected. */ Editing *ed = SEQ_editing_get(scene); - Sequence *seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); + seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); if (seq == NULL) { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 104540e2257..b12e0ae5cab 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1061,13 +1061,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id if (GS(owner_id->name) == ID_OB) { Object *ob = (Object *)owner_id; - char *bone_name; + bPoseChannel *pchan = NULL; + char bone_name[sizeof(pchan->name)]; /* Only consider if F-Curve involves `pose.bones`. */ - if (fcu->rna_path && (bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["))) { + if (fcu->rna_path && + BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) { /* Get bone-name, and check if this bone is selected. */ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); /* check whether to continue or skip */ if (pchan && pchan->bone) { @@ -1097,17 +1098,17 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id } else if (GS(owner_id->name) == ID_SCE) { Scene *scene = (Scene *)owner_id; - char *seq_name; + Sequence *seq = NULL; + char seq_name[sizeof(seq->name)]; /* Only consider if F-Curve involves `sequence_editor.sequences`. */ - if (fcu->rna_path && (seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["))) { + if (fcu->rna_path && + BLI_str_quoted_substr(fcu->rna_path, "sequences_all[", seq_name, sizeof(seq_name))) { /* Get strip name, and check if this strip is selected. */ - Sequence *seq = NULL; Editing *ed = SEQ_editing_get(scene); if (ed) { seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); } - MEM_freeN(seq_name); /* Can only add this F-Curve if it is selected. */ if (ads->filterflag & ADS_FILTER_ONLYSEL) { @@ -1139,14 +1140,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id } else if (GS(owner_id->name) == ID_NT) { bNodeTree *ntree = (bNodeTree *)owner_id; - char *node_name; + bNode *node = NULL; + char node_name[sizeof(node->name)]; /* Check for selected nodes. */ - if (fcu->rna_path && (node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["))) { - bNode *node = NULL; + if (fcu->rna_path && + (BLI_str_quoted_substr(fcu->rna_path, "nodes[", node_name, sizeof(node_name)))) { /* Get strip name, and check if this strip is selected. */ node = nodeFindNodebyName(ntree, node_name); - MEM_freeN(node_name); /* Can only add this F-Curve if it is selected. */ if (node) { diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index eda87cf1897..33b4882927a 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -106,23 +106,14 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) * - If a pointer just refers to the ID-block, then don't repeat this info * since this just introduces clutter. */ - if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) { - /* perform string 'chopping' to get "Bone Name : Constraint Name" */ - char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones["); - char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints["); + + char pchanName[256], constName[256]; + if (BLI_str_quoted_substr(fcu->rna_path, "bones[", pchanName, sizeof(pchanName)) && + BLI_str_quoted_substr(fcu->rna_path, "constraints[", constName, sizeof(constName))) { /* assemble the string to display in the UI... */ - structname = BLI_sprintfN( - "%s : %s", pchanName ? pchanName : "", constName ? constName : ""); + structname = BLI_sprintfN("%s : %s", pchanName, constName); free_structname = 1; - - /* free the temp names */ - if (pchanName) { - MEM_freeN(pchanName); - } - if (constName) { - MEM_freeN(constName); - } } else if (ptr.data != ptr.owner_id) { PropertyRNA *nameprop = RNA_struct_name_property(ptr.type); @@ -139,18 +130,15 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) * displaying the struct name alone is no meaningful information (and also cannot be * filtered well), same for modifiers. So display strip name alongside as well. */ if (GS(ptr.owner_id->name) == ID_SCE) { - if (BLI_str_startswith(fcu->rna_path, "sequence_editor.sequences_all[\"")) { + char stripname[256]; + if (BLI_str_quoted_substr( + fcu->rna_path, "sequence_editor.sequences_all[", stripname, sizeof(stripname))) { if (strstr(fcu->rna_path, ".transform.") || strstr(fcu->rna_path, ".crop.") || strstr(fcu->rna_path, ".modifiers[")) { - char *stripname = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); - const char *structname_all = BLI_sprintfN( - "%s : %s", stripname ? stripname : "", structname); + const char *structname_all = BLI_sprintfN("%s : %s", stripname, structname); if (free_structname) { MEM_freeN((void *)structname); } - if (stripname) { - MEM_freeN(stripname); - } structname = structname_all; free_structname = 1; } diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 9f3fe239113..ec33a42af3b 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -761,11 +761,10 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data) if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) { Object *ob = (Object *)aci->id; - char *bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones["); - if (bone_name) { - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); - + bPoseChannel *pchan; + char bone_name[sizeof(pchan->name)]; + if (BLI_str_quoted_substr(aci->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) { + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); if (pchan) { aci->is_bone = true; } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 292d665caca..8dc4aed9f0e 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2218,11 +2218,11 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) if (ob->mode & OB_MODE_POSE) { if (fcu->rna_path) { /* Get bone-name, and check if this bone is selected. */ - char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - if (bone_name) { - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); - + bPoseChannel *pchan = NULL; + char bone_name[sizeof(pchan->name)]; + if (BLI_str_quoted_substr( + fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) { + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); /* Delete if bone is selected. */ if ((pchan) && (pchan->bone)) { if (pchan->bone->flag & BONE_SELECTED) { @@ -2323,13 +2323,11 @@ static int delete_key_v3d_without_keying_set(bContext *C, wmOperator *op) bPoseChannel *pchan = NULL; /* Get bone-name, and check if this bone is selected. */ - char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - if (bone_name == NULL) { + char bone_name[sizeof(pchan->name)]; + if (!BLI_str_quoted_substr(fcu->rna_path, "pose.bones[", bone_name, sizeof(bone_name))) { continue; } - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - MEM_freeN(bone_name); /* skip if bone is not selected */ if ((pchan) && (pchan->bone)) { diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 4db8569a7d2..e5b8983af93 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -1106,12 +1106,12 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex for (ksp = ks->paths.first; ksp; ksp = ksp->next) { /* only items related to this object will be relevant */ if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) { - char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones["); - if (boneName == NULL) { + bPoseChannel *pchan = NULL; + char boneName[sizeof(pchan->name)]; + if (!BLI_str_quoted_substr(ksp->rna_path, "bones[", boneName, sizeof(boneName))) { continue; } - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName); - MEM_freeN(boneName); + pchan = BKE_pose_channel_find_name(pose, boneName); if (pchan) { /* select if bone is visible and can be affected */ diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 98e00c20170..8f896512410 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -145,15 +145,15 @@ static void autokeyframe_pose( if (act) { for (fcu = act->curves.first; fcu; fcu = fcu->next) { /* only insert keyframes for this F-Curve if it affects the current bone */ - char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones["); - if (pchanName == NULL) { + char pchan_name[sizeof(pchan->name)]; + if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) { continue; } /* only if bone name matches too... * NOTE: this will do constraints too, but those are ok to do here too? */ - if (STREQ(pchanName, pchan->name)) { + if (STREQ(pchan_name, pchan->name)) { insert_keyframe(bmain, reports, id, @@ -166,8 +166,6 @@ static void autokeyframe_pose( &nla_cache, flag); } - - MEM_freeN(pchanName); } } } -- cgit v1.2.3 From 9290b41381fdf02d1431b216de6477f93b2897cb Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sat, 4 Sep 2021 08:00:22 -0700 Subject: Python: Allow Area Close via Scripting Screen area maintenance "Close" function allowed to be scripted. See D12307 for usage example. Differential Revision: https://developer.blender.org/D12307 Reviewed by Campbell Barton --- source/blender/editors/screen/screen_ops.c | 38 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index daac196a90c..75f1baf30bb 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1466,15 +1466,39 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) * Close selected area, replace by expanding a neighbor * \{ */ -/* operator callback */ -static int area_close_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +/** + * \note This can be used interactively or from Python. + * + * \note Most of the window management operators don't support execution from Python. + * An exception is made for closing areas since it allows application templates + * to customize the layout. + */ +static int area_close_exec(bContext *C, wmOperator *op) { + bScreen *screen = CTX_wm_screen(C); ScrArea *area = CTX_wm_area(C); - if ((area != NULL) && screen_area_close(C, CTX_wm_screen(C), area)) { - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; + + /* This operator is scriptable, so the area passed could be invalid. */ + if (BLI_findindex(&screen->areabase, area) == -1) { + BKE_report(op->reports, RPT_ERROR, "Area not found in the active screen"); + return OPERATOR_CANCELLED; } - return OPERATOR_CANCELLED; + + if (!screen_area_close(C, screen, area)) { + BKE_report(op->reports, RPT_ERROR, "Unable to close area"); + return OPERATOR_CANCELLED; + } + + /* Ensure the event loop doesn't attempt to continue handling events. + * + * This causes execution from the Python console fail to return to the prompt as it should. + * This glitch could be solved in the event loop handling as other operators may also + * destructively manipulate windowing data. */ + CTX_wm_window_set(C, NULL); + + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; } static bool area_close_poll(bContext *C) @@ -1506,7 +1530,7 @@ static void SCREEN_OT_area_close(wmOperatorType *ot) ot->name = "Close Area"; ot->description = "Close selected area"; ot->idname = "SCREEN_OT_area_close"; - ot->invoke = area_close_invoke; + ot->exec = area_close_exec; ot->poll = area_close_poll; } -- cgit v1.2.3 From 079bd115563640b81cccba645d15b6b55efd3b8e Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Sat, 4 Sep 2021 18:28:31 +0200 Subject: Fix T91143: Gpencil Set Vertex Color not using Linear The color was not converted to Linear from Brush color. --- source/blender/editors/gpencil/gpencil_vertex_ops.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c index 402bccce2f7..5c3a7cf9e6f 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_ops.c +++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c @@ -588,6 +588,7 @@ static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op) changed = true; copy_v3_v3(gps->vert_color_fill, brush->rgb); gps->vert_color_fill[3] = factor; + srgb_to_linearrgb_v4(gps->vert_color_fill, gps->vert_color_fill); } /* Stroke points. */ @@ -596,10 +597,13 @@ static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op) int i; bGPDspoint *pt; + float color[4]; + copy_v3_v3(color, brush->rgb); + color[3] = factor; + srgb_to_linearrgb_v4(color, color); for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { if ((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) { - copy_v3_v3(pt->vert_color, brush->rgb); - pt->vert_color[3] = factor; + copy_v3_v3(pt->vert_color, color); } } } -- cgit v1.2.3 From 91bca410c0e08c6d1cd227336df91faddab7a767 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Sun, 5 Sep 2021 23:25:36 -0400 Subject: Cleanup: clang-format --- source/blender/editors/gpencil/gpencil_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 72d10d840fa..bb05b93ad81 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3284,7 +3284,8 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C, gpencil_point_to_parent_space(pt, diff_mat, &pt_parent); gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_target_end[0], &pt2d_target_end[1]); - /* If the distance to the original stroke extremes is too big, the stroke must not be joined. */ + /* If the distance to the original stroke extremes is too big, the stroke must not be joined. + */ if ((len_squared_v2v2(ctrl1, pt2d_target_start) > radius_sqr) && (len_squared_v2v2(ctrl1, pt2d_target_end) > radius_sqr) && (len_squared_v2v2(ctrl2, pt2d_target_start) > radius_sqr) && -- cgit v1.2.3 From ce71357711eb0d79916045f1e67523af21b1791e Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Mon, 6 Sep 2021 17:34:59 +0200 Subject: Fix T90414: New GPencil icons Designed by @mendio The new icons are: * Dot-Dash modifier * Length Modifier * Line Art modifier --- source/blender/editors/datafiles/CMakeLists.txt | 3 +++ source/blender/editors/include/UI_icons.h | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index c4916b9182f..669ceb37328 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -390,6 +390,9 @@ set(ICON_NAMES small_caps modifier con_action + mod_length + mod_dash + mod_lineart holdout_off holdout_on indirect_only_off diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 1708c3598b1..ddd9ca4a98c 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -490,9 +490,9 @@ DEF_ICON_MODIFIER(CON_ACTION) DEF_ICON_BLANK(745) DEF_ICON_BLANK(746) DEF_ICON_BLANK(747) -DEF_ICON_BLANK(748) -DEF_ICON_BLANK(749) -DEF_ICON_BLANK(750) +DEF_ICON_MODIFIER(MOD_LENGTH) +DEF_ICON_MODIFIER(MOD_DASH) +DEF_ICON_MODIFIER(MOD_LINEART) DEF_ICON_BLANK(751) DEF_ICON(HOLDOUT_OFF) DEF_ICON(HOLDOUT_ON) -- cgit v1.2.3 From 5a9a16334c573c4566dc9b2a314cf0d0ccdcb54f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 6 Sep 2021 18:22:24 +0200 Subject: Geometry Nodes: support for geometry instancing Previously, the Point Instance node in geometry nodes could only instance existing objects or collections. The reason was that large parts of Blender worked under the assumption that objects are the main unit of instancing. Now we also want to instance geometry within an object, so a slightly larger refactor was necessary. This should not affect files that do not use the new kind of instances. The main change is a redefinition of what "instanced data" is. Now, an instances is a cow-object + object-data (the geometry). This can be nicely seen in `struct DupliObject`. This allows the same object to generate multiple geometries of different types which can be instanced individually. A nice side effect of this refactor is that having multiple geometry components is not a special case in the depsgraph object iterator anymore, because those components are integrated with the `DupliObject` system. Unfortunately, different systems that work with instances in Blender (e.g. render engines and exporters) often work under the assumption that objects are the main unit of instancing. So those have to be updated as well to be able to handle the new instances. This patch updates Cycles, EEVEE and other viewport engines. Exporters have not been updated yet. Some minimal (not master-ready) changes to update the obj and alembic exporters can be found in P2336 and P2335. Different file formats may want to handle these new instances in different ways. For users, the only thing that changed is that the Point Instance node now has a geometry mode. This also fixes T88454. Differential Revision: https://developer.blender.org/D11841 --- source/blender/editors/object/object_add.c | 10 ++-------- .../editors/space_spreadsheet/spreadsheet_cell_value.hh | 5 +++++ .../spreadsheet_data_source_geometry.cc | 5 +++++ .../editors/space_spreadsheet/spreadsheet_layout.cc | 17 +++++++++++++++++ .../blender/editors/transform/transform_snap_object.c | 4 +--- 5 files changed, 30 insertions(+), 11 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 2e34284f46e..f95e3f3b236 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2246,13 +2246,6 @@ static bool dupliobject_instancer_cmp(const void *a_, const void *b_) return false; } -static bool object_has_geometry_set_instances(const Object *object_eval) -{ - struct GeometrySet *geometry_set = object_eval->runtime.geometry_set_eval; - - return (geometry_set != NULL) && BKE_geometry_set_has_instances(geometry_set); -} - static void make_object_duplilist_real(bContext *C, Depsgraph *depsgraph, Scene *scene, @@ -2266,7 +2259,8 @@ static void make_object_duplilist_real(bContext *C, Object *object_eval = DEG_get_evaluated_object(depsgraph, base->object); - if (!(base->object->transflag & OB_DUPLI) && !object_has_geometry_set_instances(object_eval)) { + if (!(base->object->transflag & OB_DUPLI) && + !BKE_object_has_geometry_set_instances(object_eval)) { return; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh index 680da9b6794..97170693cb3 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_cell_value.hh @@ -35,6 +35,10 @@ struct CollectionCellValue { const Collection *collection; }; +struct GeometrySetCellValue { + const GeometrySet *geometry_set; +}; + /** * This is a type that can hold the value of a cell in a spreadsheet. This type allows us to * decouple the drawing of individual cells from the code that generates the data to be displayed. @@ -53,6 +57,7 @@ class CellValue { std::optional value_color; std::optional value_object; std::optional value_collection; + std::optional value_geometry_set; }; } // namespace blender::ed::spreadsheet diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index e38c70afd0f..12815c2c7e9 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -332,6 +332,11 @@ std::unique_ptr InstancesDataSource::get_column_values( r_cell_value.value_collection = CollectionCellValue{&collection}; break; } + case InstanceReference::Type::GeometrySet: { + const GeometrySet &geometry_set = reference.geometry_set(); + r_cell_value.value_geometry_set = GeometrySetCellValue{&geometry_set}; + break; + } case InstanceReference::Type::None: { break; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc index 8079763a339..1a5eac53306 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc @@ -209,6 +209,23 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { 0, nullptr); } + else if (cell_value.value_geometry_set.has_value()) { + uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_MESH_DATA, + "Geometry", + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + } } void draw_float_vector(const CellDrawParams ¶ms, const Span values) const diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index bb04f557074..811f30c96e5 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -501,9 +501,7 @@ static void iter_snap_objects(SnapObjectContext *sctx, } Object *obj_eval = DEG_get_evaluated_object(depsgraph, base->object); - if (obj_eval->transflag & OB_DUPLI || - (obj_eval->runtime.geometry_set_eval != NULL && - BKE_geometry_set_has_instances(obj_eval->runtime.geometry_set_eval))) { + if (obj_eval->transflag & OB_DUPLI || BKE_object_has_geometry_set_instances(obj_eval)) { ListBase *lb = object_duplilist(depsgraph, sctx->scene, obj_eval); for (DupliObject *dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { BLI_assert(DEG_is_evaluated_object(dupli_ob->ob)); -- cgit v1.2.3 From 3b1a16833b5834d768eacbcfdff4ee000a8d1af5 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Mon, 6 Sep 2021 09:40:06 -0700 Subject: UI: Area Split and Join Mouse Cursor Feedback This patch just changes the mouse cursor to a "stop sign" when dragging to an unsupported location during Join or Split operations. See D11396 for details and examples. Differential Revision: https://developer.blender.org/D11396 Reviewed by Campbell Barton --- source/blender/editors/screen/screen_ops.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 75f1baf30bb..5d6f21f4854 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1134,14 +1134,22 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) if ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) && (screen_geom_area_map_find_active_scredge( AREAMAP_FROM_SCREEN(screen), &screen_rect, event->x, event->y) == NULL)) { - /* Are we still in same area? */ - if (BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y) == sad->sa1) { + + /* What area are we now in? */ + ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y); + + if (area == sad->sa1) { /* Same area, so possible split. */ WM_cursor_set(win, SCREEN_DIR_IS_VERTICAL(sad->gesture_dir) ? WM_CURSOR_H_SPLIT : WM_CURSOR_V_SPLIT); is_gesture = (delta_max > split_threshold); } + else if (!area || area->global) { + /* No area or Top bar or Status bar. */ + WM_cursor_set(win, WM_CURSOR_STOP); + is_gesture = false; + } else { /* Different area, so possible join. */ if (sad->gesture_dir == SCREEN_DIR_N) { @@ -1161,7 +1169,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) } } else { - WM_cursor_set(CTX_wm_window(C), WM_CURSOR_CROSS); + WM_cursor_set(win, WM_CURSOR_CROSS); is_gesture = false; } } -- cgit v1.2.3 From 08acbdc1ff75607001f770b4281f53ec87449b7f Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 7 Sep 2021 11:03:48 -0300 Subject: Fix T91219: Crash canceling scale keyframes in dope sheet grease pencil Caused by {rBb0d9e6797fb8} Ideally `td->loc` should always be set and point to a 3d array. --- .../editors/transform/transform_convert_action.c | 20 +++++++++++--------- .../blender/editors/transform/transform_generics.c | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c index 075db30fa61..a6658ae00a3 100644 --- a/source/blender/editors/transform/transform_convert_action.c +++ b/source/blender/editors/transform/transform_convert_action.c @@ -51,7 +51,10 @@ /* helper struct for gp-frame transforms */ typedef struct tGPFtransdata { - float val; /* where transdata writes transform */ + union { + float val; /* where transdata writes transform */ + float loc[3]; /* #td->val and #td->loc share the same pointer. */ + }; int *sdata; /* pointer to gpf->framenum */ } tGPFtransdata; @@ -245,8 +248,8 @@ static int GPLayerToTransData(TransData *td, tfd->val = (float)gpf->framenum; tfd->sdata = &gpf->framenum; - td->val = td->loc = &tfd->val; /* XXX: It's not a 3d array. */ - td->ival = td->iloc[0] = (float)gpf->framenum; + td->val = td->loc = &tfd->val; + td->ival = td->iloc[0] = tfd->val; td->center[0] = td->ival; td->center[1] = ypos; @@ -279,16 +282,15 @@ static int MaskLayerToTransData(TransData *td, masklay_shape = masklay_shape->next) { if (is_prop_edit || (masklay_shape->flag & MASK_SHAPE_SELECT)) { if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) { - /* memory is calloc'ed, so that should zero everything nicely for us */ - td->val = &tfd->val; - td->ival = (float)masklay_shape->frame; + tfd->val = (float)masklay_shape->frame; + tfd->sdata = &masklay_shape->frame; + + td->val = td->loc = &tfd->val; + td->ival = td->iloc[0] = tfd->val; td->center[0] = td->ival; td->center[1] = ypos; - tfd->val = (float)masklay_shape->frame; - tfd->sdata = &masklay_shape->frame; - /* advance td now */ td++; tfd++; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 9f5e74db501..0dfb229191c 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -791,7 +791,7 @@ static void restoreElement(TransData *td) { transdata_restore_basic((TransDataBasic *)td); - if (td->val) { + if (td->val && td->val != td->loc) { *td->val = td->ival; } -- cgit v1.2.3 From adbafe3b43d6131c74d96128b23ed24ae904d487 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Sep 2021 20:10:53 +0100 Subject: Animation: Implement generic slider in graph_slider_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements the generic slider from `ed_draw.c` to the `GRAPH_OT_decimate` operator This draws a useful UI and enables precision mode and stepping Overshoot is disabled The status message is moved to the workspace footer Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D9361 Ref: D9361 --- .../blender/editors/space_graph/graph_slider_ops.c | 46 ++++++++++------------ 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index 10629caa8b0..f04336cab84 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -41,6 +41,7 @@ #include "ED_keyframes_edit.h" #include "ED_numinput.h" #include "ED_screen.h" +#include "ED_util.h" #include "WM_api.h" #include "WM_types.h" @@ -94,6 +95,8 @@ typedef struct tDecimateGraphOp { /** The original bezt curve data (used for restoring fcurves). */ ListBase bezt_arr_list; + struct tSlider *slider; + NumInput num; } tDecimateGraphOp; @@ -161,6 +164,8 @@ static void decimate_exit(bContext *C, wmOperator *op) ScrArea *area = dgo->area; LinkData *link; + ED_slider_destroy(C, dgo->slider); + for (link = dgo->bezt_arr_list.first; link != NULL; link = link->next) { tBeztCopyData *copy = link->data; MEM_freeN(copy->bezt); @@ -178,11 +183,14 @@ static void decimate_exit(bContext *C, wmOperator *op) op->customdata = NULL; } -/* Draw a percentage indicator in header. */ -static void decimate_draw_status_header(wmOperator *op, tDecimateGraphOp *dgo) +/* Draw a percentage indicator in workspace footer. */ +static void decimate_draw_status(bContext *C, tDecimateGraphOp *dgo) { char status_str[UI_MAX_DRAW_STR]; char mode_str[32]; + char slider_string[UI_MAX_DRAW_STR]; + + ED_slider_status_string_get(dgo->slider, slider_string, UI_MAX_DRAW_STR); strcpy(mode_str, TIP_("Decimate Keyframes")); @@ -194,23 +202,10 @@ static void decimate_draw_status_header(wmOperator *op, tDecimateGraphOp *dgo) BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs); } else { - float percentage = RNA_property_float_get(op->ptr, dgo->percentage_prop); - BLI_snprintf( - status_str, sizeof(status_str), "%s: %d %%", mode_str, (int)(percentage * 100.0f)); + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string); } - ED_area_status_text(dgo->area, status_str); -} - -/* Calculate percentage based on position of mouse (we only use x-axis for now. - * Since this is more convenient for users to do), and store new percentage value. - */ -static void decimate_mouse_update_percentage(tDecimateGraphOp *dgo, - wmOperator *op, - const wmEvent *event) -{ - float percentage = (event->x - dgo->region->winrct.xmin) / ((float)dgo->region->winx); - RNA_property_float_set(op->ptr, dgo->percentage_prop, percentage); + ED_workspace_status_text(C, status_str); } static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -234,10 +229,11 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent dgo->area = CTX_wm_area(C); dgo->region = CTX_wm_region(C); - /* Initialize percentage so that it will have the correct value before the first mouse move. */ - decimate_mouse_update_percentage(dgo, op, event); + dgo->slider = ED_slider_create(C); + ED_slider_init(dgo->slider, event); + ED_slider_allow_overshoot_set(dgo->slider, false); - decimate_draw_status_header(op, dgo); + decimate_draw_status(C, dgo); /* Construct a list with the original bezt arrays so we can restore them during modal operation. */ @@ -300,13 +296,14 @@ static void graphkeys_decimate_modal_update(bContext *C, wmOperator *op) * (e.g. pressing a key or moving the mouse). */ tDecimateGraphOp *dgo = op->customdata; - decimate_draw_status_header(op, dgo); + decimate_draw_status(C, dgo); /* Reset keyframe data (so we get back to the original state). */ decimate_reset_bezts(dgo); /* Apply... */ - float remove_ratio = RNA_property_float_get(op->ptr, dgo->percentage_prop); + float remove_ratio = ED_slider_factor_get(dgo->slider); + RNA_property_float_set(op->ptr, dgo->percentage_prop, remove_ratio); /* We don't want to limit the decimation to a certain error margin. */ const float error_sq_max = FLT_MAX; decimate_graph_keys(&dgo->ac, remove_ratio, error_sq_max); @@ -323,6 +320,8 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent * const bool has_numinput = hasNumInput(&dgo->num); + ED_slider_modal(dgo->slider, event); + switch (event->type) { case LEFTMOUSE: /* Confirm */ case EVT_RETKEY: @@ -353,9 +352,6 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent * case MOUSEMOVE: /* Calculate new position. */ { if (has_numinput == false) { - /* Update percentage based on position of mouse. */ - decimate_mouse_update_percentage(dgo, op, event); - /* Update pose to reflect the new values. */ graphkeys_decimate_modal_update(C, op); } -- cgit v1.2.3 From 4abbf6d82b190e1f67e180bf4330e51a53267144 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 7 Sep 2021 23:39:50 +0200 Subject: Fix T90967: Snapping not working with single strip Even if `snap_targets` `SeqCollection` is empty, there can be static snap points defined, so don't condition snapping on non-zero target count. Differential Revision: https://developer.blender.org/D12400 --- source/blender/editors/transform/transform_snap_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index a54149912a9..e82a00bcc77 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -260,7 +260,7 @@ TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t) SeqCollection *snap_sources = SEQ_query_selected_strips(seqbase); SeqCollection *snap_targets = query_snap_targets(t, snap_sources); - if (SEQ_collection_len(snap_sources) == 0 || SEQ_collection_len(snap_targets) == 0) { + if (SEQ_collection_len(snap_sources) == 0) { SEQ_collection_free(snap_targets); SEQ_collection_free(snap_sources); MEM_freeN(snap_data); -- cgit v1.2.3 From e6a1d488ab7968729ec450f7f5674a49a555dbbd Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 8 Sep 2021 00:01:00 +0200 Subject: Cleanup: VSE select operator Operator combines more features and it wasn't very transparent which properties are used in which feature and how they are used. Features linked_time, side_of_frame and linked_handle are isolated, logic moved into own function. deselect_all property was removed as it practically equals to !extend in all cases. Functional change: Dragging existing selection will not change active strip. Previously this could happen if click happened on strip that wasn't active. Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D12320 --- .../editors/space_sequencer/sequencer_select.c | 402 ++++++++++----------- 1 file changed, 201 insertions(+), 201 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 4c938a412d2..80d3e2cbdaa 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -504,238 +504,245 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot) /** \name Select Operator * \{ */ -static int sequencer_select_exec(bContext *C, wmOperator *op) +static void sequencer_select_set_active(Scene *scene, Sequence *seq) { - View2D *v2d = UI_view2d_fromcontext(C); - Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); - const bool extend = RNA_boolean_get(op->ptr, "extend"); - const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all"); - const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle"); - const bool linked_time = RNA_boolean_get(op->ptr, "linked_time"); - bool side_of_frame = RNA_boolean_get(op->ptr, "side_of_frame"); - bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others"); - int mval[2]; - int ret_value = OPERATOR_CANCELLED; - mval[0] = RNA_int_get(op->ptr, "mouse_x"); - mval[1] = RNA_int_get(op->ptr, "mouse_y"); - - Sequence *seq, *neighbor, *act_orig; - int hand, sel_side; + SEQ_select_active_set(scene, seq); - if (ed == NULL) { - return OPERATOR_CANCELLED; + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { + if (seq->strip) { + BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); + } } - - if (extend) { - wait_to_deselect_others = false; + else if (seq->type == SEQ_TYPE_SOUND_RAM) { + if (seq->strip) { + BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); + } } + recurs_sel_seq(seq); +} - seq = find_nearest_seq(scene, v2d, &hand, mval); +static void sequencer_select_do_updates(bContext *C, Scene *scene) +{ + ED_outliner_select_sync_from_sequence_tag(C); + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); +} - /* XXX: not nice, Ctrl+RMB needs to do side_of_frame only when not over a strip. */ - if (seq && linked_time) { - side_of_frame = false; - } +static void sequencer_select_side_of_frame(const bContext *C, + const View2D *v2d, + const int mval[2], + Scene *scene) +{ + Editing *ed = SEQ_editing_get(scene); - /* Select left, right or overlapping the current frame. */ - if (side_of_frame) { - /* Use different logic for this. */ - if (extend == false) { - ED_sequencer_deselect_all(scene); + const float x = UI_view2d_region_to_view_x(v2d, mval[0]); + LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { + if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) || + ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) { + /* Select left or right. */ + seq_iter->flag |= SELECT; + recurs_sel_seq(seq_iter); } + } - const float x = UI_view2d_region_to_view_x(v2d, mval[0]); + { + SpaceSeq *sseq = CTX_wm_space_seq(C); + if (sseq && sseq->flag & SEQ_MARKER_TRANS) { + TimeMarker *tmarker; - LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) { - if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) || - ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) { - /* Select left or right. */ - seq_iter->flag |= SELECT; - recurs_sel_seq(seq_iter); + for (tmarker = scene->markers.first; tmarker; tmarker = tmarker->next) { + if (((x < CFRA) && (tmarker->frame <= CFRA)) || + ((x >= CFRA) && (tmarker->frame >= CFRA))) { + tmarker->flag |= SELECT; + } + else { + tmarker->flag &= ~SELECT; + } } } + } +} - { - SpaceSeq *sseq = CTX_wm_space_seq(C); - if (sseq && sseq->flag & SEQ_MARKER_TRANS) { - TimeMarker *tmarker; +static void sequencer_select_linked_handle(const bContext *C, + Sequence *seq, + const int handle_clicked) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); + if (!ELEM(handle_clicked, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) { + /* First click selects the strip and its adjacent handles (if valid). + * Second click selects the strip, + * both of its handles and its adjacent handles (if valid). */ + const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT); + seq->flag &= ~SEQ_ALLSEL; + seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT; + select_surrounding_handles(scene, seq); + } + else { + /* Always select the strip under the cursor. */ + seq->flag |= SELECT; - for (tmarker = scene->markers.first; tmarker; tmarker = tmarker->next) { - if (((x < CFRA) && (tmarker->frame <= CFRA)) || - ((x >= CFRA) && (tmarker->frame >= CFRA))) { - tmarker->flag |= SELECT; + /* First click selects adjacent handles on that side. + * Second click selects all strips in that direction. + * If there are no adjacent strips, it just selects all in that direction. + */ + int sel_side = handle_clicked; + Sequence *neighbor = find_neighboring_sequence(scene, seq, sel_side, -1); + if (neighbor) { + switch (sel_side) { + case SEQ_SIDE_LEFT: + if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { + seq->flag |= SELECT; + select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp); } else { - tmarker->flag &= ~SELECT; + seq->flag |= SELECT; + neighbor->flag |= SELECT; + recurs_sel_seq(neighbor); + neighbor->flag |= SEQ_RIGHTSEL; + seq->flag |= SEQ_LEFTSEL; } - } + break; + case SEQ_SIDE_RIGHT: + if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { + seq->flag |= SELECT; + select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp); + } + else { + seq->flag |= SELECT; + neighbor->flag |= SELECT; + recurs_sel_seq(neighbor); + neighbor->flag |= SEQ_LEFTSEL; + seq->flag |= SEQ_RIGHTSEL; + } + break; } } + else { - ret_value = OPERATOR_FINISHED; + select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp); + } } - else { - act_orig = ed->act_seq; - - if (seq) { - /* Are we trying to select a handle that's already selected? */ - const bool handle_selected = ((hand == SEQ_SIDE_LEFT) && (seq->flag & SEQ_LEFTSEL)) || - ((hand == SEQ_SIDE_RIGHT) && (seq->flag & SEQ_RIGHTSEL)); - - if (wait_to_deselect_others && (seq->flag & SELECT) && - (hand == SEQ_SIDE_NONE || handle_selected)) { - ret_value = OPERATOR_RUNNING_MODAL; - } - else if (!extend && !linked_handle) { - ED_sequencer_deselect_all(scene); - ret_value = OPERATOR_FINISHED; - } - else { - ret_value = OPERATOR_FINISHED; - } - - SEQ_select_active_set(scene, seq); +} - if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { - if (seq->strip) { - BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); - } - } - else if (seq->type == SEQ_TYPE_SOUND_RAM) { - if (seq->strip) { - BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); - } - } +static bool element_already_selected(const Sequence *seq, const int handle_clicked) +{ + const bool handle_already_selected = ((handle_clicked == SEQ_SIDE_LEFT) && + (seq->flag & SEQ_LEFTSEL)) || + ((handle_clicked == SEQ_SIDE_RIGHT) && + (seq->flag & SEQ_RIGHTSEL)); + return ((seq->flag & SELECT) && handle_clicked == SEQ_SIDE_NONE) || handle_already_selected; +} - /* On Alt selection, select the strip and bordering handles. */ - if (linked_handle) { - if (!ELEM(hand, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) { - /* First click selects the strip and its adjacent handles (if valid). - * Second click selects the strip, - * both of its handles and its adjacent handles (if valid). */ - const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT); +static void sequencer_select_strip_impl(const Editing *ed, + Sequence *seq, + const int handle_clicked, + const bool extend) +{ + /* Deselect strip. */ + if (extend && (seq->flag & SELECT) && ed->act_seq == seq) { + switch (handle_clicked) { + case SEQ_SIDE_NONE: + seq->flag &= ~SEQ_ALLSEL; + break; + case SEQ_SIDE_LEFT: + seq->flag ^= SEQ_LEFTSEL; + break; + case SEQ_SIDE_RIGHT: + seq->flag ^= SEQ_RIGHTSEL; + break; + } + } + else { /* Select strip. */ + seq->flag |= SELECT; + if (handle_clicked == SEQ_SIDE_LEFT) { + seq->flag |= SEQ_LEFTSEL; + } + if (handle_clicked == SEQ_SIDE_RIGHT) { + seq->flag |= SEQ_RIGHTSEL; + } + } +} - if (!extend) { - ED_sequencer_deselect_all(scene); - } - seq->flag &= ~SEQ_ALLSEL; - seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT; - select_surrounding_handles(scene, seq); - } - else { - /* Always select the strip under the cursor. */ - seq->flag |= SELECT; +static int sequencer_select_exec(bContext *C, wmOperator *op) +{ + View2D *v2d = UI_view2d_fromcontext(C); + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); + const bool extend = RNA_boolean_get(op->ptr, "extend"); - /* First click selects adjacent handles on that side. - * Second click selects all strips in that direction. - * If there are no adjacent strips, it just selects all in that direction. - */ - sel_side = hand; - neighbor = find_neighboring_sequence(scene, seq, sel_side, -1); - if (neighbor) { - switch (sel_side) { - case SEQ_SIDE_LEFT: - if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) { - if (extend == 0) { - ED_sequencer_deselect_all(scene); - } - seq->flag |= SELECT; - - select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp); - } - else { - if (extend == 0) { - ED_sequencer_deselect_all(scene); - } - seq->flag |= SELECT; - - neighbor->flag |= SELECT; - recurs_sel_seq(neighbor); - neighbor->flag |= SEQ_RIGHTSEL; - seq->flag |= SEQ_LEFTSEL; - } - break; - case SEQ_SIDE_RIGHT: - if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) { - if (extend == 0) { - ED_sequencer_deselect_all(scene); - } - seq->flag |= SELECT; - - select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp); - } - else { - if (extend == 0) { - ED_sequencer_deselect_all(scene); - } - seq->flag |= SELECT; - - neighbor->flag |= SELECT; - recurs_sel_seq(neighbor); - neighbor->flag |= SEQ_LEFTSEL; - seq->flag |= SEQ_RIGHTSEL; - } - break; - } - } - else { - if (extend == 0) { - ED_sequencer_deselect_all(scene); - } - select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp); - } - } + if (ed == NULL) { + return OPERATOR_CANCELLED; + } - ret_value = OPERATOR_FINISHED; - } - else { - if (extend && (seq->flag & SELECT) && ed->act_seq == act_orig) { - switch (hand) { - case SEQ_SIDE_NONE: - if (linked_handle == 0) { - seq->flag &= ~SEQ_ALLSEL; - } - break; - case SEQ_SIDE_LEFT: - seq->flag ^= SEQ_LEFTSEL; - break; - case SEQ_SIDE_RIGHT: - seq->flag ^= SEQ_RIGHTSEL; - break; - } - ret_value = OPERATOR_FINISHED; - } - else { - seq->flag |= SELECT; - if (hand == SEQ_SIDE_LEFT) { - seq->flag |= SEQ_LEFTSEL; - } - if (hand == SEQ_SIDE_RIGHT) { - seq->flag |= SEQ_RIGHTSEL; - } - } - } + int mval[2]; + mval[0] = RNA_int_get(op->ptr, "mouse_x"); + mval[1] = RNA_int_get(op->ptr, "mouse_y"); - recurs_sel_seq(seq); + int handle_clicked; + Sequence *seq = find_nearest_seq(scene, v2d, &handle_clicked, mval); - if (linked_time) { - select_linked_time(ed->seqbasep, seq); - } + /* NOTE: `side_of_frame` and `linked_time` functionality is designed to be shared on one keymap, + * therefore both properties can be true at the same time. */ + if (seq && RNA_boolean_get(op->ptr, "linked_time")) { + if (!extend) { + ED_sequencer_deselect_all(scene); + } + sequencer_select_strip_impl(ed, seq, handle_clicked, extend); + select_linked_time(ed->seqbasep, seq); + sequencer_select_do_updates(C, scene); + sequencer_select_set_active(scene, seq); + return OPERATOR_FINISHED; + } - BLI_assert((ret_value & OPERATOR_CANCELLED) == 0); + /* Select left, right or overlapping the current frame. */ + if (RNA_boolean_get(op->ptr, "side_of_frame")) { + if (!extend) { + ED_sequencer_deselect_all(scene); } - else if (deselect_all) { + sequencer_select_side_of_frame(C, v2d, mval, scene); + sequencer_select_do_updates(C, scene); + return OPERATOR_FINISHED; + } + + /* On Alt selection, select the strip and bordering handles. */ + if (seq && RNA_boolean_get(op->ptr, "linked_handle")) { + if (!extend) { ED_sequencer_deselect_all(scene); - ret_value = OPERATOR_FINISHED; } + sequencer_select_linked_handle(C, seq, handle_clicked); + sequencer_select_do_updates(C, scene); + sequencer_select_set_active(scene, seq); + return OPERATOR_FINISHED; } - ED_outliner_select_sync_from_sequence_tag(C); + const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others"); - WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene); + /* Clicking on already selected element falls on modal operation. + * All strips are deselected on mouse button release unless extend mode is used. */ + if (seq && element_already_selected(seq, handle_clicked) && wait_to_deselect_others && !extend) { + return OPERATOR_RUNNING_MODAL; + } + + int ret_value = OPERATOR_CANCELLED; + if (!extend) { + ED_sequencer_deselect_all(scene); + ret_value = OPERATOR_FINISHED; + } + + /* Nothing to select, but strips could be deselected. */ + if (!seq) { + sequencer_select_do_updates(C, scene); + return ret_value; + } + + /* Do actual selection. */ + sequencer_select_strip_impl(ed, seq, handle_clicked, extend); + ret_value = OPERATOR_FINISHED; + sequencer_select_do_updates(C, scene); + sequencer_select_set_active(scene, seq); return ret_value; } @@ -763,13 +770,6 @@ void SEQUENCER_OT_select(wmOperatorType *ot) prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, - "deselect_all", - false, - "Deselect On Nothing", - "Deselect all when nothing under the cursor"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "linked_handle", false, -- cgit v1.2.3 From 54f5c174a8cf480d934f3be8ecc85c76537ad148 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 8 Sep 2021 08:39:03 +0200 Subject: Asset: Dropping Material assets on material slot under mouse cursor. This patch allows dropping material assets from material slot under the mouse cursor. Before this change the material slot had to be hand-picked from the properties panel. For consistency it is chosen to do this in any shading mode as the tooltip shows what is exactly going to happen during release. The feature also works for other object types than Meshes as it uses the drawn surface on the GPU to detect the material slots. Performance of this patch has been tested with AMD GCN3.0 cards and are very responsive. Reviewed By: fclem, Severin Differential Revision: https://developer.blender.org/D12190 --- source/blender/editors/include/ED_view3d.h | 10 ++++ source/blender/editors/object/object_relations.c | 20 +++---- .../blender/editors/space_view3d/view3d_select.c | 62 +++++++++++++++++----- source/blender/editors/space_view3d/view3d_view.c | 25 ++++++--- 4 files changed, 89 insertions(+), 28 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 2c958d282f9..cf8dcbd7995 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -566,6 +566,13 @@ eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const struct Scene *sce void view3d_opengl_select_cache_begin(void); void view3d_opengl_select_cache_end(void); +int view3d_opengl_select_ex(struct ViewContext *vc, + unsigned int *buffer, + unsigned int bufsize, + const struct rcti *input, + eV3DSelectMode select_mode, + eV3DSelectObjectFilter select_filter, + const bool do_material_slot_selection); int view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, @@ -638,6 +645,9 @@ void ED_view3d_draw_setup_view(const struct wmWindowManager *wm, struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); struct Object *ED_view3d_give_object_under_cursor(struct bContext *C, const int mval[2]); +struct Object *ED_view3d_give_material_slot_under_cursor(struct bContext *C, + const int mval[2], + int *r_material_slot); bool ED_view3d_is_object_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *area, struct ARegion *region, bool do_clip); void ED_view3d_update_viewmat(struct Depsgraph *depsgraph, diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index ec72ff11683..75269dffec8 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2729,25 +2729,26 @@ char *ED_object_ot_drop_named_material_tooltip(bContext *C, PointerRNA *properties, const wmEvent *event) { - Object *ob = ED_view3d_give_object_under_cursor(C, event->mval); + int mat_slot = 0; + Object *ob = ED_view3d_give_material_slot_under_cursor(C, event->mval, &mat_slot); if (ob == NULL) { return BLI_strdup(""); } + mat_slot = max_ii(mat_slot, 1); char name[MAX_ID_NAME - 2]; RNA_string_get(properties, "name", name); - int active_mat_slot = max_ii(ob->actcol, 1); - Material *prev_mat = BKE_object_material_get(ob, active_mat_slot); + Material *prev_mat = BKE_object_material_get(ob, mat_slot); char *result; if (prev_mat) { const char *tooltip = TIP_("Drop %s on %s (slot %d, replacing %s)"); - result = BLI_sprintfN(tooltip, name, ob->id.name + 2, active_mat_slot, prev_mat->id.name + 2); + result = BLI_sprintfN(tooltip, name, ob->id.name + 2, mat_slot, prev_mat->id.name + 2); } else { const char *tooltip = TIP_("Drop %s on %s (slot %d)"); - result = BLI_sprintfN(tooltip, name, ob->id.name + 2, active_mat_slot); + result = BLI_sprintfN(tooltip, name, ob->id.name + 2, mat_slot); } return result; } @@ -2755,7 +2756,10 @@ char *ED_object_ot_drop_named_material_tooltip(bContext *C, static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Main *bmain = CTX_data_main(C); - Object *ob = ED_view3d_give_object_under_cursor(C, event->mval); + int mat_slot = 0; + Object *ob = ED_view3d_give_material_slot_under_cursor(C, event->mval, &mat_slot); + mat_slot = max_ii(mat_slot, 1); + Material *ma; char name[MAX_ID_NAME - 2]; @@ -2765,9 +2769,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; } - const short active_mat_slot = ob->actcol; - - BKE_object_material_assign(CTX_data_main(C), ob, ma, active_mat_slot, BKE_MAT_ASSIGN_USERPREF); + BKE_object_material_assign(CTX_data_main(C), ob, ma, mat_slot, BKE_MAT_ASSIGN_USERPREF); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index e3f97dd1c63..ff98762e373 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1953,7 +1953,8 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc, const int mval[2], eV3DSelectObjectFilter select_filter, bool do_nearest, - bool do_nearest_xray_if_supported) + bool do_nearest_xray_if_supported, + const bool do_material_slot_selection) { rcti rect; int hits15, hits9 = 0, hits5 = 0; @@ -1972,7 +1973,8 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc, view3d_opengl_select_cache_begin(); BLI_rcti_init_pt_radius(&rect, mval, 14); - hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter); + hits15 = view3d_opengl_select_ex( + vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter, do_material_slot_selection); if (hits15 == 1) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; @@ -2071,7 +2073,8 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, do_nearest = do_nearest && !enumerate; - int hits = mixed_bones_object_selectbuffer(vc, buffer, mval, select_filter, do_nearest, true); + int hits = mixed_bones_object_selectbuffer( + vc, buffer, mval, select_filter, do_nearest, true, false); return hits; } @@ -2088,12 +2091,14 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, int hits, Base *startbase, bool has_bones, - bool do_nearest) + bool do_nearest, + int *r_sub_selection) { ViewLayer *view_layer = vc->view_layer; View3D *v3d = vc->v3d; Base *base, *basact = NULL; int a; + int sub_selection_id = 0; if (do_nearest) { uint min = 0xFFFFFFFF; @@ -2105,6 +2110,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, if (min > buffer[4 * a + 1] && (buffer[4 * a + 3] & 0xFFFF0000)) { min = buffer[4 * a + 1]; selcol = buffer[4 * a + 3] & 0xFFFF; + sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16; } } } @@ -2118,6 +2124,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) { min = buffer[4 * a + 1]; selcol = buffer[4 * a + 3] & 0xFFFF; + sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16; } } } @@ -2184,11 +2191,16 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, } } + if (basact && r_sub_selection) { + *r_sub_selection = sub_selection_id; + } + return basact; } -/* mval comes from event->mval, only use within region handlers */ -Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) +static Base *ed_view3d_give_base_under_cursor_ex(bContext *C, + const int mval[2], + int *r_material_slot) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewContext vc; @@ -2202,18 +2214,30 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) ED_view3d_viewcontext_init(C, &vc, depsgraph); const bool do_nearest = !XRAY_ACTIVE(vc.v3d); + const bool do_material_slot_selection = r_material_slot != NULL; const int hits = mixed_bones_object_selectbuffer( - &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest, false); + &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest, false, do_material_slot_selection); if (hits > 0) { - const bool has_bones = selectbuffer_has_bones(buffer, hits); - basact = mouse_select_eval_buffer( - &vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest); + const bool has_bones = (r_material_slot == NULL) && selectbuffer_has_bones(buffer, hits); + basact = mouse_select_eval_buffer(&vc, + buffer, + hits, + vc.view_layer->object_bases.first, + has_bones, + do_nearest, + r_material_slot); } return basact; } +/* mval comes from event->mval, only use within region handlers */ +Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2]) +{ + return ed_view3d_give_base_under_cursor_ex(C, mval, NULL); +} + Object *ED_view3d_give_object_under_cursor(bContext *C, const int mval[2]) { Base *base = ED_view3d_give_base_under_cursor(C, mval); @@ -2223,6 +2247,17 @@ Object *ED_view3d_give_object_under_cursor(bContext *C, const int mval[2]) return NULL; } +struct Object *ED_view3d_give_material_slot_under_cursor(struct bContext *C, + const int mval[2], + int *r_material_slot) +{ + Base *base = ed_view3d_give_base_under_cursor_ex(C, mval, r_material_slot); + if (base) { + return base->object; + } + return NULL; +} + bool ED_view3d_is_object_under_cursor(bContext *C, const int mval[2]) { return ED_view3d_give_object_under_cursor(C, mval) != NULL; @@ -2374,7 +2409,8 @@ static bool ed_object_select_pick(bContext *C, } } else { - basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, has_bones, do_nearest); + basact = mouse_select_eval_buffer( + &vc, buffer, hits, startbase, has_bones, do_nearest, NULL); } if (has_bones && basact) { @@ -2436,7 +2472,7 @@ static bool ed_object_select_pick(bContext *C, if (!changed) { /* fallback to regular object selection if no new bundles were selected, * allows to select object parented to reconstruction object */ - basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest); + basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL); } } } @@ -2677,7 +2713,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op) uint buffer[MAXPICKBUF]; const int hits = mixed_bones_object_selectbuffer( - &vc, buffer, location, VIEW3D_SELECT_FILTER_NOP, false, true); + &vc, buffer, location, VIEW3D_SELECT_FILTER_NOP, false, true, false); retval = bone_mouse_select_menu(C, buffer, hits, true, extend, deselect, toggle); } if (!retval) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 86a610f8dd9..b9f3706b084 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -964,12 +964,13 @@ static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void * * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection. */ -int view3d_opengl_select(ViewContext *vc, - uint *buffer, - uint bufsize, - const rcti *input, - eV3DSelectMode select_mode, - eV3DSelectObjectFilter select_filter) +int view3d_opengl_select_ex(ViewContext *vc, + uint *buffer, + uint bufsize, + const rcti *input, + eV3DSelectMode select_mode, + eV3DSelectObjectFilter select_filter, + const bool do_material_slot_selection) { struct bThemeState theme_state; const wmWindowManager *wm = CTX_wm_manager(vc->C); @@ -1119,6 +1120,7 @@ int view3d_opengl_select(ViewContext *vc, use_obedit_skip, draw_surface, use_nearest, + do_material_slot_selection, &rect, drw_select_loop_pass, &drw_select_loop_user_data, @@ -1149,6 +1151,7 @@ int view3d_opengl_select(ViewContext *vc, use_obedit_skip, draw_surface, use_nearest, + do_material_slot_selection, &rect, drw_select_loop_pass, &drw_select_loop_user_data, @@ -1178,6 +1181,16 @@ finally: return hits; } +int view3d_opengl_select(ViewContext *vc, + uint *buffer, + uint bufsize, + const rcti *input, + eV3DSelectMode select_mode, + eV3DSelectObjectFilter select_filter) +{ + return view3d_opengl_select_ex(vc, buffer, bufsize, input, select_mode, select_filter, false); +} + int view3d_opengl_select_with_id_filter(ViewContext *vc, uint *buffer, uint bufsize, -- cgit v1.2.3 From f9ebd17b4b124d93e4ad94c2c1a2ce020d8d334b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Sep 2021 13:02:16 +1000 Subject: Gizmo: warn when 2D projection fails with non-invertable matrices Add a warning to quickly pinpoint the problem. This would have simplified tracking down this problem in D12105. --- .../blender/editors/gizmo_library/CMakeLists.txt | 1 + .../editors/gizmo_library/gizmo_library_utils.c | 33 +++++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt index eeb1e60166b..bfe8334b390 100644 --- a/source/blender/editors/gizmo_library/CMakeLists.txt +++ b/source/blender/editors/gizmo_library/CMakeLists.txt @@ -27,6 +27,7 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager + ../../../../intern/clog ../../../../intern/eigen ../../../../intern/glew-mx ../../../../intern/guardedalloc diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c index 7d0ae5afb9b..a0db2a8e627 100644 --- a/source/blender/editors/gizmo_library/gizmo_library_utils.c +++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c @@ -39,9 +39,13 @@ #include "ED_view3d.h" +#include "CLG_log.h" + /* own includes */ #include "gizmo_library_intern.h" +static CLG_LogRef LOG = {"ed.gizmo.library_utils"}; + /* factor for precision tweaking */ #define GIZMO_PRECISION_FAC 0.05f @@ -182,7 +186,7 @@ bool gizmo_window_project_2d(bContext *C, bool use_offset, float r_co[2]) { - float mat[4][4]; + float mat[4][4], imat[4][4]; { float mat_identity[4][4]; struct WM_GizmoMatrixParams params = {NULL}; @@ -193,6 +197,14 @@ bool gizmo_window_project_2d(bContext *C, WM_gizmo_calc_matrix_final_params(gz, ¶ms, mat); } + if (!invert_m4_m4(imat, mat)) { + CLOG_WARN(&LOG, + "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted " + "(projection will fail)", + gz->type->idname, + gz->parent_gzgroup->type->idname); + } + /* rotate mouse in relation to the center and relocate it */ if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { /* For 3d views, transform 2D mouse pos onto plane. */ @@ -202,8 +214,6 @@ bool gizmo_window_project_2d(bContext *C, plane_from_point_normal_v3(plane, mat[3], mat[2]); bool clip_ray = ((RegionView3D *)region->regiondata)->is_persp; if (ED_view3d_win_to_3d_on_plane(region, plane, mval, clip_ray, co)) { - float imat[4][4]; - invert_m4_m4(imat, mat); mul_m4_v3(imat, co); r_co[0] = co[(axis + 1) % 3]; r_co[1] = co[(axis + 2) % 3]; @@ -213,8 +223,6 @@ bool gizmo_window_project_2d(bContext *C, } float co[3] = {mval[0], mval[1], 0.0f}; - float imat[4][4]; - invert_m4_m4(imat, mat); mul_m4_v3(imat, co); copy_v2_v2(r_co, co); return true; @@ -223,7 +231,7 @@ bool gizmo_window_project_2d(bContext *C, bool gizmo_window_project_3d( bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3]) { - float mat[4][4]; + float mat[4][4], imat[4][4]; { float mat_identity[4][4]; struct WM_GizmoMatrixParams params = {NULL}; @@ -234,20 +242,25 @@ bool gizmo_window_project_3d( WM_gizmo_calc_matrix_final_params(gz, ¶ms, mat); } + if (!invert_m4_m4(imat, mat)) { + CLOG_WARN(&LOG, + "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted " + "(projection will fail)", + gz->type->idname, + gz->parent_gzgroup->type->idname); + } + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); /* NOTE: we might want a custom reference point passed in, * instead of the gizmo center. */ ED_view3d_win_to_3d(v3d, region, mat[3], mval, r_co); - invert_m4(mat); - mul_m4_v3(mat, r_co); + mul_m4_v3(imat, r_co); return true; } float co[3] = {mval[0], mval[1], 0.0f}; - float imat[4][4]; - invert_m4_m4(imat, mat); mul_m4_v3(imat, co); copy_v2_v2(r_co, co); return true; -- cgit v1.2.3 From bda9e4238a07a72c26598ea9025e00f6ca896750 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Sep 2021 14:24:22 +1000 Subject: Fix smooth-view failure to add mouse-move events View operations that left the cursor over a gizmo were not being updated because the mouse-move event was added while the view was animated instead of once the animation had completed. Mouse-move events were also missing when smooth-view was disabled. This fixes a glitch with the 3D view navigation gizmo where multiple clicks on the view aligned axis failed to switch to the opposite side unless the user moved the cursor between clicks. --- source/blender/editors/space_view3d/view3d_view.c | 86 +++++++++++------------ 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b9f3706b084..a6dd95cac04 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -137,7 +137,6 @@ void ED_view3d_smooth_view_ex( { RegionView3D *rv3d = region->regiondata; struct SmoothView3DStore sms = {{0}}; - bool ok = false; /* initialize sms */ view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d); @@ -200,29 +199,30 @@ void ED_view3d_smooth_view_ex( sms.to_camera = true; /* restore view3d values in end */ } - /* skip smooth viewing for external render engine draw */ - if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) { - bool changed = false; /* zero means no difference */ + bool changed = false; /* zero means no difference */ - if (sview->camera_old != sview->camera) { - changed = true; - } - else if (sms.dst.dist != rv3d->dist) { - changed = true; - } - else if (sms.dst.lens != v3d->lens) { - changed = true; - } - else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) { - changed = true; - } - else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) { - changed = true; - } + if (sview->camera_old != sview->camera) { + changed = true; + } + else if (sms.dst.dist != rv3d->dist) { + changed = true; + } + else if (sms.dst.lens != v3d->lens) { + changed = true; + } + else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) { + changed = true; + } + else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) { + changed = true; + } + + /* The new view is different from the previous state. */ + if (changed) { + + /* Skip smooth viewing for external render engine draw. */ + if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) { - /* The new view is different from the old one - * so animate the view */ - if (changed) { /* original values */ if (sview->camera_old) { Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old); @@ -279,27 +279,25 @@ void ED_view3d_smooth_view_ex( } /* #TIMER1 is hard-coded in key-map. */ rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); - - ok = true; } - } + else { + if (sms.to_camera == false) { + copy_v3_v3(rv3d->ofs, sms.dst.ofs); + copy_qt_qt(rv3d->viewquat, sms.dst.quat); + rv3d->dist = sms.dst.dist; + v3d->lens = sms.dst.lens; - /* if we get here nothing happens */ - if (ok == false) { - if (sms.to_camera == false) { - copy_v3_v3(rv3d->ofs, sms.dst.ofs); - copy_qt_qt(rv3d->viewquat, sms.dst.quat); - rv3d->dist = sms.dst.dist; - v3d->lens = sms.dst.lens; + ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); + } - ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); - } + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { + view3d_boxview_copy(area, region); + } - if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { - view3d_boxview_copy(area, region); - } + ED_region_tag_redraw(region); - ED_region_tag_redraw(region); + WM_event_add_mousemove(win); + } } } @@ -320,6 +318,7 @@ void ED_view3d_smooth_view(bContext *C, /* only meant for timer usage */ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, bool sync_boxview) { + wmWindowManager *wm = CTX_wm_manager(C); RegionView3D *rv3d = region->regiondata; struct SmoothView3DStore *sms = rv3d->sms; float step, step_inv; @@ -333,6 +332,7 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b /* end timer */ if (step >= 1.0f) { + wmWindow *win = CTX_wm_window(C); /* if we went to camera, store the original */ if (sms->to_camera) { @@ -355,9 +355,12 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b MEM_freeN(rv3d->sms); rv3d->sms = NULL; - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer); + WM_event_remove_timer(wm, win, rv3d->smooth_timer); rv3d->smooth_timer = NULL; rv3d->rflag &= ~RV3D_NAVIGATING; + + /* Event handling won't know if a UI item has been moved under the pointer. */ + WM_event_add_mousemove(win); } else { /* ease in/out */ @@ -380,12 +383,9 @@ static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, b const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); - if (ED_screen_animation_playing(CTX_wm_manager(C))) { + if (ED_screen_animation_playing(wm)) { ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); } - - /* Event handling won't know if a UI item has been moved under the pointer. */ - WM_event_add_mousemove(CTX_wm_window(C)); } if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) { -- cgit v1.2.3 From bf47fb40fd6f0ee9386e9936cf213a1049c55b61 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 9 Sep 2021 12:54:20 +0200 Subject: Geometry Nodes: fields and anonymous attributes This implements the initial core framework for fields and anonymous attributes (also see T91274). The new functionality is hidden behind the "Geometry Nodes Fields" feature flag. When enabled in the user preferences, the following new nodes become available: `Position`, `Index`, `Normal`, `Set Position` and `Attribute Capture`. Socket inspection has not been updated to work with fields yet. Besides these changes at the user level, this patch contains the ground work for: * building and evaluating fields at run-time (`FN_fields.hh`) and * creating and accessing anonymous attributes on geometry (`BKE_anonymous_attribute.h`). For evaluating fields we use a new so called multi-function procedure (`FN_multi_function_procedure.hh`). It allows composing multi-functions in arbitrary ways and supports efficient evaluation as is required by fields. See `FN_multi_function_procedure.hh` for more details on how this evaluation mechanism can be used. A new `AttributeIDRef` has been added which allows handling named and anonymous attributes in the same way in many places. Hans and I worked on this patch together. Differential Revision: https://developer.blender.org/D12414 --- .../spreadsheet_data_source_geometry.cc | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 12815c2c7e9..f5fef5e4486 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -45,15 +45,20 @@ namespace blender::ed::spreadsheet { void GeometryDataSource::foreach_default_column_ids( FunctionRef fn) const { - component_->attribute_foreach([&](StringRefNull name, const AttributeMetaData &meta_data) { - if (meta_data.domain != domain_) { - return true; - } - SpreadsheetColumnID column_id; - column_id.name = (char *)name.c_str(); - fn(column_id); - return true; - }); + component_->attribute_foreach( + [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) { + if (meta_data.domain != domain_) { + return true; + } + if (attribute_id.is_anonymous()) { + return true; + } + SpreadsheetColumnID column_id; + std::string name = attribute_id.name(); + column_id.name = (char *)name.c_str(); + fn(column_id); + return true; + }); } std::unique_ptr GeometryDataSource::get_column_values( -- cgit v1.2.3 From 60cfdf080929aca61c37439b601b1ef85d51391a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 10 Sep 2021 13:27:26 +0200 Subject: Anim: Keylist drawing optimization by using arrays. Change data structure of keylists. Reducing the balancing overhead and therefore increases performance. | **Function** | **Master** | **Patch** | |`draw_summary_channel`| 0.202105s| 0.083874s | When adding items to the keylist it will store it in a linked list. This linked list is accompanied with the length (key_len) and a `last_accessed_column`. last_accessed_column is a cursor that improve the performance when adding new items as they are mostly ordered by frame numbers. last_accessed_column is reset when a new fcurve/mask/... is added to the keylist. Before searching or array access. the listbase needs to be converted to an array. `ED_keylist_prepare_for_direct_access`. After that the caller can use `ED_keylist_find_*` or `ED_keylist_array*` functions. The internal array can also be accessed via the `ED_keylist_listbase` function. The items inside the array link to the previous/next item in the list. Reviewed By: sybren Differential Revision: https://developer.blender.org/D12052 --- source/blender/editors/animation/anim_draw.c | 1 + .../blender/editors/animation/anim_motion_paths.c | 2 + source/blender/editors/animation/keyframes_draw.c | 29 +- .../blender/editors/animation/keyframes_keylist.cc | 482 +++++++++++++++------ source/blender/editors/armature/pose_slide.c | 2 + .../blender/editors/include/ED_keyframes_keylist.h | 14 +- source/blender/editors/screen/screen_ops.c | 1 + .../blender/editors/space_action/action_select.c | 1 + 8 files changed, 397 insertions(+), 135 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 6d272bfc180..993d10cf303 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -521,6 +521,7 @@ static bool find_prev_next_keyframes(struct bContext *C, int *r_nextfra, int *r_ MaskLayer *masklay = BKE_mask_layer_active(mask); mask_to_keylist(&ads, masklay, keylist); } + ED_keylist_prepare_for_direct_access(keylist); /* TODO(jbakker): Keylists are ordered, no need to do any searching at all. */ /* find matching keyframe in the right direction */ diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index d976f5f72ad..d130941b9bc 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -329,6 +329,7 @@ static void motionpath_calculate_update_range(MPathTarget *mpt, for (FCurve *fcu = fcurve_list->first; fcu != NULL; fcu = fcu->next) { struct AnimKeylist *keylist = ED_keylist_create(); fcurve_to_keylist(adt, fcu, keylist, 0); + ED_keylist_prepare_for_direct_access(keylist); int fcu_sfra = motionpath_get_prev_prev_keyframe(mpt, keylist, current_frame); int fcu_efra = motionpath_get_next_next_keyframe(mpt, keylist, current_frame); @@ -443,6 +444,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, action_to_keylist(adt, adt->action, mpt->keylist, 0); } } + ED_keylist_prepare_for_direct_access(mpt->keylist); if (range == ANIMVIZ_CALC_RANGE_CHANGED) { int mpt_sfra, mpt_efra; diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 61918871b90..8a884c0bd5b 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -346,10 +346,12 @@ static void draw_keylist_block(const DrawKeylistUIData *ctx, const ActKeyColumn } static void draw_keylist_blocks(const DrawKeylistUIData *ctx, - const ListBase * /*ActKeyColumn*/ columns, + const ActKeyColumn *keys, + const int key_len, float ypos) { - LISTBASE_FOREACH (ActKeyColumn *, ab, columns) { + for (int i = 0; i < key_len; i++) { + const ActKeyColumn *ab = &keys[i]; draw_keylist_block(ctx, ab, ypos); } } @@ -362,13 +364,15 @@ static bool draw_keylist_is_visible_key(const View2D *v2d, const ActKeyColumn *a static void draw_keylist_keys(const DrawKeylistUIData *ctx, View2D *v2d, const KeyframeShaderBindings *sh_bindings, - const ListBase * /*ActKeyColumn*/ keys, + const ActKeyColumn *keys, + const int key_len, float ypos, eSAction_Flag saction_flag) { short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE; - LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { + for (int i = 0; i < key_len; i++) { + const ActKeyColumn *ak = &keys[i]; if (draw_keylist_is_visible_key(v2d, ak)) { if (ctx->show_ipo) { handle_type = ak->handle_type; @@ -469,8 +473,9 @@ static void ED_keylist_draw_list_elem_draw_blocks(AnimKeylistDrawListElem *elem, DrawKeylistUIData ctx; draw_keylist_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag); - const ListBase *keys = ED_keylist_listbase(elem->keylist); - draw_keylist_blocks(&ctx, keys, elem->ypos); + const int key_len = ED_keylist_array_len(elem->keylist); + const ActKeyColumn *keys = ED_keylist_array(elem->keylist); + draw_keylist_blocks(&ctx, keys, key_len, elem->ypos); } static void ED_keylist_draw_list_elem_draw_keys(AnimKeylistDrawListElem *elem, @@ -479,8 +484,15 @@ static void ED_keylist_draw_list_elem_draw_keys(AnimKeylistDrawListElem *elem, { DrawKeylistUIData ctx; draw_keylist_ui_data_init(&ctx, v2d, elem->yscale_fac, elem->channel_locked, elem->saction_flag); - const ListBase *keys = ED_keylist_listbase(elem->keylist); - draw_keylist_keys(&ctx, v2d, sh_bindings, keys, elem->ypos, elem->saction_flag); + + const int key_len = ED_keylist_array_len(elem->keylist); + const ActKeyColumn *keys = ED_keylist_array(elem->keylist); + draw_keylist_keys(&ctx, v2d, sh_bindings, keys, key_len, elem->ypos, elem->saction_flag); +} + +static void ED_keylist_draw_list_elem_prepare_for_drawing(AnimKeylistDrawListElem *elem) +{ + ED_keylist_prepare_for_direct_access(elem->keylist); } typedef struct AnimKeylistDrawList { @@ -496,6 +508,7 @@ static void ED_keylist_draw_list_build_keylists(AnimKeylistDrawList *draw_list) { LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { ED_keylist_draw_list_elem_build_keylist(elem); + ED_keylist_draw_list_elem_prepare_for_drawing(elem); } } diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index f6ade11a517..c1a18196a3a 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -23,15 +23,20 @@ /* System includes ----------------------------------------------------- */ +#include #include #include #include #include +#include +#include #include "MEM_guardedalloc.h" +#include "BLI_array.hh" #include "BLI_dlrbTree.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_range.h" #include "BLI_utildefines.h" @@ -50,117 +55,294 @@ extern "C" { /* *************************** Keyframe Processing *************************** */ -struct AnimKeylist { - DLRBT_Tree keys; -}; +/* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ + +BLI_INLINE bool is_cfra_eq(const float a, const float b) +{ + return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH); +} -static void ED_keylist_init(AnimKeylist *keylist) +BLI_INLINE bool is_cfra_lt(const float a, const float b) { - BLI_dlrbTree_init(&keylist->keys); + return (b - a) > BEZT_BINARYSEARCH_THRESH; } +/* --------------- */ + +struct AnimKeylist { + /* Number of ActKeyColumn's in the keylist. */ + size_t column_len = 0; + + bool is_runtime_initialized = false; + + /* Before initializing the runtime, the key_columns list base is used to quickly add columns. + * Contains `ActKeyColumn`. Should not be used after runtime is initialized. */ + ListBase /* ActKeyColumn */ key_columns; + /* Last accessed column in the key_columns list base. Inserting columns are typically done in + * order. The last accessed column is used as starting point to search for a location to add or + * update the next column.*/ + std::optional last_accessed_column = std::nullopt; + + struct { + /* When initializing the runtime the columns from the list base `AnimKeyList.key_columns` are + * transferred to an array to support binary searching and index based access. */ + blender::Array key_columns; + /* Wrapper around runtime.key_columns so it can still be accessed as a ListBase. Elements are + * owned by runtime.key_columns. */ + ListBase /* ActKeyColumn */ list_wrapper; + } runtime; + + AnimKeylist() + { + BLI_listbase_clear(&this->key_columns); + BLI_listbase_clear(&this->runtime.list_wrapper); + } + + ~AnimKeylist() + { + BLI_freelistN(&this->key_columns); + BLI_listbase_clear(&this->runtime.list_wrapper); + } + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("editors:AnimKeylist") +#endif +}; + AnimKeylist *ED_keylist_create(void) { - AnimKeylist *keylist = static_cast(MEM_callocN(sizeof(AnimKeylist), __func__)); - ED_keylist_init(keylist); + AnimKeylist *keylist = new AnimKeylist(); return keylist; } void ED_keylist_free(AnimKeylist *keylist) { BLI_assert(keylist); - BLI_dlrbTree_free(&keylist->keys); - MEM_freeN(keylist); + delete keylist; } -const ActKeyColumn *ED_keylist_find_exact(const AnimKeylist *keylist, float cfra) +static void ED_keylist_convert_key_columns_to_array(AnimKeylist *keylist) { - return (const ActKeyColumn *)BLI_dlrbTree_search_exact( - &keylist->keys, compare_ak_cfraPtr, &cfra); + size_t index; + LISTBASE_FOREACH_INDEX (ActKeyColumn *, key, &keylist->key_columns, index) { + keylist->runtime.key_columns[index] = *key; + } } -const ActKeyColumn *ED_keylist_find_next(const AnimKeylist *keylist, float cfra) +static void ED_keylist_runtime_update_key_column_next_prev(AnimKeylist *keylist) { - return (const ActKeyColumn *)BLI_dlrbTree_search_next(&keylist->keys, compare_ak_cfraPtr, &cfra); + for (size_t index = 0; index < keylist->column_len; index++) { + const bool is_first = (index == 0); + keylist->runtime.key_columns[index].prev = is_first ? nullptr : + &keylist->runtime.key_columns[index - 1]; + const bool is_last = (index == keylist->column_len - 1); + keylist->runtime.key_columns[index].next = is_last ? nullptr : + &keylist->runtime.key_columns[index + 1]; + } } -const ActKeyColumn *ED_keylist_find_prev(const AnimKeylist *keylist, float cfra) +static void ED_keylist_runtime_init_listbase(AnimKeylist *keylist) { - return (const ActKeyColumn *)BLI_dlrbTree_search_prev(&keylist->keys, compare_ak_cfraPtr, &cfra); + if (ED_keylist_is_empty(keylist)) { + BLI_listbase_clear(&keylist->runtime.list_wrapper); + return; + } + + keylist->runtime.list_wrapper.first = &keylist->runtime.key_columns[0]; + keylist->runtime.list_wrapper.last = &keylist->runtime.key_columns[keylist->column_len - 1]; } -/* TODO(jbakker): Should we change this to use `ED_keylist_find_next(keys, min_fra)` and only check - * boundary of `max_fra`. */ -const ActKeyColumn *ED_keylist_find_any_between(const AnimKeylist *keylist, - const Range2f frame_range) +static void ED_keylist_runtime_init(AnimKeylist *keylist) { - for (const ActKeyColumn *ak = static_cast(keylist->keys.root); ak; - ak = static_cast((ak->cfra < frame_range.min) ? ak->right : - ak->left)) { - if (range2f_in_range(&frame_range, ak->cfra)) { - return ak; - } + BLI_assert(!keylist->is_runtime_initialized); + + keylist->runtime.key_columns = blender::Array(keylist->column_len); + + /* Convert linked list to array to support fast searching. */ + ED_keylist_convert_key_columns_to_array(keylist); + /* Ensure that the array can also be used as a listbase for external usages. */ + ED_keylist_runtime_update_key_column_next_prev(keylist); + ED_keylist_runtime_init_listbase(keylist); + + keylist->is_runtime_initialized = true; +} + +static void ED_keylist_reset_last_accessed(AnimKeylist *keylist) +{ + BLI_assert(!keylist->is_runtime_initialized); + keylist->last_accessed_column.reset(); +} + +void ED_keylist_prepare_for_direct_access(AnimKeylist *keylist) +{ + if (keylist->is_runtime_initialized) { + return; + } + ED_keylist_runtime_init(keylist); +} + +static const ActKeyColumn *ED_keylist_find_lower_bound(const AnimKeylist *keylist, + const float cfra) +{ + BLI_assert(!ED_keylist_is_empty(keylist)); + const ActKeyColumn *begin = std::begin(keylist->runtime.key_columns); + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + ActKeyColumn value; + value.cfra = cfra; + + const ActKeyColumn *found_column = std::lower_bound( + begin, end, value, [](const ActKeyColumn &column, const ActKeyColumn &other) { + return is_cfra_lt(column.cfra, other.cfra); + }); + return found_column; +} + +static const ActKeyColumn *ED_keylist_find_upper_bound(const AnimKeylist *keylist, + const float cfra) +{ + BLI_assert(!ED_keylist_is_empty(keylist)); + const ActKeyColumn *begin = std::begin(keylist->runtime.key_columns); + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + ActKeyColumn value; + value.cfra = cfra; + + const ActKeyColumn *found_column = std::upper_bound( + begin, end, value, [](const ActKeyColumn &column, const ActKeyColumn &other) { + return is_cfra_lt(column.cfra, other.cfra); + }); + return found_column; +} + +const ActKeyColumn *ED_keylist_find_exact(const AnimKeylist *keylist, const float cfra) +{ + BLI_assert_msg(keylist->is_runtime_initialized, + "ED_keylist_prepare_for_direct_access needs to be called before searching."); + + if (ED_keylist_is_empty(keylist)) { + return nullptr; + } + + const ActKeyColumn *found_column = ED_keylist_find_lower_bound(keylist, cfra); + + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + if (found_column == end) { + return nullptr; + } + if (is_cfra_eq(found_column->cfra, cfra)) { + return found_column; } return nullptr; } -bool ED_keylist_is_empty(const struct AnimKeylist *keylist) +const ActKeyColumn *ED_keylist_find_next(const AnimKeylist *keylist, const float cfra) { - return keylist->keys.root == nullptr; + BLI_assert_msg(keylist->is_runtime_initialized, + "ED_keylist_prepare_for_direct_access needs to be called before searching."); + + if (ED_keylist_is_empty(keylist)) { + return nullptr; + } + + const ActKeyColumn *found_column = ED_keylist_find_upper_bound(keylist, cfra); + + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + if (found_column == end) { + return nullptr; + } + return found_column; } -const struct ListBase *ED_keylist_listbase(const AnimKeylist *keylist) +const ActKeyColumn *ED_keylist_find_prev(const AnimKeylist *keylist, const float cfra) { - return (ListBase *)&keylist->keys; + BLI_assert_msg(keylist->is_runtime_initialized, + "ED_keylist_prepare_for_direct_access needs to be called before searching."); + + if (ED_keylist_is_empty(keylist)) { + return nullptr; + } + + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + const ActKeyColumn *found_column = ED_keylist_find_lower_bound(keylist, cfra); + + if (found_column == end) { + /* Nothing found, return the last item. */ + return end - 1; + } + + const ActKeyColumn *prev_column = found_column->prev; + return prev_column; } -bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range) +const ActKeyColumn *ED_keylist_find_any_between(const AnimKeylist *keylist, + const Range2f frame_range) { - BLI_assert(r_frame_range); + BLI_assert_msg(keylist->is_runtime_initialized, + "ED_keylist_prepare_for_direct_access needs to be called before searching."); if (ED_keylist_is_empty(keylist)) { - return false; + return nullptr; } - const ActKeyColumn *first_column = (const ActKeyColumn *)keylist->keys.first; - r_frame_range->min = first_column->cfra; + const ActKeyColumn *column = ED_keylist_find_lower_bound(keylist, frame_range.min); + const ActKeyColumn *end = std::end(keylist->runtime.key_columns); + if (column == end) { + return nullptr; + } + if (column->cfra >= frame_range.max) { + return nullptr; + } + return column; +} - const ActKeyColumn *last_column = (const ActKeyColumn *)keylist->keys.last; - r_frame_range->max = last_column->cfra; +const ActKeyColumn *ED_keylist_array(const struct AnimKeylist *keylist) +{ + BLI_assert_msg( + keylist->is_runtime_initialized, + "ED_keylist_prepare_for_direct_access needs to be called before accessing array."); + return keylist->runtime.key_columns.data(); +} - return true; +int64_t ED_keylist_array_len(const struct AnimKeylist *keylist) +{ + return keylist->column_len; } -/* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ -BLI_INLINE bool is_cfra_eq(const float a, const float b) +bool ED_keylist_is_empty(const struct AnimKeylist *keylist) { - return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH); + return keylist->column_len == 0; } -BLI_INLINE bool is_cfra_lt(const float a, const float b) +const struct ListBase *ED_keylist_listbase(const AnimKeylist *keylist) { - return (b - a) > BEZT_BINARYSEARCH_THRESH; + if (keylist->is_runtime_initialized) { + return &keylist->runtime.list_wrapper; + } + return &keylist->key_columns; } -/* Comparator callback used for ActKeyColumns and cframe float-value pointer */ -/* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */ -short compare_ak_cfraPtr(void *node, void *data) +bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range) { - ActKeyColumn *ak = (ActKeyColumn *)node; - const float *cframe = static_cast(data); - const float val = *cframe; + BLI_assert(r_frame_range); - if (is_cfra_eq(val, ak->cfra)) { - return 0; + if (ED_keylist_is_empty(keylist)) { + return false; } - if (val < ak->cfra) { - return -1; + const ActKeyColumn *first_column; + const ActKeyColumn *last_column; + if (keylist->is_runtime_initialized) { + first_column = &keylist->runtime.key_columns[0]; + last_column = &keylist->runtime.key_columns[keylist->column_len - 1]; } - return 1; -} + else { + first_column = static_cast(keylist->key_columns.first); + last_column = static_cast(keylist->key_columns.last); + } + r_frame_range->min = first_column->cfra; + r_frame_range->max = last_column->cfra; -/* --------------- */ + return true; +} /* Set of references to three logically adjacent keys. */ struct BezTripleChain { @@ -243,16 +425,8 @@ static eKeyframeExtremeDrawOpts bezt_extreme_type(const BezTripleChain *chain) return KEYFRAME_EXTREME_NONE; } -/* Comparator callback used for ActKeyColumns and BezTripleChain */ -static short compare_ak_bezt(void *node, void *data) -{ - BezTripleChain *chain = static_cast(data); - - return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]); -} - /* New node callback used for building ActKeyColumns from BezTripleChain */ -static DLRBT_Node *nalloc_ak_bezt(void *data) +static ActKeyColumn *nalloc_ak_bezt(void *data) { ActKeyColumn *ak = static_cast( MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn")); @@ -269,13 +443,12 @@ static DLRBT_Node *nalloc_ak_bezt(void *data) /* count keyframes in this column */ ak->totkey = 1; - return (DLRBT_Node *)ak; + return ak; } /* Node updater callback used for building ActKeyColumns from BezTripleChain */ -static void nupdate_ak_bezt(void *node, void *data) +static void nupdate_ak_bezt(ActKeyColumn *ak, void *data) { - ActKeyColumn *ak = static_cast(node); const BezTripleChain *chain = static_cast(data); const BezTriple *bezt = chain->cur; @@ -312,17 +485,8 @@ static void nupdate_ak_bezt(void *node, void *data) /* ......... */ -/* Comparator callback used for ActKeyColumns and GPencil frame */ -static short compare_ak_gpframe(void *node, void *data) -{ - const bGPDframe *gpf = (bGPDframe *)data; - - float frame = gpf->framenum; - return compare_ak_cfraPtr(node, &frame); -} - /* New node callback used for building ActKeyColumns from GPencil frames */ -static DLRBT_Node *nalloc_ak_gpframe(void *data) +static ActKeyColumn *nalloc_ak_gpframe(void *data) { ActKeyColumn *ak = static_cast( MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF")); @@ -340,14 +504,13 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data) ak->block.sel = ak->sel; ak->block.flag |= ACTKEYBLOCK_FLAG_GPENCIL; - return (DLRBT_Node *)ak; + return ak; } /* Node updater callback used for building ActKeyColumns from GPencil frames */ -static void nupdate_ak_gpframe(void *node, void *data) +static void nupdate_ak_gpframe(ActKeyColumn *ak, void *data) { - ActKeyColumn *ak = (ActKeyColumn *)node; - const bGPDframe *gpf = (bGPDframe *)data; + bGPDframe *gpf = (bGPDframe *)data; /* set selection status and 'touched' status */ if (gpf->flag & GP_FRAME_SELECT) { @@ -366,17 +529,8 @@ static void nupdate_ak_gpframe(void *node, void *data) /* ......... */ -/* Comparator callback used for ActKeyColumns and GPencil frame */ -static short compare_ak_masklayshape(void *node, void *data) -{ - const MaskLayerShape *masklay_shape = (const MaskLayerShape *)data; - - float frame = masklay_shape->frame; - return compare_ak_cfraPtr(node, &frame); -} - /* New node callback used for building ActKeyColumns from GPencil frames */ -static DLRBT_Node *nalloc_ak_masklayshape(void *data) +static ActKeyColumn *nalloc_ak_masklayshape(void *data) { ActKeyColumn *ak = static_cast( MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF")); @@ -389,14 +543,13 @@ static DLRBT_Node *nalloc_ak_masklayshape(void *data) /* count keyframes in this column */ ak->totkey = 1; - return (DLRBT_Node *)ak; + return ak; } /* Node updater callback used for building ActKeyColumns from GPencil frames */ -static void nupdate_ak_masklayshape(void *node, void *data) +static void nupdate_ak_masklayshape(ActKeyColumn *ak, void *data) { - ActKeyColumn *ak = (ActKeyColumn *)node; - const MaskLayerShape *masklay_shape = (const MaskLayerShape *)data; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; /* set selection status and 'touched' status */ if (masklay_shape->flag & MASK_SHAPE_SELECT) { @@ -408,6 +561,95 @@ static void nupdate_ak_masklayshape(void *node, void *data) } /* --------------- */ +using KeylistCreateColumnFunction = std::function; +using KeylistUpdateColumnFunction = std::function; + +/* `ED_keylist_find_neighbour_front_to_back` is called before the runtime can be initialized so we + * cannot use bin searching. */ +static ActKeyColumn *ED_keylist_find_neighbour_front_to_back(ActKeyColumn *cursor, float cfra) +{ + while (cursor->next && cursor->next->cfra <= cfra) { + cursor = cursor->next; + } + return cursor; +} + +/* `ED_keylist_find_neighbour_back_to_front` is called before the runtime can be initialized so we + * cannot use bin searching. */ +static ActKeyColumn *ED_keylist_find_neighbour_back_to_front(ActKeyColumn *cursor, float cfra) +{ + while (cursor->prev && cursor->prev->cfra >= cfra) { + cursor = cursor->prev; + } + return cursor; +} + +/* + * `ED_keylist_find_exact_or_neighbour_column` is called before the runtime can be initialized so + * we cannot use bin searching. + * + * This function is called to add or update columns in the keylist. + * Typically columns are sorted by frame number so keeping track of the last_accessed_column + * reduces searching. + */ +static ActKeyColumn *ED_keylist_find_exact_or_neighbour_column(AnimKeylist *keylist, float cfra) +{ + BLI_assert(!keylist->is_runtime_initialized); + if (ED_keylist_is_empty(keylist)) { + return nullptr; + } + + ActKeyColumn *cursor = keylist->last_accessed_column.value_or( + static_cast(keylist->key_columns.first)); + if (!is_cfra_eq(cursor->cfra, cfra)) { + const bool walking_direction_front_to_back = cursor->cfra <= cfra; + if (walking_direction_front_to_back) { + cursor = ED_keylist_find_neighbour_front_to_back(cursor, cfra); + } + else { + cursor = ED_keylist_find_neighbour_back_to_front(cursor, cfra); + } + } + + keylist->last_accessed_column = cursor; + return cursor; +} + +static void ED_keylist_add_or_update_column(AnimKeylist *keylist, + float cfra, + KeylistCreateColumnFunction create_func, + KeylistUpdateColumnFunction update_func, + void *userdata) +{ + BLI_assert_msg( + !keylist->is_runtime_initialized, + "Modifying AnimKeylist isn't allowed after runtime is initialized " + "keylist->key_columns/columns_len will get out of sync with runtime.key_columns."); + if (ED_keylist_is_empty(keylist)) { + ActKeyColumn *key_column = create_func(userdata); + BLI_addhead(&keylist->key_columns, key_column); + keylist->column_len += 1; + keylist->last_accessed_column = key_column; + return; + } + + ActKeyColumn *nearest = ED_keylist_find_exact_or_neighbour_column(keylist, cfra); + if (is_cfra_eq(nearest->cfra, cfra)) { + update_func(nearest, userdata); + } + else if (is_cfra_lt(nearest->cfra, cfra)) { + ActKeyColumn *key_column = create_func(userdata); + BLI_insertlinkafter(&keylist->key_columns, nearest, key_column); + keylist->column_len += 1; + keylist->last_accessed_column = key_column; + } + else { + ActKeyColumn *key_column = create_func(userdata); + BLI_insertlinkbefore(&keylist->key_columns, nearest, key_column); + keylist->column_len += 1; + keylist->last_accessed_column = key_column; + } +} /* Add the given BezTriple to the given 'list' of Keyframes */ static void add_bezt_to_keycolumns_list(AnimKeylist *keylist, BezTripleChain *bezt) @@ -416,7 +658,8 @@ static void add_bezt_to_keycolumns_list(AnimKeylist *keylist, BezTripleChain *be return; } - BLI_dlrbTree_add(&keylist->keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt); + float cfra = bezt->cur->vec[1][0]; + ED_keylist_add_or_update_column(keylist, cfra, nalloc_ak_bezt, nupdate_ak_bezt, bezt); } /* Add the given GPencil Frame to the given 'list' of Keyframes */ @@ -426,7 +669,8 @@ static void add_gpframe_to_keycolumns_list(AnimKeylist *keylist, bGPDframe *gpf) return; } - BLI_dlrbTree_add(&keylist->keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); + float cfra = gpf->framenum; + ED_keylist_add_or_update_column(keylist, cfra, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } /* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */ @@ -436,11 +680,9 @@ static void add_masklay_to_keycolumns_list(AnimKeylist *keylist, MaskLayerShape return; } - BLI_dlrbTree_add(&keylist->keys, - compare_ak_masklayshape, - nalloc_ak_masklayshape, - nupdate_ak_masklayshape, - masklay_shape); + float cfra = masklay_shape->frame; + ED_keylist_add_or_update_column( + keylist, cfra, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape); } /* ActKeyBlocks (Long Keyframes) ------------------------------------------ */ @@ -476,7 +718,7 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) && IS_EQF(prev->vec[1][1], prev->vec[2][1]); } - /* This interpolation type induces movement even between identical keys. */ + /* This interpolation type induces movement even between identical columns. */ else { hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC); } @@ -514,7 +756,7 @@ static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block) static void add_bezt_to_keyblocks_list(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len) { - ActKeyColumn *col = static_cast(keylist->keys.first); + ActKeyColumn *col = static_cast(keylist->key_columns.first); if (bezt && bezt_len >= 2) { ActKeyBlockInfo block; @@ -532,19 +774,15 @@ static void add_bezt_to_keyblocks_list(AnimKeylist *keylist, BezTriple *bezt, co if (is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) { /* Backtrack to find the right location. */ if (is_cfra_lt(bezt[1].vec[1][0], col->cfra)) { - ActKeyColumn *newcol = (ActKeyColumn *)BLI_dlrbTree_search_exact( - &keylist->keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]); + ActKeyColumn *newcol = ED_keylist_find_exact_or_neighbour_column(keylist, col->cfra); - if (newcol != nullptr) { - col = newcol; + BLI_assert(newcol); + BLI_assert(newcol->cfra == col->cfra); - /* The previous keyblock is garbage too. */ - if (col->prev != nullptr) { - add_keyblock_info(col->prev, &dummy_keyblock); - } - } - else { - BLI_assert(false); + col = newcol; + /* The previous keyblock is garbage too. */ + if (col->prev != nullptr) { + add_keyblock_info(col->prev, &dummy_keyblock); } } @@ -577,20 +815,17 @@ static void add_bezt_to_keyblocks_list(AnimKeylist *keylist, BezTriple *bezt, co */ static void update_keyblocks(AnimKeylist *keylist, BezTriple *bezt, const int bezt_len) { - /* Recompute the prev/next linked list. */ - BLI_dlrbTree_linkedlist_sync(&keylist->keys); - /* Find the curve count */ int max_curve = 0; - LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->keys) { + LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->key_columns) { max_curve = MAX2(max_curve, col->totcurve); } /* Propagate blocks to inserted keys */ ActKeyColumn *prev_ready = nullptr; - LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->keys) { + LISTBASE_FOREACH (ActKeyColumn *, col, &keylist->key_columns) { /* Pre-existing column. */ if (col->totcurve > 0) { prev_ready = col; @@ -775,6 +1010,7 @@ void cachefile_to_keylist(bDopeSheet *ads, void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const int saction_flag) { if (fcu && fcu->totvert && fcu->bezt) { + ED_keylist_reset_last_accessed(keylist); /* apply NLA-mapping (if applicable) */ if (adt) { ANIM_nla_mapping_apply_fcurve(adt, fcu, false, false); @@ -790,7 +1026,7 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, AnimKeylist *keylist, const i for (int v = 0; v < fcu->totvert; v++) { chain.cur = &fcu->bezt[v]; - /* Neighbor keys, accounting for being cyclic. */ + /* Neighbor columns, accounting for being cyclic. */ if (do_extremes) { chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : @@ -856,6 +1092,7 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, con void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, AnimKeylist *keylist) { if (gpl && keylist) { + ED_keylist_reset_last_accessed(keylist); /* Although the frames should already be in an ordered list, * they are not suitable for displaying yet. */ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { @@ -869,6 +1106,7 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, AnimKeylist *keylis void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, AnimKeylist *keylist) { if (masklay && keylist) { + ED_keylist_reset_last_accessed(keylist); LISTBASE_FOREACH (MaskLayerShape *, masklay_shape, &masklay->splines_shapes) { add_masklay_to_keycolumns_list(keylist, masklay_shape); } diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index bc5cbd92deb..c02644cde39 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -976,6 +976,7 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, const wmEvent * } /* Cancel if no keyframes found. */ + ED_keylist_prepare_for_direct_access(pso->keylist); if (ED_keylist_is_empty(pso->keylist)) { BKE_report(op->reports, RPT_ERROR, "No keyframes to slide between"); pose_slide_exit(C, op); @@ -1712,6 +1713,7 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st FCurve *fcu = (FCurve *)ld->data; fcurve_to_keylist(adt, fcu, keylist, 0); } + ED_keylist_prepare_for_direct_access(keylist); /* Find the long keyframe (i.e. hold), and hence obtain the endFrame value * - the best case would be one that starts on the frame itself diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 3a9750c1206..4194444ca0f 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -139,14 +139,20 @@ typedef enum eKeyframeExtremeDrawOpts { struct AnimKeylist *ED_keylist_create(void); void ED_keylist_free(struct AnimKeylist *keylist); -const struct ActKeyColumn *ED_keylist_find_exact(const struct AnimKeylist *keylist, float cfra); -const struct ActKeyColumn *ED_keylist_find_next(const struct AnimKeylist *keylist, float cfra); -const struct ActKeyColumn *ED_keylist_find_prev(const struct AnimKeylist *keylist, float cfra); +void ED_keylist_prepare_for_direct_access(struct AnimKeylist *keylist); +const struct ActKeyColumn *ED_keylist_find_exact(const struct AnimKeylist *keylist, + const float cfra); +const struct ActKeyColumn *ED_keylist_find_next(const struct AnimKeylist *keylist, + const float cfra); +const struct ActKeyColumn *ED_keylist_find_prev(const struct AnimKeylist *keylist, + const float cfra); const struct ActKeyColumn *ED_keylist_find_any_between(const struct AnimKeylist *keylist, const Range2f frame_range); bool ED_keylist_is_empty(const struct AnimKeylist *keylist); const struct ListBase /* ActKeyColumn */ *ED_keylist_listbase(const struct AnimKeylist *keylist); bool ED_keylist_frame_range(const struct AnimKeylist *keylist, Range2f *r_frame_range); +const ActKeyColumn *ED_keylist_array(const struct AnimKeylist *keylist); +int64_t ED_keylist_array_len(const struct AnimKeylist *keylist); /* Key-data Generation --------------- */ @@ -197,8 +203,6 @@ void mask_to_keylist(struct bDopeSheet *ads, struct AnimKeylist *keylist); /* ActKeyColumn API ---------------- */ -/* Comparator callback used for ActKeyColumns and cframe float-value pointer */ -short compare_ak_cfraPtr(void *node, void *data); /* Checks if ActKeyColumn has any block data */ bool actkeyblock_is_valid(const ActKeyColumn *ac); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5d6f21f4854..3efe4ae85d5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3107,6 +3107,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) mask_to_keylist(&ads, masklay, keylist); } } + ED_keylist_prepare_for_direct_access(keylist); /* find matching keyframe in the right direction */ const ActKeyColumn *ak; diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 9dcfc626a50..a5e75e31e38 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -162,6 +162,7 @@ static void actkeys_find_key_in_list_element(bAnimContext *ac, struct AnimKeylist *keylist = ED_keylist_create(); actkeys_list_element_to_keylist(ac, keylist, ale); + ED_keylist_prepare_for_direct_access(keylist); AnimData *adt = ANIM_nla_mapping_get(ac, ale); -- cgit v1.2.3 From 7f1fe10595065128aab2a4aea4bc9c46e155053c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 10 Sep 2021 14:26:21 +0200 Subject: T78995: Enable keylist threaded drawing. This enabled multithreaded building of the keys that needs to be drawn in the timeline (and other action editors). On an AMD Ryzen 3800 using a mocap data test file (available in patch) the performance went from 2fps to 8fps. The performance increase depends on the number of rows of keyframes that is shown in for example the timeline editor. Each row will be using a different thread. Currently the bottleneck is the summary channel that we could split up in the future even more ( although that is a complex refactoring work). Reviewed By: sybren Differential Revision: https://developer.blender.org/D12198 --- source/blender/editors/animation/keyframes_draw.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 8a884c0bd5b..d9a22c47242 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -30,6 +30,7 @@ #include "BLI_dlrbTree.h" #include "BLI_listbase.h" #include "BLI_rect.h" +#include "BLI_task.h" #include "DNA_anim_types.h" #include "DNA_gpencil_types.h" @@ -504,12 +505,25 @@ AnimKeylistDrawList *ED_keylist_draw_list_create(void) return MEM_callocN(sizeof(AnimKeylistDrawList), __func__); } +static void ED_keylist_draw_list_elem_build_task(void *__restrict UNUSED(userdata), + void *item, + int UNUSED(index), + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + AnimKeylistDrawListElem *elem = item; + ED_keylist_draw_list_elem_build_keylist(elem); + ED_keylist_draw_list_elem_prepare_for_drawing(elem); +} + static void ED_keylist_draw_list_build_keylists(AnimKeylistDrawList *draw_list) { - LISTBASE_FOREACH (AnimKeylistDrawListElem *, elem, &draw_list->channels) { - ED_keylist_draw_list_elem_build_keylist(elem); - ED_keylist_draw_list_elem_prepare_for_drawing(elem); - } + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + /* Create a thread per item, a single item is complex enough to deserve its own thread. */ + settings.min_iter_per_thread = 1; + + BLI_task_parallel_listbase( + &draw_list->channels, NULL, ED_keylist_draw_list_elem_build_task, &settings); } static void ED_keylist_draw_list_draw_blocks(AnimKeylistDrawList *draw_list, View2D *v2d) -- cgit v1.2.3 From 7a5216497cc31e6d6e412a6d0aace8f17a51e585 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 10 Sep 2021 14:41:20 +0200 Subject: Fix possible crash displaying asset preview from current file For some reason the asset preview isn't created or loaded correctly in some instances. This could be addressed with D9974, but hard to tell since I only have a failing .blend file, no steps to recreate it from scratch. Would crash when opening an Asset Browser, selecting an object asset (that has an invalid preview stored) and opening the Asset Browser sidebar, so that the preview is visible there. --- source/blender/editors/space_file/filelist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index c7d23943b6c..46978972821 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1442,7 +1442,9 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat if (preview->in_memory_preview) { if (BKE_previewimg_is_finished(preview->in_memory_preview, ICON_SIZE_PREVIEW)) { ImBuf *imbuf = BKE_previewimg_to_imbuf(preview->in_memory_preview, ICON_SIZE_PREVIEW); - preview->icon_id = BKE_icon_imbuf_create(imbuf); + if (imbuf) { + preview->icon_id = BKE_icon_imbuf_create(imbuf); + } done = true; } } -- cgit v1.2.3 From ca39aff59d45e15297a25895f6963e134894aad4 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 10 Sep 2021 14:43:48 +0200 Subject: Cleanup: Fix comment in recent commit. A task is created for each item in a list base. It used to say that a thread was created for each item. --- source/blender/editors/animation/keyframes_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d9a22c47242..ac7db9f4f46 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -519,7 +519,7 @@ static void ED_keylist_draw_list_build_keylists(AnimKeylistDrawList *draw_list) { TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - /* Create a thread per item, a single item is complex enough to deserve its own thread. */ + /* Create a task per item, a single item is complex enough to deserve its own task. */ settings.min_iter_per_thread = 1; BLI_task_parallel_listbase( -- cgit v1.2.3 From eb96f0cf06b9b4932979541fe4032328ad23f41f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 10 Sep 2021 15:00:09 +0200 Subject: Add missing bit to own previous commit Amendment to 7a5216497cc3. Removed this before committing, because I thought it wasn't needed. Of course it was... --- source/blender/editors/space_file/filelist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 46978972821..511b5b255e9 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1955,7 +1955,9 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in if (entry->local_data.preview_image && BKE_previewimg_is_finished(entry->local_data.preview_image, ICON_SIZE_PREVIEW)) { ImBuf *ibuf = BKE_previewimg_to_imbuf(entry->local_data.preview_image, ICON_SIZE_PREVIEW); - ret->preview_icon_id = BKE_icon_imbuf_create(ibuf); + if (ibuf) { + ret->preview_icon_id = BKE_icon_imbuf_create(ibuf); + } } BLI_addtail(&cache->cached_entries, ret); return ret; -- cgit v1.2.3 From e2f99c338bd5787658ce08984e6856b7d369a41f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 10 Sep 2021 10:34:49 -0500 Subject: Geometry Nodes: Add versioning to change legacy node ID names Recently we have decided to avoid fancier versioning for nodes with string inputs for attribute names when updating the attribute workflow for 3.0. In that case we would just duplicate any node that will have an updated version to work with fields. We want to be able to use the "proper" ID names for the new versions of the nodes though, so this patch adds "Legacy" to the IDs of all nodes that will be replaced in 3.0. This commit also removes the nodes from the add menu when the fields experimental preference is enabled, in order to make it clear what has been updated and what hasn't. Nodes in the "Maybe" categories in versioning_300.c can be renamed later if necessary. For now it's probably better to be conservative, and to keep the list complete. Differential Revision: https://developer.blender.org/D12420 --- source/blender/editors/space_node/node_add.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 9264c9d3572..4d2e00e97a1 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -575,7 +575,7 @@ static int node_add_texture_exec(bContext *C, wmOperator *op) bNode *texture_node = node_add_node(C, nullptr, - GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE, + GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE, snode->runtime->cursor[0], snode->runtime->cursor[1]); if (!texture_node) { -- cgit v1.2.3 From 28f773925af01c1d9d23e58c7cce49efdc0b65a7 Mon Sep 17 00:00:00 2001 From: Henrik Dick Date: Fri, 10 Sep 2021 18:48:41 +0200 Subject: Fix Constraints not updating on move in stack Flag the changed object and its bones to update after moving a constraint in the stack up or down. The two operators for move up and move down seem to be unused, but I notices they had the same problem, so I added the update there as well. Reviewed By: sybren Differential Revision: https://developer.blender.org/D12174 --- source/blender/editors/object/object_constraint.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index e0419e0a4cc..c46e868899c 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -1862,6 +1862,7 @@ static int constraint_move_down_exec(bContext *C, wmOperator *op) BLI_remlink(conlist, con); BLI_insertlinkafter(conlist, nextCon, con); + ED_object_constraint_update(CTX_data_main(C), ob); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); return OPERATOR_FINISHED; @@ -1917,6 +1918,7 @@ static int constraint_move_up_exec(bContext *C, wmOperator *op) BLI_remlink(conlist, con); BLI_insertlinkbefore(conlist, prevCon, con); + ED_object_constraint_update(CTX_data_main(C), ob); WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); return OPERATOR_FINISHED; @@ -1970,6 +1972,8 @@ static int constraint_move_to_index_exec(bContext *C, wmOperator *op) if (con) { ED_object_constraint_move_to_index(ob, con, new_index); + ED_object_constraint_update(CTX_data_main(C), ob); + return OPERATOR_FINISHED; } -- cgit v1.2.3 From 4e78b89e487e9b9707d583c6b2578ad122c59d5e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 11 Sep 2021 13:05:20 +0200 Subject: Geometry Nodes: add field support for socket inspection Since fields were committed to master, socket inspection did not work correctly for all socket types anymore. Now the same functionality as before is back. Furthermore, fields that depend on some input will now show the inputs in the socket inspection. I added support for evaluating constant fields more immediately. This has the benefit that the same constant field is not evaluated more than once. It also helps with making the field independent of the multi-functions that it uses. We might still want to change the ownership handling for the multi-functions of nodes a bit, but that can be done separately. Differential Revision: https://developer.blender.org/D12444 --- source/blender/editors/space_node/node_draw.cc | 83 ++++++++++++++++++++------ 1 file changed, 65 insertions(+), 18 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 5b4e3b3b6f5..aa241071425 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -41,10 +41,12 @@ #include "BLI_span.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" +#include "BLI_vector_set.hh" #include "BLT_translation.h" #include "BKE_context.h" +#include "BKE_geometry_set.hh" #include "BKE_idtype.h" #include "BKE_lib_id.h" #include "BKE_main.h" @@ -78,6 +80,8 @@ #include "NOD_geometry_nodes_eval_log.hh" +#include "FN_field_cpp_type.hh" + #include "node_intern.h" /* own include */ #ifdef WITH_COMPOSITOR @@ -88,7 +92,11 @@ using blender::Map; using blender::Set; using blender::Span; using blender::Vector; +using blender::VectorSet; using blender::fn::CPPType; +using blender::fn::FieldCPPType; +using blender::fn::FieldInput; +using blender::fn::GField; using blender::fn::GPointer; namespace geo_log = blender::nodes::geometry_nodes_eval_log; @@ -850,31 +858,70 @@ static void create_inspection_string_for_generic_value(const geo_log::GenericVal }; const GPointer value = value_log.value(); - if (value.is_type()) { - ss << *value.get() << TIP_(" (Integer)"); - } - else if (value.is_type()) { - ss << *value.get() << TIP_(" (Float)"); - } - else if (value.is_type()) { - ss << *value.get() << TIP_(" (Vector)"); - } - else if (value.is_type()) { - ss << (*value.get() ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)"); - } - else if (value.is_type()) { - ss << *value.get() << TIP_(" (String)"); + const CPPType &type = *value.type(); + if (const FieldCPPType *field_type = dynamic_cast(&type)) { + const CPPType &base_type = field_type->field_type(); + BUFFER_FOR_CPP_TYPE_VALUE(base_type, buffer); + const GField &field = field_type->get_gfield(value.get()); + if (field.node().depends_on_input()) { + if (base_type.is()) { + ss << TIP_("Integer Field"); + } + else if (base_type.is()) { + ss << TIP_("Float Field"); + } + else if (base_type.is()) { + ss << TIP_("Vector Field"); + } + else if (base_type.is()) { + ss << TIP_("Boolean Field"); + } + else if (base_type.is()) { + ss << TIP_("String Field"); + } + ss << TIP_(" based on:\n"); + + /* Use vector set to deduplicate inputs. */ + VectorSet> field_inputs; + field.node().foreach_field_input( + [&](const FieldInput &field_input) { field_inputs.add(field_input); }); + for (const FieldInput &field_input : field_inputs) { + ss << "\u2022 " << field_input.socket_inspection_name(); + if (field_input != field_inputs.as_span().last().get()) { + ss << ".\n"; + } + } + } + else { + blender::fn::evaluate_constant_field(field, buffer); + if (base_type.is()) { + ss << *(int *)buffer << TIP_(" (Integer)"); + } + else if (base_type.is()) { + ss << *(float *)buffer << TIP_(" (Float)"); + } + else if (base_type.is()) { + ss << *(blender::float3 *)buffer << TIP_(" (Vector)"); + } + else if (base_type.is()) { + ss << ((*(bool *)buffer) ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)"); + } + else if (base_type.is()) { + ss << *(std::string *)buffer << TIP_(" (String)"); + } + base_type.destruct(buffer); + } } - else if (value.is_type()) { + else if (type.is()) { id_to_inspection_string((ID *)*value.get(), ID_OB); } - else if (value.is_type()) { + else if (type.is()) { id_to_inspection_string((ID *)*value.get(), ID_MA); } - else if (value.is_type()) { + else if (type.is()) { id_to_inspection_string((ID *)*value.get(), ID_TE); } - else if (value.is_type()) { + else if (type.is()) { id_to_inspection_string((ID *)*value.get(), ID_GR); } } -- cgit v1.2.3 From c946fdb2e5fc1eab139f70f01ea4e673435455bd Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sat, 11 Sep 2021 09:06:47 -0700 Subject: Calm Warning: Unused Variable Calms warning for unused variable in `constraint_copy_to_selected_poll` by using UNUSED_VARS. See D12453 for further details Differential Revision: https://developer.blender.org/D12453 Reviewed by Campbell Barton --- source/blender/editors/object/object_constraint.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index c46e868899c..8702b18a46f 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -1786,7 +1786,8 @@ static bool constraint_copy_to_selected_poll(bContext *C) if (pchan) { bool found = false; - CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, chan, selected_pose_bones, Object *, UNUSED(ob)) { + CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, chan, selected_pose_bones, Object *, ob) { + UNUSED_VARS(ob); if (pchan != chan) { /** NOTE: Can not return here, because CTX_DATA_BEGIN_WITH_ID allocated * a list that needs to be freed by CTX_DATA_END. */ -- cgit v1.2.3 From b9febb54a492ac6c93802fb0aa189d4c3fd99b0b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 11 Sep 2021 13:54:40 -0500 Subject: Geometry Nodes: Support modifier on curve objects With this commit, curve objects support the geometry nodes modifier. Curves objects now evaluate to `CurveEval` unless there was a previous implicit conversion (tessellating modifiers, mesh modifiers, or the settings in the curve "Geometry" panel). In the new code, curves are only considered to be the wire edges-- any generated surface is a mesh instead, stored in the evaluated geometry set. The consolidation of concepts mentioned above allows remove a lot of code that had to do with maintaining the `DispList` type temporarily for modifiers and rendering. Instead, render engines see a separate object for the mesh from the mesh geometry component, and when the curve object evaluates to a curve, the `CurveEval` is always used for drawing wire edges. However, currently the `DispList` type is still maintained and used as an intermediate step in implicit mesh conversion. In the future, more uses of it could be changed to use `CurveEval` and `Mesh` instead. This is mostly not changed behavior, it is just a formalization of existing logic after recent fixes for 2.8 versions last year and two years ago. Also, in the future more functionality can be converted to nodes, removing cases of implicit conversions. For more discussion on that topic, see T89676. The `use_fill_deform` option is removed. It has not worked properly since 2.62, and the choice for filling a curve before or after deformation will work much better and be clearer with a node system. Applying the geometry nodes modifier to generate a curve is not implemented with this commit, so applying the modifier won't work at all. This is a separate technical challenge, and should be solved in a separate step. Differential Revision: https://developer.blender.org/D11597 --- source/blender/editors/curve/editcurve_add.c | 1 - source/blender/editors/space_spreadsheet/space_spreadsheet.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index d1fe162fc4a..19aad20cbc1 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -535,7 +535,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) newob = true; cu = (Curve *)obedit->data; - cu->flag |= CU_DEFORM_FILL; if (type & CU_PRIM_PATH) { cu->flag |= CU_PATH | CU_3D; diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index fcc92345bea..d503297f540 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -270,7 +270,7 @@ Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet, return nullptr; } Object *object_orig = (Object *)used_id; - if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) { + if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVE, OB_FONT)) { return nullptr; } -- cgit v1.2.3 From 2aa7edbe6b4428d8f7915a9dc402d1209a4b114b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Sep 2021 19:51:16 +1000 Subject: Cleanup: spelling --- source/blender/editors/space_action/action_edit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 6f4e295cbb2..3e38be243c9 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -192,7 +192,7 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const bGPDlayer *gpl = ale->data; bGPDframe *gpf; - /* find gp-frame which is less than or equal to cframe */ + /* Find gp-frame which is less than or equal to current-frame. */ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { const float framenum = (float)gpf->framenum; *min = min_ff(*min, framenum); @@ -204,7 +204,7 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const MaskLayer *masklay = ale->data; MaskLayerShape *masklay_shape; - /* find mask layer which is less than or equal to cframe */ + /* Find mask layer which is less than or equal to current-frame. */ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { const float framenum = (float)masklay_shape->frame; -- cgit v1.2.3 From b5a1c194c5dde20b13e3dd3372055d8b5e58a18e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Sep 2021 19:51:17 +1000 Subject: Cleanup: early return from smoothview when the view is unchanged --- source/blender/editors/space_view3d/view3d_view.c | 156 ++++++++++------------ 1 file changed, 71 insertions(+), 85 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index a6dd95cac04..f5da7c14a88 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -199,105 +199,91 @@ void ED_view3d_smooth_view_ex( sms.to_camera = true; /* restore view3d values in end */ } - bool changed = false; /* zero means no difference */ - - if (sview->camera_old != sview->camera) { - changed = true; - } - else if (sms.dst.dist != rv3d->dist) { - changed = true; - } - else if (sms.dst.lens != v3d->lens) { - changed = true; - } - else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) { - changed = true; - } - else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) { - changed = true; + if ((sview->camera_old == sview->camera) && /* Camera. */ + (sms.dst.dist == rv3d->dist) && /* Distance. */ + (sms.dst.lens == v3d->lens) && /* Lens. */ + equals_v3v3(sms.dst.ofs, rv3d->ofs) && /* Offset. */ + equals_v4v4(sms.dst.quat, rv3d->viewquat) /* Rotation. */ + ) { + /* Early return if nothing changed. */ + return; } - /* The new view is different from the previous state. */ - if (changed) { - - /* Skip smooth viewing for external render engine draw. */ - if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) { + /* Skip smooth viewing for external render engine draw. */ + if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) { - /* original values */ - if (sview->camera_old) { - Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old); - if (sview->ofs != NULL) { - sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, sview->ofs, 0.0f); - } - ED_view3d_from_object( - ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens); - } - /* grid draw as floor */ - if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { - /* use existing if exists, means multiple calls to smooth view - * won't lose the original 'view' setting */ - rv3d->view = RV3D_VIEW_USER; + /* original values */ + if (sview->camera_old) { + Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old); + if (sview->ofs != NULL) { + sms.src.dist = ED_view3d_offset_distance(ob_camera_old_eval->obmat, sview->ofs, 0.0f); } + ED_view3d_from_object( + ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens); + } + /* grid draw as floor */ + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { + /* use existing if exists, means multiple calls to smooth view + * won't lose the original 'view' setting */ + rv3d->view = RV3D_VIEW_USER; + } - sms.time_allowed = (double)smooth_viewtx / 1000.0; - - /* if this is view rotation only - * we can decrease the time allowed by - * the angle between quats - * this means small rotations won't lag */ - if (sview->quat && !sview->ofs && !sview->dist) { - /* scale the time allowed by the rotation */ - /* 180deg == 1.0 */ - sms.time_allowed *= (double)fabsf( - angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) / - M_PI; - } + sms.time_allowed = (double)smooth_viewtx / 1000.0; - /* ensure it shows correct */ - if (sms.to_camera) { - /* use ortho if we move from an ortho view to an ortho camera */ - Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera); - rv3d->persp = (((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) && - (((Camera *)ob_camera_eval->data)->type == CAM_ORTHO)) ? - RV3D_ORTHO : - RV3D_PERSP); - } + /* If this is view rotation only we can decrease the time allowed by the angle between quats + * this means small rotations won't lag. */ + if (sview->quat && !sview->ofs && !sview->dist) { + /* scale the time allowed by the rotation */ + /* 180deg == 1.0 */ + sms.time_allowed *= (double)fabsf(angle_signed_normalized_qtqt(sms.dst.quat, sms.src.quat)) / + M_PI; + } - rv3d->rflag |= RV3D_NAVIGATING; + /* ensure it shows correct */ + if (sms.to_camera) { + /* use ortho if we move from an ortho view to an ortho camera */ + Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera); + rv3d->persp = (((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) && + (((Camera *)ob_camera_eval->data)->type == CAM_ORTHO)) ? + RV3D_ORTHO : + RV3D_PERSP); + } - /* not essential but in some cases the caller will tag the area for redraw, and in that - * case we can get a flicker of the 'org' user view but we want to see 'src' */ - view3d_smooth_view_state_restore(&sms.src, v3d, rv3d); + rv3d->rflag |= RV3D_NAVIGATING; - /* keep track of running timer! */ - if (rv3d->sms == NULL) { - rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d"); - } - *rv3d->sms = sms; - if (rv3d->smooth_timer) { - WM_event_remove_timer(wm, win, rv3d->smooth_timer); - } - /* #TIMER1 is hard-coded in key-map. */ - rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); + /* not essential but in some cases the caller will tag the area for redraw, and in that + * case we can get a flicker of the 'org' user view but we want to see 'src' */ + view3d_smooth_view_state_restore(&sms.src, v3d, rv3d); + + /* keep track of running timer! */ + if (rv3d->sms == NULL) { + rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d"); } - else { - if (sms.to_camera == false) { - copy_v3_v3(rv3d->ofs, sms.dst.ofs); - copy_qt_qt(rv3d->viewquat, sms.dst.quat); - rv3d->dist = sms.dst.dist; - v3d->lens = sms.dst.lens; + *rv3d->sms = sms; + if (rv3d->smooth_timer) { + WM_event_remove_timer(wm, win, rv3d->smooth_timer); + } + /* #TIMER1 is hard-coded in key-map. */ + rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); + } + else { + /* Animation is disabled, apply immediately. */ + if (sms.to_camera == false) { + copy_v3_v3(rv3d->ofs, sms.dst.ofs); + copy_qt_qt(rv3d->viewquat, sms.dst.quat); + rv3d->dist = sms.dst.dist; + v3d->lens = sms.dst.lens; - ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); - } + ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); + } - if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { - view3d_boxview_copy(area, region); - } + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { + view3d_boxview_copy(area, region); + } - ED_region_tag_redraw(region); + ED_region_tag_redraw(region); - WM_event_add_mousemove(win); - } + WM_event_add_mousemove(win); } } -- cgit v1.2.3 From 9b2b32a3338d873529a9b2c402feae4e9d25afdf Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Sep 2021 17:50:41 +1000 Subject: Fix T84638: Wrong scale for primitives with radius Creating some primitives allows for a scale value (via python) that will scale the object accordingly. For objects with a radius parameter (like cylinders, spheres, etc.) passing a scale different to (1,1,1) would result in unexpected behavior. For example: `>>> bpy.ops.mesh.primitive_uv_sphere_add(radius=2, scale=(1,1,2))` We would expect this to create a sphere with a radius of 2 (dimensions 4,4,4) and then be scaled *2 along the z-axis (dimensions 4,4,8). But this would previously create a scaled sphere with dimensions (2,2,4). The scale was simply divided by two. Maybe because the "radius" parameter for creating the primitives was confusingly named "diameter" (but used as the radius). The fix adds a scale parameter to `ED_object_new_primitive_matrix` and also renames the wrongly named "diameter" parameters to "radius". Reviewed By: campbellbarton Maniphest Tasks: T84638 Ref D10093 --- source/blender/editors/curve/editcurve_add.c | 8 +++--- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mesh/editmesh_add.c | 14 ++++------ source/blender/editors/object/object_add.c | 39 ++++++++++++++++------------ 4 files changed, 32 insertions(+), 30 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 19aad20cbc1..75fb17e8cc1 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -515,7 +515,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) bool newob = false; bool enter_editmode; ushort local_view_bits; - float dia; float loc[3], rot[3]; float mat[4][4]; @@ -555,9 +554,10 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) } } - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); - dia = RNA_float_get(op->ptr, "radius"); - mul_mat3_m4_fl(mat, dia); + float radius = RNA_float_get(op->ptr, "radius"); + float scale[3]; + copy_v3_fl(scale, radius); + ED_object_new_primitive_matrix(C, obedit, loc, rot, scale, mat); nu = ED_curve_add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index a9cf04e1ad7..5397cd95ace 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -286,6 +286,7 @@ float ED_object_new_primitive_matrix(struct bContext *C, struct Object *obedit, const float loc[3], const float rot[3], + const float scale[3], float primmat[4][4]); /* Avoid allowing too much insane values even by typing diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index a64b90e15a3..c826da74010 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -73,11 +73,7 @@ static Object *make_prim_init(bContext *C, r_creation_data->was_editmode = true; } - ED_object_new_primitive_matrix(C, obedit, loc, rot, r_creation_data->mat); - - if (scale) { - rescale_m4(r_creation_data->mat, scale); - } + ED_object_new_primitive_matrix(C, obedit, loc, rot, scale, r_creation_data->mat); return obedit; } @@ -351,7 +347,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) op, "verts.out", false, - "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b " + "create_cone segments=%i radius1=%f radius2=%f cap_ends=%b " "cap_tris=%b depth=%f matrix=%m4 calc_uvs=%b", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), @@ -427,7 +423,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) op, "verts.out", false, - "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b " + "create_cone segments=%i radius1=%f radius2=%f cap_ends=%b " "cap_tris=%b depth=%f matrix=%m4 calc_uvs=%b", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), @@ -642,7 +638,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) op, "verts.out", false, - "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4 calc_uvs=%b", + "create_uvsphere u_segments=%i v_segments=%i radius=%f matrix=%m4 calc_uvs=%b", RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), RNA_float_get(op->ptr, "radius"), @@ -710,7 +706,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) op, "verts.out", false, - "create_icosphere subdivisions=%i diameter=%f matrix=%m4 calc_uvs=%b", + "create_icosphere subdivisions=%i radius=%f matrix=%m4 calc_uvs=%b", RNA_int_get(op->ptr, "subdivisions"), RNA_float_get(op->ptr, "radius"), creation_data.mat, diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index f95e3f3b236..beadbf2689e 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -332,8 +332,12 @@ void ED_object_base_init_transform_on_add(Object *object, const float loc[3], co /* Uses context to figure out transform for primitive. * Returns standard diameter. */ -float ED_object_new_primitive_matrix( - bContext *C, Object *obedit, const float loc[3], const float rot[3], float r_primmat[4][4]) +float ED_object_new_primitive_matrix(bContext *C, + Object *obedit, + const float loc[3], + const float rot[3], + const float scale[3], + float r_primmat[4][4]) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -356,6 +360,10 @@ float ED_object_new_primitive_matrix( invert_m3_m3(imat, mat); mul_m3_v3(imat, r_primmat[3]); + if (scale != NULL) { + rescale_m4(r_primmat, scale); + } + { const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) : ED_scene_grid_scale(scene, NULL); @@ -863,7 +871,7 @@ static int effector_add_exec(bContext *C, wmOperator *op) ED_object_editmode_enter_ex(bmain, scene, ob, 0); float mat[4][4]; - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, NULL, mat); mul_mat3_m4_fl(mat, dia); BLI_addtail(&cu->editnurb->nurbs, ED_curve_add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); @@ -999,7 +1007,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) } float mat[4][4]; - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + ED_object_new_primitive_matrix(C, obedit, loc, rot, NULL, mat); /* Halving here is done to account for constant values from #BKE_mball_element_add. * While the default radius of the resulting meta element is 2, * we want to pass in 1 so other values such as resolution are scaled by 1.0. */ @@ -1365,30 +1373,28 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) case GP_EMPTY: { float mat[4][4]; - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, NULL, mat); ED_gpencil_create_blank(C, ob, mat); break; } case GP_STROKE: { float radius = RNA_float_get(op->ptr, "radius"); + float scale[3]; + copy_v3_fl(scale, radius); float mat[4][4]; - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); - mul_v3_fl(mat[0], radius); - mul_v3_fl(mat[1], radius); - mul_v3_fl(mat[2], radius); + ED_object_new_primitive_matrix(C, ob, loc, rot, scale, mat); ED_gpencil_create_stroke(C, ob, mat); break; } case GP_MONKEY: { float radius = RNA_float_get(op->ptr, "radius"); + float scale[3]; + copy_v3_fl(scale, radius); float mat[4][4]; - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); - mul_v3_fl(mat[0], radius); - mul_v3_fl(mat[1], radius); - mul_v3_fl(mat[2], radius); + ED_object_new_primitive_matrix(C, ob, loc, rot, scale, mat); ED_gpencil_create_monkey(C, ob, mat); break; @@ -1397,12 +1403,11 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) case GP_LRT_COLLECTION: case GP_LRT_OBJECT: { float radius = RNA_float_get(op->ptr, "radius"); + float scale[3]; + copy_v3_fl(scale, radius); float mat[4][4]; - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); - mul_v3_fl(mat[0], radius); - mul_v3_fl(mat[1], radius); - mul_v3_fl(mat[2], radius); + ED_object_new_primitive_matrix(C, ob, loc, rot, scale, mat); ED_gpencil_create_lineart(C, ob); -- cgit v1.2.3 From 410dc76177af4258f3813d623c3cdaaddf1f0300 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 13 Sep 2021 12:40:10 +0200 Subject: Various UI messages fixes and updates. --- source/blender/editors/undo/ed_undo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 84d5d3b9aae..22064e04e86 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -578,8 +578,8 @@ static bool ed_undo_is_init_poll(bContext *C) * it will be part of the exception when attempting to call undo in background mode. */ CTX_wm_operator_poll_msg_set( C, - "Undo disabled at startup in background-mode. " - "Call `ed.undo_push()` to explicitly initialize the undo-system."); + "Undo disabled at startup in background-mode " + "(call `ed.undo_push()` to explicitly initialize the undo-system)"); return false; } return true; -- cgit v1.2.3 From 1bcdd1c54e6e9034af2ad1d78b30b891ac42a655 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 13 Sep 2021 15:56:53 +0200 Subject: Fix T91320: Support flipping sides in mesh bisect Changing active side was introduced in {rB7ff6bfd1e0af} but was never working for tools/operators other than the sculpt line mask tool. While for most tools/operators this actually does not make sense, the bisect tool/operator can actually benefit from it. thx @campbellbarton for additional input! Maniphest Tasks: T91320 Differential Revision: https://developer.blender.org/D12473 --- source/blender/editors/mesh/editmesh_bisect.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 3c8afe8e7db..9f6968542a2 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -88,6 +88,7 @@ static void mesh_bisect_interactive_calc(bContext *C, int y_start = RNA_int_get(op->ptr, "ystart"); int x_end = RNA_int_get(op->ptr, "xend"); int y_end = RNA_int_get(op->ptr, "yend"); + const bool use_flip = RNA_boolean_get(op->ptr, "flip"); /* reference location (some point in front of the view) for finding a point on a plane */ const float *co_ref = rv3d->ofs; @@ -105,6 +106,9 @@ static void mesh_bisect_interactive_calc(bContext *C, /* cross both to get a normal */ cross_v3_v3v3(plane_no, co_a, co_b); normalize_v3(plane_no); /* not needed but nicer for user */ + if (use_flip) { + negate_v3(plane_no); + } /* point on plane, can use either start or endpoint */ ED_view3d_win_to_3d(v3d, region, co_ref, co_a_ss, plane_co); @@ -140,7 +144,18 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } - int ret = WM_gesture_straightline_invoke(C, op, event); + /* Support flipping if side matters. */ + int ret; + const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner"); + const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer"); + const bool use_fill = RNA_boolean_get(op->ptr, "use_fill"); + if ((clear_inner != clear_outer) || use_fill) { + ret = WM_gesture_straightline_active_side_invoke(C, op, event); + } + else { + ret = WM_gesture_straightline_invoke(C, op, event); + } + if (ret & OPERATOR_RUNNING_MODAL) { View3D *v3d = CTX_wm_view3d(C); -- cgit v1.2.3 From a78410386b05f375b53ed867980234b61c2eba10 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 13 Sep 2021 16:49:32 +0200 Subject: Cleanup: fix typo in comment --- source/blender/editors/mesh/editmesh_bisect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 9f6968542a2..b511a1d2c14 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -120,7 +120,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) int valid_objects = 0; /* If the properties are set or there is no rv3d, - * skip model and exec immediately. */ + * skip modal and exec immediately. */ if ((CTX_wm_region_view3d(C) == NULL) || (RNA_struct_property_is_set(op->ptr, "plane_co") && RNA_struct_property_is_set(op->ptr, "plane_no"))) { return mesh_bisect_exec(C, op); -- cgit v1.2.3 From 3ff60bcad8cccd6c2f82ea44527f4e6ef619f0be Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 13 Sep 2021 18:40:21 +0200 Subject: Asset Template: Extra UI options This allow users to show/hide: * Library name / refresh. * Assets names. * Filter. To set them in Python use: display_options={'NO_NAMES', 'NO_FILTER', 'NO_LIBRARY'} With contributions by Julian Eisel. Differential Revision: https://developer.blender.org/D12476 --- source/blender/editors/include/UI_interface.h | 12 ++++++++++ .../interface/interface_template_asset_view.cc | 26 +++++++++++++++++----- .../editors/interface/interface_template_list.cc | 9 +++++++- .../blender/editors/interface/interface_widgets.c | 11 +++++++-- 4 files changed, 49 insertions(+), 9 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7211cf9f893..916105b0f8e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2209,6 +2209,11 @@ enum uiTemplateListFlags { UI_TEMPLATE_LIST_SORT_LOCK = (1 << 1), /* Don't allow resizing the list, i.e. don't add the grip button. */ UI_TEMPLATE_LIST_NO_GRIP = (1 << 2), + /** Do not show filtering options, not even the button to expand/collapse them. Also hides the + * grip button. */ + UI_TEMPLATE_LIST_NO_FILTER_OPTIONS = (1 << 3), + /** For #UILST_LAYOUT_BIG_PREVIEW_GRID, don't reserve space for the name label. */ + UI_TEMPLATE_LIST_NO_NAMES = (1 << 4), UI_TEMPLATE_LIST_FLAGS_LAST }; @@ -2289,6 +2294,12 @@ int uiTemplateRecentFiles(struct uiLayout *layout, int rows); void uiTemplateFileSelectPath(uiLayout *layout, struct bContext *C, struct FileSelectParams *params); + +enum { + UI_TEMPLATE_ASSET_DRAW_NO_NAMES = (1 << 0), + UI_TEMPLATE_ASSET_DRAW_NO_FILTER = (1 << 1), + UI_TEMPLATE_ASSET_DRAW_NO_LIBRARY = (1 << 2), +}; void uiTemplateAssetView(struct uiLayout *layout, struct bContext *C, const char *list_id, @@ -2299,6 +2310,7 @@ void uiTemplateAssetView(struct uiLayout *layout, struct PointerRNA *active_dataptr, const char *active_propname, const struct AssetFilterSettings *filter_settings, + const int display_flags, const char *activate_opname, struct PointerRNA *r_activate_op_properties, const char *drag_opname, diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc index 9b601727e29..f27b37a27de 100644 --- a/source/blender/editors/interface/interface_template_asset_view.cc +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -46,6 +46,7 @@ struct AssetViewListData { AssetLibraryReference asset_library_ref; bScreen *screen; + bool show_names; }; static void asset_view_item_but_drag_set(uiBut *but, @@ -95,14 +96,15 @@ static void asset_view_draw_item(uiList *ui_list, uiLayoutSetContextPointer(layout, "asset_handle", itemptr); uiBlock *block = uiLayoutGetBlock(layout); + const bool show_names = list_data->show_names; /* TODO ED_fileselect_init_layout(). Share somehow? */ const float size_x = (96.0f / 20.0f) * UI_UNIT_X; - const float size_y = (96.0f / 20.0f) * UI_UNIT_Y; + const float size_y = (96.0f / 20.0f) * UI_UNIT_Y - (show_names ? 0 : UI_UNIT_Y); uiBut *but = uiDefIconTextBut(block, UI_BTYPE_PREVIEW_TILE, 0, ED_asset_handle_get_preview_icon_id(asset_handle), - ED_asset_handle_get_name(asset_handle), + show_names ? ED_asset_handle_get_name(asset_handle) : "", 0, 0, size_x, @@ -202,6 +204,7 @@ void uiTemplateAssetView(uiLayout *layout, PointerRNA *active_dataptr, const char *active_propname, const AssetFilterSettings *filter_settings, + const int display_flags, const char *activate_opname, PointerRNA *r_activate_op_properties, const char *drag_opname, @@ -220,9 +223,11 @@ void uiTemplateAssetView(uiLayout *layout, RNA_property_enum_get(asset_library_dataptr, asset_library_prop)); uiLayout *row = uiLayoutRow(col, true); - uiItemFullR(row, asset_library_dataptr, asset_library_prop, RNA_NO_INDEX, 0, 0, "", 0); - if (asset_library_ref.type != ASSET_LIBRARY_LOCAL) { - uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_list_refresh"); + if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_LIBRARY) == 0) { + uiItemFullR(row, asset_library_dataptr, asset_library_prop, RNA_NO_INDEX, 0, 0, "", 0); + if (asset_library_ref.type != ASSET_LIBRARY_LOCAL) { + uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_list_refresh"); + } } ED_assetlist_storage_fetch(&asset_library_ref, C); @@ -236,6 +241,15 @@ void uiTemplateAssetView(uiLayout *layout, "AssetViewListData"); list_data->asset_library_ref = asset_library_ref; list_data->screen = CTX_wm_screen(C); + list_data->show_names = (display_flags & UI_TEMPLATE_ASSET_DRAW_NO_NAMES) == 0; + + uiTemplateListFlags template_list_flags = UI_TEMPLATE_LIST_NO_GRIP; + if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_NAMES) != 0) { + template_list_flags |= UI_TEMPLATE_LIST_NO_NAMES; + } + if ((display_flags & UI_TEMPLATE_ASSET_DRAW_NO_FILTER) != 0) { + template_list_flags |= UI_TEMPLATE_LIST_NO_FILTER_OPTIONS; + } /* TODO can we have some kind of model-view API to handle referencing, filtering and lazy loading * (of previews) of the items? */ @@ -252,7 +266,7 @@ void uiTemplateAssetView(uiLayout *layout, 0, UILST_LAYOUT_BIG_PREVIEW_GRID, 0, - UI_TEMPLATE_LIST_NO_GRIP, + template_list_flags, list_data); if (!list) { /* List creation failed. */ diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc index 0ab45ea0f81..8246759ad36 100644 --- a/source/blender/editors/interface/interface_template_list.cc +++ b/source/blender/editors/interface/interface_template_list.cc @@ -944,10 +944,16 @@ static void ui_template_list_layout_draw(bContext *C, /* For scrollbar. */ row = uiLayoutRow(glob, false); + const bool show_names = (flags & UI_TEMPLATE_LIST_NO_NAMES) == 0; + /* TODO ED_fileselect_init_layout(). Share somehow? */ float size_x = (96.0f / 20.0f) * UI_UNIT_X; float size_y = (96.0f / 20.0f) * UI_UNIT_Y; + if (!show_names) { + size_y -= UI_UNIT_Y; + } + const int cols_per_row = MAX2((uiLayoutGetWidth(box) - V2D_SCROLL_WIDTH) / size_x, 1); uiLayout *grid = uiLayoutGridFlow(row, true, cols_per_row, true, true, true); @@ -1033,7 +1039,8 @@ static void ui_template_list_layout_draw(bContext *C, break; } - if (glob) { + const bool add_filters_but = (flags & UI_TEMPLATE_LIST_NO_FILTER_OPTIONS) == 0; + if (glob && add_filters_but) { const bool add_grip_but = (flags & UI_TEMPLATE_LIST_NO_GRIP) == 0; /* About #UI_BTYPE_GRIP drag-resize: diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index a2b86ccd947..0dc7c2d3f9a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -5443,13 +5443,20 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle, rcti trect = *rect; const float text_size = UI_UNIT_Y; float font_dims[2] = {0.0f, 0.0f}; + const bool has_text = name && name[0]; - /* draw icon in rect above the space reserved for the label */ - rect->ymin += text_size; + if (has_text) { + /* draw icon in rect above the space reserved for the label */ + rect->ymin += text_size; + } GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(iconid, 1.0f, rect); GPU_blend(GPU_BLEND_NONE); + if (!has_text) { + return; + } + BLF_width_and_height( fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]); -- cgit v1.2.3 From 917a972b56af103aee406dfffe1f42745b5ad360 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 14 Sep 2021 12:49:36 +1000 Subject: UI: keep navigation gizmos visible during modal operators Hiding viewport navigation gizmos caused the UI to "flicker" unnecessarily, the axis could also be useful as a reference. Resolves T73684 --- source/blender/editors/mesh/editmesh_bevel.c | 2 +- source/blender/editors/mesh/editmesh_bisect.c | 2 +- source/blender/editors/mesh/editmesh_inset.c | 2 +- source/blender/editors/transform/transform_generics.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 01736f2919a..cdbbdd820b7 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -310,7 +310,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) if (v3d) { opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag = V3D_GIZMO_HIDE; + v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; } } diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index b511a1d2c14..f525f2c2e91 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -182,7 +182,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* Misc other vars. */ G.moving = G_TRANSFORM_EDIT; opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag = V3D_GIZMO_HIDE; + v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; /* Initialize modal callout. */ ED_workspace_status_text(C, TIP_("LMB: Click and drag to draw cut line")); diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index 18f51ae9df2..159e84db4ef 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -191,7 +191,7 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal) G.moving = G_TRANSFORM_EDIT; if (v3d) { opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag = V3D_GIZMO_HIDE; + v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0dfb229191c..b7f579cc12f 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -252,7 +252,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve /* turn gizmo off during transform */ if (t->flag & T_MODAL) { t->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag = V3D_GIZMO_HIDE; + v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; } if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) { -- cgit v1.2.3 From 1c1be5bdf4fb9be0658b7d0b1ac13c563a003f1a Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 30 Aug 2021 15:36:39 +0200 Subject: Fix T90862: Texts in Outliner can have wrong icon In contrast to the Filebrowser, the Outliner (Blender File view) did not distinguish icons for text-based formats (if they have a filepath this can be done though). Maniphest Tasks: T90862 Differential Revision: https://developer.blender.org/D12347 --- source/blender/editors/space_outliner/outliner_draw.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index db37c8c1c8c..a094dfb0834 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -32,6 +32,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_text_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" @@ -59,6 +60,7 @@ #include "DEG_depsgraph_build.h" #include "ED_armature.h" +#include "ED_fileselect.h" #include "ED_outliner.h" #include "ED_screen.h" @@ -2625,9 +2627,17 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case ID_NLA: data.icon = ICON_NLA; break; - case ID_TXT: - data.icon = ICON_SCRIPT; + case ID_TXT: { + Text *text = (Text *)tselem->id; + if (text->filepath == NULL || (text->flags & TXT_ISMEM)) { + data.icon = ICON_FILE_TEXT; + } + else { + /* Helps distinguish text-based formats like the filebrowser does. */ + data.icon = ED_file_extension_icon(text->filepath); + } break; + } case ID_GR: data.icon = ICON_OUTLINER_COLLECTION; break; -- cgit v1.2.3 From dee0b56b9216de8f37589b15be2d21cc1b946773 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 14 Sep 2021 16:08:09 +0200 Subject: Cleanup: simplify resource scope methods Previously, a debug name had to be passed to all methods that added a resource to the `ResourceScope`. The idea was that this would make it easier to find certain bugs. In reality I never found this to be useful, and it was mostly annoying. The thing is, something that is in a resource scope never leaks (unless the resource scope is not destructed of course). Removing the name parameter makes the structure easier to use. --- source/blender/editors/space_spreadsheet/space_spreadsheet.cc | 2 +- .../editors/space_spreadsheet/spreadsheet_data_source_geometry.cc | 2 +- source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index d503297f540..a82648aeee0 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -370,7 +370,7 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) std::unique_ptr values_ptr = data_source->get_column_values(*column->id); /* Should have been removed before if it does not exist anymore. */ BLI_assert(values_ptr); - const ColumnValues *values = scope.add(std::move(values_ptr), __func__); + const ColumnValues *values = scope.add(std::move(values_ptr)); const int width = get_column_width_in_pixels(*values); spreadsheet_layout.columns.append({values, width}); diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index f5fef5e4486..bd2d89e4f27 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -70,7 +70,7 @@ std::unique_ptr GeometryDataSource::get_column_values( if (!attribute) { return {}; } - const fn::GVArray *varray = scope_.add(std::move(attribute.varray), __func__); + const fn::GVArray *varray = scope_.add(std::move(attribute.varray)); if (attribute.domain != domain_) { return {}; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc index ae336edfead..1e46fef8d71 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc @@ -328,7 +328,7 @@ Span spreadsheet_filter_rows(const SpaceSpreadsheet &sspreadsheet, geometry_data_source->apply_selection_filter(rows_included); } - Vector &indices = scope.construct>(__func__); + Vector &indices = scope.construct>(); index_vector_from_bools(rows_included, indices); return indices; -- cgit v1.2.3 From 7c7348f78d1b094c4fdc20f2c9dbfe521b68c11e Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 14 Sep 2021 19:24:36 +0100 Subject: Fix T89027: "factor" field in pose breakdowner not updated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After applying the pose breakdowner, the "factor" slider in the redo panel wasn't set to the correct value This would cause the pose to jump around once you start dragging the slider Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D12187 Ref: D12187 --- source/blender/editors/armature/pose_slide.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index c02644cde39..f23376867af 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -1268,6 +1268,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Perform pose updates - in response to some user action * (e.g. pressing a key or moving the mouse). */ if (do_pose_update) { + RNA_float_set(op->ptr, "factor", ED_slider_factor_get(pso->slider)); + /* Update percentage indicator in header. */ pose_slide_draw_status(C, pso); -- cgit v1.2.3 From e6fa74ffed5ffaf2a7cd550415d8216883fd1961 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 14 Sep 2021 18:13:52 -0500 Subject: Fix: Use after free in spreadsheet attribute column ID A temporary string was created in the attribute_foreach callback and used in a map at a higher scope. When the callback finished, the string went out of scope, was freed, then the elements in the set pointed to freed memory. --- .../editors/space_spreadsheet/spreadsheet_data_source_geometry.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index bd2d89e4f27..78d9f61d8d5 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -54,8 +54,7 @@ void GeometryDataSource::foreach_default_column_ids( return true; } SpreadsheetColumnID column_id; - std::string name = attribute_id.name(); - column_id.name = (char *)name.c_str(); + column_id.name = (char *)attribute_id.name().data(); fn(column_id); return true; }); -- cgit v1.2.3 From e1714ce8c90974f563d5071e4a67a249e7626fb3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Sep 2021 10:50:36 +1000 Subject: Cleanup: spelling --- source/blender/editors/space_outliner/outliner_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a094dfb0834..c06a1010168 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2633,7 +2633,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) data.icon = ICON_FILE_TEXT; } else { - /* Helps distinguish text-based formats like the filebrowser does. */ + /* Helps distinguish text-based formats like the file-browser does. */ data.icon = ED_file_extension_icon(text->filepath); } break; -- cgit v1.2.3 From a2c5c2b4068d12e26a8c9d640a389b410c7507f3 Mon Sep 17 00:00:00 2001 From: YimingWu Date: Wed, 15 Sep 2021 14:24:28 +0800 Subject: GPencil: Dot dash modifier. Create dot-dash effect for grease pencil strokes. User can manually edit the length, gap and styles for each segment of dashed lines. The values in each segment can all be key-framed to make animations. Reviewed By: Hans Goudey (HooglyBoogly), Antonio Vazquez (antoniov) Differential Revision: http://developer.blender.org/D11876 --- source/blender/editors/datafiles/CMakeLists.txt | 1 + source/blender/editors/object/CMakeLists.txt | 5 + .../editors/object/object_gpencil_modifier.c | 238 +++++++++++++++++++++ source/blender/editors/object/object_intern.h | 4 + source/blender/editors/object/object_ops.c | 4 + 5 files changed, 252 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 669ceb37328..702fd2e375a 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -336,6 +336,7 @@ set(ICON_NAMES lightprobe_cubemap lightprobe_planar lightprobe_grid + mod_dash color_red color_green color_blue diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 18f2b58eb65..040b5cd5066 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -37,6 +37,9 @@ set(INC ../../../../intern/clog ../../../../intern/glew-mx ../../../../intern/guardedalloc + + # dna_type_offsets.h in BLO_read_write.h + ${CMAKE_BINARY_DIR}/source/blender/makesdna/intern ) set(SRC @@ -93,3 +96,5 @@ if(WITH_EXPERIMENTAL_FEATURES) endif() blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +add_dependencies(bf_editor_object bf_dna) diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index 3995728c428..e3c2932e17a 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -28,6 +28,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_defaults.h" #include "DNA_gpencil_modifier_types.h" #include "DNA_gpencil_types.h" #include "DNA_object_types.h" @@ -35,6 +36,7 @@ #include "BLI_listbase.h" #include "BLI_string_utf8.h" +#include "BLI_string_utils.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -55,6 +57,8 @@ #include "ED_object.h" #include "ED_screen.h" +#include "BLT_translation.h" + #include "UI_interface.h" #include "WM_api.h" @@ -939,3 +943,237 @@ void OBJECT_OT_gpencil_modifier_copy_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; gpencil_edit_modifier_properties(ot); } + +/************************* Dash Modifier *******************************/ + +static bool dash_segment_poll(bContext *C) +{ + return gpencil_edit_modifier_poll_generic(C, &RNA_DashGpencilModifierData, 0, false); +} + +static bool dash_segment_name_exists_fn(void *arg, const char *name) +{ + const DashGpencilModifierData *dmd = (const DashGpencilModifierData *)arg; + for (int i = 0; i < dmd->segments_len; i++) { + if (STREQ(dmd->segments[i].name, name)) { + return true; + } + } + return false; +} + +static int dash_segment_add_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + DashGpencilModifierData *dmd = (DashGpencilModifierData *)gpencil_edit_modifier_property_get( + op, ob, eGpencilModifierType_Dash); + + const int new_active_index = dmd->segment_active_index + 1; + DashGpencilModifierSegment *new_segments = MEM_malloc_arrayN( + dmd->segments_len + 1, sizeof(DashGpencilModifierSegment), __func__); + + if (dmd->segments_len != 0) { + /* Copy the segments before the new segment. */ + memcpy(new_segments, dmd->segments, sizeof(DashGpencilModifierSegment) * new_active_index); + /* Copy the segments after the new segment. */ + memcpy(new_segments + new_active_index + 1, + dmd->segments + new_active_index, + sizeof(DashGpencilModifierSegment) * (dmd->segments_len - new_active_index)); + } + + /* Create the new segment. */ + DashGpencilModifierSegment *ds = &new_segments[new_active_index]; + memcpy( + ds, DNA_struct_default_get(DashGpencilModifierSegment), sizeof(DashGpencilModifierSegment)); + BLI_uniquename_cb( + dash_segment_name_exists_fn, dmd, DATA_("Segment"), '.', ds->name, sizeof(ds->name)); + ds->dmd = dmd; + + MEM_SAFE_FREE(dmd->segments); + dmd->segments = new_segments; + dmd->segments_len++; + dmd->segment_active_index++; + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int dash_segment_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) { + return dash_segment_add_exec(C, op); + } + return OPERATOR_CANCELLED; +} + +void GPENCIL_OT_segment_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Segment"; + ot->description = "Add a segment to the dash modifier"; + ot->idname = "GPENCIL_OT_segment_add"; + + /* api callbacks */ + ot->poll = dash_segment_poll; + ot->invoke = dash_segment_add_invoke; + ot->exec = dash_segment_add_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_modifier_properties(ot); +} + +static int dash_segment_remove_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + + DashGpencilModifierData *dmd = (DashGpencilModifierData *)gpencil_edit_modifier_property_get( + op, ob, eGpencilModifierType_Dash); + + if (dmd->segment_active_index < 0 || dmd->segment_active_index >= dmd->segments_len) { + return OPERATOR_CANCELLED; + } + + if (dmd->segments_len == 1) { + MEM_SAFE_FREE(dmd->segments); + dmd->segment_active_index = -1; + } + else { + DashGpencilModifierSegment *new_segments = MEM_malloc_arrayN( + dmd->segments_len, sizeof(DashGpencilModifierSegment), __func__); + + /* Copy the segments before the deleted segment. */ + memcpy(new_segments, + dmd->segments, + sizeof(DashGpencilModifierSegment) * dmd->segment_active_index); + + /* Copy the segments after the deleted segment. */ + memcpy(new_segments + dmd->segment_active_index, + dmd->segments + dmd->segment_active_index + 1, + sizeof(DashGpencilModifierSegment) * + (dmd->segments_len - dmd->segment_active_index - 1)); + + MEM_freeN(dmd->segments); + dmd->segments = new_segments; + dmd->segment_active_index = MAX2(dmd->segment_active_index - 1, 0); + } + + dmd->segments_len--; + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int dash_segment_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) { + return dash_segment_remove_exec(C, op); + } + return OPERATOR_CANCELLED; +} + +void GPENCIL_OT_segment_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Dash Segment"; + ot->description = "Remove the active segment from the dash modifier"; + ot->idname = "GPENCIL_OT_segment_remove"; + + /* api callbacks */ + ot->poll = dash_segment_poll; + ot->invoke = dash_segment_remove_invoke; + ot->exec = dash_segment_remove_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_modifier_properties(ot); + + RNA_def_int( + ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX); +} + +enum { + GP_SEGEMENT_MOVE_UP = -1, + GP_SEGEMENT_MOVE_DOWN = 1, +}; + +static int dash_segment_move_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + + DashGpencilModifierData *dmd = (DashGpencilModifierData *)gpencil_edit_modifier_property_get( + op, ob, eGpencilModifierType_Dash); + + if (dmd->segments_len < 2) { + return OPERATOR_CANCELLED; + } + + const int direction = RNA_enum_get(op->ptr, "type"); + if (direction == GP_SEGEMENT_MOVE_UP) { + if (dmd->segment_active_index == 0) { + return OPERATOR_CANCELLED; + } + + SWAP(DashGpencilModifierSegment, + dmd->segments[dmd->segment_active_index], + dmd->segments[dmd->segment_active_index - 1]); + + dmd->segment_active_index--; + } + else if (direction == GP_SEGEMENT_MOVE_DOWN) { + if (dmd->segment_active_index == dmd->segments_len - 1) { + return OPERATOR_CANCELLED; + } + + SWAP(DashGpencilModifierSegment, + dmd->segments[dmd->segment_active_index], + dmd->segments[dmd->segment_active_index + 1]); + + dmd->segment_active_index++; + } + else { + return OPERATOR_CANCELLED; + } + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int dash_segment_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op, NULL, NULL)) { + return dash_segment_move_exec(C, op); + } + return OPERATOR_CANCELLED; +} + +void GPENCIL_OT_segment_move(wmOperatorType *ot) +{ + static const EnumPropertyItem segment_move[] = { + {GP_SEGEMENT_MOVE_UP, "UP", 0, "Up", ""}, + {GP_SEGEMENT_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Move Dash Segment"; + ot->description = "Move the active dash segment up or down"; + ot->idname = "GPENCIL_OT_segment_move"; + + /* api callbacks */ + ot->poll = dash_segment_poll; + ot->invoke = dash_segment_move_invoke; + ot->exec = dash_segment_move_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_modifier_properties(ot); + + ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", ""); +} diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 10e016738d0..b2d3216b101 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -202,6 +202,10 @@ void OBJECT_OT_gpencil_modifier_apply(struct wmOperatorType *ot); void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot); void OBJECT_OT_gpencil_modifier_copy_to_selected(struct wmOperatorType *ot); +void GPENCIL_OT_segment_add(struct wmOperatorType *ot); +void GPENCIL_OT_segment_remove(struct wmOperatorType *ot); +void GPENCIL_OT_segment_move(struct wmOperatorType *ot); + /* object_shader_fx.c */ void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index c1928cf7f8a..4b8431be530 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -156,6 +156,10 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_gpencil_modifier_copy); WM_operatortype_append(OBJECT_OT_gpencil_modifier_copy_to_selected); + WM_operatortype_append(GPENCIL_OT_segment_add); + WM_operatortype_append(GPENCIL_OT_segment_remove); + WM_operatortype_append(GPENCIL_OT_segment_move); + /* grease pencil line art */ WM_operatortypes_lineart(); -- cgit v1.2.3 From 5c6cc931b2203d97aa9d570ff3b353c2a3dfebed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Sep 2021 22:34:21 +1000 Subject: Gizmo: add flag to hide the gizmo group during interaction This allows a hack to be removed that temporarily overwrote the 3D views gizmo display flag. Also reverse change from fb27a9bb983ce74b8d8f5f871cf0706dd1e25051 that runs poll on modal gizmo groups as there is some risk that the poll function unlinks the gizmo. --- source/blender/editors/mesh/editmesh_bevel.c | 10 ---------- source/blender/editors/mesh/editmesh_bisect.c | 11 ++--------- source/blender/editors/mesh/editmesh_inset.c | 10 ---------- source/blender/editors/space_image/space_image.c | 8 ++++---- source/blender/editors/transform/transform.h | 3 --- source/blender/editors/transform/transform_generics.c | 13 ------------- source/blender/editors/transform/transform_gizmo_3d.c | 12 ++++++------ 7 files changed, 12 insertions(+), 55 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index cdbbdd820b7..0d74187b50e 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -97,7 +97,6 @@ typedef struct { int launch_event; float mcenter[2]; void *draw_handle_pixel; - short gizmo_flag; short value_mode; /* Which value does mouse movement and numeric input affect? */ float segments; /* Segments as float so smooth mouse pan works in small increments */ @@ -307,11 +306,6 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) opdata->draw_handle_pixel = ED_region_draw_cb_activate( region->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL); G.moving = G_TRANSFORM_EDIT; - - if (v3d) { - opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; - } } return true; @@ -433,15 +427,11 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op) } if (opdata->is_modal) { - View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup); } ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel); - if (v3d) { - v3d->gizmo_flag = opdata->gizmo_flag; - } G.moving = 0; } MEM_SAFE_FREE(opdata->ob_store); diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index f525f2c2e91..5cb57594ec3 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -72,7 +72,6 @@ typedef struct { bool is_dirty; } * backup; int backup_len; - short gizmo_flag; } BisectData; static void mesh_bisect_interactive_calc(bContext *C, @@ -157,8 +156,6 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) } if (ret & OPERATOR_RUNNING_MODAL) { - View3D *v3d = CTX_wm_view3d(C); - wmGesture *gesture = op->customdata; BisectData *opdata; @@ -181,8 +178,6 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* Misc other vars. */ G.moving = G_TRANSFORM_EDIT; - opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; /* Initialize modal callout. */ ED_workspace_status_text(C, TIP_("LMB: Click and drag to draw cut line")); @@ -191,10 +186,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) return ret; } -static void edbm_bisect_exit(bContext *C, BisectData *opdata) +static void edbm_bisect_exit(BisectData *opdata) { - View3D *v3d = CTX_wm_view3d(C); - v3d->gizmo_flag = opdata->gizmo_flag; G.moving = 0; for (int ob_index = 0; ob_index < opdata->backup_len; ob_index++) { @@ -225,7 +218,7 @@ static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event) } if (ret & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) { - edbm_bisect_exit(C, &opdata_back); + edbm_bisect_exit(&opdata_back); #ifdef USE_GIZMO /* Setup gizmos */ diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index 159e84db4ef..7be169f70f4 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -76,7 +76,6 @@ typedef struct { int launch_event; float mcenter[2]; void *draw_handle_pixel; - short gizmo_flag; } InsetData; static void edbm_inset_update_header(wmOperator *op, bContext *C) @@ -177,7 +176,6 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal) opdata->num_input.unit_type[1] = B_UNIT_LENGTH; if (is_modal) { - View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { @@ -189,10 +187,6 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal) opdata->draw_handle_pixel = ED_region_draw_cb_activate( region->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL); G.moving = G_TRANSFORM_EDIT; - if (v3d) { - opdata->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; - } } return true; @@ -206,15 +200,11 @@ static void edbm_inset_exit(bContext *C, wmOperator *op) opdata = op->customdata; if (opdata->is_modal) { - View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { EDBM_redo_state_free(&opdata->ob_store[ob_index].mesh_backup); } ED_region_draw_cb_exit(region->type, opdata->draw_handle_pixel); - if (v3d) { - v3d->gizmo_flag = opdata->gizmo_flag; - } G.moving = 0; } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 4107fd619aa..de8e4684d45 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -461,7 +461,7 @@ static void IMAGE_GGT_gizmo2d(wmGizmoGroupType *gzgt) gzgt->name = "UV Transform Gizmo"; gzgt->idname = "IMAGE_GGT_gizmo2d"; - gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | + gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK); gzgt->gzmap_params.spaceid = SPACE_IMAGE; @@ -475,7 +475,7 @@ static void IMAGE_GGT_gizmo2d_translate(wmGizmoGroupType *gzgt) gzgt->name = "UV Translate Gizmo"; gzgt->idname = "IMAGE_GGT_gizmo2d_translate"; - gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | + gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK); gzgt->gzmap_params.spaceid = SPACE_IMAGE; @@ -489,7 +489,7 @@ static void IMAGE_GGT_gizmo2d_resize(wmGizmoGroupType *gzgt) gzgt->name = "UV Transform Gizmo Resize"; gzgt->idname = "IMAGE_GGT_gizmo2d_resize"; - gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | + gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK); gzgt->gzmap_params.spaceid = SPACE_IMAGE; @@ -503,7 +503,7 @@ static void IMAGE_GGT_gizmo2d_rotate(wmGizmoGroupType *gzgt) gzgt->name = "UV Transform Gizmo Resize"; gzgt->idname = "IMAGE_GGT_gizmo2d_rotate"; - gzgt->flag |= (WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | + gzgt->flag |= (WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK); gzgt->gzmap_params.spaceid = SPACE_IMAGE; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 013c5faa54a..d1a1937cef1 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -618,9 +618,6 @@ typedef struct TransInfo { O_SET, } orient_curr; - /** backup from view3d, to restore on end. */ - short gizmo_flag; - short prop_mode; /** Value taken as input, either through mouse coordinates or entered as a parameter. */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index b7f579cc12f..c493b9bd102 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -249,12 +249,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->view = v3d; t->animtimer = (animscreen) ? animscreen->animtimer : NULL; - /* turn gizmo off during transform */ - if (t->flag & T_MODAL) { - t->gizmo_flag = v3d->gizmo_flag; - v3d->gizmo_flag |= V3D_GIZMO_HIDE_DEFAULT_MODAL; - } - if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) { t->flag |= T_V3D_ALIGN; } @@ -742,13 +736,6 @@ void postTrans(bContext *C, TransInfo *t) } } } - else if (t->spacetype == SPACE_VIEW3D) { - View3D *v3d = t->area->spacedata.first; - /* restore gizmo */ - if (t->flag & T_MODAL) { - v3d->gizmo_flag = t->gizmo_flag; - } - } if (t->mouse.data) { MEM_freeN(t->mouse.data); diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 8dc4f107837..0fa179c4f74 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1974,8 +1974,8 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt) gzgt->name = "3D View: Transform Gizmo"; gzgt->idname = "VIEW3D_GGT_xform_gizmo"; - gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | - WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; + gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | + WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; @@ -2216,8 +2216,8 @@ void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt) gzgt->name = "Transform Cage"; gzgt->idname = "VIEW3D_GGT_xform_cage"; - gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | - WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | + WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; @@ -2459,8 +2459,8 @@ void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt) gzgt->name = "Transform Shear"; gzgt->idname = "VIEW3D_GGT_xform_shear"; - gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | - WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE | + WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; -- cgit v1.2.3 From 28bd74c18650a8362bc791df602097967ff5efdf Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 15 Sep 2021 14:44:56 -0500 Subject: Cleanup: Use function to mark mesh normals dirty --- source/blender/editors/sculpt_paint/paint_mask.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index d968b6cc319..4a8dcd7a934 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1300,7 +1300,7 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) }), sculpt_mesh); BM_mesh_free(bm); - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + BKE_mesh_normals_tag_dirty(result); BKE_mesh_nomain_to_mesh( result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true); } -- cgit v1.2.3 From 0530b679092e44bda2bf67b5096573718d108364 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 16 Sep 2021 16:36:53 +1000 Subject: Fix bisect gizmo offset while dragging --- source/blender/editors/mesh/editmesh_bisect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 5cb57594ec3..27a1bf9658f 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -777,7 +777,7 @@ static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt) gzgt->name = "Mesh Bisect"; gzgt->idname = "MESH_GGT_bisect"; - gzgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE; gzgt->gzmap_params.spaceid = SPACE_VIEW3D; gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; -- cgit v1.2.3 From 4f38624bf5df66ed1cf03a7167c9f959bab21ef9 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 16 Sep 2021 11:11:45 +0200 Subject: IDType: Add `BKE_idtype_idcode_is_localizable`. This is the same as `BKE_idtype_idcode_is_linkable` currently, used only in one place in UI code of IDtemplate. --- source/blender/editors/interface/interface_templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 08d78552710..b9e4f2ef44a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1031,7 +1031,7 @@ static void template_ID(const bContext *C, UI_but_flag_enable(but, UI_BUT_DISABLED); } else { - const bool disabled = (!BKE_lib_id_make_local(CTX_data_main(C), id, true /* test */, 0) || + const bool disabled = (!BKE_idtype_idcode_is_localizable(GS(id->name)) || (idfrom && idfrom->lib)); but = uiDefIconBut(block, UI_BTYPE_BUT, -- cgit v1.2.3 From 236a9f081462d249043e2bd00a015a6c5cafe377 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 16 Sep 2021 11:45:06 +0200 Subject: IDManagement: refactor: Remove 'test' part from `BKE_lib_id_make_local`. Mixing testing and actual action in a single function is just not a good way to do things, and the 'testing' feature is not used anywhere anymore, time to get rid of it. --- source/blender/editors/interface/interface_templates.c | 2 +- source/blender/editors/space_outliner/outliner_tools.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b9e4f2ef44a..9787b101572 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -673,7 +673,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) } } else { - if (BKE_lib_id_make_local(bmain, id, false, 0)) { + if (BKE_lib_id_make_local(bmain, id, 0)) { BKE_main_id_newptr_and_tag_clear(bmain); /* Reassign to get proper updates/notifiers. */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 7709c6bb053..062d98c93af 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -739,7 +739,7 @@ static void id_local_fn(bContext *C, Main *bmain = CTX_data_main(C); /* if the ID type has no special local function, * just clear the lib */ - if (BKE_lib_id_make_local(bmain, tselem->id, false, 0) == false) { + if (!BKE_lib_id_make_local(bmain, tselem->id, 0)) { BKE_lib_id_clear_library_data(bmain, tselem->id); } else { -- cgit v1.2.3 From e04a10adabea33cf4b3f92e721f86fdbd50c8ac5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 16 Sep 2021 12:40:41 +0200 Subject: Cleanup: no need to clear new flags and pointers from whole Main when making a single ID local. --- source/blender/editors/interface/interface_templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 9787b101572..0c9eb20af19 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -674,7 +674,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) } else { if (BKE_lib_id_make_local(bmain, id, 0)) { - BKE_main_id_newptr_and_tag_clear(bmain); + BKE_id_newptr_and_tag_clear(id); /* Reassign to get proper updates/notifiers. */ idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); -- cgit v1.2.3 From 3deb56424f2927ffe8a7ca8ef3de3fa5bc56e304 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 16 Sep 2021 12:41:21 +0200 Subject: Cleanup/Fix outliner 'make local' code. While likely harmless, this code was doing extremely bad thing, by-passing the whole lower-level `BKE_lib_id_make_local` call in case it would fail and deciding by itself to forcefully make the given ID local. Bad. Very, very, very bad. --- source/blender/editors/space_outliner/outliner_tools.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 062d98c93af..9e314701719 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -737,13 +737,8 @@ static void id_local_fn(bContext *C, { if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) { Main *bmain = CTX_data_main(C); - /* if the ID type has no special local function, - * just clear the lib */ - if (!BKE_lib_id_make_local(bmain, tselem->id, 0)) { - BKE_lib_id_clear_library_data(bmain, tselem->id); - } - else { - BKE_main_id_newptr_and_tag_clear(bmain); + if (BKE_lib_id_make_local(bmain, tselem->id, 0)) { + BKE_id_newptr_and_tag_clear(tselem->id); } } else if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) { -- cgit v1.2.3 From c938d9a0e554b49354e7f6bb8168b88c279cb2c0 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 15 Sep 2021 13:06:23 +0200 Subject: Cleanup: Rename USER_APP_LOCK_UI_LAYOUT There will be other settings that lock other aspects of the UI layout (e.g., resizing of editors). So better to name this setting what it actually handles (the corners). New name: USER_APP_LOCK_CORNER_SPLIT Differential Revision: D12516 --- source/blender/editors/screen/area.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index e08a4e946f6..e907c7e153f 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -882,7 +882,7 @@ static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area) return; } - if (U.app_flag & USER_APP_LOCK_UI_LAYOUT) { + if (U.app_flag & USER_APP_LOCK_CORNER_SPLIT) { return; } -- cgit v1.2.3 From f2cfad77f9f8876edfdc9930206fc12db71f25b0 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 16 Sep 2021 15:27:36 +0200 Subject: App Settings: Regions Visbility Toggle The toggle that allow users to "show" the region (header, toolbar, ...) when it is collapsed can now be configured for the apps. Note: This option is not visibile in the UI. Differential Revision: D12516 --- source/blender/editors/screen/area.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index e907c7e153f..384445db9fb 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1058,6 +1058,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre return false; } + if (is_hidden && (U.app_flag & USER_APP_HIDE_REGION_TOGGLE)) { + return false; + } + return true; } -- cgit v1.2.3 From 867e6ffe88f830cbfa158de95dea7cbb155e3fdb Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 15 Sep 2021 13:12:40 +0200 Subject: App Settings: Edge Resize This prevents both editor resize as well as regions (e.g., the toolbar). Note: This option is not visible in the UI. Differential Revision: D12516 --- source/blender/editors/screen/area.c | 4 ++++ source/blender/editors/screen/screen_geometry.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 384445db9fb..9546035375c 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1062,6 +1062,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre return false; } + if (!is_hidden && (U.app_flag & USER_APP_LOCK_EDGE_RESIZE)) { + return false; + } + return true; } diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c index 51edad0332b..e67c933cb8e 100644 --- a/source/blender/editors/screen/screen_geometry.c +++ b/source/blender/editors/screen/screen_geometry.c @@ -130,6 +130,10 @@ ScrEdge *screen_geom_find_active_scredge(const wmWindow *win, const int mx, const int my) { + if (U.app_flag & USER_APP_LOCK_EDGE_RESIZE) { + return NULL; + } + /* Use layout size (screen excluding global areas) for screen-layout area edges */ rcti screen_rect; WM_window_screen_rect_calc(win, &screen_rect); -- cgit v1.2.3 From c9daab7936562b1e02262cd28f1d6cc4dde91d71 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 16 Sep 2021 16:39:51 +0200 Subject: Assets: Recursive reading of asset libraries With this, asset libraries can be directory structures and all assets in sub-directories will show up in an Asset Browser. With complex directory structures and many .blend files inside, asset library reading will be quite slow for now. There's initial work being done to introduce indexing for this (T82979), other optimizations are being discussed as well. Addresses T91406. Differential Revision: https://developer.blender.org/D12139 --- source/blender/editors/space_file/filesel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 4ab7014cf82..11b06d2b414 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -135,7 +135,8 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) base_params->filter_id = FILTER_ID_OB | FILTER_ID_GR; base_params->display = FILE_IMGDISPLAY; base_params->sort = FILE_SORT_ALPHA; - base_params->recursion_level = 1; + /* Asset libraries include all sub-directories, so enable maximal recursion. */ + base_params->recursion_level = FILE_SELECT_MAX_RECURSIONS; /* 'SMALL' size by default. More reasonable since this is typically used as regular editor, * space is more of an issue here. */ base_params->thumbnail_size = 96; -- cgit v1.2.3 From 8e21d528cab98447fd072718a649906551de78d9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 16 Sep 2021 20:49:10 -0500 Subject: Geometry Nodes: Add a toggle to use attributes as input values This adds a toggle to node group inputs exposed in the modifier to use an attribute instead of a single value. When the toggle is pressed, the button switches to a text button to choose an attribute name. Attribute search isn't implemented here yet. One confusing thing is that some values can't be driven by attributes at all, like the size of a primitive node. In that case, we should have a node warning, but that will be separate since it's more general. We can also have an option to turn off this toggle in node group input settings. The two new properties for each input are stored with the same name as the value, but with `"_use_attribute"` and `"_attribute_name"`` suffixes. The properties are not added for socket types that don't support attribute input, like object sockets. Differential Revision: https://developer.blender.org/D12504 --- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_modifier.c | 51 +++++++++++++++++++++++++ source/blender/editors/object/object_ops.c | 1 + 3 files changed, 53 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b2d3216b101..50dd9322c5c 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -191,6 +191,7 @@ void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot); void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot); void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot); void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot); +void OBJECT_OT_geometry_nodes_input_attribute_toggle(struct wmOperatorType *ot); /* object_gpencil_modifiers.c */ void OBJECT_OT_gpencil_modifier_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 2a1a6696493..b9942bc563a 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -3242,3 +3242,54 @@ void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot) } /** \} */ + +/* ------------------------------------------------------------------- */ +/** \name Toggle Value or Attribute Operator + * + * \note This operator basically only exists to provide a better tooltip for the toggle button, + * since it is stored as an IDProperty. It also stops the button from being highlighted when + * "use_attribute" is on, which isn't expected. + * \{ */ + +static int geometry_nodes_input_attribute_toggle_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + + char modifier_name[MAX_NAME]; + RNA_string_get(op->ptr, "modifier_name", modifier_name); + NodesModifierData *nmd = (NodesModifierData *)BKE_modifiers_findby_name(ob, modifier_name); + if (nmd == NULL) { + return OPERATOR_CANCELLED; + } + + char prop_path[MAX_NAME]; + RNA_string_get(op->ptr, "prop_path", prop_path); + + PointerRNA mod_ptr; + RNA_pointer_create(&ob->id, &RNA_Modifier, nmd, &mod_ptr); + + const int old_value = RNA_int_get(&mod_ptr, prop_path); + const int new_value = !old_value; + RNA_int_set(&mod_ptr, prop_path, new_value); + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot) +{ + ot->name = "Input Attribute Toggle"; + ot->description = + "Switch between an attribute and a single value to define the data for every element"; + ot->idname = "OBJECT_OT_geometry_nodes_input_attribute_toggle"; + + ot->exec = geometry_nodes_input_attribute_toggle_exec; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + RNA_def_string(ot->srna, "prop_path", NULL, 0, "Prop Path", ""); + RNA_def_string(ot->srna, "modifier_name", NULL, MAX_NAME, "Modifier Name", ""); +} + +/** \} */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 4b8431be530..aa9ae082317 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -145,6 +145,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_skin_loose_mark_clear); WM_operatortype_append(OBJECT_OT_skin_radii_equalize); WM_operatortype_append(OBJECT_OT_skin_armature_create); + WM_operatortype_append(OBJECT_OT_geometry_nodes_input_attribute_toggle); /* grease pencil modifiers */ WM_operatortype_append(OBJECT_OT_gpencil_modifier_add); -- cgit v1.2.3 From da2ba402689d7ed752b0b37ad49dce1a5851cc77 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Sep 2021 12:09:24 +1000 Subject: UI: wait for input for operators that depend on cursor location Support waiting for input so operators that depend on the cursor location are usable from menus / buttons. Use an operator type flag which the user interface code checks for, waiting for input when run from a menu item. This patch only supports this feature, there are no functional changes. The motivation for this change is discoverability since some actions were either hidden or broken when accessed from menus (where the behavior of the operator depended on the menu location). In general, waiting for input is *not* an efficient way to access tools, however there are over 50 operators with a "wait_for_input" property so this isn't introducing a new kind of interaction, rather exposing this in a way that does not need to be hard-coded into each operator, or having modal callbacks added for the sole purpose of waiting for input. Besides requiring boiler plate code using a "wait_for_input" property has the added down-side of preventing key shortcuts from showing. Only the menu items will enable the property, causing them not to match key-map items. Reviewed By: Severin Ref D12255 --- source/blender/editors/interface/interface_handlers.c | 19 ++++++++++++++----- .../interface/interface_template_search_menu.c | 3 ++- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 977e9661dd9..77ae16d7cc7 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -508,6 +508,7 @@ typedef struct uiAfterFunc { bContextStore *context; char undostr[BKE_UNDO_STR_MAX]; + char drawstr[UI_MAX_DRAW_STR]; } uiAfterFunc; static void button_activate_init(bContext *C, @@ -790,6 +791,10 @@ static void ui_handle_afterfunc_add_operator_ex(wmOperatorType *ot, if (context_but && context_but->context) { after->context = CTX_store_copy(context_but->context); } + + if (context_but) { + ui_but_drawstr_without_sep_char(context_but, after->drawstr, sizeof(after->drawstr)); + } } void ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext) @@ -900,6 +905,8 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->context = CTX_store_copy(but->context); } + ui_but_drawstr_without_sep_char(but, after->drawstr, sizeof(after->drawstr)); + but->optype = NULL; but->opcontext = 0; but->opptr = NULL; @@ -1021,7 +1028,8 @@ static void ui_apply_but_funcs_after(bContext *C) } if (after.optype) { - WM_operator_name_call_ptr(C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL); + WM_operator_name_call_ptr_with_depends_on_cursor( + C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL, after.drawstr); } if (after.opptr) { @@ -4190,10 +4198,11 @@ static void ui_but_extra_operator_icon_apply(bContext *C, uiBut *but, uiButExtra ui_apply_but(C, but->block, but, but->active, true); } button_activate_state(C, but, BUTTON_STATE_EXIT); - WM_operator_name_call_ptr(C, - op_icon->optype_params->optype, - op_icon->optype_params->opcontext, - op_icon->optype_params->opptr); + WM_operator_name_call_ptr_with_depends_on_cursor(C, + op_icon->optype_params->optype, + op_icon->optype_params->opcontext, + op_icon->optype_params->opptr, + NULL); /* Force recreation of extra operator icons (pseudo update). */ ui_but_extra_operator_icons_free(but); diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 3105891142f..672f1b64943 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -955,7 +955,8 @@ static void menu_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2) switch (item->type) { case MENU_SEARCH_TYPE_OP: { CTX_store_set(C, item->op.context); - WM_operator_name_call_ptr(C, item->op.type, item->op.opcontext, item->op.opptr); + WM_operator_name_call_ptr_with_depends_on_cursor( + C, item->op.type, item->op.opcontext, item->op.opptr, item->drawstr); CTX_store_set(C, NULL); break; } -- cgit v1.2.3 From 180bafe22537e89422591c92e7d2495a3ae30ea6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Sep 2021 12:09:25 +1000 Subject: UI: split screenshot area into a separate operator While the screenshot operator showed an "Area" option, it wasn't usable from the main menu (unless accessed via menu search). Split screenshot area into an operator that depends on cursor. --- source/blender/editors/screen/screen_intern.h | 1 + source/blender/editors/screen/screen_ops.c | 1 + source/blender/editors/screen/screendump.c | 60 +++++++++++++++++++-------- 3 files changed, 44 insertions(+), 18 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 683f2844371..4016ef84bfd 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -128,6 +128,7 @@ extern const char *screen_context_dir[]; /* doc access */ /* screendump.c */ void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screenshot_area(struct wmOperatorType *ot); /* workspace_layout_edit.c */ bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 3efe4ae85d5..674a2deb929 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5690,6 +5690,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_back_to_previous); WM_operatortype_append(SCREEN_OT_spacedata_cleanup); WM_operatortype_append(SCREEN_OT_screenshot); + WM_operatortype_append(SCREEN_OT_screenshot_area); WM_operatortype_append(SCREEN_OT_userpref_show); WM_operatortype_append(SCREEN_OT_drivers_editor_show); WM_operatortype_append(SCREEN_OT_info_log_show); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 6df96b1e30f..8056e02d17a 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -42,6 +42,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_report.h" +#include "BKE_screen.h" #include "RNA_access.h" #include "RNA_define.h" @@ -57,12 +58,13 @@ typedef struct ScreenshotData { uint *dumprect; int dumpsx, dumpsy; rcti crop; + bool use_crop; ImageFormatData im_format; } ScreenshotData; /* call from both exec and invoke */ -static int screenshot_data_create(bContext *C, wmOperator *op) +static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area) { int dumprect_size[2]; @@ -76,7 +78,6 @@ static int screenshot_data_create(bContext *C, wmOperator *op) if (dumprect) { ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot"); - ScrArea *area = CTX_wm_area(C); scd->dumpsx = dumprect_size[0]; scd->dumpsy = dumprect_size[1]; @@ -110,12 +111,13 @@ static void screenshot_data_free(wmOperator *op) static int screenshot_exec(bContext *C, wmOperator *op) { + const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area"); ScreenshotData *scd = op->customdata; bool ok = false; if (scd == NULL) { /* when running exec directly */ - screenshot_data_create(C, op); + screenshot_data_create(C, op, use_crop ? CTX_wm_area(C) : NULL); scd = op->customdata; } @@ -132,7 +134,7 @@ static int screenshot_exec(bContext *C, wmOperator *op) ibuf->rect = scd->dumprect; /* crop to show only single editor */ - if (!RNA_boolean_get(op->ptr, "full")) { + if (use_crop) { IMB_rect_crop(ibuf, &scd->crop); scd->dumprect = ibuf->rect; } @@ -157,9 +159,20 @@ static int screenshot_exec(bContext *C, wmOperator *op) return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } -static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (screenshot_data_create(C, op)) { + const bool use_crop = STREQ(op->idname, "SCREEN_OT_screenshot_area"); + ScrArea *area = NULL; + if (use_crop) { + area = CTX_wm_area(C); + bScreen *screen = CTX_wm_screen(C); + ScrArea *area_test = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y); + if (area_test != NULL) { + area = area_test; + } + } + + if (screenshot_data_create(C, op, area)) { if (RNA_struct_property_is_set(op->ptr, "filepath")) { return screenshot_exec(C, op); } @@ -226,12 +239,8 @@ static bool screenshot_poll(bContext *C) return WM_operator_winactive(C); } -void SCREEN_OT_screenshot(wmOperatorType *ot) +static void screen_screenshot_impl(wmOperatorType *ot) { - ot->name = "Save Screenshot"; - ot->idname = "SCREEN_OT_screenshot"; - ot->description = "Capture a picture of the active area or whole Blender window"; - ot->invoke = screenshot_invoke; ot->check = screenshot_check; ot->exec = screenshot_exec; @@ -239,8 +248,6 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) ot->ui = screenshot_draw; ot->poll = screenshot_poll; - ot->flag = 0; - WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, @@ -248,9 +255,26 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - RNA_def_boolean(ot->srna, - "full", - 1, - "Full Screen", - "Capture the whole window (otherwise only capture the active area)"); +} + +void SCREEN_OT_screenshot(wmOperatorType *ot) +{ + ot->name = "Save Screenshot"; + ot->idname = "SCREEN_OT_screenshot"; + ot->description = "Capture a picture of the whole Blender window"; + + screen_screenshot_impl(ot); + + ot->flag = 0; +} + +void SCREEN_OT_screenshot_area(wmOperatorType *ot) +{ + ot->name = "Save Screenshot (Area)"; + ot->idname = "SCREEN_OT_screenshot_area"; + ot->description = "Capture a picture of the active area"; + + screen_screenshot_impl(ot); + + ot->flag = OPTYPE_DEPENDS_ON_CURSOR; } -- cgit v1.2.3 From f8b51f702cf7865054bc557afcf468ccd0c8533e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Sep 2021 12:09:26 +1000 Subject: UI: enable the depend-on-cursor flag for some operators - Bend (Transform). - Extrude to Cursor. - Lasso Select (related operators such as node-cut links, mask.. etc). - Rip Mesh / UV's. - Vertex/Edge Slide. --- source/blender/editors/armature/armature_add.c | 2 +- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/gpencil/gpencil_edit.c | 2 +- source/blender/editors/gpencil/gpencil_select.c | 2 +- source/blender/editors/mask/mask_select.c | 2 +- source/blender/editors/mesh/editmesh_extrude.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/mesh/editmesh_rip_edge.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/sculpt_paint/paint_mask.c | 6 ++++-- source/blender/editors/space_action/action_select.c | 2 +- source/blender/editors/space_clip/tracking_select.c | 2 +- source/blender/editors/space_graph/graph_select.c | 2 +- source/blender/editors/space_node/node_add.cc | 2 +- source/blender/editors/space_node/node_relationships.cc | 4 ++-- source/blender/editors/space_node/node_select.cc | 2 +- source/blender/editors/space_view3d/view3d_select.c | 2 +- source/blender/editors/transform/transform_ops.c | 7 ++++--- source/blender/editors/uvedit/uvedit_rip.c | 2 +- source/blender/editors/uvedit/uvedit_select.c | 2 +- 20 files changed, 27 insertions(+), 24 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 45bf18fe1bb..ebe9b2ab60b 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -269,7 +269,7 @@ void ARMATURE_OT_click_extrude(wmOperatorType *ot) ot->poll = ED_operator_editarmature; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* props */ } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index c399abfa52d..b5a5d5cfcca 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5630,7 +5630,7 @@ void CURVE_OT_vertex_add(wmOperatorType *ot) ot->poll = ED_operator_editcurve; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ RNA_def_float_vector_xyz(ot->srna, diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index aa3178ddc2c..75ddfa47c57 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -5243,7 +5243,7 @@ void GPENCIL_OT_stroke_cutter(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flag */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 93bae7d3614..6ad2fffc773 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -2347,7 +2347,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_select_operation(ot); diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 6a1be8dcef3..fe6acac7d29 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -629,7 +629,7 @@ void MASK_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 907881a44f3..63f910e034f 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -935,7 +935,7 @@ void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) ot->poll = ED_operator_editmesh_region_view3d; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; RNA_def_boolean(ot->srna, "rotate_source", diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 0553fa077f8..d1df063d9d0 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1124,7 +1124,7 @@ void MESH_OT_rip(wmOperatorType *ot) ot->poll = EDBM_view3d_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY); diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c index f7e88284d93..ce49f0f80a3 100644 --- a/source/blender/editors/mesh/editmesh_rip_edge.c +++ b/source/blender/editors/mesh/editmesh_rip_edge.c @@ -249,7 +249,7 @@ void MESH_OT_rip_edge(wmOperatorType *ot) ot->poll = EDBM_view3d_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 956658bd2b7..122214b87d5 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4323,7 +4323,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot) ot->poll = EDBM_view3d_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ PropertyRNA *prop; diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 4a8dcd7a934..e65d6ce2d48 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1651,7 +1651,7 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) ot->poll = SCULPT_mode_poll_view3d; - ot->flag = OPTYPE_REGISTER; + ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR; /* Properties. */ WM_operator_properties_gesture_lasso(ot); @@ -1714,6 +1714,8 @@ void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot) ot->poll = SCULPT_mode_poll_view3d; + ot->flag = OPTYPE_DEPENDS_ON_CURSOR; + /* Properties. */ WM_operator_properties_gesture_lasso(ot); sculpt_gesture_operator_properties(ot); @@ -1750,7 +1752,7 @@ void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot) ot->poll = SCULPT_mode_poll_view3d; - ot->flag = OPTYPE_REGISTER; + ot->flag = OPTYPE_REGISTER | OPTYPE_DEPENDS_ON_CURSOR; /* Properties. */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index a5e75e31e38..26d71178b68 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -834,7 +834,7 @@ void ACTION_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index c7f0f4c228f..73a73eb7911 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -721,7 +721,7 @@ void CLIP_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index a853efb1ace..ffe74e20bdf 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1006,7 +1006,7 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* Flags. */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* Properties. */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 4d2e00e97a1..7b6ca5e6e61 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -312,7 +312,7 @@ void NODE_OT_add_reroute(wmOperatorType *ot) ot->poll = ED_operator_node_editable; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ PropertyRNA *prop; diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index e908a61eed9..7d95659e403 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -1427,7 +1427,7 @@ void NODE_OT_links_cut(wmOperatorType *ot) ot->poll = ED_operator_node_editable; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ PropertyRNA *prop; @@ -1533,7 +1533,7 @@ void NODE_OT_links_mute(wmOperatorType *ot) ot->poll = ED_operator_node_editable; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ PropertyRNA *prop; diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index adff85a2b8c..29b8372d043 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -923,7 +923,7 @@ void NODE_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ RNA_def_boolean(ot->srna, diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index ff98762e373..3f572bf9d5a 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1438,7 +1438,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 9638ec8750e..3a4a9342e18 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -911,7 +911,8 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) ot->name = "Bend"; ot->description = "Bend selected items between the 3D cursor and the mouse"; ot->idname = OP_BEND; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + /* Depend on cursor location because the cursor location is used to define the region to bend. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR; /* api callbacks */ ot->invoke = transform_invoke; @@ -1091,7 +1092,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) ot->name = "Edge Slide"; ot->description = "Slide an edge loop along a mesh"; ot->idname = OP_EDGE_SLIDE; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR; /* api callbacks */ ot->invoke = transform_invoke; @@ -1129,7 +1130,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) ot->name = "Vertex Slide"; ot->description = "Slide a vertex along a mesh"; ot->idname = OP_VERT_SLIDE; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_DEPENDS_ON_CURSOR; /* api callbacks */ ot->invoke = transform_invoke; diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index 631b831411f..7e4b18340c5 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -953,7 +953,7 @@ void UV_OT_rip(wmOperatorType *ot) ot->name = "UV Rip"; ot->description = "Rip selected vertices or a selected region"; ot->idname = "UV_OT_rip"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* api callbacks */ ot->exec = uv_rip_exec; diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 5a82cd31112..c0ccf1b7095 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -3450,7 +3450,7 @@ void UV_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; /* properties */ WM_operator_properties_gesture_lasso(ot); -- cgit v1.2.3 From 8bc27c508ae311111a6b436d4c90f8b131d98bc4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Sep 2021 12:09:30 +1000 Subject: UI: expose "Lasso Select" & "Extrude to Cursor" in menus - Show "Lasso Select" in menus (along with Box & Circle select) - Show "Extrude to Cursor" (along with other extrude actions). - Rename operators that add/extrude on Ctrl-Click since their names were inconsistent. This is mainly for discoverability. --- source/blender/editors/armature/armature_add.c | 2 +- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/mesh/editmesh_extrude.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index ebe9b2ab60b..21a5c6c2865 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -259,7 +259,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv void ARMATURE_OT_click_extrude(wmOperatorType *ot) { /* identifiers */ - ot->name = "Click-Extrude"; + ot->name = "Extrude to Cursor"; ot->idname = "ARMATURE_OT_click_extrude"; ot->description = "Create a new bone going from the last selected joint to the mouse position"; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index b5a5d5cfcca..9b43e23bd32 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5620,7 +5620,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) void CURVE_OT_vertex_add(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Vertex"; + ot->name = "Extrude to Cursor or Add"; ot->idname = "CURVE_OT_vertex_add"; ot->description = "Add a new control point (linked to only selected end-curve one, if any)"; diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 63f910e034f..e4cd48d95bb 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -925,7 +925,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) { /* identifiers */ - ot->name = "Duplicate or Extrude to Cursor"; + ot->name = "Extrude to Cursor or Add"; ot->idname = "MESH_OT_dupli_extrude_cursor"; ot->description = "Duplicate and extrude selected vertices, edges or faces towards the mouse cursor"; -- cgit v1.2.3 From 06ac655b8dda53aa2122844d487ed68510211395 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 16 Sep 2021 23:20:57 +1000 Subject: WM: expose the "any" state of KeyMapItem modifiers Change KeyMapItem.alt/ctrl/shift/oskey to integer types, where -1 is used to ignore the modifier when matching key-map items. It was only possible to set all modifiers to -1 at once from RNA using the 'any' property. Afterwards individual modifiers could be set back to true/false. Although these key-map items could not be exported/imported. Exposing the values directly avoids the need for cumbersome workarounds. --- source/blender/editors/interface/interface_layout.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index ec5a30f7793..66c75c63050 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -921,10 +921,10 @@ static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_ { uiBut *but = but_v; - RNA_boolean_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) != 0); - RNA_boolean_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) != 0); - RNA_boolean_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) != 0); - RNA_boolean_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) != 0); + RNA_int_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) ? KM_MOD_HELD : KM_NOTHING); + RNA_int_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) ? KM_MOD_HELD : KM_NOTHING); + RNA_int_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) ? KM_MOD_HELD : KM_NOTHING); + RNA_int_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) ? KM_MOD_HELD : KM_NOTHING); } /** -- cgit v1.2.3