diff options
Diffstat (limited to 'source/blender/editors')
39 files changed, 554 insertions, 233 deletions
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index a9ba8c405ba..3ae578279ca 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -287,7 +287,8 @@ void POSE_OT_paths_calculate(wmOperatorType *ot) RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", "Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0); - RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0, + RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, + MOTIONPATH_BAKE_HEADS, "Bake Location", "Which point on the bones is used when calculating paths"); } diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index ccdbcba71f9..79bfc5149ba 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1382,8 +1382,9 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool gp_convert_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { + PointerRNA *ptr = op->ptr; const char *prop_id = RNA_property_identifier(prop); const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes"); int timing_mode = RNA_enum_get(ptr, "timing_mode"); @@ -1446,18 +1447,6 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) return false; } -static void gp_convert_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); -} - void GPENCIL_OT_convert(wmOperatorType *ot) { PropertyRNA *prop; @@ -1471,7 +1460,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot) ot->invoke = WM_menu_invoke; ot->exec = gp_convert_layer_exec; ot->poll = gp_convert_poll; - ot->ui = gp_convert_ui; + ot->poll_property = gp_convert_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 38545137740..9fd5cc99073 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -112,6 +112,7 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, const bool do_connected); +void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode); void ED_object_base_activate(struct bContext *C, struct Base *base); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 087e0c4ab7b..b4756eaed0f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -772,7 +772,7 @@ typedef enum { uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2); eAutoPropButsReturn uiDefAutoButsRNA( uiLayout *layout, struct PointerRNA *ptr, - bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), + bool (*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data, eButLabelAlign label_align, const bool compact); /* use inside searchfunc to add items */ @@ -935,6 +935,7 @@ enum { UI_TEMPLATE_OP_PROPS_SHOW_TITLE = (1 << 0), UI_TEMPLATE_OP_PROPS_SHOW_EMPTY = (1 << 1), UI_TEMPLATE_OP_PROPS_COMPACT = (1 << 2), + UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED = (1 << 3), }; /* used for transp checkers */ @@ -1085,7 +1086,6 @@ void UI_but_func_operator_search(uiBut *but); void uiTemplateOperatorSearch(uiLayout *layout); eAutoPropButsReturn uiTemplateOperatorPropertyButs( const struct bContext *C, uiLayout *layout, struct wmOperator *op, - bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const eButLabelAlign label_align, const short flag); void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 651081c46bb..a34c4938b86 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -59,7 +59,7 @@ typedef struct IconFile { /* * Resizable Icons for Blender */ -void UI_icons_init(int first_dyn_id); +void UI_icons_init(void); int UI_icon_get_width(int icon_id); int UI_icon_get_height(int icon_id); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 22b82898288..7255640bedc 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -934,9 +934,8 @@ int UI_icon_get_height(int icon_id) return 0; } -void UI_icons_init(int first_dyn_id) +void UI_icons_init() { - BKE_icons_init(first_dyn_id); #ifndef WITH_HEADLESS init_iconfile_list(&iconfilelist); init_internal_icons(); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 59fdf7e672d..aa67d58fd57 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -454,9 +454,9 @@ static void ui_offset_panel_block(uiBlock *block) /* triangle 'icon' for panel header */ void UI_draw_icon_tri(float x, float y, char dir, const float color[4]) { - float f3 = 0.15 * U.widget_unit; - float f5 = 0.25 * U.widget_unit; - float f7 = 0.35 * U.widget_unit; + float f3 = 0.05 * U.widget_unit; + float f5 = 0.15 * U.widget_unit; + float f7 = 0.25 * U.widget_unit; if (dir == 'h') { UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 2dcc18af4ea..131ffbca377 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1542,11 +1542,6 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) /************************ Redo Buttons Template *************************/ -static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop) -{ - return (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED) == 0; -} - static void template_operator_redo_property_buts_draw( const bContext *C, wmOperator *op, uiLayout *layout, int layout_flags, @@ -1560,8 +1555,9 @@ static void template_operator_redo_property_buts_draw( else { /* Might want to make label_align adjustable somehow. */ eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs( - C, layout, op, r_has_advanced ? template_operator_redo_property_buts_poll : NULL, - UI_BUT_LABEL_ALIGN_NONE, layout_flags); + C, layout, op, + UI_BUT_LABEL_ALIGN_NONE, + layout_flags); if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) { if (r_has_advanced) { *r_has_advanced = true; @@ -3948,13 +3944,30 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, } #endif +struct uiTemplateOperatorPropertyPollParam { + const bContext *C; + wmOperator *op; + short flag; +}; + +static bool ui_layout_operator_buts_poll_property( + struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data) +{ + struct uiTemplateOperatorPropertyPollParam *params = user_data; + if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) && + (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED)) + { + return false; + } + return params->op->type->poll_property(params->C, params->op, prop); +} + /** * Draw Operator property buttons for redoing execution with different settings. * This function does not initialize the layout, functions can be called on the layout before and after. */ eAutoPropButsReturn uiTemplateOperatorPropertyButs( const bContext *C, uiLayout *layout, wmOperator *op, - bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const eButLabelAlign label_align, const short flag) { uiBlock *block = uiLayoutGetBlock(layout); @@ -4013,13 +4026,32 @@ eAutoPropButsReturn uiTemplateOperatorPropertyButs( else { wmWindowManager *wm = CTX_wm_manager(C); PointerRNA ptr; + struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = flag}; + + + +#if 0 +static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +{ +} +#endif + + + + + + RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); uiLayoutSetPropSep(layout, true); /* main draw call */ - return_info = uiDefAutoButsRNA(layout, &ptr, check_prop, label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT)); + return_info = uiDefAutoButsRNA( + layout, &ptr, + op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL, + op->type->poll_property ? &user_data : NULL, + label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT)); if ((return_info & UI_PROP_BUTS_NONE_ADDED) && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) { uiItemL(layout, IFACE_("No Properties"), ICON_NONE); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index d080397c488..60aa79e1093 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -159,7 +159,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind */ eAutoPropButsReturn uiDefAutoButsRNA( uiLayout *layout, PointerRNA *ptr, - bool (*check_prop)(PointerRNA *, PropertyRNA *), + bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data, const eButLabelAlign label_align, const bool compact) { eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED; @@ -174,7 +174,7 @@ eAutoPropButsReturn uiDefAutoButsRNA( if (flag & PROP_HIDDEN) { continue; } - if (check_prop && check_prop(ptr, prop) == 0) { + if (check_prop && check_prop(ptr, prop, user_data) == 0) { return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK; continue; } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 47d664eaeb2..3cb8a277e9a 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -83,7 +83,7 @@ static struct bThemeState g_theme_state = { void ui_resources_init(void) { - UI_icons_init(BIFICONID_LAST); + UI_icons_init(); } void ui_resources_free(void) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 99756269c1f..61f55451b17 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1048,14 +1048,15 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void GPU_matrix_push(); GPU_matrix_mul(kcd->ob->obmat); + if (kcd->mode == MODE_DRAGGING && kcd->is_angle_snapping) { + knifetool_draw_angle_snapping(kcd); + } + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); if (kcd->mode == MODE_DRAGGING) { - if (kcd->is_angle_snapping) - knifetool_draw_angle_snapping(kcd); - immUniformColor3ubv(kcd->colors.line); GPU_line_width(2.0); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 2e7cf1fc76f..cdb8981801a 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1462,6 +1462,18 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op) static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + /* Bypass when in UV non sync-select mode, fall through to keymap that edits. */ + if (CTX_wm_space_image(C)) { + ToolSettings *ts = CTX_data_tool_settings(C); + if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) { + return OPERATOR_PASS_THROUGH; + } + /* Bypass when no action is needed. */ + if (!RNA_struct_property_is_set(op->ptr, "type")) { + return OPERATOR_CANCELLED; + } + } + /* detecting these options based on shift/ctrl here is weak, but it's done * to make this work when clicking buttons or menus */ if (!RNA_struct_property_is_set(op->ptr, "use_extend")) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d7617a14ff3..b2a2291f4f6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -6001,10 +6001,10 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { const char *prop_id = RNA_property_identifier(prop); - const int action = RNA_enum_get(ptr, "type"); + const int action = RNA_enum_get(op->ptr, "type"); /* Only show seed for randomize action! */ if (STREQ(prop_id, "seed")) { @@ -6025,18 +6025,6 @@ static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *pro return true; } -static void edbm_sort_elements_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); -} - void MESH_OT_sort_elements(wmOperatorType *ot) { static const EnumPropertyItem type_items[] = { @@ -6072,7 +6060,7 @@ void MESH_OT_sort_elements(wmOperatorType *ot) ot->invoke = WM_menu_invoke; ot->exec = edbm_sort_elements_exec; ot->poll = ED_operator_editmesh; - ot->ui = edbm_sort_elements_ui; + ot->poll_property = edbm_sort_elements_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 0fcc5ada854..79c8f5c0b09 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -335,22 +335,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "vertex_only", true); - /* selecting */ - for (int i = 0; i < 4; i++) { - const bool is_extend = (i & 1); - const bool is_expand = (i & 2); - const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0); - for (int j = 0; j < 3; j++) { - kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0); - RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j); - if (is_extend) { - RNA_boolean_set(kmi->ptr, "use_extend", true); - } - if (is_expand) { - RNA_boolean_set(kmi->ptr, "use_expand", true); - } - } - } + /* Selec Vert/Edge/Face. */ + ED_keymap_editmesh_elem_mode(keyconf, keymap); /* standard mouse selection goes via space_view3d */ kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index b456342f8f0..1d93d664a5a 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -49,6 +49,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" @@ -360,17 +361,24 @@ static bool is_noncolor_pass(eScenePassType pass_type) } /* if all is good tag image and return true */ -static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports) +static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports) { Image *image; + Base *base = BKE_view_layer_base_find(view_layer, ob); void *lock; int i; - if ((ob->lay & scene->lay) == 0) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not on a scene layer", ob->id.name + 2); + if (base == NULL) { + BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2); return false; } + if (!(base->flag & BASE_ENABLED_RENDER)) { + BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2); + return false; + } + + if (ob->type != OB_MESH) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2); return false; @@ -500,7 +508,7 @@ static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filt } /* before even getting in the bake function we check for some basic errors */ -static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *selected_objects, +static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects, ReportList *reports, const bool is_selected_to_active) { CollectionPointerLink *link; @@ -511,7 +519,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase * if (is_selected_to_active) { int tot_objects = 0; - if (!bake_object_check(scene, ob, reports)) + if (!bake_object_check(view_layer, ob, reports)) return false; for (link = selected_objects->first; link; link = link->next) { @@ -539,7 +547,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase * } for (link = selected_objects->first; link; link = link->next) { - if (!bake_object_check(scene, link->ptr.data, reports)) + if (!bake_object_check(view_layer, link->ptr.data, reports)) return false; } } @@ -1207,7 +1215,7 @@ static int bake_exec(bContext *C, wmOperator *op) goto finally; } - if (!bake_objects_check(bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { + if (!bake_objects_check(bkr.main, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { goto finally; } @@ -1266,7 +1274,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa return; } - if (!bake_objects_check(bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { + if (!bake_objects_check(bkr->main, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { bkr->result = OPERATOR_CANCELLED; return; } diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index f56fd560946..ad0b091ede9 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -450,8 +450,9 @@ static bool data_transfer_poll(bContext *C) } /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */ -static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool data_transfer_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { + PointerRNA *ptr = op->ptr; PropertyRNA *prop_other; const char *prop_id = RNA_property_identifier(prop); @@ -512,19 +513,6 @@ static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) return true; } -/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */ -static void data_transfer_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); -} - /* transfers weight from active to selected */ void OBJECT_OT_data_transfer(wmOperatorType *ot) { @@ -537,10 +525,10 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot) /* API callbacks.*/ ot->poll = data_transfer_poll; + ot->poll_property = data_transfer_poll_property; ot->invoke = WM_menu_invoke; ot->exec = data_transfer_exec; ot->check = data_transfer_check; - ot->ui = data_transfer_ui; /* Flags.*/ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -700,10 +688,10 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot) ot->idname = "OBJECT_OT_datalayout_transfer"; ot->poll = datalayout_transfer_poll; + ot->poll_property = data_transfer_poll_property; ot->invoke = datalayout_transfer_invoke; ot->exec = datalayout_transfer_exec; ot->check = data_transfer_check; - ot->ui = data_transfer_ui; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 53cabe3759e..72c5fde2955 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -411,6 +411,9 @@ static int collection_add_exec(bContext *C, wmOperator *UNUSED(op)) id_fake_user_set(&collection->id); BKE_collection_object_add(bmain, collection, ob); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -460,6 +463,9 @@ static int collection_link_exec(bContext *C, wmOperator *op) BKE_collection_object_add(bmain, collection, ob); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -500,6 +506,9 @@ static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op)) BKE_collection_object_remove(bmain, collection, ob, false); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -531,6 +540,8 @@ static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op)) BKE_libblock_delete(bmain, collection); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 5a83d085aee..7b6c1156874 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -40,6 +40,7 @@ #include "BKE_context.h" #include "RNA_access.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -490,3 +491,26 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct RNA_string_set(kmi->ptr, "value_2", "CONNECTED"); } } + +/** + * Map 1..3 to Vert/Edge/Face. + */ +void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) +{ + for (int i = 0; i < 4; i++) { + const bool is_extend = (i & 1); + const bool is_expand = (i & 2); + const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0); + for (int j = 0; j < 3; j++) { + wmKeyMapItem *kmi = WM_keymap_add_item( + keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0); + RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j); + if (is_extend) { + RNA_boolean_set(kmi->ptr, "use_extend", true); + } + if (is_expand) { + RNA_boolean_set(kmi->ptr, "use_expand", true); + } + } + } +} diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 2c3ff8b6afe..4745a484475 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -947,13 +947,13 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent return OPERATOR_INTERFACE; } -static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool parent_set_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { const char *prop_id = RNA_property_identifier(prop); - const int type = RNA_enum_get(ptr, "type"); /* Only show XMirror for PAR_ARMATURE_ENVELOPE and PAR_ARMATURE_AUTO! */ if (STREQ(prop_id, "xmirror")) { + const int type = RNA_enum_get(op->ptr, "type"); if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO)) return true; else @@ -963,18 +963,6 @@ static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) return true; } -static void parent_set_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); -} - void OBJECT_OT_parent_set(wmOperatorType *ot) { /* identifiers */ @@ -986,7 +974,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot) ot->invoke = parent_set_invoke; ot->exec = parent_set_exec; ot->poll = ED_operator_object_active; - ot->ui = parent_set_ui; + ot->poll_property = parent_set_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2329,6 +2317,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op) if (new_ob != NULL && new_ob->id.override_static != NULL) { if ((base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) { BKE_collection_object_add_from(bmain, scene, obcollection, new_ob); + base = BKE_view_layer_base_find(view_layer, new_ob); DEG_id_tag_update_ex(bmain, &new_ob->id, DEG_TAG_TRANSFORM | DEG_TAG_BASE_FLAGS_UPDATE); } /* parent to 'collection' empty */ diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index afaad3963d5..9c0c59a7160 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -247,7 +247,7 @@ static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op) screenshot_data_free(op); } -static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -266,7 +266,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); + uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false); } static bool screenshot_poll(bContext *C) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 3fc68a50057..15f688549a8 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -482,7 +482,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *even #ifdef WITH_AUDASPACE -static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); return !(STREQ(prop_id, "filepath") || @@ -635,7 +635,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* main draw call */ - uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); + uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false); } #endif // WITH_AUDASPACE diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 812a671ff33..abe9f173b09 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -43,6 +43,7 @@ #include "MEM_guardedalloc.h" #include "RNA_access.h" +#include "RNA_define.h" #include "ED_fileselect.h" @@ -71,25 +72,28 @@ static void file_panel_operator_header(const bContext *C, Panel *pa) BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname)); } -static bool file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) -{ - const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath") || - STREQ(prop_id, "directory") || - STREQ(prop_id, "filename") - ); -} - static void file_panel_operator(const bContext *C, Panel *pa) { SpaceFile *sfile = CTX_wm_space_file(C); wmOperator *op = sfile->op; - // int empty = 1, flag; UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); - uiTemplateOperatorPropertyButs(C, pa->layout, op, file_panel_check_prop, UI_BUT_LABEL_ALIGN_NONE, - UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); + /* Hack: temporary hide.*/ + const char *hide[3] = {"filepath", "directory", "filename"}; + for (int i = 0; i < ARRAY_SIZE(hide); i++) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); + RNA_def_property_flag(prop, PROP_HIDDEN); + } + + uiTemplateOperatorPropertyButs( + C, pa->layout, op, UI_BUT_LABEL_ALIGN_NONE, + UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); + + for (int i = 0; i < ARRAY_SIZE(hide); i++) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); + RNA_def_property_clear_flag(prop, PROP_HIDDEN); + } UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index f1012c46f2f..bcbfa1342d5 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1487,7 +1487,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( return OPERATOR_RUNNING_MODAL; } -static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -1506,7 +1506,7 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); + uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false); /* image template */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr); @@ -2243,7 +2243,7 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op) image_save_as_free(op); } -static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -2268,7 +2268,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); + uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false); /* multiview template */ if (is_multiview) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 4b3a3abc642..bba46771674 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -951,18 +951,18 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* open/close entirely? */ { uiBut *but; - int but_size = UI_UNIT_X * 0.6f; + int but_size = UI_UNIT_X * 1.2f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ UI_block_emboss_set(node->block, UI_EMBOSS_NONE); but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", - rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, + rct->xmin + 0.6f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.2f - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); UI_block_emboss_set(node->block, UI_EMBOSS); UI_GetThemeColor4fv(TH_TEXT, color); /* custom draw function for this button */ - UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color); + UI_draw_icon_tri(rct->xmin + 0.6f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color); } nodeLabel(ntree, node, showname, sizeof(showname)); @@ -1071,7 +1071,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* open entirely icon */ { uiBut *but; - int but_size = UI_UNIT_X * 0.6f; + int but_size = UI_UNIT_X * 1.2f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ UI_block_emboss_set(node->block, UI_EMBOSS_NONE); but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index ed7379acca9..3644c8d09e6 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -238,7 +238,7 @@ extern const char *node_context_dir[]; // nodes draw without dpi - the view zoom is flexible #define HIDDEN_RAD (0.75f * U.widget_unit) -#define BASIS_RAD (0.4f * U.widget_unit) +#define BASIS_RAD (0.2f * U.widget_unit) #define NODE_DYS (U.widget_unit / 2) #define NODE_DY U.widget_unit #define NODE_SOCKDY (0.08f * U.widget_unit) diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index ad94615a0d2..e480cac2dcc 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -574,7 +574,7 @@ static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, v return TRAVERSE_CONTINUE; } -static bool collections_view_layer_poll(bContext *C, bool include) +static bool collections_view_layer_poll(bContext *C, bool clear, int flag) { /* Poll function so the right click menu show current state of selected collections. */ SpaceOops *soops = CTX_wm_space_outliner(C); @@ -593,10 +593,10 @@ static bool collections_view_layer_poll(bContext *C, bool include) GSET_ITER(collections_to_edit_iter, data.collections_to_edit) { LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); - if (include && (lc->flag & LAYER_COLLECTION_EXCLUDE)) { + if (clear && (lc->flag & flag)) { result = true; } - else if (!include && !(lc->flag & LAYER_COLLECTION_EXCLUDE)) { + else if (!clear && !(lc->flag & flag)) { result = true; } } @@ -605,27 +605,47 @@ static bool collections_view_layer_poll(bContext *C, bool include) return result; } -static bool collections_exclude_poll(bContext *C) +static bool collections_exclude_set_poll(bContext *C) { - return collections_view_layer_poll(C, false); + return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE); } -static bool collections_include_poll(bContext *C) +static bool collections_exclude_clear_poll(bContext *C) { - return collections_view_layer_poll(C, true); + return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE); } -static void layer_collection_exclude_recursive_set(LayerCollection *lc) +static bool collections_holdout_set_poll(bContext *C) +{ + return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT); +} + +static bool collections_holdout_clear_poll(bContext *C) +{ + return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT); +} + +static bool collections_indirect_only_set_poll(bContext *C) +{ + return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY); +} + +static bool collections_indirect_only_clear_poll(bContext *C) +{ + return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY); +} + +static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag) { for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { - if (lc->flag & LAYER_COLLECTION_EXCLUDE) { - nlc->flag |= LAYER_COLLECTION_EXCLUDE; + if (lc->flag & flag) { + nlc->flag |= flag; } else { - nlc->flag &= ~LAYER_COLLECTION_EXCLUDE; + nlc->flag &= ~flag; } - layer_collection_exclude_recursive_set(nlc); + layer_collection_flag_recursive_set(nlc, flag); } } @@ -636,7 +656,10 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); SpaceOops *soops = CTX_wm_space_outliner(C); struct CollectionEditData data = {.scene = scene, .soops = soops}; - bool include = STREQ(op->idname, "OUTLINER_OT_collection_include_set"); + bool clear = strstr(op->idname, "clear") != NULL; + int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT : + strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY : + LAYER_COLLECTION_EXCLUDE; data.collections_to_edit = BLI_gset_ptr_new(__func__); @@ -647,14 +670,14 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); if (!(lc->collection->flag & COLLECTION_IS_MASTER)) { - if (include) { - lc->flag &= ~LAYER_COLLECTION_EXCLUDE; + if (clear) { + lc->flag &= ~flag; } else { - lc->flag |= LAYER_COLLECTION_EXCLUDE; + lc->flag |= flag; } - layer_collection_exclude_recursive_set(lc); + layer_collection_flag_recursive_set(lc, flag); } } @@ -671,28 +694,88 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot) { /* identifiers */ - ot->name = "Exclude from View Layer"; + ot->name = "Set Exclude"; ot->idname = "OUTLINER_OT_collection_exclude_set"; ot->description = "Exclude collection from the active view layer"; /* api callbacks */ ot->exec = collection_view_layer_exec; - ot->poll = collections_exclude_poll; + ot->poll = collections_exclude_set_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -void OUTLINER_OT_collection_include_set(wmOperatorType *ot) +void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot) { /* identifiers */ - ot->name = "Include in View Layer"; - ot->idname = "OUTLINER_OT_collection_include_set"; + ot->name = "Clear Exclude"; + ot->idname = "OUTLINER_OT_collection_exclude_clear"; ot->description = "Include collection in the active view layer"; /* api callbacks */ ot->exec = collection_view_layer_exec; - ot->poll = collections_include_poll; + ot->poll = collections_exclude_clear_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Holdout"; + ot->idname = "OUTLINER_OT_collection_holdout_set"; + ot->description = "Mask collection in the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_holdout_set_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Holdout"; + ot->idname = "OUTLINER_OT_collection_holdout_clear"; + ot->description = "Clear masking of collection in the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_holdout_clear_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Indirect Only"; + ot->idname = "OUTLINER_OT_collection_indirect_only_set"; + ot->description = "Set collection to only contribute indirectly (through shadows and reflections) in the view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_indirect_only_set_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Indirect Only"; + ot->idname = "OUTLINER_OT_collection_indirect_only_clear"; + ot->description = "Clear collection contributing only indirectly in the view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_indirect_only_clear_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 783a03f3993..e1049d02e37 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1341,16 +1341,9 @@ static void tselem_draw_icon( static void outliner_draw_iconrow_number( const uiFontStyle *fstyle, int offsx, int ys, - const eOLDrawState active, const int num_elements) { - float color[4] = {0.4f, 0.4f, 0.4f, 0.9f}; - copy_v3_fl(color, 0.2f); - if (active != OL_DRAWSEL_NONE) { - copy_v3_fl(color, 0.65f); - color[3] = 1.0f; - } - + float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float ufac = 0.25f * UI_UNIT_X; float offset_x = (float) offsx + UI_UNIT_X * 0.35f; @@ -1414,13 +1407,13 @@ static void outliner_draw_iconrow_doit( } /* No inlined icon should be clickable. */ - tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac, false); + tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false); te->xs = *offsx; te->ys = ys; te->xend = (short)*offsx + UI_UNIT_X; if (num_elements > 1) { - outliner_draw_iconrow_number(fstyle, *offsx, ys, active, num_elements); + outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements); } (*offsx) += UI_UNIT_X; } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 093ad9361c2..461d4bd7c56 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -358,7 +358,11 @@ void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot); void OUTLINER_OT_collection_link(struct wmOperatorType *ot); void OUTLINER_OT_collection_instance(struct wmOperatorType *ot); void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot); -void OUTLINER_OT_collection_include_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_exclude_clear(struct wmOperatorType *ot); +void OUTLINER_OT_collection_holdout_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_holdout_clear(struct wmOperatorType *ot); +void OUTLINER_OT_collection_indirect_only_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_indirect_only_clear(struct wmOperatorType *ot); /* outliner_utils.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 0dd492839c9..576038979d3 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -457,7 +457,11 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_link); WM_operatortype_append(OUTLINER_OT_collection_instance); WM_operatortype_append(OUTLINER_OT_collection_exclude_set); - WM_operatortype_append(OUTLINER_OT_collection_include_set); + WM_operatortype_append(OUTLINER_OT_collection_exclude_clear); + WM_operatortype_append(OUTLINER_OT_collection_holdout_set); + WM_operatortype_append(OUTLINER_OT_collection_holdout_clear); + WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set); + WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) @@ -570,6 +574,9 @@ void outliner_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_clear", EKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "select", false); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 5d2ceced904..3cd5bfc3e58 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -627,7 +627,7 @@ static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op) op->customdata = NULL; } -static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -693,7 +693,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); + uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false); /* image template */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index cefc6cdd814..199ff06cc8b 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -739,7 +739,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM); } if (seqn) { @@ -848,7 +848,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM); } if (seqn) { @@ -2091,6 +2091,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op) SEQP_BEGIN (ed, seq) { + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); if (seq->seq1 || seq->seq2 || seq->seq3) { BKE_sequence_calc(scene, seq); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 71bdd2e20c2..2577077002e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1406,7 +1406,7 @@ static void space_view3d_listener( switch (wmn->data) { case ND_WORLD_DRAW: case ND_WORLD: - if (v3d->flag3 & V3D_SHOW_WORLD) + if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD) ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 552d84ebb39..941f9262694 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1599,7 +1599,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( v3d.flag2 |= V3D_SOLID_TEX; } - v3d.flag3 |= V3D_SHOW_WORLD; + v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD; if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) { if (camera->type == OB_CAMERA) { diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7799854db49..6a8589f5468 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -72,6 +72,7 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r /* *********************** operators ******************** */ +/** Snaps every individual object center to its nearest point on the grid. **/ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -212,7 +213,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Grid"; - ot->description = "Snap selected item(s) to nearest grid division"; + ot->description = "Snap selected item(s) to their nearest grid division"; ot->idname = "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ @@ -225,6 +226,12 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* *************************************************** */ +/** Snaps the selection as a whole (use_offset=true) or each selected object to the given location. + * + * \param snap_target_global: a location in global space to snap to (eg. 3D cursor or active object). + * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection + * pivot point (median, active), or if every object origin should be snapped to the given location. +**/ static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -434,7 +441,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Cursor"; - ot->description = "Snap selected item(s) to cursor"; + ot->description = "Snap selected item(s) to the 3D cursor"; ot->idname = "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ @@ -445,9 +452,13 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* rna */ - RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", ""); + RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", + "If the selection should be snapped as a whole or by each object center"); } +/* *************************************************** */ + +/** Snaps each selected object to the location of the active selected object. **/ static int snap_selected_to_active_exec(bContext *C, wmOperator *op) { float snap_target_global[3]; @@ -478,6 +489,7 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot) /* *************************************************** */ +/** Snaps the 3D cursor location to its nearest point on the grid. **/ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -502,7 +514,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Grid"; - ot->description = "Snap cursor to nearest grid division"; + ot->description = "Snap 3D cursor to the nearest grid division"; ot->idname = "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ @@ -515,7 +527,8 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* **************************************************** */ -static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float vec[3]) +/** Returns the center position of a tracking marker visible on the viewport (useful to snap to). **/ +static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_vec[3]) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); MovieTracking *tracking; @@ -563,10 +576,11 @@ static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, floa } if (ok) { - mid_v3_v3v3(vec, min, max); + mid_v3_v3v3(r_vec, min, max); } } +/** Snaps the 3D cursor location to the median point of the selection. **/ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -690,7 +704,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Selected"; - ot->description = "Snap cursor to center of selected item(s)"; + ot->description = "Snap 3D cursor to the middle of the selected item(s)"; ot->idname = "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ @@ -703,9 +717,11 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* ********************************************** */ -/* this could be exported to be a generic function - * see: calculateCenterActive */ - +/** Calculates the center position of the active object in global space. + * + * Note: this could be exported to be a generic function. + * see: calculateCenterActive +**/ static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]) { const Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -770,7 +786,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Active"; - ot->description = "Snap cursor to active item"; + ot->description = "Snap 3D cursor to the active item"; ot->idname = "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ @@ -782,7 +798,8 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) } /* **************************************************** */ -/*New Code - Snap Cursor to Center -*/ + +/** Snaps the 3D cursor location to the origin. **/ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -802,7 +819,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Center"; - ot->description = "Snap cursor to world origin"; + ot->description = "Snap 3D cursor to the world origin"; ot->idname = "VIEW3D_OT_snap_cursor_to_center"; /* api callbacks */ @@ -815,23 +832,22 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) /* **************************************************** */ - -bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) +/** Calculates the bounding box corners (min and max) for \a obedit. The returned values are in global space. **/ +bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3]) { TransVertStore tvs = {NULL}; TransVert *tv; float centroid[3], vec[3], bmat[3][3]; - int a; - /* metaballs are an exception */ + /* Metaballs are an exception. */ if (obedit->type == OB_MBALL) { float ob_min[3], ob_max[3]; bool changed; changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT); if (changed) { - minmax_v3v3_v3(min, max, ob_min); - minmax_v3v3_v3(min, max, ob_max); + minmax_v3v3_v3(r_min, r_max, ob_min); + minmax_v3v3_v3(r_min, r_max, ob_max); } return changed; } @@ -845,12 +861,12 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) copy_m3_m4(bmat, obedit->obmat); tv = tvs.transverts; - for (a = 0; a < tvs.transverts_tot; a++, tv++) { + for (int a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); add_v3_v3(centroid, vec); - minmax_v3v3_v3(min, max, vec); + minmax_v3v3_v3(r_min, r_max, vec); } ED_transverts_free(&tvs); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index dab53c04806..07ef6b9a819 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2153,7 +2153,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } } - RNA_property_boolean_set_array(op->ptr, prop, constraint_axis); + /* Only set if needed, so we can hide in the UI when nothing is set. + * See 'transform_poll_property'. */ + if (ELEM(true, UNPACK3(constraint_axis))) { + RNA_property_boolean_set_array(op->ptr, prop, constraint_axis); + } } { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index c9a97c8530c..580bae71cc8 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -507,6 +507,36 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event) } } +static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + + /* Orientation/Constraints. */ + { + /* Hide orientation axis if no constraints are set, since it wont be used. */ + PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "constraint_axis"); + if (prop_con && !RNA_property_is_set(op->ptr, prop_con)) { + if (STRPREFIX(prop_id, "constraint")) { + return false; + } + } + } + + /* Proportional Editing. */ + { + PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional"); + if (prop_pet && (prop_pet != prop) && + (RNA_property_enum_get(op->ptr, prop_pet) == PROP_EDIT_OFF)) + { + if (STRPREFIX(prop_id, "proportional")) { + return false; + } + } + } + + return true; +} + void Transform_Properties(struct wmOperatorType *ot, int flags) { PropertyRNA *prop; @@ -615,6 +645,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -640,6 +671,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -673,6 +705,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = skin_resize_poll; + ot->poll_property = transform_poll_property; RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -695,6 +728,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; /* Maybe we could use float_vector_xyz here too? */ RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX); @@ -718,6 +752,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -744,6 +779,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -766,6 +802,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_region_view3d_active; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -788,6 +825,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); @@ -811,6 +849,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX); @@ -833,6 +872,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); @@ -858,6 +898,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); @@ -880,6 +921,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT | P_CENTER); } @@ -900,6 +942,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh_region_view3d; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); @@ -932,6 +975,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh_region_view3d; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); RNA_def_boolean(ot->srna, "use_even", false, "Even", @@ -961,6 +1005,7 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f); @@ -1050,6 +1095,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; prop = RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", ""); RNA_def_property_flag(prop, PROP_HIDDEN); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index b67fd22dbff..54253e36351 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1462,7 +1462,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2]) float xmouse, ymouse; int frame; int mframe; - TransSeq *ts = t->custom.type.data; + TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; /* reuse increment, strictly speaking could be another snap mode, but leave as is */ if (!(t->modifiers & MOD_SNAP_INVERT)) return; diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index e19320fa220..a6e857c4a60 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -111,6 +111,10 @@ typedef struct SnapObjectData_EditMesh { SnapObjectData sd; BVHTreeFromEditMesh *bvh_trees[3]; + /* It's like a boundbox. It is tested first to avoid + * to create a bvhtree for all the edited objects. */ + float min[3], max[3]; + } SnapObjectData_EditMesh; struct SnapObjectContext { @@ -156,6 +160,39 @@ struct SnapObjectContext { typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data); +static void min_max_from_bmesh( + BMesh *bm, float r_min[3], float r_max[3]) +{ + BMIter iter; + BMVert *eve; + + INIT_MINMAX(r_min, r_max); + BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) { + minmax_v3v3_v3(r_min, r_max, eve->co); + } +} + +static SnapObjectData_Mesh *snap_object_data_mesh_create(SnapObjectContext *sctx) +{ + SnapObjectData_Mesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod->sd.type = SNAP_MESH; + /* start assuming that it has each of these element types */ + sod->has_looptris = true; + sod->has_loose_edge = true; + sod->has_loose_vert = true; + + return sod; +} + +static SnapObjectData_EditMesh *snap_object_data_editmesh_create(SnapObjectContext *sctx, BMesh *bm) +{ + SnapObjectData_EditMesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod->sd.type = SNAP_EDIT_MESH; + min_max_from_bmesh(bm, sod->min, sod->max); + + return sod; +} + /** * Walks through all objects in the scene to create the list of objets to snap. * @@ -169,9 +206,9 @@ static void iter_snap_objects( IterSnapObjsCallback sob_callback, void *data) { - ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph); - Object *obedit = params->use_object_edit_cage ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL; + ViewLayer *view_layer = DEG_get_input_view_layer(sctx->depsgraph); const eSnapSelect snap_select = params->snap_select; + const bool use_object_edit_cage = params->use_object_edit_cage; Base *base_act = view_layer->basact; for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) { @@ -179,20 +216,17 @@ static void iter_snap_objects( !((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) || (snap_select == SNAP_NOT_ACTIVE && base == base_act))) { - bool use_obedit; - Object *obj = base->object; - if (obj->transflag & OB_DUPLI) { + Object *obj_eval = DEG_get_evaluated_object(sctx->depsgraph, base->object); + if (obj_eval->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj); + ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj_eval); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { - use_obedit = obedit && dupli_ob->ob->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data); + sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data); } free_object_duplilist(lb); } - use_obedit = obedit && obj->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data); + sob_callback(sctx, use_object_edit_cage, obj_eval, obj_eval->obmat, data); } } } @@ -372,13 +406,12 @@ static bool raycastMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_MESH; + sod = *sod_p = snap_object_data_mesh_create(sctx); } BVHTreeFromMesh *treedata = &sod->treedata; - /* The tree is owned by the DM and may have been freed since we last used. */ + /* The tree is owned by the Mesh and may have been freed since we last used. */ if (treedata->tree) { BLI_assert(treedata->cached); if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) { @@ -502,14 +535,30 @@ static bool raycastEditMesh( SnapObjectData_EditMesh *sod = NULL; BVHTreeFromEditMesh *treedata = NULL; + Object *em_ob = em->ob; + + BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob)); void **sod_p; - if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { + /* Use `em->ob` as the key in ghash since the editmesh is used + * to create bvhtree and is the same for each linked object. */ + if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) { sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_EDIT_MESH; + sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm); + } + + { + float min[3], max[3]; + mul_v3_m4v3(min, obmat, sod->min); + mul_v3_m4v3(max, obmat, sod->max); + + if (!isect_ray_aabb_v3_simple( + ray_start, ray_dir, min, max, NULL, NULL)) + { + return retval; + } } if (sod->bvh_trees[2] == NULL) { @@ -517,7 +566,17 @@ static bool raycastEditMesh( } treedata = sod->bvh_trees[2]; + BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache; + + if (sctx->callbacks.edit_mesh.test_face_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata->tree)) { + free_bvhtree_from_editmesh(treedata); + } + } + if (treedata->tree == NULL) { + BVHCache **bvh_cache = NULL; BLI_bitmap *elem_mask = NULL; int looptri_num_active = -1; @@ -527,7 +586,15 @@ static bool raycastEditMesh( em->bm, elem_mask, sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data); } - bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL); + else { + /* Only cache if bvhtree is created without a mask. + * This helps keep a standardized bvhtree in cache. */ + bvh_cache = &em_bvh_cache; + } + + bvhtree_from_editmesh_looptri_ex( + treedata, em, elem_mask, looptri_num_active, + 0.0f, 4, 6, bvh_cache); if (elem_mask) { MEM_freeN(elem_mask); @@ -669,7 +736,7 @@ static bool raycastObj( switch (ob->type) { case OB_MESH: - if (use_obedit) { + if (use_obedit && BKE_object_is_in_editmode(ob)) { BMEditMesh *em = BKE_editmesh_from_object(ob); retval = raycastEditMesh( sctx, @@ -718,7 +785,7 @@ struct RaycastObjUserData { bool ret; }; -static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) +static void raycast_obj_cb(SnapObjectContext *sctx, bool use_obedit, Object *ob, float obmat[4][4], void *data) { struct RaycastObjUserData *dt = data; @@ -726,7 +793,7 @@ static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, sctx, dt->ray_start, dt->ray_dir, ob, obmat, dt->ob_index++, - is_obedit, dt->use_occlusion_test, + use_obedit, dt->use_occlusion_test, dt->ray_depth, dt->r_loc, dt->r_no, dt->r_index, dt->r_ob, dt->r_obmat, @@ -1118,6 +1185,13 @@ static short snap_mesh_polygon( }; SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); + if (sod == NULL) { + /* The object is in edit mode, and the key used + * was the object referenced in BMEditMesh */ + BMEditMesh *em = BKE_editmesh_from_object(ob); + sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob); + } + BLI_assert(sod != NULL); if (sod->type == SNAP_MESH) { @@ -1335,6 +1409,8 @@ static short snapArmature( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); + use_obedit = use_obedit && BKE_object_is_in_editmode(ob); + if (use_obedit == false) { /* Test BoundBox */ BoundBox *bb = BKE_armature_boundbox_get(ob); @@ -1469,6 +1545,8 @@ static short snapCurve( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); + use_obedit = use_obedit && BKE_object_is_in_editmode(ob); + if (use_obedit == false) { /* Test BoundBox */ BoundBox *bb = BKE_curve_boundbox_get(ob); @@ -1779,12 +1857,7 @@ static short snapMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_MESH; - /* start assuming that it has each of these element types */ - sod->has_looptris = true; - sod->has_loose_edge = true; - sod->has_loose_vert = true; + sod = *sod_p = snap_object_data_mesh_create(sctx); } BVHTreeFromMesh *treedata, dummy_treedata; @@ -1792,7 +1865,7 @@ static short snapMesh( treedata = &sod->treedata; bvhtree = sod->bvhtree; - /* the tree is owned by the DM and may have been freed since we last used! */ + /* The tree is owned by the Mesh and may have been freed since we last used! */ if ((sod->has_looptris && treedata->tree && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) || (sod->has_loose_edge && bvhtree[0] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0])) || (sod->has_loose_vert && bvhtree[1] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1]))) @@ -1982,21 +2055,57 @@ static short snapEditMesh( SnapObjectData_EditMesh *sod = NULL; BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL; + Object *em_ob = em->ob; + + BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob)); + UNUSED_VARS_NDEBUG(ob); void **sod_p; - if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { + /* Use `em->ob` as the key in ghash since the editmesh is used + * to create bvhtree and is the same for each linked object. */ + if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) { sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_EDIT_MESH; + sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm); + } + + float dist_px_sq = SQUARE(*dist_px); + + { + float min[3], max[3]; + mul_v3_m4v3(min, obmat, sod->min); + mul_v3_m4v3(max, obmat, sod->max); + + /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ + struct DistProjectedAABBPrecalc data_precalc; + dist_squared_to_projected_aabb_precalc( + &data_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval); + + bool dummy[3]; + float bb_dist_px_sq = dist_squared_to_projected_aabb( + &data_precalc, min, max, dummy); + + if (bb_dist_px_sq > dist_px_sq) { + return 0; + } } + BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache; + if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (sod->bvh_trees[0] == NULL) { sod->bvh_trees[0] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees)); } treedata_vert = sod->bvh_trees[0]; + + if (sctx->callbacks.edit_mesh.test_vert_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata_vert->tree)) { + free_bvhtree_from_editmesh(treedata_vert); + } + } + if (treedata_vert->tree == NULL) { BLI_bitmap *verts_mask = NULL; int verts_num_active = -1; @@ -2006,9 +2115,13 @@ static short snapEditMesh( BM_VERTS_OF_MESH, em->bm, verts_mask, (bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn, sctx->callbacks.edit_mesh.user_data); + + bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6); + MEM_freeN(verts_mask); + } + else { + bvhtree_from_editmesh_verts(treedata_vert, em, 0.0f, 2, 6, &em_bvh_cache); } - bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6); - MEM_SAFE_FREE(verts_mask); } } @@ -2017,6 +2130,14 @@ static short snapEditMesh( sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees)); } treedata_edge = sod->bvh_trees[1]; + + if (sctx->callbacks.edit_mesh.test_edge_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata_edge->tree)) { + free_bvhtree_from_editmesh(treedata_edge); + } + } + if (treedata_edge->tree == NULL) { BLI_bitmap *edges_mask = NULL; int edges_num_active = -1; @@ -2027,9 +2148,12 @@ static short snapEditMesh( (bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn, sctx->callbacks.edit_mesh.user_data); + bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6); + MEM_freeN(edges_mask); + } + else { + bvhtree_from_editmesh_edges(treedata_edge, em, 0.0f, 2, 6, &em_bvh_cache); } - bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6); - MEM_SAFE_FREE(edges_mask); } } @@ -2043,7 +2167,7 @@ static short snapEditMesh( BVHTreeNearest nearest = { .index = -1, - .dist_sq = SQUARE(*dist_px), + .dist_sq = dist_px_sq, }; int last_index = nearest.index; short elem = SCE_SNAP_MODE_VERTEX; @@ -2119,7 +2243,7 @@ static short snapObject( switch (ob->type) { case OB_MESH: - if (use_obedit) { + if (use_obedit && BKE_object_is_in_editmode(ob)) { BMEditMesh *em = BKE_editmesh_from_object(ob); retval = snapEditMesh( sctx, snapdata, ob, em, obmat, diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 51e2c1b6334..32bf32b03ab 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -80,6 +80,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -4404,6 +4405,15 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf) RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt"); #endif + /* Select Element (Sync Select: on) */ + ED_keymap_editmesh_elem_mode(keyconf, keymap); + /* Hack to prevent fall-through, when the button isn't visible. */ + WM_keymap_add_item(keymap, "MESH_OT_select_mode", FOURKEY, KM_PRESS, 0, 0); + /* Select Element (Sync Select: off) */ + WM_keymap_add_context_enum_set_items( + keymap, rna_enum_mesh_select_mode_uv_items, "tool_settings.uv_select_mode", + ONEKEY, KM_PRESS, 0, 0); + /* Mark edge seam */ WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0); |