From e0852368bc2b19c924a458df4e21d3112998a180 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 22 Apr 2021 10:04:59 -0300 Subject: Fix missing include --- source/blender/editors/transform/transform_snap_object.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender') diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index e97d49e0971..541d173ca28 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -43,6 +43,7 @@ #include "BKE_curve.h" #include "BKE_duplilist.h" #include "BKE_editmesh.h" +#include "BKE_geometry_set.h" #include "BKE_layer.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" -- cgit v1.2.3 From f240b5e5f712d375c82763057c1c29e95d011ca5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 22 Apr 2021 15:12:16 +0200 Subject: Fix T87701: debug assert generating scene preview render --- source/blender/render/intern/engine.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'source/blender') diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c index 817f09f5bfe..66d38eb19c7 100644 --- a/source/blender/render/intern/engine.c +++ b/source/blender/render/intern/engine.c @@ -143,12 +143,9 @@ RenderEngine *RE_engine_create(RenderEngineType *type) static void engine_depsgraph_free(RenderEngine *engine) { if (engine->depsgraph) { - /* Need GPU context since this might free GPU buffers. This function can - * only be called from a render thread. We do not currently support - * persistent data with GPU contexts for that reason. */ + /* Need GPU context since this might free GPU buffers. */ const bool use_gpu_context = (engine->type->flag & RE_USE_GPU_CONTEXT); if (use_gpu_context) { - BLI_assert(!BLI_thread_is_main()); DRW_render_context_enable(engine->re); } @@ -623,8 +620,8 @@ RenderData *RE_engine_get_render_data(Render *re) bool RE_engine_use_persistent_data(RenderEngine *engine) { - /* See engine_depsgraph_free() for why preserving the depsgraph for - * re-renders is not supported with GPU contexts. */ + /* Re-rendering is not supported with GPU contexts, since the GPU context + * is destroyed when the render thread exists. */ return (engine->re->r.mode & R_PERSISTENT_DATA) && !(engine->type->flag & RE_USE_GPU_CONTEXT); } -- cgit v1.2.3 From bbb52a462ef91c9f84f673102b851a897b5968ac Mon Sep 17 00:00:00 2001 From: Falk David Date: Thu, 22 Apr 2021 19:01:37 +0200 Subject: Fix T87688: Crash entering valid text into number field When the user entered a driver expression like `#frame` into a number field, Blender would crash sometime after. This is because e1a9ba94c599 did not handle this case properly and ignored the fact that the user can enter text into the field. The fix makes sure that we only cancel if the value is a *number* equal to the previous value in the field. Note that this could also be handled by `ui_but_string_set` which would be a bit nicer potentially. However, I was unable to find a clean way of passing `data->startvalue` into that function. `uiHandleButtonData` is only known locally inside `interface_handlers.c`. Reviewed By: Severin Maniphest Tasks: T87688 Differential Revision: https://developer.blender.org/D11049 --- source/blender/editors/interface/interface_handlers.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4cbf5fca49a..4931b35ca75 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1114,6 +1114,13 @@ static void ui_apply_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) { if (data->str) { + double value; + /* Check if the string value is a number and cancel if it's equal to the startvalue. */ + if (ui_but_string_eval_number(C, but, data->str, &value) && (value == data->startvalue)) { + data->cancel = true; + return; + } + if (ui_but_string_set(C, but, data->str)) { data->value = ui_but_value_get(but); } @@ -1121,12 +1128,6 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) data->cancel = true; return; } - - /* If the value entered is the exact same, do not trigger an update. */ - if (data->value == data->startvalue) { - data->cancel = true; - return; - } } else { ui_but_value_set(but, data->value); -- cgit v1.2.3 From 6ebe0b8cf0463771d30c592e6926e591ee773557 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 22 Apr 2021 19:26:09 +0200 Subject: Assets: Correct name of own recently added BPY functions Makes the functions (introduced in 557b3d2762a6) follow existing naming conventions for the API. Changes: `bpy.types.ID.mark_asset` to `bpy.types.ID.asset_mark` `bpy.types.ID.clear_asset` to `bpy.types.ID.asset_clear` --- source/blender/makesrna/intern/rna_ID.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 3c641c6ec1a..4fe19493614 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -577,7 +577,7 @@ static ID *rna_ID_copy(ID *id, Main *bmain) return newid; } -static void rna_ID_mark_asset(ID *id, bContext *C) +static void rna_ID_asset_mark(ID *id, bContext *C) { if (ED_asset_mark_id(C, id)) { WM_main_add_notifier(NC_ID | NA_EDITED, NULL); @@ -585,7 +585,7 @@ static void rna_ID_mark_asset(ID *id, bContext *C) } } -static void rna_ID_clear_asset(ID *id) +static void rna_ID_asset_clear(ID *id) { if (ED_asset_clear_id(id)) { WM_main_add_notifier(NC_ID | NA_EDITED, NULL); @@ -1734,14 +1734,14 @@ static void rna_def_ID(BlenderRNA *brna) parm = RNA_def_pointer(func, "id", "ID", "", "New copy of the ID"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "mark_asset", "rna_ID_mark_asset"); + func = RNA_def_function(srna, "asset_mark", "rna_ID_asset_mark"); RNA_def_function_ui_description( func, "Enable easier reuse of the data-block through the Asset Browser, with the help of " "customizable metadata (like previews, descriptions and tags)"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - func = RNA_def_function(srna, "clear_asset", "rna_ID_clear_asset"); + func = RNA_def_function(srna, "asset_clear", "rna_ID_asset_clear"); RNA_def_function_ui_description( func, "Delete all asset metadata and turn the asset data-block back into a normal data-block"); -- cgit v1.2.3 From 47892d6695bc9a8e3fab012c3ba4005a2cb4a767 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 22 Apr 2021 19:40:04 +0200 Subject: Fix too big grid plane for Add Object tool on Retina displays The grid plane was drawn too big on retina displays compared to other screens, because the factor was multiplied by the native pixel-size, which is 2 for Retina displays. --- source/blender/editors/space_view3d/view3d_placement.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index 1afdcdd2993..00e30f8afae 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -2061,7 +2061,7 @@ static void cursor_plane_draw(bContext *C, int x, int y, void *customdata) GPU_matrix_projection_set(rv3d->winmat); GPU_matrix_set(rv3d->viewmat); - const float scale_mod = U.gizmo_size * 2 * U.dpi_fac; + const float scale_mod = U.gizmo_size * 2 * U.dpi_fac / U.pixelsize; float final_scale = (scale_mod * pixel_size); -- cgit v1.2.3 From 3cb09f7a835b5af9c39e1599b44af4b151b7e77d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Apr 2021 09:01:57 +1000 Subject: Cleanup: quiet clang-tidy warning --- source/blender/editors/transform/transform_snap_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 541d173ca28..e5f6f207e3c 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2237,7 +2237,7 @@ static short snapMesh(SnapObjectContext *sctx, if (me->totvert == 0) { return 0; } - else if (me->totedge == 0 && !(snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) { + if (me->totedge == 0 && !(snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX)) { return 0; } -- cgit v1.2.3 From a23e49c696cf9ac66ecb9c1ad009d38b0a5e9f9f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Apr 2021 09:02:49 +1000 Subject: Fix T86170: Memory leak clearing the Python instance for COW id data As Python can access COW ID's, ensure it's instance is kept on update. This could happen when the "Use Self" argument was enabled for a driver. --- source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc | 5 +++++ source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'source/blender') diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc index 7a0c1b5b693..0064240db23 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc @@ -33,6 +33,7 @@ namespace blender::deg { RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph) : have_backup(false), + id_data({.py_instance = nullptr}), animation_backup(depsgraph), scene_backup(depsgraph), sound_backup(depsgraph), @@ -51,6 +52,8 @@ void RuntimeBackup::init_from_id(ID *id) } have_backup = true; + id_data.py_instance = id->py_instance; + animation_backup.init_from_id(id); const ID_Type id_type = GS(id->name); @@ -89,6 +92,8 @@ void RuntimeBackup::restore_to_id(ID *id) return; } + id->py_instance = id_data.py_instance; + animation_backup.restore_to_id(id); const ID_Type id_type = GS(id->name); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h index c6249c83daa..0629dbe62b4 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h @@ -58,6 +58,11 @@ class RuntimeBackup { * copy-on-write mechanism. */ bool have_backup; + /* Struct members of the ID pointer. */ + struct { + void *py_instance; + } id_data; + AnimationBackup animation_backup; SceneBackup scene_backup; SoundBackup sound_backup; -- cgit v1.2.3 From 0817763624dbcb095dd172910cc39144f840e19c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Apr 2021 11:32:32 +1000 Subject: Fix for building with MSVC --- source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc index 0064240db23..7893e8c64c1 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc @@ -33,7 +33,7 @@ namespace blender::deg { RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph) : have_backup(false), - id_data({.py_instance = nullptr}), + id_data({nullptr}), animation_backup(depsgraph), scene_backup(depsgraph), sound_backup(depsgraph), -- cgit v1.2.3 From 8b049e4c2a53e51db295ab300bf8377d63086708 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 22 Apr 2021 19:57:49 -0700 Subject: UI: Join or Close Any Screen Area Corner action zones allow joining any neighbors. New 'Area Close' operator. Improved Header Context Menu. Differential Revision: https://developer.blender.org/D8084 Reviewed by Campbell Barton --- source/blender/editors/include/ED_screen.h | 2 +- source/blender/editors/screen/screen_draw.c | 303 +++++++------------------- source/blender/editors/screen/screen_edit.c | 190 +++++++++++++--- source/blender/editors/screen/screen_intern.h | 7 +- source/blender/editors/screen/screen_ops.c | 140 ++++++++++-- 5 files changed, 362 insertions(+), 280 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index b3205acb8ee..169b25a1358 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -200,7 +200,7 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area); /* screens */ void ED_screens_init(struct Main *bmain, struct wmWindowManager *wm); void ED_screen_draw_edges(struct wmWindow *win); -void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2); +void ED_screen_draw_join_highlight(struct ScrArea *sa1, struct ScrArea *sa2); void ED_screen_draw_split_preview(struct ScrArea *area, const int dir, const float fac); void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win); void ED_screen_ensure_updated(struct wmWindowManager *wm, diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 2ba7ef8f972..6d1409a9044 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -33,184 +33,11 @@ #include "WM_api.h" +#include "UI_interface.h" #include "UI_resources.h" #include "screen_intern.h" -/** - * Draw horizontal shape visualizing future joining - * (left as well right direction of future joining). - */ -static void draw_horizontal_join_shape(ScrArea *area, char dir, uint pos) -{ - const float width = screen_geom_area_width(area) - 1; - const float height = screen_geom_area_height(area) - 1; - - float w, h; - if (height < width) { - h = height / 8; - w = height / 4; - } - else { - h = width / 8; - w = width / 4; - } - - vec2f points[10]; - points[0].x = area->v1->vec.x; - points[0].y = area->v1->vec.y + height / 2; - - points[1].x = area->v1->vec.x; - points[1].y = area->v1->vec.y; - - points[2].x = area->v4->vec.x - w; - points[2].y = area->v4->vec.y; - - points[3].x = area->v4->vec.x - w; - points[3].y = area->v4->vec.y + height / 2 - 2 * h; - - points[4].x = area->v4->vec.x - 2 * w; - points[4].y = area->v4->vec.y + height / 2; - - points[5].x = area->v4->vec.x - w; - points[5].y = area->v4->vec.y + height / 2 + 2 * h; - - points[6].x = area->v3->vec.x - w; - points[6].y = area->v3->vec.y; - - points[7].x = area->v2->vec.x; - points[7].y = area->v2->vec.y; - - points[8].x = area->v4->vec.x; - points[8].y = area->v4->vec.y + height / 2 - h; - - points[9].x = area->v4->vec.x; - points[9].y = area->v4->vec.y + height / 2 + h; - - if (dir == 'l') { - /* when direction is left, then we flip direction of arrow */ - float cx = area->v1->vec.x + width; - for (int i = 0; i < 10; i++) { - points[i].x -= cx; - points[i].x = -points[i].x; - points[i].x += area->v1->vec.x; - } - } - - immBegin(GPU_PRIM_TRI_FAN, 5); - - for (int i = 0; i < 5; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } - - immEnd(); - - immBegin(GPU_PRIM_TRI_FAN, 5); - - for (int i = 4; i < 8; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } - - immVertex2f(pos, points[0].x, points[0].y); - immEnd(); - - immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); - immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); -} - -/** - * Draw vertical shape visualizing future joining (up/down direction). - */ -static void draw_vertical_join_shape(ScrArea *area, char dir, uint pos) -{ - const float width = screen_geom_area_width(area) - 1; - const float height = screen_geom_area_height(area) - 1; - - float w, h; - if (height < width) { - h = height / 4; - w = height / 8; - } - else { - h = width / 4; - w = width / 8; - } - - vec2f points[10]; - points[0].x = area->v1->vec.x + width / 2; - points[0].y = area->v3->vec.y; - - points[1].x = area->v2->vec.x; - points[1].y = area->v2->vec.y; - - points[2].x = area->v1->vec.x; - points[2].y = area->v1->vec.y + h; - - points[3].x = area->v1->vec.x + width / 2 - 2 * w; - points[3].y = area->v1->vec.y + h; - - points[4].x = area->v1->vec.x + width / 2; - points[4].y = area->v1->vec.y + 2 * h; - - points[5].x = area->v1->vec.x + width / 2 + 2 * w; - points[5].y = area->v1->vec.y + h; - - points[6].x = area->v4->vec.x; - points[6].y = area->v4->vec.y + h; - - points[7].x = area->v3->vec.x; - points[7].y = area->v3->vec.y; - - points[8].x = area->v1->vec.x + width / 2 - w; - points[8].y = area->v1->vec.y; - - points[9].x = area->v1->vec.x + width / 2 + w; - points[9].y = area->v1->vec.y; - - if (dir == 'u') { - /* when direction is up, then we flip direction of arrow */ - float cy = area->v1->vec.y + height; - for (int i = 0; i < 10; i++) { - points[i].y -= cy; - points[i].y = -points[i].y; - points[i].y += area->v1->vec.y; - } - } - - immBegin(GPU_PRIM_TRI_FAN, 5); - - for (int i = 0; i < 5; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } - - immEnd(); - - immBegin(GPU_PRIM_TRI_FAN, 5); - - for (int i = 4; i < 8; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } - - immVertex2f(pos, points[0].x, points[0].y); - immEnd(); - - immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); - immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); -} - -/** - * Draw join shape due to direction of joining. - */ -static void draw_join_shape(ScrArea *area, char dir, uint pos) -{ - if (ELEM(dir, 'u', 'd')) { - draw_vertical_join_shape(area, dir, pos); - } - else { - draw_horizontal_join_shape(area, dir, pos); - } -} - #define CORNER_RESOLUTION 3 static void do_vert_pair(GPUVertBuf *vbo, uint pos, uint *vidx, int corner, int i) @@ -290,28 +117,6 @@ static GPUBatch *batch_screen_edges_get(int *corner_len) #undef CORNER_RESOLUTION -/** - * Draw screen area darker with arrow (visualization of future joining). - */ -static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos) -{ - GPU_blend(GPU_BLEND_ALPHA); - immUniformColor4ub(0, 0, 0, 50); - - draw_join_shape(area, dir, pos); -} - -/** - * Draw screen area lighter with arrow shape ("eraser" of previous dark shape). - */ -static void scrarea_draw_shape_light(ScrArea *area, char UNUSED(dir), uint pos) -{ - GPU_blend(GPU_BLEND_ALPHA); - immUniformColor4ub(255, 255, 255, 25); - - immRectf(pos, area->v1->vec.x, area->v1->vec.y, area->v3->vec.x, area->v3->vec.y); -} - static void drawscredge_area_draw( int sizex, int sizey, short x1, short y1, short x2, short y2, float edge_thickness) { @@ -427,50 +232,92 @@ void ED_screen_draw_edges(wmWindow *win) } /** - * The blended join arrows. + * Visual indication of the two areas involved in a proposed join. * * \param sa1: Area from which the resultant originates. * \param sa2: Target area that will be replaced. */ -void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) +void ED_screen_draw_join_highlight(ScrArea *sa1, ScrArea *sa2) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - GPU_line_width(1); - - /* blended join arrow */ int dir = area_getorientation(sa1, sa2); - int dira = -1; - if (dir != -1) { - switch (dir) { - case 0: /* W */ - dir = 'r'; - dira = 'l'; - break; - case 1: /* N */ - dir = 'd'; - dira = 'u'; - break; - case 2: /* E */ - dir = 'l'; - dira = 'r'; - break; - case 3: /* S */ - dir = 'u'; - dira = 'd'; - break; - } + if (dir == -1) { + return; + } - GPU_blend(GPU_BLEND_ALPHA); + /* Rect of the combined areas.*/ + bool vertical = ELEM(dir, 1, 3); + rctf combined = {.xmin = vertical ? MAX2(sa1->totrct.xmin, sa2->totrct.xmin) : + MIN2(sa1->totrct.xmin, sa2->totrct.xmin), + .xmax = vertical ? MIN2(sa1->totrct.xmax, sa2->totrct.xmax) : + MAX2(sa1->totrct.xmax, sa2->totrct.xmax), + .ymin = vertical ? MIN2(sa1->totrct.ymin, sa2->totrct.ymin) : + MAX2(sa1->totrct.ymin, sa2->totrct.ymin), + .ymax = vertical ? MAX2(sa1->totrct.ymax, sa2->totrct.ymax) : + MIN2(sa1->totrct.ymax, sa2->totrct.ymax)}; - scrarea_draw_shape_dark(sa2, dir, pos); - scrarea_draw_shape_light(sa1, dira, pos); + uint pos_id = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + GPU_blend(GPU_BLEND_ALPHA); - GPU_blend(GPU_BLEND_NONE); + /* Highlight source (sa1) within combined area. */ + immUniformColor4fv((const float[4]){1.0f, 1.0f, 1.0f, 0.10f}); + immRectf(pos_id, + MAX2(sa1->totrct.xmin, combined.xmin), + MAX2(sa1->totrct.ymin, combined.ymin), + MIN2(sa1->totrct.xmax, combined.xmax), + MIN2(sa1->totrct.ymax, combined.ymax)); + + /* Highlight destination (sa2) within combined area. */ + immUniformColor4fv((const float[4]){0.0f, 0.0f, 0.0f, 0.25f}); + immRectf(pos_id, + MAX2(sa2->totrct.xmin, combined.xmin), + MAX2(sa2->totrct.ymin, combined.ymin), + MIN2(sa2->totrct.xmax, combined.xmax), + MIN2(sa2->totrct.ymax, combined.ymax)); + + int offset1; + int offset2; + area_getoffsets(sa1, sa2, dir, &offset1, &offset2); + if (offset1 < 0 || offset2 > 0) { + /* Show partial areas that will be closed. */ + immUniformColor4fv((const float[4]){0.0f, 0.0f, 0.0f, 0.8f}); + if (vertical) { + if (sa1->totrct.xmin < combined.xmin) { + immRectf(pos_id, sa1->totrct.xmin, sa1->totrct.ymin, combined.xmin, sa1->totrct.ymax); + } + if (sa2->totrct.xmin < combined.xmin) { + immRectf(pos_id, sa2->totrct.xmin, sa2->totrct.ymin, combined.xmin, sa2->totrct.ymax); + } + if (sa1->totrct.xmax > combined.xmax) { + immRectf(pos_id, combined.xmax, sa1->totrct.ymin, sa1->totrct.xmax, sa1->totrct.ymax); + } + if (sa2->totrct.xmax > combined.xmax) { + immRectf(pos_id, combined.xmax, sa2->totrct.ymin, sa2->totrct.xmax, sa2->totrct.ymax); + } + } + else { + if (sa1->totrct.ymin < combined.ymin) { + immRectf(pos_id, sa1->totrct.xmin, combined.ymin, sa1->totrct.xmax, sa1->totrct.ymin); + } + if (sa2->totrct.ymin < combined.ymin) { + immRectf(pos_id, sa2->totrct.xmin, combined.ymin, sa2->totrct.xmax, sa2->totrct.ymin); + } + if (sa1->totrct.ymax > combined.ymax) { + immRectf(pos_id, sa1->totrct.xmin, sa1->totrct.ymax, sa1->totrct.xmax, combined.ymax); + } + if (sa2->totrct.ymax > combined.ymax) { + immRectf(pos_id, sa2->totrct.xmin, sa2->totrct.ymax, sa2->totrct.xmax, combined.ymax); + } + } } immUnbindProgram(); + GPU_blend(GPU_BLEND_NONE); + + /* Outline the combined area. */ + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_4fv(&combined, false, 7 * U.pixelsize, (float[4]){1.0f, 1.0f, 1.0f, 0.8f}); } void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 7ad8eada3b9..8e51772d801 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -284,42 +284,37 @@ void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new) /* used with join operator */ int area_getorientation(ScrArea *area, ScrArea *sb) { - if (area == NULL || sb == NULL) { + if (area == NULL || sb == NULL || area == sb) { return -1; } - ScrVert *saBL = area->v1; - ScrVert *saTL = area->v2; - ScrVert *saTR = area->v3; - ScrVert *saBR = area->v4; + vec2s saBL = area->v1->vec; + vec2s saTL = area->v2->vec; + vec2s saTR = area->v3->vec; + vec2s saBR = area->v4->vec; - ScrVert *sbBL = sb->v1; - ScrVert *sbTL = sb->v2; - ScrVert *sbTR = sb->v3; - ScrVert *sbBR = sb->v4; + vec2s sbBL = sb->v1->vec; + vec2s sbTL = sb->v2->vec; + vec2s sbTR = sb->v3->vec; + vec2s sbBR = sb->v4->vec; - if (saBL->vec.x == sbBR->vec.x && saTL->vec.x == sbTR->vec.x) { /* area to right of sb = W */ - if ((abs(saBL->vec.y - sbBR->vec.y) <= AREAJOINTOLERANCE) && - (abs(saTL->vec.y - sbTR->vec.y) <= AREAJOINTOLERANCE)) { + if (saBL.x == sbBR.x && saTL.x == sbTR.x) { /* area to right of sb = W */ + if ((MIN2(saTL.y, sbTR.y) - MAX2(saBL.y, sbBR.y)) > AREAJOINTOLERANCEY) { return 0; } } - else if (saTL->vec.y == sbBL->vec.y && - saTR->vec.y == sbBR->vec.y) { /* area to bottom of sb = N */ - if ((abs(saTL->vec.x - sbBL->vec.x) <= AREAJOINTOLERANCE) && - (abs(saTR->vec.x - sbBR->vec.x) <= AREAJOINTOLERANCE)) { + else if (saTL.y == sbBL.y && saTR.y == sbBR.y) { /* area to bottom of sb = N */ + if ((MIN2(saTR.x, sbBR.x) - MAX2(saTL.x, sbBL.x)) > AREAJOINTOLERANCEX) { return 1; } } - else if (saTR->vec.x == sbTL->vec.x && saBR->vec.x == sbBL->vec.x) { /* area to left of sb = E */ - if ((abs(saTR->vec.y - sbTL->vec.y) <= AREAJOINTOLERANCE) && - (abs(saBR->vec.y - sbBL->vec.y) <= AREAJOINTOLERANCE)) { + else if (saTR.x == sbTL.x && saBR.x == sbBL.x) { /* area to left of sb = E */ + if ((MIN2(saTR.y, sbTL.y) - MAX2(saBR.y, sbBL.y)) > AREAJOINTOLERANCEY) { return 2; } } - else if (saBL->vec.y == sbTL->vec.y && saBR->vec.y == sbTR->vec.y) { /* area on top of sb = S*/ - if ((abs(saBL->vec.x - sbTL->vec.x) <= AREAJOINTOLERANCE) && - (abs(saBR->vec.x - sbTR->vec.x) <= AREAJOINTOLERANCE)) { + else if (saBL.y == sbTL.y && saBR.y == sbTR.y) { /* area on top of sb = S */ + if ((MIN2(saBR.x, sbTR.x) - MAX2(saBL.x, sbTL.x)) > AREAJOINTOLERANCEX) { return 3; } } @@ -327,6 +322,35 @@ int area_getorientation(ScrArea *area, ScrArea *sb) return -1; } +/* Get alignment offset of adjacent areas. 'dir' value is like area_getorientation(). */ +void area_getoffsets(ScrArea *area, ScrArea *sb, const int dir, int *offset1, int *offset2) +{ + if (area == NULL || sb == NULL) { + *offset1 = INT_MAX; + *offset2 = INT_MAX; + } + else if (dir == 0) { /* West: sa on right and sb to the left. */ + *offset1 = sb->v3->vec.y - area->v2->vec.y; + *offset2 = sb->v4->vec.y - area->v1->vec.y; + } + else if (dir == 1) { /* North: sa below and sb above. */ + *offset1 = area->v2->vec.x - sb->v1->vec.x; + *offset2 = area->v3->vec.x - sb->v4->vec.x; + } + else if (dir == 2) { /* East: sa on left and sb to the right. */ + *offset1 = sb->v2->vec.y - area->v3->vec.y; + *offset2 = sb->v1->vec.y - area->v4->vec.y; + } + else if (dir == 3) { /* South: sa above and sb below. */ + *offset1 = area->v1->vec.x - sb->v2->vec.x; + *offset2 = area->v4->vec.x - sb->v3->vec.x; + } + else { + *offset1 = INT_MAX; + *offset2 = INT_MAX; + } +} + /* Screen verts with horizontal position equal to from_x are moved to to_x. */ static void screen_verts_halign(const wmWindow *win, const bScreen *screen, @@ -390,18 +414,24 @@ static void screen_areas_align( } } -/* Helper function to join 2 areas, it has a return value, 0=failed 1=success - * used by the split, join operators - */ -int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2) +/* Simple join of two areas without any splitting. Will return false if not possible. */ +static bool screen_area_join_aligned(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2) { int dir = area_getorientation(sa1, sa2); - if (dir == -1) { - return 0; + return false; + } + + int offset1; + int offset2; + area_getoffsets(sa1, sa2, dir, &offset1, &offset2); + + int tolerance = ELEM(dir, 0, 2) ? AREAJOINTOLERANCEY : AREAJOINTOLERANCEX; + if ((abs(offset1) >= tolerance) || (abs(offset2) >= tolerance)) { + return false; } - /* Align areas if they are not. Do sanity checking before getting here. */ + /* Align areas if they are not. */ screen_areas_align(C, screen, sa1, sa2, dir); if (dir == 0) { /* sa1 to right of sa2 = W */ @@ -434,7 +464,107 @@ int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2) /* Update preview thumbnail */ BKE_icon_changed(screen->id.icon_id); - return 1; + return true; +} + +/* Slice off and return new area. "Reverse" gives right/bottom, rather than left/top. */ +static ScrArea *screen_area_trim( + bContext *C, bScreen *screen, ScrArea **area, int size, int dir, bool reverse) +{ + bool vertical = ELEM(dir, 1, 3); + if (abs(size) < (vertical ? AREAJOINTOLERANCEX : AREAJOINTOLERANCEY)) { + return NULL; + } + + /* Measurement with ScrVerts because winx and winy might not be correct at this time. */ + float fac = abs(size) / (float)(vertical ? ((*area)->v3->vec.x - (*area)->v1->vec.x) : + ((*area)->v3->vec.y - (*area)->v1->vec.y)); + fac = (reverse == vertical) ? 1.0f - fac : fac; + ScrArea *newsa = area_split(CTX_wm_window(C), screen, *area, vertical ? 'v' : 'h', fac, 1); + + /* area_split always returns smallest of the two areas, so might have to swap. */ + if (((fac > 0.5f) == vertical) != reverse) { + ScrArea *temp = *area; + *area = newsa; + newsa = temp; + } + + return newsa; +} + +/* Join any two neighboring areas. Might create new areas, kept if over min_remainder. */ +static bool screen_area_join_ex( + bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2, bool close_all_remainders) +{ + int dir = area_getorientation(sa1, sa2); + if (dir == -1) { + return false; + } + + int offset1; + int offset2; + area_getoffsets(sa1, sa2, dir, &offset1, &offset2); + + /* Split Left/Top into new area if overhanging. */ + ScrArea *side1 = screen_area_trim(C, screen, (offset1 > 0) ? &sa2 : &sa1, offset1, dir, false); + + /* Split Right/Bottom into new area if overhanging. */ + ScrArea *side2 = screen_area_trim(C, screen, (offset2 > 0) ? &sa1 : &sa2, offset2, dir, true); + + /* The two areas now line up, so join them. */ + screen_area_join_aligned(C, screen, sa1, sa2); + + if (close_all_remainders || offset1 < 0 || offset2 > 0) { + /* Close both if trimiming sa1. */ + screen_area_close(C, screen, side1); + screen_area_close(C, screen, side2); + } + + BKE_icon_changed(screen->id.icon_id); + return true; +} + +/* Join any two neighboring areas. Might involve complex changes. */ +int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2) +{ + return screen_area_join_ex(C, screen, sa1, sa2, false); +} + +/* Close a screen area, allowing any neighbor to take its place. */ +bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area) +{ + if (area == NULL) { + return false; + } + + ScrArea *sa2 = NULL; + + /* Find the most-aligned joinable area. Larger size breaks ties. */ + int min_alignment = INT_MAX; + int max_size = 0; + LISTBASE_FOREACH (ScrArea *, ar, &screen->areabase) { + int dir = area_getorientation(area, ar); + if (dir != -1) { + int offset1; + int offset2; + area_getoffsets(area, ar, dir, &offset1, &offset2); + int area_alignment = abs(offset1) + abs(offset2); + if (area_alignment < min_alignment) { + min_alignment = area_alignment; + max_size = ar->winx * ar->winy; + sa2 = ar; + } + else if (area_alignment == min_alignment) { + int area_size = ar->winx * ar->winy; + if (area_size > max_size) { + max_size = area_size; + sa2 = ar; + } + } + } + } + + return screen_area_join_ex(C, screen, sa2, area, true); } /* ****************** EXPORTED API TO OTHER MODULES *************************** */ diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index c51ff559786..cda7ba6a4a9 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -34,7 +34,9 @@ struct bContextDataResult; #define AZONEFADEIN (5.0f * U.widget_unit) /* when #AZone is totally visible */ #define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the #AZone */ -#define AREAJOINTOLERANCE (1.0f * U.widget_unit) /* Edges must be close to allow joining. */ +/* Edges must be within these to allow joining. */ +#define AREAJOINTOLERANCEX (AREAMINX * U.dpi_fac) +#define AREAJOINTOLERANCEY (HEADERY * U.dpi_fac) /* Expanded interaction influence of area borders. */ #define BORDERPADDING (U.dpi_fac + U.pixelsize) @@ -58,7 +60,8 @@ ScrArea *area_split( const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge); int screen_area_join(struct bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2); int area_getorientation(ScrArea *area, ScrArea *sb); - +void area_getoffsets(ScrArea *area, ScrArea *sb, const int dir, int *offset1, int *offset2); +bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area); struct AZone *ED_area_actionzone_find_xy(ScrArea *area, const int xy[2]); /* screen_geometry.c */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5cd4e8c353b..c19049b49e2 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1386,6 +1386,58 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Area Close Operator + * + * Close selected area, replace by expanding a neighbor + * \{ */ + +/* operator callback */ +static int area_close_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +{ + ScrArea *area = CTX_wm_area(C); + if ((area != NULL) && screen_area_close(C, CTX_wm_screen(C), area)) { + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + return OPERATOR_FINISHED; + } + return OPERATOR_CANCELLED; +} + +static bool area_close_poll(bContext *C) +{ + if (!ED_operator_areaactive(C)) { + return false; + } + + ScrArea *area = CTX_wm_area(C); + + if (ED_area_is_global(area)) { + return false; + } + + bScreen *screen = CTX_wm_screen(C); + + /* Can this area join with ANY other area? */ + LISTBASE_FOREACH (ScrArea *, ar, &screen->areabase) { + if (area_getorientation(ar, area) != -1) { + return true; + } + } + + return false; +} + +static void SCREEN_OT_area_close(wmOperatorType *ot) +{ + ot->name = "Close Area"; + ot->description = "Close selected area"; + ot->idname = "SCREEN_OT_area_close"; + ot->invoke = area_close_invoke; + ot->poll = area_close_poll; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Move Area Edge Operator * \{ */ @@ -3212,7 +3264,7 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot) typedef struct sAreaJoinData { ScrArea *sa1; /* first area to be considered */ ScrArea *sa2; /* second area to be considered */ - void *draw_callback; /* call `ED_screen_draw_join_shape` */ + void *draw_callback; /* call 'ED_screen_draw_join_highlight' */ } sAreaJoinData; @@ -3222,7 +3274,7 @@ static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata sAreaJoinData *sd = op->customdata; if (sd->sa1 && sd->sa2) { - ED_screen_draw_join_shape(sd->sa1, sd->sa2); + ED_screen_draw_join_highlight(sd->sa1, sd->sa2); } } @@ -4069,6 +4121,69 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot) /** \name Region Context Menu Operator (Header/Footer/Navbar) * \{ */ +static void screen_area_menu_items(ScrArea *area, uiLayout *layout) +{ + if (ED_area_is_global(area)) { + return; + } + + PointerRNA ptr; + + /* Mouse position as if in middle of area. */ + const int loc[2] = {BLI_rcti_cent_x(&area->totrct), BLI_rcti_cent_y(&area->totrct)}; + + /* Vertical Split */ + uiItemFullO(layout, + "SCREEN_OT_area_split", + IFACE_("Vertical Split"), + ICON_NONE, + NULL, + WM_OP_INVOKE_DEFAULT, + 0, + &ptr); + + RNA_int_set_array(&ptr, "cursor", loc); + RNA_enum_set(&ptr, "direction", 'v'); + + /* Horizontal Split */ + uiItemFullO(layout, + "SCREEN_OT_area_split", + IFACE_("Horizontal Split"), + ICON_NONE, + NULL, + WM_OP_INVOKE_DEFAULT, + 0, + &ptr); + + RNA_int_set_array(&ptr, "cursor", &loc[0]); + RNA_enum_set(&ptr, "direction", 'h'); + + uiItemS(layout); + + if (area->spacetype != SPACE_FILE) { + uiItemO(layout, + area->full ? IFACE_("Restore Areas") : IFACE_("Maximize Area"), + ICON_NONE, + "SCREEN_OT_screen_full_area"); + + if (!area->full) { + uiItemFullO(layout, + "SCREEN_OT_screen_full_area", + IFACE_("Full Screen Area"), + ICON_NONE, + NULL, + WM_OP_INVOKE_DEFAULT, + 0, + &ptr); + RNA_boolean_set(&ptr, "use_hide_panels", true); + } + } + + uiItemO(layout, NULL, ICON_NONE, "SCREEN_OT_area_dupli"); + uiItemS(layout); + uiItemO(layout, NULL, ICON_NONE, "SCREEN_OT_area_close"); +} + void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) { ScrArea *area = CTX_wm_area(C); @@ -4102,17 +4217,9 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN if (!ELEM(area->spacetype, SPACE_TOPBAR)) { uiItemS(layout); - uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); - } - - /* File browser should be fullscreen all the time, top-bar should - * never be. But other regions can be maximized/restored. */ - if (!ELEM(area->spacetype, SPACE_FILE, SPACE_TOPBAR)) { uiItemS(layout); - - const char *but_str = area->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); - uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); + screen_area_menu_items(area, layout); } } @@ -4134,14 +4241,8 @@ void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UN uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); - /* File browser should be fullscreen all the time, top-bar should - * never be. But other regions can be maximized/restored... */ - if (!ELEM(area->spacetype, SPACE_FILE, SPACE_TOPBAR)) { - uiItemS(layout); - - const char *but_str = area->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); - uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); - } + uiItemS(layout); + screen_area_menu_items(area, layout); } void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) @@ -5461,6 +5562,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_area_move); WM_operatortype_append(SCREEN_OT_area_split); WM_operatortype_append(SCREEN_OT_area_join); + WM_operatortype_append(SCREEN_OT_area_close); WM_operatortype_append(SCREEN_OT_area_options); WM_operatortype_append(SCREEN_OT_area_dupli); WM_operatortype_append(SCREEN_OT_area_swap); -- cgit v1.2.3 From cfa20ff03bdeb87b1625196d58a1dbe0e22cc2f9 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Thu, 22 Apr 2021 20:08:17 -0700 Subject: Fix T86566: Do Not Close if File Cannot Be Saved If saving a file using CloseSave dialog, do not close if there is an error doing so, like if read-only. Differential Revision: https://developer.blender.org/D10722 Reviewed by Julian Eisel --- source/blender/windowmanager/intern/wm_files.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 614824ef7e2..d0ee7075516 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -3265,7 +3265,10 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat bool file_has_been_saved_before = BKE_main_blendfile_path(bmain)[0] != '\0'; if (file_has_been_saved_before) { - WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL); + if (WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL) & + OPERATOR_CANCELLED) { + execute_callback = false; + } } else { WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_INVOKE_DEFAULT, NULL); -- cgit v1.2.3 From dc1e98d8a041e161a7bbda97cfac3df57d0ff320 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 23 Apr 2021 17:05:41 +1000 Subject: Fix T86765: Custom properties are included in `__dir__` Remove custom properties from `__dir__` method result since these can't be accessed using `__getattr__`. Introduced in the 2.5x Python API update. --- source/blender/python/intern/bpy_rna.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source/blender') diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index b9ab0ce4c29..354aa9b6986 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4207,6 +4207,10 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr) iterprop = RNA_struct_iterator_property(ptr->type); RNA_PROP_BEGIN (ptr, itemptr, iterprop) { + /* Custom-properties are exposed using `__getitem__`, exclude from `__dir__`. */ + if (RNA_property_is_idprop(itemptr.data)) { + continue; + } nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { -- cgit v1.2.3 From 2f6219c48df4e39addca3b462d5a753c71a1374e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 23 Apr 2021 10:02:53 +0200 Subject: Fix T78845: Eevee wrong material selection. In cases where the same node tree is used in different materials with small changes, the wrong material could be selected. Cause: Hair shaders GPU resources weren't updated and used the previous bound data. Reviewed By: fclem Differential Revision: https://developer.blender.org/D11036 --- source/blender/draw/engines/eevee/eevee_materials.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender') diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index f05aa562e6b..131f9a954cf 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -765,12 +765,15 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata, if (matcache.depth_grp) { *matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp); + DRW_shgroup_add_material_resources(*matcache.depth_grp_p, matcache.shading_gpumat); } if (matcache.shading_grp) { *matcache.shading_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shading_grp); + DRW_shgroup_add_material_resources(*matcache.shading_grp_p, matcache.shading_gpumat); } if (matcache.shadow_grp) { *matcache.shadow_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.shadow_grp); + DRW_shgroup_add_material_resources(*matcache.shadow_grp_p, matcache.shading_gpumat); *cast_shadow = true; } -- cgit v1.2.3 From 425e19bc1fca91116d5fceb7e994bdbf7656acc2 Mon Sep 17 00:00:00 2001 From: Jagannadhan Ravi Date: Fri, 23 Apr 2021 10:06:46 +0200 Subject: Modifiers: Performance Simple Deformation Use multiprocessing with simple deform modifiers. Master 2.92 fps this patch 3.13 fps on Ryzen 1700X With Vega 64 GPU. 3970X: 2.85 fps -> 2.95 fps 3990X: 3.15 fps -> 3.41 fps 3995WX: 3.21 fps -> 3.38 fps Reviewed By: jbakker Differential Revision: https://developer.blender.org/D10609 --- source/blender/blenlib/BLI_compiler_attrs.h | 7 + source/blender/modifiers/intern/MOD_simpledeform.c | 183 +++++++++++++-------- 2 files changed, 120 insertions(+), 70 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h index 680c4bc78da..4b5a7d671f2 100644 --- a/source/blender/blenlib/BLI_compiler_attrs.h +++ b/source/blender/blenlib/BLI_compiler_attrs.h @@ -98,3 +98,10 @@ #else # define ATTR_ALIGN(x) __attribute__((aligned(x))) #endif + +/* Alignment directive */ +#ifdef _WIN64 +# define ALIGN_STRUCT __declspec(align(64)) +#else +# define ALIGN_STRUCT +#endif diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index ea31bdc6e31..f9d1d5ae566 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -22,9 +22,8 @@ */ #include "BLI_utildefines.h" - #include "BLI_math.h" - +#include "BLI_task.h" #include "BLT_translation.h" #include "DNA_defaults.h" @@ -57,6 +56,21 @@ #define BEND_EPS 0.000001f +ALIGN_STRUCT struct DeformUserData { + bool invert_vgroup; + char mode; + char deform_axis; + int lock_axis; + int vgroup; + int limit_axis; + float weight; + float smd_factor; + float smd_limit[2]; + float (*vertexCos)[3]; + SpaceTransform *transf; + MDeformVert *dvert; +}; + /* Re-maps the indices for X Y Z by shifting them up and wrapping, such that * X = Y, Y = Z, Z = X (for X axis), and X = Z, Y = X, Z = Y (for Y axis). This * exists because the deformations (excluding bend) are based on the Z axis. @@ -203,6 +217,86 @@ static void simpleDeform_bend(const float factor, } } +static void simple_helper(void *__restrict userdata, + const int iter, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + struct DeformUserData *curr_deform_data = userdata; + float weight = BKE_defvert_array_find_weight_safe(curr_deform_data->dvert, iter, curr_deform_data->vgroup); + const uint *axis_map = axis_map_table[(curr_deform_data->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? + curr_deform_data->deform_axis : + 2]; + const float base_limit[2] = {0.0f, 0.0f}; + + if (curr_deform_data->invert_vgroup) { + weight = 1.0f - weight; + } + + if (weight != 0.0f) { + float co[3], dcut[3] = {0.0f, 0.0f, 0.0f}; + + if (curr_deform_data->transf) { + BLI_space_transform_apply(curr_deform_data->transf, curr_deform_data->vertexCos[iter]); + } + + copy_v3_v3(co, curr_deform_data->vertexCos[iter]); + + /* Apply axis limits, and axis mappings */ + if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) { + axis_limit(0, base_limit, co, dcut); + } + if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) { + axis_limit(1, base_limit, co, dcut); + } + if (curr_deform_data->lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) { + axis_limit(2, base_limit, co, dcut); + } + axis_limit(curr_deform_data->limit_axis, curr_deform_data->smd_limit, co, dcut); + + /* apply the deform to a mapped copy of the vertex, and then re-map it back. */ + float co_remap[3]; + float dcut_remap[3]; + copy_v3_v3_map(co_remap, co, axis_map); + copy_v3_v3_map(dcut_remap, dcut, axis_map); + switch (curr_deform_data->mode) { + case MOD_SIMPLEDEFORM_MODE_TWIST: + simpleDeform_twist(curr_deform_data->smd_factor, + curr_deform_data->deform_axis, + dcut_remap, + co_remap); /* apply deform */ + break; + case MOD_SIMPLEDEFORM_MODE_BEND: + simpleDeform_bend(curr_deform_data->smd_factor, + curr_deform_data->deform_axis, + dcut_remap, + co_remap); /* apply deform */ + break; + case MOD_SIMPLEDEFORM_MODE_TAPER: + simpleDeform_taper(curr_deform_data->smd_factor, + curr_deform_data->deform_axis, + dcut_remap, + co_remap); /* apply deform */ + break; + case MOD_SIMPLEDEFORM_MODE_STRETCH: + simpleDeform_stretch(curr_deform_data->smd_factor, + curr_deform_data->deform_axis, + dcut_remap, + co_remap); /* apply deform */ + break; + default: + return; /* No simple-deform mode? */ + } + copy_v3_v3_unmap(co, co_remap, axis_map); + + /* Use vertex weight has coef of linear interpolation */ + interp_v3_v3v3(curr_deform_data->vertexCos[iter], curr_deform_data->vertexCos[iter], co, weight); + + if (curr_deform_data->transf) { + BLI_space_transform_invert(curr_deform_data->transf, curr_deform_data->vertexCos[iter]); + } + } +} + /* simple deform modifier */ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, const ModifierEvalContext *UNUSED(ctx), @@ -211,14 +305,9 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, float (*vertexCos)[3], int numVerts) { - const float base_limit[2] = {0.0f, 0.0f}; int i; float smd_limit[2], smd_factor; SpaceTransform *transf = NULL, tmp_transf; - void (*simpleDeform_callback)(const float factor, - const int axis, - const float dcut[3], - float co[3]) = NULL; /* Mode callback */ int vgroup; MDeformVert *dvert; @@ -300,23 +389,6 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, smd_factor = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]); } - switch (smd->mode) { - case MOD_SIMPLEDEFORM_MODE_TWIST: - simpleDeform_callback = simpleDeform_twist; - break; - case MOD_SIMPLEDEFORM_MODE_BEND: - simpleDeform_callback = simpleDeform_bend; - break; - case MOD_SIMPLEDEFORM_MODE_TAPER: - simpleDeform_callback = simpleDeform_taper; - break; - case MOD_SIMPLEDEFORM_MODE_STRETCH: - simpleDeform_callback = simpleDeform_stretch; - break; - default: - return; /* No simple-deform mode? */ - } - if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) { if (fabsf(smd_factor) < BEND_EPS) { return; @@ -325,53 +397,24 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, MOD_get_vgroup(ob, mesh, smd->vgroup_name, &dvert, &vgroup); const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0; - const uint *axis_map = - axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2]; - - for (i = 0; i < numVerts; i++) { - float weight = BKE_defvert_array_find_weight_safe(dvert, i, vgroup); - - if (invert_vgroup) { - weight = 1.0f - weight; - } - - if (weight != 0.0f) { - float co[3], dcut[3] = {0.0f, 0.0f, 0.0f}; - if (transf) { - BLI_space_transform_apply(transf, vertexCos[i]); - } - - copy_v3_v3(co, vertexCos[i]); - - /* Apply axis limits, and axis mappings */ - if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) { - axis_limit(0, base_limit, co, dcut); - } - if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) { - axis_limit(1, base_limit, co, dcut); - } - if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) { - axis_limit(2, base_limit, co, dcut); - } - axis_limit(limit_axis, smd_limit, co, dcut); - - /* apply the deform to a mapped copy of the vertex, and then re-map it back. */ - float co_remap[3]; - float dcut_remap[3]; - copy_v3_v3_map(co_remap, co, axis_map); - copy_v3_v3_map(dcut_remap, dcut, axis_map); - simpleDeform_callback(smd_factor, deform_axis, dcut_remap, co_remap); /* apply deform */ - copy_v3_v3_unmap(co, co_remap, axis_map); - - /* Use vertex weight has coef of linear interpolation */ - interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); - - if (transf) { - BLI_space_transform_invert(transf, vertexCos[i]); - } - } - } + // build our data + struct DeformUserData deform_pool_data = {.mode = smd->mode, + .smd_factor = smd_factor, + .deform_axis = deform_axis, + .transf = transf, + .vertexCos = vertexCos, + .invert_vgroup = invert_vgroup, + .lock_axis = lock_axis, + .vgroup = vgroup, + .smd_limit[0] = smd_limit[0], + .smd_limit[1] = smd_limit[1], + .dvert = dvert, + .limit_axis = limit_axis}; + /* Do deformation. */ + TaskParallelSettings settings; + BLI_parallel_range_settings_defaults(&settings); + BLI_task_parallel_range(0, numVerts, &deform_pool_data, simple_helper, &settings); } /* SimpleDeform */ -- cgit v1.2.3 From f8e1526fa61b8a79b6514e4f265586732d28280d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 23 Apr 2021 12:44:21 +0200 Subject: Fix T87661: Attribute Combine XYZ node can't overwrite existing attribute --- source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender') diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc index 69e628267a4..d7ed8b6caf8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_combine_xyz.cc @@ -112,6 +112,7 @@ static void combine_attributes(GeometryComponent &component, const GeoNodeExecPa const float z = attribute_z[i]; attribute_result->set(i, {x, y, z}); } + attribute_result.save(); } static void geo_node_attribute_combine_xyz_exec(GeoNodeExecParams params) -- cgit v1.2.3 From 4cb8438e08cb64d755f627c8eeb3e8cda73864f1 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 23 Apr 2021 12:44:59 +0200 Subject: Geometry Nodes: warn when output attribute has not been saved --- source/blender/blenkernel/BKE_attribute_access.hh | 5 +++++ source/blender/blenkernel/intern/attribute_access.cc | 10 ++++++++++ 2 files changed, 15 insertions(+) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh index f6a6de04b70..5feae1bf4ca 100644 --- a/source/blender/blenkernel/BKE_attribute_access.hh +++ b/source/blender/blenkernel/BKE_attribute_access.hh @@ -94,6 +94,7 @@ class OutputAttribute { SaveFn save_; std::optional optional_span_varray_; bool ignore_old_values_ = false; + bool save_has_been_called_ = false; public: OutputAttribute() = default; @@ -109,6 +110,10 @@ class OutputAttribute { { } + OutputAttribute(OutputAttribute &&other) = default; + + ~OutputAttribute(); + operator bool() const { return varray_.get() != nullptr; diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 6c37d34dc9b..5b2f588959f 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -184,6 +184,7 @@ AttributeDomain attribute_domain_highest_priority(Span domains) void OutputAttribute::save() { + save_has_been_called_ = true; if (optional_span_varray_.has_value()) { optional_span_varray_->save(); } @@ -192,6 +193,15 @@ void OutputAttribute::save() } } +OutputAttribute::~OutputAttribute() +{ + if (!save_has_been_called_) { + if (varray_) { + std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n"; + } + } +} + GVArrayPtr BuiltinCustomDataLayerProvider::try_get_for_read( const GeometryComponent &component) const { -- cgit v1.2.3 From 5441f5fc90c600aa5bbd08c8cd212fb0734f86cc Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 23 Apr 2021 13:07:29 +0200 Subject: Fix T87582: incorrect interpolation from edge to corner domain --- source/blender/blenkernel/intern/geometry_component_mesh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 150cc4589c8..5697fb2ccde 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -547,7 +547,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, /* For every corner, mix the values from the adjacent edges on the face. */ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const int loop_index_prev = (loop_index - 1) % poly.totloop; + const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop; const MLoop &loop = mesh.mloop[loop_index]; const MLoop &loop_prev = mesh.mloop[loop_index_prev]; mixer.mix_in(loop_index, old_values[loop.e]); -- cgit v1.2.3 From 9afa738542881cf69aa89fd893351200324c107f Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 23 Apr 2021 12:28:54 +0200 Subject: Fix bug/crash in ID bulk deletion code. This is complex situation. Tagged ID deletion (used to delete several data-blocks at once) removes IDs to be deleted from Main. But when we remove deleted IDs' usages of other IDs (using `BKE_libblock_relink_ex`), some specific post-process is required on some types, like Collections. Those post-processes would in some cases rely on data actually being in Main. That failing condition would lead in existing code on missing processing the very ID (collection) we were working on, leading to missing removing some child collection pointers, leading to the crash (later on in LayerCollection resync process). For now we go with an optimization & fix that avoids processing all collections in Main when we actually know which one we are working one (case of `BKE_libblock_relink_ex`, but not of `BKE_libblock_remap_locked`). This is however yet another demonstration of the need to rework that whole collection/layer resync process, since it is not only extremely inneficient currently, but it also requires valid Main/ID state way too deep into the remapping code. NOTE: This fix may very well not catch/address all possible fail cases here, dealing with the double parent/child relationships of collections is challenging... Issue reported by @eyecandy from the studio, thanks. --- source/blender/blenkernel/BKE_collection.h | 4 ++- source/blender/blenkernel/intern/collection.c | 49 ++++++++++++++++----------- source/blender/blenkernel/intern/lib_remap.c | 15 +++++--- 3 files changed, 43 insertions(+), 25 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 3412be92a3a..7963d54126e 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -112,7 +112,9 @@ bool BKE_scene_collections_object_remove(struct Main *bmain, struct Object *object, const bool free_us); void BKE_collections_object_remove_nulls(struct Main *bmain); -void BKE_collections_child_remove_nulls(struct Main *bmain, struct Collection *old_collection); +void BKE_collections_child_remove_nulls(struct Main *bmain, + struct Collection *parent_collection, + struct Collection *child_collection); /* Dependencies. */ diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 89bb7b36406..b29dd007c51 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -1302,41 +1302,50 @@ static void collection_missing_parents_remove(Collection *collection) * * \note caller must ensure #BKE_main_collection_sync_remap() is called afterwards! * - * \param collection: may be \a NULL, + * \param parent_collection: The collection owning the pointers that were remapped. May be \a NULL, + * in which case whole \a bmain database of collections is checked. + * \param child_collection: The collection that was remapped to another pointer. May be \a NULL, * in which case whole \a bmain database of collections is checked. */ -void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection) -{ - if (collection == NULL) { - /* We need to do the checks in two steps when more than one collection may be involved, - * otherwise we can miss some cases... - * Also, master collections are not in bmain, so we also need to loop over scenes. - */ - for (collection = bmain->collections.first; collection != NULL; - collection = collection->id.next) { - collection_null_children_remove(collection); - } - for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { - collection_null_children_remove(scene->master_collection); +void BKE_collections_child_remove_nulls(Main *bmain, + Collection *parent_collection, + Collection *child_collection) +{ + if (child_collection == NULL) { + if (parent_collection != NULL) { + collection_null_children_remove(parent_collection); + } + else { + /* We need to do the checks in two steps when more than one collection may be involved, + * otherwise we can miss some cases... + * Also, master collections are not in bmain, so we also need to loop over scenes. + */ + for (child_collection = bmain->collections.first; child_collection != NULL; + child_collection = child_collection->id.next) { + collection_null_children_remove(child_collection); + } + for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { + collection_null_children_remove(scene->master_collection); + } } - for (collection = bmain->collections.first; collection != NULL; - collection = collection->id.next) { - collection_missing_parents_remove(collection); + for (child_collection = bmain->collections.first; child_collection != NULL; + child_collection = child_collection->id.next) { + collection_missing_parents_remove(child_collection); } for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { collection_missing_parents_remove(scene->master_collection); } } else { - for (CollectionParent *parent = collection->parents.first, *parent_next; parent; + for (CollectionParent *parent = child_collection->parents.first, *parent_next; parent; parent = parent_next) { parent_next = parent->next; collection_null_children_remove(parent->collection); - if (!collection_find_child(parent->collection, collection)) { - BLI_freelinkN(&collection->parents, parent); + if (!collection_find_child(parent->collection, child_collection)) { + BLI_freelinkN(&child_collection->parents, parent); } } } diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c index 1f597bbb9a6..b32b97dc250 100644 --- a/source/blender/blenkernel/intern/lib_remap.c +++ b/source/blender/blenkernel/intern/lib_remap.c @@ -303,6 +303,7 @@ static void libblock_remap_data_postprocess_object_update(Main *bmain, /* Can be called with both old_collection and new_collection being NULL, * this means we have to check whole Main database then. */ static void libblock_remap_data_postprocess_collection_update(Main *bmain, + Collection *owner_collection, Collection *UNUSED(old_collection), Collection *new_collection) { @@ -311,7 +312,7 @@ static void libblock_remap_data_postprocess_collection_update(Main *bmain, * and BKE_main_collection_sync_remap() does not tolerate any of those, so for now always check * whole existing collections for NULL pointers. * I'd consider optimizing that whole collection remapping process a TODO for later. */ - BKE_collections_child_remove_nulls(bmain, NULL /*old_collection*/); + BKE_collections_child_remove_nulls(bmain, owner_collection, NULL /*old_collection*/); } else { /* Temp safe fix, but a "tad" brute force... We should probably be able to use parents from @@ -523,7 +524,7 @@ void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const break; case ID_GR: libblock_remap_data_postprocess_collection_update( - bmain, (Collection *)old_id, (Collection *)new_id); + bmain, NULL, (Collection *)old_id, (Collection *)new_id); break; case ID_ME: case ID_CU: @@ -628,6 +629,12 @@ void BKE_libblock_relink_ex( switch (GS(id->name)) { case ID_SCE: case ID_GR: { + /* Note: here we know which collection we have affected, so at lest for NULL children + * detection we can only process that one. + * This is also a required fix in case `id` would not be in Main anymore, which can happen + * e.g. when called from `id_delete`. */ + Collection *owner_collection = (GS(id->name) == ID_GR) ? (Collection *)id : + ((Scene *)id)->master_collection; if (old_id) { switch (GS(old_id->name)) { case ID_OB: @@ -636,7 +643,7 @@ void BKE_libblock_relink_ex( break; case ID_GR: libblock_remap_data_postprocess_collection_update( - bmain, (Collection *)old_id, (Collection *)new_id); + bmain, owner_collection, (Collection *)old_id, (Collection *)new_id); break; default: break; @@ -644,7 +651,7 @@ void BKE_libblock_relink_ex( } else { /* No choice but to check whole objects/collections. */ - libblock_remap_data_postprocess_collection_update(bmain, NULL, NULL); + libblock_remap_data_postprocess_collection_update(bmain, owner_collection, NULL, NULL); libblock_remap_data_postprocess_object_update(bmain, NULL, NULL); } break; -- cgit v1.2.3 From 877711e9e45f2cf2484e0112ae0404992e675cff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 24 Apr 2021 00:02:44 +1000 Subject: Cleanup: use const arguments, reduce right shift --- source/blender/modifiers/intern/MOD_simpledeform.c | 44 ++++++++++++---------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'source/blender') diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index f9d1d5ae566..71ecc69eccb 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -21,9 +21,9 @@ * \ingroup modifiers */ -#include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_task.h" +#include "BLI_utildefines.h" #include "BLT_translation.h" #include "DNA_defaults.h" @@ -67,8 +67,8 @@ ALIGN_STRUCT struct DeformUserData { float smd_factor; float smd_limit[2]; float (*vertexCos)[3]; - SpaceTransform *transf; - MDeformVert *dvert; + const SpaceTransform *transf; + const MDeformVert *dvert; }; /* Re-maps the indices for X Y Z by shifting them up and wrapping, such that @@ -221,8 +221,9 @@ static void simple_helper(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls)) { - struct DeformUserData *curr_deform_data = userdata; - float weight = BKE_defvert_array_find_weight_safe(curr_deform_data->dvert, iter, curr_deform_data->vgroup); + const struct DeformUserData *curr_deform_data = userdata; + float weight = BKE_defvert_array_find_weight_safe( + curr_deform_data->dvert, iter, curr_deform_data->vgroup); const uint *axis_map = axis_map_table[(curr_deform_data->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? curr_deform_data->deform_axis : 2]; @@ -289,7 +290,8 @@ static void simple_helper(void *__restrict userdata, copy_v3_v3_unmap(co, co_remap, axis_map); /* Use vertex weight has coef of linear interpolation */ - interp_v3_v3v3(curr_deform_data->vertexCos[iter], curr_deform_data->vertexCos[iter], co, weight); + interp_v3_v3v3( + curr_deform_data->vertexCos[iter], curr_deform_data->vertexCos[iter], co, weight); if (curr_deform_data->transf) { BLI_space_transform_invert(curr_deform_data->transf, curr_deform_data->vertexCos[iter]); @@ -398,23 +400,25 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, MOD_get_vgroup(ob, mesh, smd->vgroup_name, &dvert, &vgroup); const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0; - // build our data - struct DeformUserData deform_pool_data = {.mode = smd->mode, - .smd_factor = smd_factor, - .deform_axis = deform_axis, - .transf = transf, - .vertexCos = vertexCos, - .invert_vgroup = invert_vgroup, - .lock_axis = lock_axis, - .vgroup = vgroup, - .smd_limit[0] = smd_limit[0], - .smd_limit[1] = smd_limit[1], - .dvert = dvert, - .limit_axis = limit_axis}; + /* Build our data. */ + const struct DeformUserData deform_pool_data = { + .mode = smd->mode, + .smd_factor = smd_factor, + .deform_axis = deform_axis, + .transf = transf, + .vertexCos = vertexCos, + .invert_vgroup = invert_vgroup, + .lock_axis = lock_axis, + .vgroup = vgroup, + .smd_limit[0] = smd_limit[0], + .smd_limit[1] = smd_limit[1], + .dvert = dvert, + .limit_axis = limit_axis, + }; /* Do deformation. */ TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - BLI_task_parallel_range(0, numVerts, &deform_pool_data, simple_helper, &settings); + BLI_task_parallel_range(0, numVerts, (void *)&deform_pool_data, simple_helper, &settings); } /* SimpleDeform */ -- cgit v1.2.3 From 23185262abe45ea71c77fe37488ef1a797159181 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 24 Apr 2021 00:03:14 +1000 Subject: Cleanup: clang-format --- source/blender/editors/interface/interface_handlers.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/windowmanager/wm_files.h | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4931b35ca75..5a254db0eec 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1120,7 +1120,7 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) data->cancel = true; return; } - + if (ui_but_string_set(C, but, data->str)) { data->value = ui_but_value_get(but); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c19049b49e2..cc920aece0a 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4219,7 +4219,7 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN uiItemS(layout); uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); uiItemS(layout); - screen_area_menu_items(area, layout); + screen_area_menu_items(area, layout); } } diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index 533084e96e8..c7fe07cad7f 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -45,7 +45,9 @@ void wm_homefile_read(struct bContext *C, void wm_file_read_report(bContext *C, struct Main *bmain); void wm_close_file_dialog(bContext *C, struct wmGenericCallback *post_action); -bool wm_operator_close_file_dialog_if_needed(bContext *C, wmOperator *op, wmGenericCallbackFn exec_fn); +bool wm_operator_close_file_dialog_if_needed(bContext *C, + wmOperator *op, + wmGenericCallbackFn exec_fn); bool wm_file_or_image_is_modified(const Main *bmain, const wmWindowManager *wm); void WM_OT_save_homefile(struct wmOperatorType *ot); -- cgit v1.2.3 From 5e509f966fa1aaee903703e10d6970ece21f8d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 23 Apr 2021 15:36:54 +0200 Subject: Cleanup: VSE, reduce cognitive complexity of sequencer_rendersize_exec() Reduce the cognitive complexity of the `sequencer_rendersize_exec()` function by flipping some conditions and returning early. No functional changes. --- .../editors/space_sequencer/sequencer_edit.c | 48 ++++++++++------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 52cfeeecb5c..f665225e8f5 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2274,43 +2274,39 @@ void SEQUENCER_OT_swap(wmOperatorType *ot) static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) { - int retval = OPERATOR_CANCELLED; Scene *scene = CTX_data_scene(C); Sequence *active_seq = SEQ_select_active_get(scene); StripElem *se = NULL; - if (active_seq == NULL) { + if (active_seq == NULL || active_seq->strip == NULL) { return OPERATOR_CANCELLED; } - if (active_seq->strip) { - switch (active_seq->type) { - case SEQ_TYPE_IMAGE: - se = SEQ_render_give_stripelem(active_seq, scene->r.cfra); - break; - case SEQ_TYPE_MOVIE: - se = active_seq->strip->stripdata; - break; - case SEQ_TYPE_SCENE: - case SEQ_TYPE_META: - case SEQ_TYPE_SOUND_RAM: - case SEQ_TYPE_SOUND_HD: - default: - break; - } + switch (active_seq->type) { + case SEQ_TYPE_IMAGE: + se = SEQ_render_give_stripelem(active_seq, scene->r.cfra); + break; + case SEQ_TYPE_MOVIE: + se = active_seq->strip->stripdata; + break; + default: + return OPERATOR_CANCELLED; } - if (se) { - /* Prevent setting the render size if sequence values aren't initialized. */ - if ((se->orig_width > 0) && (se->orig_height > 0)) { - scene->r.xsch = se->orig_width; - scene->r.ysch = se->orig_height; - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); - retval = OPERATOR_FINISHED; - } + if (se == NULL) { + return OPERATOR_CANCELLED; + } + + /* Prevent setting the render size if sequence values aren't initialized. */ + if (se->orig_width <= 0 || se->orig_height <= 0) { + return OPERATOR_CANCELLED; } - return retval; + scene->r.xsch = se->orig_width; + scene->r.ysch = se->orig_height; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + return OPERATOR_FINISHED; } void SEQUENCER_OT_rendersize(wmOperatorType *ot) -- cgit v1.2.3 From 8aa853763269c39b74d253f575e39357573d5f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 23 Apr 2021 16:39:21 +0200 Subject: VSE: reset strip transform with "Set Render Size" operator Reset the active strip offset and scale, in the "Set Render Size" operator (`SEQUENCER_OT_rendersize`). This ensures that the active strip will actually fit the new render size, which is what the operator is intended to achieve. --- source/blender/editors/space_sequencer/sequencer_edit.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source/blender') diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index f665225e8f5..7279fdd2da2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2305,7 +2305,13 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) scene->r.xsch = se->orig_width; scene->r.ysch = se->orig_height; + active_seq->strip->transform->scale_x = active_seq->strip->transform->scale_y = 1.0f; + active_seq->strip->transform->xofs = active_seq->strip->transform->yofs = 0.0f; + + SEQ_relations_invalidate_cache_preprocessed(scene, active_seq); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + return OPERATOR_FINISHED; } -- cgit v1.2.3 From c46367518827af5aebeb6377d0d04b59432b9107 Mon Sep 17 00:00:00 2001 From: Leon Leno Date: Fri, 23 Apr 2021 09:55:58 -0500 Subject: Fix T87749 (partially): Text jitter in buttons and spreadsheet editor This patch fixes jittering text when resizing regions of the UI as described in T87749. The jitter was caused by the text padding being stored as an integer which lead to inconsistent rounding. Most notably this patch fixes the jitter in the new spreadsheet editor, but not all occurrences of jitter described in T87749 (e.g. in UI lists) are addressed. Differential Revision: https://developer.blender.org/D11060 --- source/blender/editors/interface/interface_widgets.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e351cd30c14..8dbebe2a94c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2420,7 +2420,8 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, } if (!no_text_padding) { - const int text_padding = (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; + const int text_padding = round_fl_to_int((UI_TEXT_MARGIN_X * U.widget_unit) / + but->block->aspect); if (but->editstr) { rect->xmin += text_padding; } -- cgit v1.2.3 From be68d00c3663f5239a87120841874f468904a972 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 23 Apr 2021 16:58:30 +0200 Subject: GPencil: Change maximum value for Fill precission The old value of 5 was not enough for some situations. --- source/blender/makesdna/DNA_gpencil_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender') diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 8facdca2f9c..bf7b9d70fb6 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -47,7 +47,7 @@ struct Curve; #define GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE M_PI_2 #define GPENCIL_MIN_FILL_FAC 0.05f -#define GPENCIL_MAX_FILL_FAC 5.0f +#define GPENCIL_MAX_FILL_FAC 8.0f /* ***************************************** */ /* GP Stroke Points */ -- cgit v1.2.3 From e4cebec647fb7cfb09f359a33fee34c4ac13f074 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 23 Apr 2021 17:26:47 +0200 Subject: GPencil: Add Multiframe support to Move to Layer Reviewed By: mendio Maniphest Tasks: T87426 Differential Revision: https://developer.blender.org/D11013 --- source/blender/editors/gpencil/gpencil_edit.c | 83 ++++++++++++++------------- 1 file changed, 42 insertions(+), 41 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index a2a69d94ce9..3284230d8c6 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1818,18 +1818,13 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; - Scene *scene = CTX_data_scene(C); bGPDlayer *target_layer = NULL; ListBase strokes = {NULL, NULL}; int layer_num = RNA_int_get(op->ptr, "layer"); const bool use_autolock = (bool)(gpd->flag & GP_DATA_AUTOLOCK_LAYERS); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { - BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); - return OPERATOR_CANCELLED; - } - - /* if autolock enabled, disabled now */ + /* If autolock enabled, disabled now. */ if (use_autolock) { gpd->flag &= ~GP_DATA_AUTOLOCK_LAYERS; } @@ -1852,53 +1847,59 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* Extract all strokes to move to this layer - * NOTE: We need to do this in a two-pass system to avoid conflicts with strokes - * getting repeatedly moved - */ - CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - - /* skip if no frame with strokes, or if this is the layer we're moving strokes to */ - if ((gpl == target_layer) || (gpf == NULL)) { + /* Extract all strokes to move to this layer. */ + CTX_DATA_BEGIN (C, bGPDlayer *, gpl_src, editable_gpencil_layers) { + /* Skip if this is the layer we're moving strokes to. */ + if (gpl_src == target_layer) { continue; } + bGPDframe *init_gpf = (is_multiedit) ? gpl_src->frames.first : gpl_src->actframe; + for (bGPDframe *gpf_src = init_gpf; gpf_src; gpf_src = gpf_src->next) { + if ((gpf_src == gpl_src->actframe) || + ((gpf_src->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf_src == NULL) { + continue; + } - /* make copies of selected strokes, and deselect these once we're done */ - LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { + bGPDstroke *gpsn = NULL; + BLI_listbase_clear(&strokes); + for (bGPDstroke *gps = gpf_src->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + /* Skip strokes that are invalid for current view. */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* Check if the color is editable. */ + if (ED_gpencil_stroke_material_editable(ob, gpl_src, gps) == false) { + continue; + } - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } + if (gps->flag & GP_STROKE_SELECT) { + BLI_remlink(&gpf_src->strokes, gps); + BLI_addtail(&strokes, gps); + } + } + /* Paste them all in one go. */ + if (strokes.first) { + bGPDframe *gpf_dst = BKE_gpencil_layer_frame_get( + target_layer, gpf_src->framenum, GP_GETFRAME_ADD_NEW); - /* Check if the color is editable. */ - if (ED_gpencil_stroke_material_editable(ob, gpl, gps) == false) { - continue; + BLI_movelisttolist(&gpf_dst->strokes, &strokes); + BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL)); + } } - - /* TODO: Don't just move entire strokes - instead, only copy the selected portions... */ - if (gps->flag & GP_STROKE_SELECT) { - BLI_remlink(&gpf->strokes, gps); - BLI_addtail(&strokes, gps); + /* If not multi-edit, exit loop. */ + if (!is_multiedit) { + break; } } - - /* if new layer and autolock, lock old layer */ + /* If new layer and autolock, lock old layer. */ if ((layer_num == -1) && (use_autolock)) { - gpl->flag |= GP_LAYER_LOCKED; + gpl_src->flag |= GP_LAYER_LOCKED; } } CTX_DATA_END; - /* Paste them all in one go */ - if (strokes.first) { - bGPDframe *gpf = BKE_gpencil_layer_frame_get(target_layer, CFRA, GP_GETFRAME_ADD_NEW); - - BLI_movelisttolist(&gpf->strokes, &strokes); - BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL)); - } - /* back autolock status */ if (use_autolock) { gpd->flag |= GP_DATA_AUTOLOCK_LAYERS; -- cgit v1.2.3 From 2e513afe803d7388210516895aeb8f8d8fd73ccc Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 23 Apr 2021 17:42:56 +0200 Subject: GPencil: Fix unreported reproject error This bug was introduced in e1acefd45e23 --- source/blender/editors/gpencil/gpencil_edit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 3284230d8c6..d90f74fbf4f 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3815,13 +3815,13 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) } changed = true; - /* If not multi-edit, exit loop. */ - if (!is_multiedit) { - break; - } } } } + /* If not multi-edit, exit loop. */ + if (!is_multiedit) { + break; + } } } CTX_DATA_END; -- cgit v1.2.3