diff --git a/source/blender/blenkernel/BKE_screen.hh b/source/blender/blenkernel/BKE_screen.hh index 49b50238d9f..edb3b8b97ed 100644 --- a/source/blender/blenkernel/BKE_screen.hh +++ b/source/blender/blenkernel/BKE_screen.hh @@ -198,6 +198,14 @@ struct RegionPollParams { const bContext *context; }; +/* #ARegionType::lock */ +enum ARegionDrawLockFlags { + REGION_DRAW_LOCK_NONE = 0, + REGION_DRAW_LOCK_RENDER = (1 << 0), + REGION_DRAW_LOCK_BAKING = (1 << 1), + REGION_DRAW_LOCK_ALL = (REGION_DRAW_LOCK_RENDER | REGION_DRAW_LOCK_BAKING) +}; + struct ARegionType { ARegionType *next, *prev; /** Unique identifier within this space, defines `RGN_TYPE_xxxx`. */ @@ -288,7 +296,8 @@ struct ARegionType { int keymapflag; /** * Return without drawing. - * lock is set by region definition, and copied to do_lock by render. can become flag. + * lock is set by region definition, and copied to do_lock by render. + * Set as bitflag value in #ARegionDrawLockFlags. */ short do_lock, lock; /** Don't handle gizmos events behind #uiBlock's with #UI_BLOCK_CLIP_EVENTS flag set. */ @@ -695,10 +704,11 @@ void BKE_spacedata_copylist(ListBase *lb_dst, ListBase *lb_src); /** * Facility to set locks for drawing to survive (render) threads accessing drawing data. * - * \note Lock can become bit-flag too. * \note Should be replaced in future by better local data handling for threads. + * \note Effect of multiple calls to this function is not accumulative. The locking flags + * will be set to by the last call. */ -void BKE_spacedata_draw_locks(bool set); +void BKE_spacedata_draw_locks(ARegionDrawLockFlags lock_flags); /** * Version of #BKE_area_find_region_type that also works if \a slink diff --git a/source/blender/blenkernel/intern/screen.cc b/source/blender/blenkernel/intern/screen.cc index f9170612a7d..b245f319791 100644 --- a/source/blender/blenkernel/intern/screen.cc +++ b/source/blender/blenkernel/intern/screen.cc @@ -418,15 +418,15 @@ void BKE_spacedata_copylist(ListBase *lb_dst, ListBase *lb_src) } } -void BKE_spacedata_draw_locks(bool set) +void BKE_spacedata_draw_locks(ARegionDrawLockFlags lock_flags) { for (std::unique_ptr &st : get_space_types()) { LISTBASE_FOREACH (ARegionType *, art, &st->regiontypes) { - if (set) { - art->do_lock = art->lock; + if (lock_flags != 0) { + art->do_lock = (art->lock & lock_flags); } else { - art->do_lock = false; + art->do_lock = 0; } } } diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_lineart.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_lineart.cc index 2519ce51b46..5ac74f51c92 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_lineart.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_lineart.cc @@ -296,7 +296,7 @@ static void lineart_bake_startjob(void *customdata, wmJobWorkerStatus *worker_st guard_modifiers(*bj); - BKE_spacedata_draw_locks(true); + BKE_spacedata_draw_locks(REGION_DRAW_LOCK_BAKING); for (int frame = bj->frame_begin; frame <= bj->frame_end; frame += bj->frame_increment) { @@ -334,7 +334,6 @@ static void lineart_bake_endjob(void *customdata) { LineartBakeJob *bj = static_cast(customdata); - BKE_spacedata_draw_locks(false); WM_set_locked_interface(CTX_wm_manager(bj->C), false); WM_main_add_notifier(NC_SCENE | ND_FRAME, bj->scene); @@ -401,7 +400,7 @@ static wmOperatorStatus lineart_bake_common(bContext *C, WM_jobs_timer(wm_job, 0.1, NC_GPENCIL | ND_DATA | NA_EDITED, NC_GPENCIL | ND_DATA | NA_EDITED); WM_jobs_callbacks(wm_job, lineart_bake_startjob, nullptr, nullptr, lineart_bake_endjob); - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_set_locked_interface_with_flags(CTX_wm_manager(C), REGION_DRAW_LOCK_BAKING); WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/interface/regions/interface_region_hud.cc b/source/blender/editors/interface/regions/interface_region_hud.cc index 2e1274c2cdd..d94c128dc73 100644 --- a/source/blender/editors/interface/regions/interface_region_hud.cc +++ b/source/blender/editors/interface/regions/interface_region_hud.cc @@ -309,7 +309,7 @@ ARegionType *ED_area_type_hud(int space_type) hud_panels_register(art, space_type, art->regionid); - art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */ + art->lock = REGION_DRAW_LOCK_ALL; return art; } diff --git a/source/blender/editors/interface/templates/interface_template_node_inputs.cc b/source/blender/editors/interface/templates/interface_template_node_inputs.cc index 36a2ac5e219..9ae1e34caa9 100644 --- a/source/blender/editors/interface/templates/interface_template_node_inputs.cc +++ b/source/blender/editors/interface/templates/interface_template_node_inputs.cc @@ -160,8 +160,20 @@ void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr) blender::ui::nodes::draw_node_inputs_recursive(C, layout, node, ptr, *panel_decl); } else if (const auto *socket_decl = dynamic_cast(item_decl)) { - if (socket_decl->in_out == SOCK_IN) { - blender::ui::nodes::draw_node_input(C, layout, ptr, node.socket_by_decl(*socket_decl)); + bNodeSocket &socket = node.socket_by_decl(*socket_decl); + if (socket_decl->custom_draw_fn) { + CustomSocketDrawParams params{ + *C, + *layout, + tree, + node, + socket, + *ptr, + RNA_pointer_create_discrete(ptr->owner_id, &RNA_NodeSocket, &socket)}; + (*socket_decl->custom_draw_fn)(params); + } + else if (socket_decl->in_out == SOCK_IN) { + blender::ui::nodes::draw_node_input(C, layout, ptr, socket); } } else if (const auto *layout_decl = dynamic_cast(item_decl)) { diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index bc0cc6333c1..b7dcca869d4 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -738,7 +738,7 @@ wmOperatorStatus ED_mesh_shapes_join_objects_exec(bContext *C, }; auto topology_count_matches = [](const Mesh &a, const Mesh &b) { - return a.verts_num == b.verts_num && a.edges_num == b.edges_num && a.faces_num == b.faces_num; + return a.verts_num == b.verts_num; }; bool found_object = false; @@ -778,9 +778,7 @@ wmOperatorStatus ED_mesh_shapes_join_objects_exec(bContext *C, } if (found_non_equal_count) { - BKE_report(reports, - RPT_WARNING, - "Selected meshes must have equal numbers of vertices, edges, and faces"); + BKE_report(reports, RPT_WARNING, "Selected meshes must have equal numbers of vertices"); return OPERATOR_CANCELLED; } @@ -799,10 +797,12 @@ wmOperatorStatus ED_mesh_shapes_join_objects_exec(bContext *C, } int keys_changed = 0; + bool any_keys_added = false; for (const ObjectInfo &info : compatible_objects) { if (ensure_keys_exist) { KeyBlock *kb = BKE_keyblock_add(active_mesh.key, info.name.c_str()); BKE_keyblock_convert_from_mesh(&info.mesh, active_mesh.key, kb); + any_keys_added = true; } else if (KeyBlock *kb = BKE_keyblock_find_name(active_mesh.key, info.name.c_str())) { keys_changed++; @@ -821,6 +821,11 @@ wmOperatorStatus ED_mesh_shapes_join_objects_exec(bContext *C, DEG_id_tag_update(&active_mesh.id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &active_mesh.id); + if (any_keys_added && bmain) { + /* Adding a new shape key should trigger a rebuild of relationships. */ + DEG_relations_tag_update(bmain); + } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/dynamicpaint_ops.cc b/source/blender/editors/physics/dynamicpaint_ops.cc index 397cbcd6788..84a4af22409 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.cc +++ b/source/blender/editors/physics/dynamicpaint_ops.cc @@ -316,7 +316,6 @@ static void dpaint_bake_endjob(void *customdata) dynamicPaint_freeSurfaceData(job->surface); G.is_rendering = false; - BKE_spacedata_draw_locks(false); WM_set_locked_interface(static_cast(G_MAIN->wm.first), false); @@ -445,7 +444,7 @@ static void dpaint_bake_startjob(void *customdata, wmJobWorkerStatus *worker_sta * scene frame in separate threads */ G.is_rendering = true; - BKE_spacedata_draw_locks(true); + BKE_spacedata_draw_locks(REGION_DRAW_LOCK_BAKING); dynamicPaint_bakeImageSequence(job); @@ -506,7 +505,7 @@ static wmOperatorStatus dynamicpaint_bake_exec(bContext *C, wmOperator *op) WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER); WM_jobs_callbacks(wm_job, dpaint_bake_startjob, nullptr, nullptr, dpaint_bake_endjob); - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_set_locked_interface_with_flags(CTX_wm_manager(C), REGION_DRAW_LOCK_BAKING); /* Bake Dynamic Paint */ WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/physics/physics_fluid.cc b/source/blender/editors/physics/physics_fluid.cc index 47bb5870052..2040e3a5a03 100644 --- a/source/blender/editors/physics/physics_fluid.cc +++ b/source/blender/editors/physics/physics_fluid.cc @@ -329,7 +329,6 @@ static void fluid_bake_endjob(void *customdata) DEG_id_tag_update(&job->ob->id, ID_RECALC_GEOMETRY); G.is_rendering = false; - BKE_spacedata_draw_locks(false); WM_set_locked_interface(static_cast(G_MAIN->wm.first), false); /* Bake was successful: @@ -367,7 +366,7 @@ static void fluid_bake_startjob(void *customdata, wmJobWorkerStatus *worker_stat G.is_break = false; G.is_rendering = true; - BKE_spacedata_draw_locks(true); + BKE_spacedata_draw_locks(REGION_DRAW_LOCK_BAKING); if (fluid_is_bake_noise(job) || fluid_is_bake_all(job)) { BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE); @@ -436,7 +435,6 @@ static void fluid_free_endjob(void *customdata) FluidDomainSettings *fds = job->fmd->domain; G.is_rendering = false; - BKE_spacedata_draw_locks(false); WM_set_locked_interface(static_cast(G_MAIN->wm.first), false); /* Reflect the now empty cache in the viewport too. */ @@ -474,7 +472,7 @@ static void fluid_free_startjob(void *customdata, wmJobWorkerStatus *worker_stat G.is_break = false; G.is_rendering = true; - BKE_spacedata_draw_locks(true); + BKE_spacedata_draw_locks(REGION_DRAW_LOCK_BAKING); int cache_map = 0; @@ -571,7 +569,7 @@ static wmOperatorStatus fluid_bake_invoke(bContext *C, wmOperator *op, const wmE WM_jobs_timer(wm_job, 0.01, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER); WM_jobs_callbacks(wm_job, fluid_bake_startjob, nullptr, nullptr, fluid_bake_endjob); - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_set_locked_interface_with_flags(CTX_wm_manager(C), REGION_DRAW_LOCK_BAKING); WM_jobs_start(CTX_wm_manager(C), wm_job); WM_event_add_modal_handler(C, op); @@ -653,7 +651,7 @@ static wmOperatorStatus fluid_free_exec(bContext *C, wmOperator *op) WM_jobs_timer(wm_job, 0.01, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER); WM_jobs_callbacks(wm_job, fluid_free_startjob, nullptr, nullptr, fluid_free_endjob); - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_set_locked_interface_with_flags(CTX_wm_manager(C), REGION_DRAW_LOCK_BAKING); /* Free Fluid Geometry */ WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc index f0d193ad6ce..81f1b37bfef 100644 --- a/source/blender/editors/render/render_internal.cc +++ b/source/blender/editors/render/render_internal.cc @@ -881,7 +881,7 @@ static void render_drawlock(void *rjv, bool lock) /* If interface is locked, renderer callback shall do nothing. */ if (!rj->interface_locked) { - BKE_spacedata_draw_locks(lock); + BKE_spacedata_draw_locks(lock ? REGION_DRAW_LOCK_RENDER : REGION_DRAW_LOCK_NONE); } } @@ -1061,7 +1061,7 @@ static wmOperatorStatus screen_render_invoke(bContext *C, wmOperator *op, const /* Lock the user interface depending on render settings. */ if (scene->r.use_lock_interface) { - WM_set_locked_interface(CTX_wm_manager(C), true); + WM_set_locked_interface_with_flags(CTX_wm_manager(C), REGION_DRAW_LOCK_RENDER); /* Set flag interface need to be unlocked. * diff --git a/source/blender/editors/space_buttons/space_buttons.cc b/source/blender/editors/space_buttons/space_buttons.cc index 75ba393eae3..cdc933717a1 100644 --- a/source/blender/editors/space_buttons/space_buttons.cc +++ b/source/blender/editors/space_buttons/space_buttons.cc @@ -1100,7 +1100,7 @@ void ED_spacetype_buttons() art->draw = ED_region_panels_draw; art->listener = buttons_main_region_listener; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; - art->lock = true; + art->lock = REGION_DRAW_LOCK_ALL; buttons_context_register(art); BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_image/space_image.cc b/source/blender/editors/space_image/space_image.cc index 49e3aa06e55..e9f7e464f81 100644 --- a/source/blender/editors/space_image/space_image.cc +++ b/source/blender/editors/space_image/space_image.cc @@ -1239,7 +1239,7 @@ void ED_spacetype_image() art->init = image_main_region_init; art->draw = image_main_region_draw; art->listener = image_main_region_listener; - art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */ + art->lock = REGION_DRAW_LOCK_BAKING; BLI_addhead(&st->regiontypes, art); /* regions: list-view/buttons/scopes */ diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 460095db9f8..4e53e71842b 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2790,7 +2790,9 @@ static void node_add_error_message_button(const TreeDrawContext &tree_draw_ctx, 0, nullptr); UI_but_func_quick_tooltip_set( - but, [warnings](const uiBut * /*but*/) { return node_errors_tooltip_fn(warnings); }); + but, [warnings = Array(warnings)](const uiBut * /*but*/) { + return node_errors_tooltip_fn(warnings); + }); UI_block_emboss_set(&block, blender::ui::EmbossType::Emboss); } diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 655434a57ef..b04f52db946 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -2264,7 +2264,7 @@ void ED_spacetype_node() art->cursor = node_cursor; art->event_cursor = true; art->clip_gizmo_events_by_ui = true; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 38fddf1c0b0..85630d3ca57 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -793,7 +793,7 @@ void register_spacetype() art = MEM_callocN("spacetype spreadsheet region"); art->regionid = RGN_TYPE_WINDOW; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; art->init = spreadsheet_main_region_init; art->draw = spreadsheet_main_region_draw; @@ -808,7 +808,7 @@ void register_spacetype() art->prefsizey = HEADERY; art->keymapflag = 0; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER | ED_KEYMAP_FRAMES; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; art->init = spreadsheet_header_region_init; art->draw = spreadsheet_header_region_draw; @@ -822,7 +822,7 @@ void register_spacetype() art->prefsizey = HEADERY; art->keymapflag = 0; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER | ED_KEYMAP_FRAMES; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; art->init = spreadsheet_footer_region_init; art->draw = spreadsheet_footer_region_draw; @@ -835,7 +835,7 @@ void register_spacetype() art->regionid = RGN_TYPE_UI; art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; art->init = spreadsheet_sidebar_init; art->layout = ED_region_panels_layout; @@ -851,7 +851,7 @@ void register_spacetype() art->regionid = RGN_TYPE_TOOLS; art->prefsizex = 150 + V2D_SCROLL_WIDTH; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; - art->lock = 1; + art->lock = REGION_DRAW_LOCK_ALL; art->init = ED_region_panels_init; art->draw = spreadsheet_dataset_region_draw; art->listener = spreadsheet_dataset_region_listener; diff --git a/source/blender/editors/space_view3d/space_view3d.cc b/source/blender/editors/space_view3d/space_view3d.cc index b6a9aa9d7e4..f4f760ff228 100644 --- a/source/blender/editors/space_view3d/space_view3d.cc +++ b/source/blender/editors/space_view3d/space_view3d.cc @@ -1621,7 +1621,7 @@ void ED_spacetype_view3d() art->listener = view3d_main_region_listener; art->message_subscribe = view3d_main_region_message_subscribe; art->cursor = view3d_main_region_cursor; - art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */ + art->lock = REGION_DRAW_LOCK_ALL; BLI_addhead(&st->regiontypes, art); /* regions: list-view/buttons */ diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index a42eb626502..9078f3063e6 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -46,6 +46,7 @@ #include "BKE_mesh.hh" #include "BKE_object_types.hh" #include "BKE_report.hh" +#include "BKE_screen.hh" #include "BKE_subdiv.hh" #include "BKE_subdiv_mesh.hh" #include "BKE_subdiv_modifier.hh" @@ -1800,7 +1801,7 @@ static wmOperatorStatus pack_islands_exec(bContext *C, wmOperator *op) pid->wm, CTX_wm_window(C), scene, "Packing UVs", WM_JOB_PROGRESS, WM_JOB_TYPE_UV_PACK); WM_jobs_customdata_set(wm_job, pid, pack_islands_freejob); WM_jobs_timer(wm_job, 0.1, 0, 0); - WM_set_locked_interface(pid->wm, true); + WM_set_locked_interface_with_flags(pid->wm, REGION_DRAW_LOCK_RENDER); WM_jobs_callbacks(wm_job, pack_islands_startjob, nullptr, nullptr, pack_islands_endjob); WM_cursor_wait(true); diff --git a/source/blender/windowmanager/WM_api.hh b/source/blender/windowmanager/WM_api.hh index 183c6362c88..4695210a6f7 100644 --- a/source/blender/windowmanager/WM_api.hh +++ b/source/blender/windowmanager/WM_api.hh @@ -1954,8 +1954,10 @@ void WM_autosave_write(wmWindowManager *wm, Main *bmain); /** * Lock the interface for any communication. + * For #WM_set_locked_interface_with_flags, #lock_flags is #ARegionDrawLockFlags */ void WM_set_locked_interface(wmWindowManager *wm, bool lock); +void WM_set_locked_interface_with_flags(wmWindowManager *wm, short lock_flags); void WM_event_tablet_data_default_set(wmTabletData *tablet_data); diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 83775dc079d..fc0cc954141 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -6456,7 +6456,7 @@ static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot) return true; } -void WM_set_locked_interface(wmWindowManager *wm, bool lock) +void WM_set_locked_interface_with_flags(wmWindowManager *wm, short lock_flags) { /* This will prevent events from being handled while interface is locked * @@ -6465,16 +6465,14 @@ void WM_set_locked_interface(wmWindowManager *wm, bool lock) * wouldn't be useful anywhere outside of window manager, so let's not * pollute global context with such an information for now). */ - wm->runtime->is_interface_locked = lock; + wm->runtime->is_interface_locked = (lock_flags != 0); - /* This will prevent drawing regions which uses non-thread-safe data. - * Currently it'll be just a 3D viewport. - * - * TODO(sergey): Make it different locked states, so different jobs - * could lock different areas of blender and allow - * interaction with others? - */ - BKE_spacedata_draw_locks(lock); + BKE_spacedata_draw_locks(static_cast(lock_flags)); +} + +void WM_set_locked_interface(wmWindowManager *wm, bool lock) +{ + WM_set_locked_interface_with_flags(wm, lock ? REGION_DRAW_LOCK_ALL : 0); } /** \} */