Merge branch 'blender-v4.5-release'

This commit is contained in:
Jacques Lucke
2025-07-14 16:30:38 +02:00
18 changed files with 75 additions and 49 deletions

View File

@@ -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

View File

@@ -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<SpaceType> &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;
}
}
}

View File

@@ -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<LineartBakeJob *>(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);

View File

@@ -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;
}

View File

@@ -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<const SocketDeclaration *>(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<const LayoutDeclaration *>(item_decl)) {

View File

@@ -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;
}

View File

@@ -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<wmWindowManager *>(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);

View File

@@ -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<wmWindowManager *>(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<wmWindowManager *>(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);

View File

@@ -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.
*

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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<geo_log::NodeWarning>(warnings)](const uiBut * /*but*/) {
return node_errors_tooltip_fn(warnings);
});
UI_block_emboss_set(&block, blender::ui::EmbossType::Emboss);
}

View File

@@ -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);

View File

@@ -793,7 +793,7 @@ void register_spacetype()
art = MEM_callocN<ARegionType>("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;

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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<ARegionDrawLockFlags>(lock_flags));
}
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
{
WM_set_locked_interface_with_flags(wm, lock ? REGION_DRAW_LOCK_ALL : 0);
}
/** \} */