diff options
author | Hans Goudey <h.goudey@me.com> | 2021-08-27 07:15:27 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-08-27 07:15:27 +0300 |
commit | ad0dbde6536c1ac21554451ce922611287afafb9 (patch) | |
tree | 98e52be91df997110392aec094ff6489741a6412 | |
parent | ef2a48329d8db78d7c98580970fbe15a84334f38 (diff) | |
parent | 523bc981cfeecead5050e7af44bbe252c166d718 (diff) |
Merge branch 'master' into temp-geometry-nodes-fields
17 files changed, 668 insertions, 137 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index b273eee4e19..793c4a52350 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -342,6 +342,11 @@ class DATA_PT_gpencil_vertex_groups(ObjectButtonsPanel, Panel): col.operator("object.vertex_group_add", icon='ADD', text="") col.operator("object.vertex_group_remove", icon='REMOVE', text="").all = False + if group: + col.separator() + col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + if ob.vertex_groups: row = layout.row() diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index b52bfc81b7a..2e7b0ce532c 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -125,24 +125,13 @@ void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const cha eyedropper_draw_cursor_text_ex(x, y, name); } -void eyedropper_draw_cursor_text_region(const struct bContext *C, - const ARegion *region, - const char *name) +void eyedropper_draw_cursor_text_region(const int x, const int y, const char *name) { - wmWindow *win = CTX_wm_window(C); - const int x = win->eventstate->x; - const int y = win->eventstate->y; - - if ((name[0] == '\0') || (BLI_rcti_isect_pt(®ion->winrct, x, y) == false)) { + if (name[0] == '\0') { return; } - const int mval[2] = { - x - region->winrct.xmin, - y - region->winrct.ymin, - }; - - eyedropper_draw_cursor_text_ex(mval[0], mval[1], name); + eyedropper_draw_cursor_text_ex(x, y, name); } /** @@ -168,4 +157,25 @@ uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *ev return but; } +void datadropper_win_area_find( + const bContext *C, const int mval[2], int r_mval[2], wmWindow **r_win, ScrArea **r_area) +{ + bScreen *screen = CTX_wm_screen(C); + + *r_win = CTX_wm_window(C); + *r_area = BKE_screen_find_area_xy(screen, -1, mval[0], mval[1]); + if (*r_area == NULL) { + wmWindowManager *wm = CTX_wm_manager(C); + *r_win = WM_window_find_under_cursor(wm, NULL, *r_win, mval, r_mval); + if (*r_win) { + screen = WM_window_get_active_screen(*r_win); + *r_area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, r_mval[0], r_mval[1]); + } + } + else if (mval != r_mval) { + r_mval[0] = mval[0]; + r_mval[1] = mval[1]; + } +} + /** \} */ diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c index ba72cecc514..9d06fb2b27a 100644 --- a/source/blender/editors/interface/interface_eyedropper_color.c +++ b/source/blender/editors/interface/interface_eyedropper_color.c @@ -337,52 +337,41 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) const char *display_device = CTX_data_scene(C)->display_settings.display_device; struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device); - wmWindow *win = CTX_wm_window(C); - bScreen *screen = CTX_wm_screen(C); - ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my); - if (area == NULL) { - int mval[2] = {mx, my}; - if (WM_window_find_under_cursor(wm, NULL, win, mval, &win, mval)) { - mx = mval[0]; - my = mval[1]; - screen = WM_window_get_active_screen(win); - area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my); - } - else { - win = NULL; - } - } + wmWindow *win; + ScrArea *area; + int mval[2] = {mx, my}; + datadropper_win_area_find(C, mval, mval, &win, &area); if (area) { if (area->spacetype == SPACE_IMAGE) { - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval[0], mval[1]); if (region) { SpaceImage *sima = area->spacedata.first; - int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin}; - if (ED_space_image_color_sample(sima, region, mval, r_col, NULL)) { + if (ED_space_image_color_sample(sima, region, region_mval, r_col, NULL)) { return; } } } else if (area->spacetype == SPACE_NODE) { - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval[0], mval[1]); if (region) { SpaceNode *snode = area->spacedata.first; - const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin}; - if (ED_space_node_color_sample(bmain, snode, region, mval, r_col)) { + if (ED_space_node_color_sample(bmain, snode, region, region_mval, r_col)) { return; } } } else if (area->spacetype == SPACE_CLIP) { - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mval[0], mval[1]); if (region) { SpaceClip *sc = area->spacedata.first; - int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + int region_mval[2] = {mval[0] - region->winrct.xmin, mval[1] - region->winrct.ymin}; - if (ED_space_clip_color_sample(sc, region, mval, r_col)) { + if (ED_space_clip_color_sample(sc, region, region_mval, r_col)) { return; } } @@ -391,7 +380,6 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) if (win) { /* Fallback to simple opengl picker. */ - const int mval[2] = {mx, my}; WM_window_pixel_sample_read(wm, win, mval, r_col); IMB_colormanagement_display_to_scene_linear_v3(r_col, display); } diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c index 8c605598cbc..4996c803dfe 100644 --- a/source/blender/editors/interface/interface_eyedropper_datablock.c +++ b/source/blender/editors/interface/interface_eyedropper_datablock.c @@ -71,13 +71,16 @@ typedef struct DataDropper { ScrArea *cursor_area; /* Area under the cursor */ ARegionType *art; void *draw_handle_pixel; + int name_pos[2]; char name[200]; } DataDropper; -static void datadropper_draw_cb(const struct bContext *C, ARegion *region, void *arg) +static void datadropper_draw_cb(const struct bContext *UNUSED(C), + ARegion *UNUSED(region), + void *arg) { DataDropper *ddr = arg; - eyedropper_draw_cursor_text_region(C, region, ddr->name); + eyedropper_draw_cursor_text_region(UNPACK2(ddr->name_pos), ddr->name); } static int datadropper_init(bContext *C, wmOperator *op) @@ -148,12 +151,10 @@ static void datadropper_exit(bContext *C, wmOperator *op) /** * \brief get the ID from the 3D view or outliner. */ -static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id) +static void datadropper_id_sample_pt( + bContext *C, wmWindow *win, ScrArea *area, DataDropper *ddr, int mx, int my, ID **r_id) { - /* we could use some clever */ - bScreen *screen = CTX_wm_screen(C); - ScrArea *area = BKE_screen_find_area_xy(screen, -1, mx, my); - + wmWindow *win_prev = CTX_wm_window(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *region_prev = CTX_wm_region(C); @@ -166,6 +167,7 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; Base *base; + CTX_wm_window_set(C, win); CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); @@ -202,11 +204,15 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2); *r_id = id; } + + ddr->name_pos[0] = mval[0]; + ddr->name_pos[1] = mval[1]; } } } } + CTX_wm_window_set(C, win_prev); CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, region_prev); } @@ -232,7 +238,13 @@ static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my) { ID *id = NULL; - datadropper_id_sample_pt(C, ddr, mx, my, &id); + wmWindow *win; + ScrArea *area; + + int mval[] = {mx, my}; + datadropper_win_area_find(C, mval, mval, &win, &area); + + datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id); return datadropper_id_set(C, ddr, id); } @@ -244,14 +256,8 @@ static void datadropper_cancel(bContext *C, wmOperator *op) } /* To switch the draw callback when region under mouse event changes */ -static void datadropper_set_draw_callback_region(bContext *C, - DataDropper *ddr, - const int mx, - const int my) +static void datadropper_set_draw_callback_region(ScrArea *area, DataDropper *ddr) { - bScreen *screen = CTX_wm_screen(C); - ScrArea *area = BKE_screen_find_area_xy(screen, -1, mx, my); - if (area) { /* If spacetype changed */ if (area->spacetype != ddr->cursor_area->spacetype) { @@ -300,10 +306,16 @@ static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event) else if (event->type == MOUSEMOVE) { ID *id = NULL; + wmWindow *win; + ScrArea *area; + + int mval[] = {event->x, event->y}; + datadropper_win_area_find(C, mval, mval, &win, &area); + /* Set the region for eyedropper cursor text drawing */ - datadropper_set_draw_callback_region(C, ddr, event->x, event->y); + datadropper_set_draw_callback_region(area, ddr); - datadropper_id_sample_pt(C, ddr, event->x, event->y, &id); + datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id); } return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c index a64fad8c333..311f718d950 100644 --- a/source/blender/editors/interface/interface_eyedropper_depth.c +++ b/source/blender/editors/interface/interface_eyedropper_depth.c @@ -72,13 +72,16 @@ typedef struct DepthDropper { ARegionType *art; void *draw_handle_pixel; + int name_pos[2]; char name[200]; } DepthDropper; -static void depthdropper_draw_cb(const struct bContext *C, ARegion *region, void *arg) +static void depthdropper_draw_cb(const struct bContext *UNUSED(C), + ARegion *UNUSED(region), + void *arg) { DepthDropper *ddr = arg; - eyedropper_draw_cursor_text_region(C, region, ddr->name); + eyedropper_draw_cursor_text_region(UNPACK2(ddr->name_pos), ddr->name); } static int depthdropper_init(bContext *C, wmOperator *op) @@ -172,6 +175,8 @@ static void depthdropper_depth_sample_pt( /* weak, we could pass in some reference point */ const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3]; const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + copy_v2_v2_int(ddr->name_pos, mval); + float co[3]; CTX_wm_area_set(C, area); diff --git a/source/blender/editors/interface/interface_eyedropper_intern.h b/source/blender/editors/interface/interface_eyedropper_intern.h index 96a2c6ed111..f9f3fcfb5d1 100644 --- a/source/blender/editors/interface/interface_eyedropper_intern.h +++ b/source/blender/editors/interface/interface_eyedropper_intern.h @@ -24,10 +24,13 @@ /* interface_eyedropper.c */ void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const char *name); -void eyedropper_draw_cursor_text_region(const struct bContext *C, - const struct ARegion *region, - const char *name); +void eyedropper_draw_cursor_text_region(const int x, const int y, const char *name); uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event); +void datadropper_win_area_find(const struct bContext *C, + const int mval[2], + int r_mval[2], + struct wmWindow **r_win, + struct ScrArea **r_area); /* interface_eyedropper_color.c (expose for color-band picker) */ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7a42c9d5d8b..f0ab082cd9c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -28,6 +28,7 @@ #include "MEM_guardedalloc.h" #include "DNA_curve_types.h" +#include "DNA_gpencil_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -39,6 +40,7 @@ #include "BLI_alloca.h" #include "BLI_array.h" #include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_utildefines_stack.h" @@ -4083,16 +4085,38 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op) } else { int dvert_tot = 0; + /* Grease pencil stores vertex groups separately for each stroke, + * so remap each stroke's weights separately. */ + if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + dvert = gps->dvert; + dvert_tot = gps->totpoints; + if (dvert) { + while (dvert_tot--) { + if (dvert->totweight) { + BKE_defvert_remap(dvert, sort_map, defbase_tot); + } + dvert++; + } + } + } + } + } + } + else { + BKE_object_defgroup_array_get(ob->data, &dvert, &dvert_tot); - BKE_object_defgroup_array_get(ob->data, &dvert, &dvert_tot); - - /* Create as necessary. */ - if (dvert) { - while (dvert_tot--) { - if (dvert->totweight) { - BKE_defvert_remap(dvert, sort_map, defbase_tot); + /* Create as necessary. */ + if (dvert) { + while (dvert_tot--) { + if (dvert->totweight) { + BKE_defvert_remap(dvert, sort_map, defbase_tot); + } + dvert++; } - dvert++; } } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index cff3ecfbbd3..daac196a90c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1738,19 +1738,19 @@ static int area_snap_calc_location(const bScreen *screen, int snap_dist_best = INT_MAX; { const float div_array[] = { - /* Middle. */ - 1.0f / 2.0f, - /* Thirds. */ - 1.0f / 3.0f, - 2.0f / 3.0f, - /* Quarters. */ - 1.0f / 4.0f, - 3.0f / 4.0f, - /* Eighth. */ - 1.0f / 8.0f, - 3.0f / 8.0f, - 5.0f / 8.0f, - 7.0f / 8.0f, + 0.0f, + 1.0f / 12.0f, + 2.0f / 12.0f, + 3.0f / 12.0f, + 4.0f / 12.0f, + 5.0f / 12.0f, + 6.0f / 12.0f, + 7.0f / 12.0f, + 8.0f / 12.0f, + 9.0f / 12.0f, + 10.0f / 12.0f, + 11.0f / 12.0f, + 1.0f, }; /* Test the snap to the best division. */ for (int i = 0; i < ARRAY_SIZE(div_array); i++) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 1bebbc35747..13213f70fed 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -298,6 +298,7 @@ enum { /* Mask Modifier -> flag */ enum { MOD_MASK_INV = (1 << 0), + MOD_MASK_SMOOTH = (1 << 1), }; typedef struct ArrayModifierData { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 486d8d13564..f11d845c582 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -4431,6 +4431,12 @@ static void rna_def_modifier_mask(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Invert", "Use vertices that are not part of region defined"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MASK_SMOOTH); + RNA_def_property_ui_text( + prop, "Smooth", "Use vertex group weights to cut faces at the weight contour"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "threshold"); RNA_def_property_range(prop, 0.0, 1.0); diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 9aa8e3dd7c8..aca90e0533c 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -27,6 +27,7 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLT_translation.h" @@ -214,6 +215,40 @@ static void computed_masked_edges(const Mesh *mesh, *r_num_masked_edges = num_masked_edges; } +static void computed_masked_edges_smooth(const Mesh *mesh, + Span<bool> vertex_mask, + MutableSpan<int> r_edge_map, + uint *r_num_masked_edges, + uint *r_num_add_vertices) +{ + BLI_assert(mesh->totedge == r_edge_map.size()); + + uint num_masked_edges = 0; + uint num_add_vertices = 0; + for (int i : IndexRange(mesh->totedge)) { + const MEdge &edge = mesh->medge[i]; + + /* only add if both verts will be in new mesh */ + bool v1 = vertex_mask[edge.v1]; + bool v2 = vertex_mask[edge.v2]; + if (v1 && v2) { + r_edge_map[i] = num_masked_edges; + num_masked_edges++; + } + else if (v1 != v2) { + r_edge_map[i] = -2; + num_add_vertices++; + } + else { + r_edge_map[i] = -1; + } + } + + num_masked_edges += num_add_vertices; + *r_num_masked_edges = num_masked_edges; + *r_num_add_vertices = num_add_vertices; +} + static void computed_masked_polygons(const Mesh *mesh, Span<bool> vertex_mask, Vector<int> &r_masked_poly_indices, @@ -224,7 +259,7 @@ static void computed_masked_polygons(const Mesh *mesh, BLI_assert(mesh->totvert == vertex_mask.size()); r_masked_poly_indices.reserve(mesh->totpoly); - r_loop_starts.reserve(mesh->totloop); + r_loop_starts.reserve(mesh->totpoly); uint num_masked_loops = 0; for (int i : IndexRange(mesh->totpoly)) { @@ -250,6 +285,76 @@ static void computed_masked_polygons(const Mesh *mesh, *r_num_masked_loops = num_masked_loops; } +static void compute_interpolated_polygons(const Mesh *mesh, + Span<bool> vertex_mask, + uint num_add_vertices, + uint num_masked_loops, + Vector<int> &r_masked_poly_indices, + Vector<int> &r_loop_starts, + uint *r_num_add_edges, + uint *r_num_add_polys, + uint *r_num_add_loops) +{ + BLI_assert(mesh->totvert == vertex_mask.size()); + + /* Can't really know ahead of time how much space to use exactly. Estimate limit instead. */ + /* NOTE: this reserve can only lift the capacity if there are ngons, which get split. */ + r_masked_poly_indices.reserve(r_masked_poly_indices.size() + num_add_vertices); + r_loop_starts.reserve(r_loop_starts.size() + num_add_vertices); + + uint num_add_edges = 0; + uint num_add_polys = 0; + uint num_add_loops = 0; + for (int i : IndexRange(mesh->totpoly)) { + const MPoly &poly_src = mesh->mpoly[i]; + + int in_count = 0; + int start = -1; + int dst_totloop = -1; + Span<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop); + for (const int j : loops_src.index_range()) { + const MLoop &loop = loops_src[j]; + if (vertex_mask[loop.v]) { + in_count++; + } + else if (start == -1) { + start = j; + } + } + if (0 < in_count && in_count < poly_src.totloop) { + /* Ring search starting at a vertex which is not included in the mask. */ + const MLoop *last_loop = &loops_src[start]; + bool v_loop_in_mask_last = vertex_mask[last_loop->v]; + for (const int j : loops_src.index_range()) { + const MLoop &loop = loops_src[(start + 1 + j) % poly_src.totloop]; + const bool v_loop_in_mask = vertex_mask[loop.v]; + if (v_loop_in_mask && !v_loop_in_mask_last) { + dst_totloop = 3; + } + else if (!v_loop_in_mask && v_loop_in_mask_last) { + BLI_assert(dst_totloop > 2); + r_masked_poly_indices.append(i); + r_loop_starts.append(num_masked_loops + num_add_loops); + num_add_loops += dst_totloop; + num_add_polys++; + num_add_edges++; + dst_totloop = -1; + } + else if (v_loop_in_mask && v_loop_in_mask_last) { + BLI_assert(dst_totloop > 2); + dst_totloop++; + } + last_loop = &loop; + v_loop_in_mask_last = v_loop_in_mask; + } + } + } + + *r_num_add_edges = num_add_edges; + *r_num_add_polys = num_add_polys; + *r_num_add_loops = num_add_loops; +} + void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<int> vertex_map) { BLI_assert(src_mesh.totvert == vertex_map.size()); @@ -267,6 +372,89 @@ void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span } } +static float get_interp_factor_from_vgroup( + MDeformVert *dvert, int defgrp_index, float threshold, uint v1, uint v2) +{ + /* NOTE: this calculation is done twice for every vertex, + * instead of storing it the first time and then reusing it. */ + float value1 = BKE_defvert_find_weight(&dvert[v1], defgrp_index); + float value2 = BKE_defvert_find_weight(&dvert[v2], defgrp_index); + return (threshold - value1) / (value2 - value1); +} + +static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + Span<bool> vertex_mask, + Span<int> vertex_map, + MDeformVert *dvert, + int defgrp_index, + float threshold, + uint num_masked_edges, + uint num_add_verts, + MutableSpan<int> r_edge_map) +{ + BLI_assert(src_mesh.totvert == vertex_mask.size()); + BLI_assert(src_mesh.totedge == r_edge_map.size()); + + uint vert_index = dst_mesh.totvert - num_add_verts; + uint edge_index = num_masked_edges - num_add_verts; + for (int i_src : IndexRange(src_mesh.totedge)) { + if (r_edge_map[i_src] != -1) { + int i_dst = r_edge_map[i_src]; + if (i_dst == -2) { + i_dst = edge_index; + } + const MEdge &e_src = src_mesh.medge[i_src]; + MEdge &e_dst = dst_mesh.medge[i_dst]; + + CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1); + e_dst = e_src; + e_dst.v1 = vertex_map[e_src.v1]; + e_dst.v2 = vertex_map[e_src.v2]; + } + if (r_edge_map[i_src] == -2) { + const int i_dst = edge_index++; + r_edge_map[i_src] = i_dst; + const MEdge &e_src = src_mesh.medge[i_src]; + /* Cut destination edge and make v1 the new vertex. */ + MEdge &e_dst = dst_mesh.medge[i_dst]; + if (!vertex_mask[e_src.v1]) { + e_dst.v1 = vert_index; + } + else { + BLI_assert(!vertex_mask[e_src.v2]); + e_dst.v2 = e_dst.v1; + e_dst.v1 = vert_index; + } + /* Create the new vertex. */ + float fac = get_interp_factor_from_vgroup( + dvert, defgrp_index, threshold, e_src.v1, e_src.v2); + + float weights[2] = {1.0f - fac, fac}; + CustomData_interp( + &src_mesh.vdata, &dst_mesh.vdata, (int *)&e_src.v1, weights, NULL, 2, vert_index); + MVert &v = dst_mesh.mvert[vert_index]; + MVert &v1 = src_mesh.mvert[e_src.v1]; + MVert &v2 = src_mesh.mvert[e_src.v2]; + + interp_v3_v3v3(v.co, v1.co, v2.co, fac); + + float no1[3]; + float no2[3]; + normal_short_to_float_v3(no1, v1.no); + normal_short_to_float_v3(no2, v2.no); + mul_v3_fl(no1, weights[0]); + madd_v3_v3fl(no1, no2, weights[1]); + normalize_v3(no1); + normal_float_to_short_v3(v.no, no1); + + vert_index++; + } + } + BLI_assert(vert_index == dst_mesh.totvert); + BLI_assert(edge_index == num_masked_edges); +} + void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<int> vertex_map, @@ -276,7 +464,7 @@ void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, BLI_assert(src_mesh.totedge == edge_map.size()); for (const int i_src : IndexRange(src_mesh.totedge)) { const int i_dst = edge_map[i_src]; - if (i_dst == -1) { + if (i_dst == -1 || i_dst == -2) { continue; } @@ -290,6 +478,36 @@ void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, } } +static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + Span<int> vertex_map, + Span<int> edge_map, + Span<int> masked_poly_indices, + Span<int> new_loop_starts, + int num_masked_polys) +{ + for (const int i_dst : IndexRange(num_masked_polys)) { + const int i_src = masked_poly_indices[i_dst]; + + const MPoly &mp_src = src_mesh.mpoly[i_src]; + MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const int i_ml_src = mp_src.loopstart; + const int i_ml_dst = new_loop_starts[i_dst]; + + CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1); + CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop); + + const MLoop *ml_src = src_mesh.mloop + i_ml_src; + MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + for (int i : IndexRange(mp_src.totloop)) { + ml_dst[i].v = vertex_map[ml_src[i].v]; + ml_dst[i].e = edge_map[ml_src[i].e]; + } + } +} void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<int> vertex_map, @@ -320,6 +538,137 @@ void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, } } +static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, + Mesh &dst_mesh, + Span<bool> vertex_mask, + Span<int> vertex_map, + Span<int> edge_map, + MDeformVert *dvert, + int defgrp_index, + float threshold, + Span<int> masked_poly_indices, + Span<int> new_loop_starts, + int num_masked_polys, + int num_add_edges) +{ + int edge_index = dst_mesh.totedge - num_add_edges; + int sub_poly_index = 0; + int last_i_src = -1; + for (const int i_dst : + IndexRange(num_masked_polys, masked_poly_indices.size() - num_masked_polys)) { + const int i_src = masked_poly_indices[i_dst]; + if (i_src == last_i_src) { + sub_poly_index++; + } + else { + sub_poly_index = 0; + last_i_src = i_src; + } + + const MPoly &mp_src = src_mesh.mpoly[i_src]; + MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const int i_ml_src = mp_src.loopstart; + int i_ml_dst = new_loop_starts[i_dst]; + const int mp_totloop = (i_dst + 1 < new_loop_starts.size() ? new_loop_starts[i_dst + 1] : + dst_mesh.totloop) - + i_ml_dst; + + CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1); + + mp_dst = mp_src; + mp_dst.loopstart = i_ml_dst; + mp_dst.totloop = mp_totloop; + + /* Ring search starting at a vertex which is not included in the mask. */ + int start = -sub_poly_index - 1; + bool skip = false; + Span<MLoop> loops_src(&src_mesh.mloop[i_ml_src], mp_src.totloop); + for (const int j : loops_src.index_range()) { + if (!vertex_mask[loops_src[j].v]) { + if (start == -1) { + start = j; + break; + } + else if (!skip) { + skip = true; + } + } + else if (skip) { + skip = false; + start++; + } + } + + BLI_assert(start >= 0); + BLI_assert(edge_index < dst_mesh.totedge); + + const MLoop *last_loop = &loops_src[start]; + bool v_loop_in_mask_last = vertex_mask[last_loop->v]; + int last_index = start; + for (const int j : loops_src.index_range()) { + const int index = (start + 1 + j) % mp_src.totloop; + const MLoop &loop = loops_src[index]; + const bool v_loop_in_mask = vertex_mask[loop.v]; + if (v_loop_in_mask && !v_loop_in_mask_last) { + /* Start new cut. */ + float fac = get_interp_factor_from_vgroup( + dvert, defgrp_index, threshold, last_loop->v, loop.v); + float weights[2] = {1.0f - fac, fac}; + int indices[2] = {i_ml_src + last_index, i_ml_src + index}; + CustomData_interp(&src_mesh.ldata, &dst_mesh.ldata, indices, weights, NULL, 2, i_ml_dst); + MLoop &cut_dst_loop = dst_mesh.mloop[i_ml_dst]; + cut_dst_loop.e = edge_map[last_loop->e]; + cut_dst_loop.v = dst_mesh.medge[cut_dst_loop.e].v1; + i_ml_dst++; + + CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); + MLoop &next_dst_loop = dst_mesh.mloop[i_ml_dst]; + next_dst_loop.v = vertex_map[loop.v]; + next_dst_loop.e = edge_map[loop.e]; + i_ml_dst++; + } + else if (!v_loop_in_mask && v_loop_in_mask_last) { + BLI_assert(i_ml_dst != mp_dst.loopstart); + /* End active cut. */ + float fac = get_interp_factor_from_vgroup( + dvert, defgrp_index, threshold, last_loop->v, loop.v); + float weights[2] = {1.0f - fac, fac}; + int indices[2] = {i_ml_src + last_index, i_ml_src + index}; + CustomData_interp(&src_mesh.ldata, &dst_mesh.ldata, indices, weights, NULL, 2, i_ml_dst); + MLoop &cut_dst_loop = dst_mesh.mloop[i_ml_dst]; + cut_dst_loop.e = edge_index; + cut_dst_loop.v = dst_mesh.medge[edge_map[last_loop->e]].v1; + i_ml_dst++; + + /* Create closing edge. */ + MEdge &cut_edge = dst_mesh.medge[edge_index]; + cut_edge.v1 = dst_mesh.mloop[mp_dst.loopstart].v; + cut_edge.v2 = cut_dst_loop.v; + BLI_assert(cut_edge.v1 != cut_edge.v2); + cut_edge.flag = ME_EDGEDRAW | ME_EDGERENDER; + edge_index++; + + /* Only handle one of the cuts per iteration. */ + break; + } + else if (v_loop_in_mask && v_loop_in_mask_last) { + BLI_assert(i_ml_dst != mp_dst.loopstart); + /* Extend active poly. */ + CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); + MLoop &dst_loop = dst_mesh.mloop[i_ml_dst]; + dst_loop.v = vertex_map[loop.v]; + dst_loop.e = edge_map[loop.e]; + i_ml_dst++; + } + last_loop = &loop; + last_index = index; + v_loop_in_mask_last = v_loop_in_mask; + } + BLI_assert(mp_dst.loopstart + mp_dst.totloop == i_ml_dst); + } + BLI_assert(edge_index == dst_mesh.totedge); +} + /* Components of the algorithm: * 1. Figure out which vertices should be present in the output mesh. * 2. Find edges and polygons only using those vertices. @@ -329,6 +678,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) { MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md); const bool invert_mask = mmd->flag & MOD_MASK_INV; + const bool use_interpolation = mmd->mode == MOD_MASK_MODE_VGROUP && + (mmd->flag & MOD_MASK_SMOOTH); /* Return empty or input mesh when there are no vertex groups. */ MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); @@ -342,6 +693,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) return mesh; } + int defgrp_index = -1; + Array<bool> vertex_mask; if (mmd->mode == MOD_MASK_MODE_ARM) { Object *armature_ob = mmd->ob_arm; @@ -355,7 +708,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) compute_vertex_mask__armature_mode(dvert, mesh, armature_ob, mmd->threshold, vertex_mask); } else { - int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, mmd->vgroup); + BLI_assert(mmd->mode == MOD_MASK_MODE_VGROUP); + defgrp_index = BKE_id_defgroup_name_index(&mesh->id, mmd->vgroup); /* Return input mesh if the vertex group does not exist. */ if (defgrp_index == -1) { @@ -376,7 +730,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) Array<int> edge_map(mesh->totedge); uint num_masked_edges; - computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges); + uint num_add_vertices; + if (use_interpolation) { + computed_masked_edges_smooth( + mesh, vertex_mask, edge_map, &num_masked_edges, &num_add_vertices); + } + else { + computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges); + num_add_vertices = 0; + } Vector<int> masked_poly_indices; Vector<int> new_loop_starts; @@ -389,13 +751,65 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) &num_masked_polys, &num_masked_loops); - Mesh *result = BKE_mesh_new_nomain_from_template( - mesh, num_masked_vertices, num_masked_edges, 0, num_masked_loops, num_masked_polys); + uint num_add_edges = 0; + uint num_add_polys = 0; + uint num_add_loops = 0; + if (use_interpolation) { + compute_interpolated_polygons(mesh, + vertex_mask, + num_add_vertices, + num_masked_loops, + masked_poly_indices, + new_loop_starts, + &num_add_edges, + &num_add_polys, + &num_add_loops); + } + + Mesh *result = BKE_mesh_new_nomain_from_template(mesh, + num_masked_vertices + num_add_vertices, + num_masked_edges + num_add_edges, + 0, + num_masked_loops + num_add_loops, + num_masked_polys + num_add_polys); copy_masked_vertices_to_new_mesh(*mesh, *result, vertex_map); - copy_masked_edges_to_new_mesh(*mesh, *result, vertex_map, edge_map); - copy_masked_polys_to_new_mesh( - *mesh, *result, vertex_map, edge_map, masked_poly_indices, new_loop_starts); + if (use_interpolation) { + add_interp_verts_copy_edges_to_new_mesh(*mesh, + *result, + vertex_mask, + vertex_map, + dvert, + defgrp_index, + mmd->threshold, + num_masked_edges, + num_add_vertices, + edge_map); + } + else { + copy_masked_edges_to_new_mesh(*mesh, *result, vertex_map, edge_map); + } + copy_masked_polys_to_new_mesh(*mesh, + *result, + vertex_map, + edge_map, + masked_poly_indices, + new_loop_starts, + num_masked_polys); + if (use_interpolation) { + add_interpolated_polys_to_new_mesh(*mesh, + *result, + vertex_mask, + vertex_map, + edge_map, + dvert, + defgrp_index, + mmd->threshold, + masked_poly_indices, + new_loop_starts, + num_masked_polys, + num_add_edges); + } BKE_mesh_calc_edges_loose(result); /* Tag to recalculate normals later. */ @@ -441,6 +855,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) } else if (mode == MOD_MASK_MODE_VGROUP) { modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); + uiItemR(layout, ptr, "use_smooth", 0, nullptr, ICON_NONE); } uiItemR(layout, ptr, "threshold", 0, nullptr, ICON_NONE); diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 145586d8ab0..c7b59ee0d6e 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -70,6 +70,12 @@ static const struct PyC_StringEnumItems pygpu_shader_builtin_items[] = { {0, NULL}, }; +static const struct PyC_StringEnumItems pygpu_shader_config_items[] = { + {GPU_SHADER_CFG_DEFAULT, "DEFAULT"}, + {GPU_SHADER_CFG_CLIPPED, "CLIPPED"}, + {0, NULL}, +}; + static int pygpu_shader_uniform_location_get(GPUShader *shader, const char *name, const char *error_prefix) @@ -711,29 +717,48 @@ static PyObject *pygpu_shader_unbind(BPyGPUShader *UNUSED(self)) } PyDoc_STRVAR(pygpu_shader_from_builtin_doc, - ".. function:: from_builtin(pygpu_shader_name)\n" + ".. function:: from_builtin(shader_name, config='DEFAULT')\n" "\n" " Shaders that are embedded in the blender internal code.\n" " They all read the uniform ``mat4 ModelViewProjectionMatrix``,\n" " which can be edited by the :mod:`gpu.matrix` module.\n" + " You can also choose a shader configuration that uses clip_planes by setting the " + "``CLIPPED`` value to the config parameter. Note that in this case you also need to " + "manually set the value of ``ModelMatrix``.\n" + "\n" " For more details, you can check the shader code with the\n" " :func:`gpu.shader.code_from_builtin` function.\n" "\n" - " :param pygpu_shader_name: One of these builtin shader names:\n" + " :param shader_name: One of these builtin shader names:\n" "\n" PYDOC_BUILTIN_SHADER_LIST - " :type pygpu_shader_name: str\n" + " :type shader_name: str\n" + " :param config: One of these types of shader configuration:\n" + " - ``DEFAULT``\n" + " - ``CLIPPED``\n" + " :type config: str\n" " :return: Shader object corresponding to the given name.\n" " :rtype: :class:`bpy.types.GPUShader`\n"); -static PyObject *pygpu_shader_from_builtin(PyObject *UNUSED(self), PyObject *arg) +static PyObject *pygpu_shader_from_builtin(PyObject *UNUSED(self), PyObject *args, PyObject *kwds) { BPYGPU_IS_INIT_OR_ERROR_OBJ; struct PyC_StringEnum pygpu_bultinshader = {pygpu_shader_builtin_items}; - if (!PyC_ParseStringEnum(arg, &pygpu_bultinshader)) { + struct PyC_StringEnum pygpu_config = {pygpu_shader_config_items, GPU_SHADER_CFG_DEFAULT}; + + static const char *_keywords[] = {"shader_name", "config", NULL}; + static _PyArg_Parser _parser = {"O&|$O&:from_builtin", _keywords, 0}; + if (!_PyArg_ParseTupleAndKeywordsFast(args, + kwds, + &_parser, + PyC_ParseStringEnum, + &pygpu_bultinshader, + PyC_ParseStringEnum, + &pygpu_config)) { return NULL; } - GPUShader *shader = GPU_shader_get_builtin_shader(pygpu_bultinshader.value_found); + GPUShader *shader = GPU_shader_get_builtin_shader_with_config(pygpu_bultinshader.value_found, + pygpu_config.value_found); return BPyGPUShader_CreatePyObject(shader, true); } @@ -788,7 +813,7 @@ static struct PyMethodDef pygpu_shader_module__tp_methods[] = { {"unbind", (PyCFunction)pygpu_shader_unbind, METH_NOARGS, pygpu_shader_unbind_doc}, {"from_builtin", (PyCFunction)pygpu_shader_from_builtin, - METH_O, + METH_VARARGS | METH_KEYWORDS, pygpu_shader_from_builtin_doc}, {"code_from_builtin", (PyCFunction)pygpu_shader_code_from_builtin, diff --git a/source/blender/python/gpu/gpu_py_state.c b/source/blender/python/gpu/gpu_py_state.c index 7b7a61cc338..757c787882b 100644 --- a/source/blender/python/gpu/gpu_py_state.c +++ b/source/blender/python/gpu/gpu_py_state.c @@ -123,6 +123,28 @@ static PyObject *pygpu_state_blend_get(PyObject *UNUSED(self)) return PyUnicode_FromString(PyC_StringEnum_FindIDFromValue(pygpu_state_blend_items, blend)); } +PyDoc_STRVAR(pygpu_state_clip_distances_set_doc, + ".. function:: clip_distances_set(distances_enabled)\n" + "\n" + " Sets number of `gl_ClipDistance`s that will be used for clip geometry.\n" + "\n" + " :param distances_enabled: Number of clip distances enabled.\n" + " :type distances_enabled: int\n"); +static PyObject *pygpu_state_clip_distances_set(PyObject *UNUSED(self), PyObject *value) +{ + int distances_enabled = (int)PyLong_AsUnsignedLong(value); + if (distances_enabled == -1) { + return NULL; + } + + if (distances_enabled > 6) { + PyErr_SetString(PyExc_ValueError, "too many distances enabled, max is 6"); + } + + GPU_clip_distances(distances_enabled); + Py_RETURN_NONE; +} + PyDoc_STRVAR(pygpu_state_depth_test_set_doc, ".. function:: depth_test_set(mode)\n" "\n" @@ -356,6 +378,10 @@ static struct PyMethodDef pygpu_state__tp_methods[] = { /* Manage Stack */ {"blend_set", (PyCFunction)pygpu_state_blend_set, METH_O, pygpu_state_blend_set_doc}, {"blend_get", (PyCFunction)pygpu_state_blend_get, METH_NOARGS, pygpu_state_blend_get_doc}, + {"clip_distances_set", + (PyCFunction)pygpu_state_clip_distances_set, + METH_O, + pygpu_state_clip_distances_set_doc}, {"depth_test_set", (PyCFunction)pygpu_state_depth_test_set, METH_O, diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index d4adad9a34d..37bac523645 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -39,6 +39,7 @@ #include "BLI_utildefines.h" #include "DNA_anim_types.h" +#include "DNA_packedFile_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_space_types.h" @@ -3755,31 +3756,47 @@ static void init_text_effect(Sequence *seq) void SEQ_effect_text_font_unload(TextVars *data, const bool do_id_user) { - if (data) { - /* Unlink the VFont */ - if (do_id_user && data->text_font != NULL) { - id_us_min(&data->text_font->id); - data->text_font = NULL; - } + if (data == NULL) { + return; + } - /* Unload the BLF font. */ - if (data->text_blf_id >= 0) { - BLF_unload_id(data->text_blf_id); - } + /* Unlink the VFont */ + if (do_id_user && data->text_font != NULL) { + id_us_min(&data->text_font->id); + data->text_font = NULL; + } + + /* Unload the BLF font. */ + if (data->text_blf_id >= 0) { + BLF_unload_id(data->text_blf_id); } } void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user) { - if (data->text_font != NULL) { - if (do_id_user) { - id_us_plus(&data->text_font->id); - } + VFont *vfont = data->text_font; + if (vfont == NULL) { + return; + } + + if (do_id_user) { + id_us_plus(&vfont->id); + } + if (vfont->packedfile != NULL) { + PackedFile *pf = vfont->packedfile; + /* Create a name that's unique between library data-blocks to avoid loading + * a font per strip which will load fonts many times. */ + char name[MAX_ID_FULL_NAME]; + BKE_id_full_name_get(name, &vfont->id, 0); + + data->text_blf_id = BLF_load_mem(name, pf->data, pf->size); + } + else { char path[FILE_MAX]; - STRNCPY(path, data->text_font->filepath); + STRNCPY(path, vfont->filepath); BLI_assert(BLI_thread_is_main()); - BLI_path_abs(path, ID_BLEND_PATH_FROM_GLOBAL(&data->text_font->id)); + BLI_path_abs(path, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); data->text_blf_id = BLF_load(path); } @@ -3850,9 +3867,7 @@ static ImBuf *do_text_effect(const SeqRenderData *context, if (data->text_blf_id == SEQ_FONT_NOT_LOADED) { data->text_blf_id = -1; - if (data->text_font) { - data->text_blf_id = BLF_load(data->text_font->filepath); - } + SEQ_effect_text_font_load(data, false); } if (data->text_blf_id >= 0) { diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 3027df41e77..ca1610a8101 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -111,12 +111,11 @@ void WM_reinit_gizmomap_all(struct Main *bmain); void WM_script_tag_reload(void); -bool WM_window_find_under_cursor(const wmWindowManager *wm, - const wmWindow *win_ignore, - const wmWindow *win, - const int mval[2], - wmWindow **r_win, - int r_mval[2]); +wmWindow *WM_window_find_under_cursor(const wmWindowManager *wm, + const wmWindow *win_ignore, + const wmWindow *win, + const int mval[2], + int r_mval[2]); void WM_window_pixel_sample_read(const wmWindowManager *wm, const wmWindow *win, const int pos[2], @@ -263,9 +262,8 @@ struct wmEventHandler_Keymap *WM_event_add_keymap_handler_priority(ListBase *han wmKeyMap *keymap, int priority); -typedef struct wmKeyMap *(wmEventHandler_KeymapDynamicFn)(wmWindowManager *wm, - struct wmEventHandler_Keymap *handler) - ATTR_WARN_UNUSED_RESULT; +typedef struct wmKeyMap *(wmEventHandler_KeymapDynamicFn)( + wmWindowManager *wm, struct wmEventHandler_Keymap *handler)ATTR_WARN_UNUSED_RESULT; struct wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback( struct wmWindowManager *wm, struct wmEventHandler_Keymap *handler); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index b9a3dd0c3fb..1f47b152a2b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -4357,8 +4357,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi } } - wmWindow *win_other; - if (WM_window_find_under_cursor(wm, win, win, mval, &win_other, mval)) { + wmWindow *win_other = WM_window_find_under_cursor(wm, win, win, mval, mval); + if (win_other) { event->x = mval[0]; event->y = mval[1]; return win_other; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 93417213a65..e9d0adf6798 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1922,12 +1922,11 @@ static void wm_window_screen_pos_get(const wmWindow *win, r_scr_pos[1] = desktop_pos[1] - (int)(U.pixelsize * win->posy); } -bool WM_window_find_under_cursor(const wmWindowManager *wm, - const wmWindow *win_ignore, - const wmWindow *win, - const int mval[2], - wmWindow **r_win, - int r_mval[2]) +wmWindow *WM_window_find_under_cursor(const wmWindowManager *wm, + const wmWindow *win_ignore, + const wmWindow *win, + const int mval[2], + int r_mval[2]) { int desk_pos[2]; wm_window_desktop_pos_get(win, mval, desk_pos); @@ -1949,13 +1948,12 @@ bool WM_window_find_under_cursor(const wmWindowManager *wm, if (scr_pos[0] >= 0 && win_iter->posy >= 0 && scr_pos[0] <= WM_window_pixels_x(win_iter) && scr_pos[1] <= WM_window_pixels_y(win_iter)) { - *r_win = win_iter; copy_v2_v2_int(r_mval, scr_pos); - return true; + return win_iter; } } - return false; + return NULL; } void WM_window_pixel_sample_read(const wmWindowManager *wm, |