diff options
author | Julian Eisel <julian@blender.org> | 2020-03-16 20:14:24 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-16 20:14:24 +0300 |
commit | ddbbd9928ec443f813ee4d46011288e360278e9f (patch) | |
tree | 91f50fc6e8e8b68be5686903aca191d43cdafae5 /source/blender/editors | |
parent | b86be9b2145458037fd0b17433b7af0efa7b6472 (diff) | |
parent | d2ef342b2a50a7eac725889708fd689ffa126e25 (diff) |
Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside
Diffstat (limited to 'source/blender/editors')
83 files changed, 788 insertions, 446 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index ebde475a075..24ffc60453b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -71,6 +71,7 @@ #include "UI_interface.h" #include "UI_interface_icons.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "ED_anim_api.h" #include "ED_keyframing.h" @@ -916,7 +917,8 @@ static bool acf_group_setting_valid(bAnimContext *ac, /* for now, all settings are supported, though some are only conditionally */ switch (setting) { /* unsupported */ - case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */ + case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */ + case ACHANNEL_SETTING_PINNED: /* Only for NLA actions */ return false; /* conditionally supported */ @@ -1963,6 +1965,25 @@ static int acf_dsskey_icon(bAnimListElem *UNUSED(ale)) return ICON_SHAPEKEY_DATA; } +/* check if some setting exists for this channel */ +static bool acf_dsskey_setting_valid(bAnimContext *ac, + bAnimListElem *UNUSED(ale), + eAnimChannel_Settings setting) +{ + switch (setting) { + case ACHANNEL_SETTING_SELECT: + case ACHANNEL_SETTING_EXPAND: + return true; + + /* mute is only supported for NLA */ + case ACHANNEL_SETTING_MUTE: + return ((ac) && (ac->spacetype == SPACE_NLA)); + + default: + return false; + } +} + /* get the appropriate flag(s) for the setting when it is valid */ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, @@ -2029,9 +2050,9 @@ static bAnimChannelType ACF_DSSKEY = { acf_generic_idblock_name_prop, /* name prop */ acf_dsskey_icon, /* icon */ - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsskey_setting_flag, /* flag for setting */ - acf_dsskey_setting_ptr, /* pointer for setting */ + acf_dsskey_setting_valid, /* has setting */ + acf_dsskey_setting_flag, /* flag for setting */ + acf_dsskey_setting_ptr, /* pointer for setting */ }; /* World Expander ------------------------------------------- */ @@ -3155,6 +3176,8 @@ static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), /* unsupported */ case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */ case ACHANNEL_SETTING_SOLO: /* nla editor only */ + case ACHANNEL_SETTING_MOD_OFF: + case ACHANNEL_SETTING_PINNED: /* nla actions only */ return false; /* always available */ @@ -3335,6 +3358,9 @@ static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ case ACHANNEL_SETTING_SOLO: /* nla editor only */ + case ACHANNEL_SETTING_MOD_OFF: + case ACHANNEL_SETTING_PINNED: /* nla actions only */ + case ACHANNEL_SETTING_MUTE: return false; /* always available */ @@ -4112,10 +4138,6 @@ void ANIM_channel_draw( /* just skip - drawn as widget now */ offset += ICON_WIDTH; } - else if (ale->type == ANIMTYPE_GPLAYER) { - /* just skip - drawn as a widget */ - offset += ICON_WIDTH; - } } /* step 5) draw name ............................................... */ @@ -4163,8 +4185,16 @@ void ANIM_channel_draw( } /* step 6) draw backdrops behind mute+protection toggles + (sliders) ....................... */ - /* reset offset - now goes from RHS of panel */ - offset = 0; + /* - Reset offset - now goes from RHS of panel. + * - Exception for graph editor, which needs extra space for the scroll bar. + */ + if (ac->spacetype == SPACE_GRAPH && + ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_GROUP)) { + offset = V2D_SCROLL_WIDTH; + } + else { + offset = 0; + } /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space */ @@ -4207,10 +4237,17 @@ void ANIM_channel_draw( if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) { offset += ICON_WIDTH; } + + /* grease pencil visibility... */ if (ale->type == ANIMTYPE_GPLAYER) { offset += ICON_WIDTH; } + /* modifiers toggle... */ + if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) { + offset += ICON_WIDTH; + } + /* pinned... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) { offset += ICON_WIDTH; @@ -4957,8 +4994,7 @@ void ANIM_channel_draw_widgets(const bContext *C, /* modifiers disable */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) { - /* hack: extra spacing, to avoid touching the mute toggle */ - offset -= ICON_WIDTH * 1.2f; + offset -= ICON_WIDTH; draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MOD_OFF); } @@ -5073,37 +5109,19 @@ void ANIM_channel_draw_widgets(const bContext *C, else if (ale->type == ANIMTYPE_GPLAYER) { bGPdata *gpd = (bGPdata *)ale->id; if ((gpd != NULL) && ((gpd->flag & GP_DATA_ANNOTATIONS) == 0)) { - /* Add some offset to make it more pleasing to the eye. */ - offset += SLIDER_WIDTH / 2.1f; + /* Reset slider offset, in order to add special gp icons. */ + offset += SLIDER_WIDTH; char *gp_rna_path = NULL; bGPDlayer *gpl = (bGPDlayer *)ale->data; - const short width = SLIDER_WIDTH / 5; /* Create the RNA pointers. */ RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr); RNA_id_pointer_create(ale->id, &id_ptr); int icon; - /* Layer opacity. */ - UI_block_emboss_set(block, UI_EMBOSS); - prop = RNA_struct_find_property(&ptr, "opacity"); - gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); - if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { - uiDefAutoButR(block, - &ptr, - prop, - array_index, - "", - ICON_NONE, - offset, - ymid, - width * 3, - channel_height); - } - MEM_freeN(gp_rna_path); - /* Mask Layer. */ + offset -= ICON_WIDTH; UI_block_emboss_set(block, UI_EMBOSS_NONE); prop = RNA_struct_find_property(&ptr, "use_mask_layer"); gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); @@ -5121,14 +5139,15 @@ void ANIM_channel_draw_widgets(const bContext *C, array_index, "", icon, - offset + (width * 3), + offset, ymid, - width, + ICON_WIDTH, channel_height); } MEM_freeN(gp_rna_path); /* Layer onion skinning switch. */ + offset -= ICON_WIDTH; prop = RNA_struct_find_property(&ptr, "use_onion_skinning"); gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { @@ -5140,7 +5159,27 @@ void ANIM_channel_draw_widgets(const bContext *C, array_index, "", icon, - offset + (width * 4), + offset, + ymid, + ICON_WIDTH, + channel_height); + } + MEM_freeN(gp_rna_path); + + /* Layer opacity. */ + const short width = SLIDER_WIDTH * 0.6; + offset -= width; + UI_block_emboss_set(block, UI_EMBOSS); + prop = RNA_struct_find_property(&ptr, "opacity"); + gp_rna_path = RNA_path_from_ID_to_property(&ptr, prop); + if (RNA_path_resolve_property(&id_ptr, gp_rna_path, &ptr, &prop)) { + uiDefAutoButR(block, + &ptr, + prop, + array_index, + "", + ICON_NONE, + offset, ymid, width, channel_height); diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 98fcb9c5ce5..439b8071deb 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -368,9 +368,7 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data) if (ale->update & ANIM_UPDATE_ORDER) { ale->update &= ~ANIM_UPDATE_ORDER; if (gpl) { - /* While correct & we could enable it: 'posttrans_gpd_clean' currently - * both sorts and removes doubles, so this is not necessary here. */ - // gpencil_sort_frames(gpl); + BKE_gpencil_layer_frames_sort(gpl, NULL); } } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 4b0a4bcf46b..8dfc9cd8d1a 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1715,22 +1715,33 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, /* loop over layers as the conditions are acceptable (top-Down order) */ for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) { /* only if selected */ - if (ANIMCHANNEL_SELOK(SEL_GPL(gpl))) { - /* only if editable */ - if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) { - /* active... */ - if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) { - /* skip layer if the name doesn't match the filter string */ - if ((ads) && (ads->searchstr[0] != '\0')) { - if (name_matches_dopesheet_filter(ads, gpl->info) == false) { - continue; - } - } - /* add to list */ - ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd, NULL); - } - } + if (!ANIMCHANNEL_SELOK(SEL_GPL(gpl))) { + continue; + } + + /* only if editable */ + if ((filter_mode & ANIMFILTER_FOREDIT) && !EDITABLE_GPL(gpl)) { + continue; + } + + /* active... */ + if ((filter_mode & ANIMFILTER_ACTIVE) && (gpl->flag & GP_LAYER_ACTIVE) == 0) { + continue; } + + /* skip layer if the name doesn't match the filter string */ + if (ads != NULL && ads->searchstr[0] != '\0' && + name_matches_dopesheet_filter(ads, gpl->info) == false) { + continue; + } + + /* Skip empty layers. */ + if (BLI_listbase_is_empty(&gpl->frames)) { + continue; + } + + /* add to list */ + ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd, NULL); } return items; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 22a42d56fcd..c290a2ac70a 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2709,7 +2709,7 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot) /* ******************************************* */ /* AUTO KEYFRAME */ -bool autokeyframe_cfra_can_key(Scene *scene, ID *id) +bool autokeyframe_cfra_can_key(const Scene *scene, ID *id) { float cfra = (float)CFRA; // XXX for now, this will do diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 721953f41c8..6f9769f9785 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -673,7 +673,7 @@ bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id) /* Getters for Active/Indices ----------------------------- */ /* Get the active Keying Set for the Scene provided */ -KeyingSet *ANIM_scene_get_active_keyingset(Scene *scene) +KeyingSet *ANIM_scene_get_active_keyingset(const Scene *scene) { /* if no scene, we've got no hope of finding the Keying Set */ if (scene == NULL) { @@ -728,7 +728,7 @@ int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks) } /* Get Keying Set to use for Auto-Keyframing some transforms */ -KeyingSet *ANIM_get_keyingset_for_autokeying(Scene *scene, const char *transformKSName) +KeyingSet *ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName) { /* get KeyingSet to use * - use the active KeyingSet if defined (and user wants to use it for all autokeying), diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index d1352c66f75..1b147663a7e 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -609,6 +609,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES brush.gpencil_draw.draw brush.gpencil_draw.erase brush.gpencil_draw.fill + brush.gpencil_draw.tint brush.paint_texture.airbrush brush.paint_texture.clone brush.paint_texture.draw @@ -622,6 +623,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES brush.paint_vertex.average brush.paint_vertex.blur brush.paint_vertex.draw + brush.paint_vertex.replace brush.paint_vertex.smear brush.paint_weight.average brush.paint_weight.blur @@ -638,8 +640,11 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES brush.sculpt.blob brush.sculpt.clay brush.sculpt.clay_strips + brush.sculpt.clay_thumb + brush.sculpt.cloth brush.sculpt.crease brush.sculpt.draw + brush.sculpt.draw_face_sets brush.sculpt.draw_sharp brush.sculpt.elastic_deform brush.sculpt.fill @@ -703,6 +708,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES ops.gpencil.sculpt_twist ops.gpencil.sculpt_weight ops.gpencil.stroke_cutter + ops.gpencil.transform_fill ops.mesh.bevel ops.mesh.bisect ops.mesh.dupli_extrude_cursor @@ -776,6 +782,7 @@ if(WITH_BLENDER) # images data_to_c_simple(../../../../release/datafiles/splash.png SRC) data_to_c_simple(../../../../release/datafiles/splash_2x.png SRC) + data_to_c_simple(../../../../release/datafiles/alert_icons.png SRC) # XXX These are handy, but give nasty "false changes" in svn :/ # svg_to_png(../../../../release/datafiles/blender_icons.svg # ../../../../release/datafiles/blender_icons16.png diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 512e1ec6270..4083169d65c 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -58,8 +58,8 @@ set(SRC gpencil_undo.c gpencil_utils.c gpencil_uv.c - gpencil_vertex_paint.c gpencil_vertex_ops.c + gpencil_vertex_paint.c gpencil_weight_paint.c gpencil_intern.h diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 9b33e999a25..e5d332a86de 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -3179,7 +3179,7 @@ void GPENCIL_OT_color_unlock_all(wmOperatorType *ot) /* ***************** Select all strokes using color ************************ */ -static int gpencil_color_select_exec(bContext *C, wmOperator *op) +static int gpencil_select_material_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); Object *ob = CTX_data_active_object(C); @@ -3249,15 +3249,15 @@ static int gpencil_color_select_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GPENCIL_OT_color_select(wmOperatorType *ot) +void GPENCIL_OT_select_material(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Color"; - ot->idname = "GPENCIL_OT_color_select"; - ot->description = "Select all Grease Pencil strokes using current color"; + ot->name = "Select Material"; + ot->idname = "GPENCIL_OT_select_material"; + ot->description = "Select/Deselect all Grease Pencil strokes using current material"; /* callbacks */ - ot->exec = gpencil_color_select_exec; + ot->exec = gpencil_select_material_exec; ot->poll = gpencil_active_color_poll; /* flags */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 2d36e426835..a12fd81e032 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -407,7 +407,7 @@ void GPENCIL_OT_select_less(struct wmOperatorType *ot); void GPENCIL_OT_select_first(struct wmOperatorType *ot); void GPENCIL_OT_select_last(struct wmOperatorType *ot); void GPENCIL_OT_select_alternate(struct wmOperatorType *ot); -void GPENCIL_OT_select_color(struct wmOperatorType *ot); +void GPENCIL_OT_select_vertex_color(struct wmOperatorType *ot); void GPENCIL_OT_duplicate(struct wmOperatorType *ot); void GPENCIL_OT_delete(struct wmOperatorType *ot); @@ -552,7 +552,7 @@ void GPENCIL_OT_color_hide(struct wmOperatorType *ot); void GPENCIL_OT_color_reveal(struct wmOperatorType *ot); void GPENCIL_OT_color_lock_all(struct wmOperatorType *ot); void GPENCIL_OT_color_unlock_all(struct wmOperatorType *ot); -void GPENCIL_OT_color_select(struct wmOperatorType *ot); +void GPENCIL_OT_select_material(struct wmOperatorType *ot); void GPENCIL_OT_set_active_material(struct wmOperatorType *ot); /* convert old 2.7 files to 2.8 */ diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 275075c38db..233bebfc9b6 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -544,7 +544,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_select_first); WM_operatortype_append(GPENCIL_OT_select_last); WM_operatortype_append(GPENCIL_OT_select_alternate); - WM_operatortype_append(GPENCIL_OT_select_color); + WM_operatortype_append(GPENCIL_OT_select_vertex_color); WM_operatortype_append(GPENCIL_OT_duplicate); WM_operatortype_append(GPENCIL_OT_delete); @@ -653,7 +653,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_color_reveal); WM_operatortype_append(GPENCIL_OT_color_lock_all); WM_operatortype_append(GPENCIL_OT_color_unlock_all); - WM_operatortype_append(GPENCIL_OT_color_select); + WM_operatortype_append(GPENCIL_OT_select_material); /* Editing (Time) --------------- */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 46788eba370..e7586d95d29 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1653,9 +1653,6 @@ static void gp_session_validatebuffer(tGPsdata *p) /* reset flags */ gpd->runtime.sbuffer_sflag = 0; - /* reset region */ - gpd->runtime.ar = NULL; - /* reset inittime */ p->inittime = 0.0; @@ -1884,7 +1881,6 @@ static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p) /* setup active color */ /* region where paint was originated */ - p->gpd->runtime.ar = CTX_wm_region(C); int totcol = p->ob->totcol; gp_init_colors(p); diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 96522d1750c..66c0131cd61 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -1157,8 +1157,6 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op) /* set GP datablock */ tgpi->gpd = gpd; - /* region where paint was originated */ - tgpi->gpd->runtime.ar = tgpi->region; /* if brush doesn't exist, create a new set (fix damaged files from old versions) */ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) { diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 26b68707d55..133891cda13 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -1655,7 +1655,50 @@ void GPENCIL_OT_select(wmOperatorType *ot) } /* Select by Vertex Color. */ -static bool gpencil_select_color_poll(bContext *C) +/* Helper to create a hash of colors. */ +static void gpencil_selected_hue_table(bContext *C, + Object *ob, + const int threshold, + GHash *hue_table) +{ + const float range = pow(10, 5 - threshold); + float hsv[3]; + + /* Extract all colors. */ + CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + if ((gps->flag & GP_STROKE_SELECT) == 0) { + continue; + } + + /* Read all points to get all colors selected. */ + bGPDspoint *pt; + int i; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (((pt->flag & GP_SPOINT_SELECT) == 0) || (pt->vert_color[3] == 0.0f)) { + continue; + } + /* Round Hue value. */ + rgb_to_hsv_compat_v(pt->vert_color, hsv); + uint key = truncf(hsv[0] * range); + if (!BLI_ghash_haskey(hue_table, POINTER_FROM_INT(key))) { + BLI_ghash_insert(hue_table, POINTER_FROM_INT(key), POINTER_FROM_INT(key)); + } + } + } + } + } + CTX_DATA_END; +} + +static bool gpencil_select_vertex_color_poll(bContext *C) { ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = CTX_data_active_object(C); @@ -1678,38 +1721,46 @@ static bool gpencil_select_color_poll(bContext *C) return false; } -static int gpencil_select_color_exec(bContext *C, wmOperator *op) +static int gpencil_select_vertex_color_exec(bContext *C, wmOperator *op) { - const float threshold = RNA_float_get(op->ptr, "threshold"); - ToolSettings *ts = CTX_data_tool_settings(C); Object *ob = CTX_data_active_object(C); + + const float threshold = RNA_int_get(op->ptr, "threshold"); + const int selectmode = gpencil_select_mode_from_vertex(ts->gpencil_selectmode_vertex); bGPdata *gpd = (bGPdata *)ob->data; - if (!GPENCIL_VERTEX_MODE(gpd)) { - return OPERATOR_CANCELLED; - } + const float range = pow(10, 5 - threshold); - Paint *paint = &ts->gp_vertexpaint->paint; - Brush *brush = paint->brush; bool done = false; - float hsv_brush[3], hsv_stroke[3]; - rgb_to_hsv_compat_v(brush->rgb, hsv_brush); + /* Create a hash table with all selected colors. */ + GHash *hue_table = BLI_ghash_int_new(__func__); + gpencil_selected_hue_table(C, ob, threshold, hue_table); + if (BLI_ghash_len(hue_table) == 0) { + BKE_report(op->reports, RPT_ERROR, "Select before some Vertex to use as a filter color"); + BLI_ghash_free(hue_table, NULL, NULL); + + return OPERATOR_CANCELLED; + } - /* Select any visible stroke that uses this color */ + /* Select any visible stroke that uses any of these colors. */ CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) { bGPDspoint *pt; int i; bool gps_selected = false; /* Check all stroke points. */ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->vert_color[3] < 0.03f) { + if (pt->vert_color[3] == 0.0f) { continue; } - rgb_to_hsv_compat_v(pt->vert_color, hsv_stroke); - /* Only check Hue to get full value and saturation ranges. */ - if (compare_ff(hsv_stroke[0], hsv_brush[0], threshold)) { + /* Only check Hue to get value and saturation full ranges. */ + float hsv[3]; + /* Round Hue value. */ + rgb_to_hsv_compat_v(pt->vert_color, hsv); + uint key = truncf(hsv[0] * range); + + if (BLI_ghash_haskey(hue_table, POINTER_FROM_INT(key))) { pt->flag |= GP_SPOINT_SELECT; gps_selected = true; } @@ -1718,6 +1769,15 @@ static int gpencil_select_color_exec(bContext *C, wmOperator *op) if (gps_selected) { gps->flag |= GP_STROKE_SELECT; done = true; + + /* Extend stroke selection. */ + if (selectmode == GP_SELECTMODE_STROKE) { + bGPDspoint *pt1 = NULL; + + for (i = 0, pt1 = gps->points; i < gps->totpoints; i++, pt1++) { + pt1->flag |= GP_SPOINT_SELECT; + } + } } } CTX_DATA_END; @@ -1733,27 +1793,41 @@ static int gpencil_select_color_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); } + /* Free memory. */ + if (hue_table != NULL) { + BLI_ghash_free(hue_table, NULL, NULL); + } + return OPERATOR_FINISHED; } -void GPENCIL_OT_select_color(wmOperatorType *ot) +void GPENCIL_OT_select_vertex_color(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Select Color"; - ot->idname = "GPENCIL_OT_select_color"; - ot->description = "Select all strokes with same color"; + ot->name = "Select Vertex Color"; + ot->idname = "GPENCIL_OT_select_vertex_color"; + ot->description = "Select all points with similar vertex color of current selected"; /* callbacks */ - ot->exec = gpencil_select_color_exec; - ot->poll = gpencil_select_color_poll; + ot->exec = gpencil_select_vertex_color_exec; + ot->poll = gpencil_select_vertex_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_float(ot->srna, "threshold", 0.01f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f); + prop = RNA_def_int( + ot->srna, + "threshold", + 0, + 0, + 5, + "Threshold", + "Tolerance of the selection. Higher values select a wider range of similar colors", + 0, + 5); /* avoid re-using last var */ RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index a975af1c19a..7fe6f374766 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -2583,10 +2583,9 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc, bGPDspoint pt_dummy, pt_dummy_ps; float boundbox_min[2] = {0.0f}; float boundbox_max[2] = {0.0f}; - float zerov3[3]; /* Check we have something to use (only for old files). */ - if (equals_v3v3(zerov3, gps->boundbox_min)) { + if (is_zero_v3(gps->boundbox_min)) { BKE_gpencil_stroke_boundingbox_calc(gps); } diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c index c730d1b493e..45dc22bafba 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_paint.c +++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c @@ -104,6 +104,7 @@ typedef struct tGP_BrushVertexpaintData { bGPdata *gpd; Brush *brush; + float linear_color[3]; eGPDvertex_brush_Flag flag; eGP_Vertex_SelectMaskFlag mask; @@ -444,7 +445,7 @@ static bool brush_tint_apply(tGP_BrushVertexpaintData *gso, /* Premult. */ mul_v3_fl(pt->vert_color, pt->vert_color[3]); /* "Alpha over" blending. */ - interp_v3_v3v3(pt->vert_color, pt->vert_color, brush->rgb, inf); + interp_v3_v3v3(pt->vert_color, pt->vert_color, gso->linear_color, inf); pt->vert_color[3] = pt->vert_color[3] * (1.0 - inf) + inf; /* Un-premult. */ if (pt->vert_color[3] > 0.0f) { @@ -463,7 +464,7 @@ static bool brush_tint_apply(tGP_BrushVertexpaintData *gso, /* Premult. */ mul_v3_fl(gps->vert_color_fill, gps->vert_color_fill[3]); /* "Alpha over" blending. */ - interp_v3_v3v3(gps->vert_color_fill, gps->vert_color_fill, brush->rgb, inf_fill); + interp_v3_v3v3(gps->vert_color_fill, gps->vert_color_fill, gso->linear_color, inf_fill); gps->vert_color_fill[3] = gps->vert_color_fill[3] * (1.0 - inf_fill) + inf_fill; /* Un-premult. */ if (gps->vert_color_fill[3] > 0.0f) { @@ -483,19 +484,15 @@ static bool brush_replace_apply(tGP_BrushVertexpaintData *gso, bGPDstroke *gps, /* Apply color to Stroke point. */ if (GPENCIL_TINT_VERTEX_COLOR_STROKE(brush)) { - copy_v3_v3(pt->vert_color, brush->rgb); - /* If not mix color, full replace. */ - if (pt->vert_color[3] == 0.0f) { - pt->vert_color[3] = 1.0f; + if (pt->vert_color[3] > 0.0f) { + copy_v3_v3(pt->vert_color, gso->linear_color); } } /* Apply color to Fill area (all with same color and factor). */ if (GPENCIL_TINT_VERTEX_COLOR_FILL(brush)) { - copy_v3_v3(gps->vert_color_fill, brush->rgb); - /* If not mix color, full replace. */ - if (gps->vert_color_fill[3] == 0.0f) { - gps->vert_color_fill[3] = 1.0f; + if (gps->vert_color_fill[3] > 0.0f) { + copy_v3_v3(gps->vert_color_fill, gso->linear_color); } } @@ -731,6 +728,7 @@ static bool gp_vertexpaint_brush_init(bContext *C, wmOperator *op) op->customdata = gso; gso->brush = paint->brush; + srgb_to_linearrgb_v3_v3(gso->linear_color, gso->brush->rgb); BKE_curvemapping_initialize(gso->brush->curve); gso->is_painting = false; diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index c1f5eddd8df..a2ad343da37 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -48,6 +48,9 @@ extern char datatoc_blender_icons32_png[]; extern int datatoc_prvicons_png_size; extern char datatoc_prvicons_png[]; +extern int datatoc_alert_icons_png_size; +extern char datatoc_alert_icons_png[]; + extern int datatoc_splash_png_size; extern char datatoc_splash_png[]; diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 06af48cd476..a523e924e54 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -30,6 +30,7 @@ extern "C" { struct ARegion; struct FileSelectParams; +struct Scene; struct ScrArea; struct SpaceFile; struct bContext; @@ -133,9 +134,13 @@ void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y); void ED_operatormacros_file(void); -void ED_fileselect_clear(struct wmWindowManager *wm, struct ScrArea *sa, struct SpaceFile *sfile); +void ED_fileselect_clear(struct wmWindowManager *wm, + struct Scene *owner_scene, + struct SpaceFile *sfile); -void ED_fileselect_exit(struct wmWindowManager *wm, struct ScrArea *sa, struct SpaceFile *sfile); +void ED_fileselect_exit(struct wmWindowManager *wm, + struct Scene *owner_scene, + struct SpaceFile *sfile); void ED_fileselect_window_params_get(const struct wmWindow *win, int win_size[2], diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 8dd162ea538..66aa301f08c 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -33,13 +33,13 @@ struct ListBase; struct PointerRNA; struct Brush; +struct GP_SpaceConversion; struct bGPDframe; struct bGPDlayer; struct bGPDspoint; struct bGPDstroke; struct bGPdata; struct tGPspoint; -struct GP_SpaceConversion; struct ARegion; struct Depsgraph; @@ -47,8 +47,8 @@ struct Main; struct RegionView3D; struct ReportList; struct Scene; -struct ToolSettings; struct ScrArea; +struct ToolSettings; struct View3D; struct ViewLayer; struct bContext; diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 2f81e28b496..6cac3e60531 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -259,13 +259,13 @@ void ANIM_keyingset_infos_exit(void); /* -------- */ /* Get the active KeyingSet for the given scene */ -struct KeyingSet *ANIM_scene_get_active_keyingset(struct Scene *scene); +struct KeyingSet *ANIM_scene_get_active_keyingset(const struct Scene *scene); /* Get the index of the Keying Set provided, for the given Scene */ int ANIM_scene_get_keyingset_index(struct Scene *scene, struct KeyingSet *ks); /* Get Keying Set to use for Auto-Keyframing some transforms */ -struct KeyingSet *ANIM_get_keyingset_for_autokeying(struct Scene *scene, +struct KeyingSet *ANIM_get_keyingset_for_autokeying(const struct Scene *scene, const char *tranformKSName); /* Dynamically populate an enum of Keying Sets */ @@ -442,7 +442,7 @@ void ANIM_copy_as_driver(struct ID *target_id, const char *target_path, const ch (U.autokey_flag & AUTOKEY_FLAG_##flag)) /* auto-keyframing feature - checks for whether anything should be done for the current frame */ -bool autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id); +bool autokeyframe_cfra_can_key(const struct Scene *scene, struct ID *id); /* ************ Keyframe Checking ******************** */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 1dd40f27fbb..0785b0e97f7 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -431,6 +431,7 @@ int ED_region_generic_tools_region_snap_size(const struct ARegion *region, int s bool ED_region_overlap_isect_x(const ARegion *region, const int event_x); bool ED_region_overlap_isect_y(const ARegion *region, const int event_y); bool ED_region_overlap_isect_xy(const ARegion *region, const int event_xy[2]); +bool ED_region_overlap_isect_any_xy(const ScrArea *area, const int event_xy[2]); bool ED_region_overlap_isect_x_with_margin(const ARegion *region, const int event_x, const int margin); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7b9e4cfe7bf..f882d6be9a2 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -581,7 +581,7 @@ void ED_draw_object_facemap(struct Depsgraph *depsgraph, const float col[4], const int facemap); -struct RenderEngineType *ED_view3d_engine_type(struct Scene *scene, int drawtype); +struct RenderEngineType *ED_view3d_engine_type(const struct Scene *scene, int drawtype); bool ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_setup_view(struct wmWindow *win, @@ -598,7 +598,7 @@ struct Object *ED_view3d_give_object_under_cursor(struct bContext *C, const int bool ED_view3d_is_object_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *region, bool do_clip); void ED_view3d_update_viewmat(struct Depsgraph *depsgraph, - struct Scene *scene, + const struct Scene *scene, struct View3D *v3d, struct ARegion *region, float viewmat[4][4], @@ -648,7 +648,7 @@ bool ED_view3d_camera_lock_sync(const struct Depsgraph *depsgraph, struct View3D *v3d, struct RegionView3D *rv3d); -bool ED_view3d_camera_autokey(struct Scene *scene, +bool ED_view3d_camera_autokey(const struct Scene *scene, struct ID *id_key, struct bContext *C, const bool do_rotate, @@ -670,9 +670,9 @@ bool ED_view3d_distance_set_from_location(struct RegionView3D *rv3d, const float dist_co[3], const float dist_min); -float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); -float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); -void ED_view3d_grid_steps(struct Scene *scene, +float ED_scene_grid_scale(const struct Scene *scene, const char **grid_unit); +float ED_view3d_grid_scale(const struct Scene *scene, struct View3D *v3d, const char **grid_unit); +void ED_view3d_grid_steps(const struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d, float *r_grid_steps); @@ -681,7 +681,7 @@ float ED_view3d_grid_view_scale(struct Scene *scene, struct RegionView3D *rv3d, const char **grid_unit); -void ED_scene_draw_fps(struct Scene *scene, int xoffset, int *yoffset); +void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset); /* view matrix properties utilities */ /* unused */ @@ -708,7 +708,7 @@ void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrAr /* view3d_draw_legacy.c */ /* Try avoid using these more move out of legacy. */ -void ED_view3d_draw_bgpic_test(struct Scene *scene, +void ED_view3d_draw_bgpic_test(const struct Scene *scene, struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, diff --git a/source/blender/editors/include/ED_view3d_offscreen.h b/source/blender/editors/include/ED_view3d_offscreen.h index f69d8367dca..539a4d13ccd 100644 --- a/source/blender/editors/include/ED_view3d_offscreen.h +++ b/source/blender/editors/include/ED_view3d_offscreen.h @@ -34,16 +34,16 @@ extern "C" { #endif /* ********* exports for space_view3d/ module for offscreen rendering ********** */ -struct Depsgraph; -struct Scene; -struct View3D; struct ARegion; +struct Depsgraph; struct GPUOffScreen; struct GPUViewport; +struct Scene; +struct View3D; struct View3DShading; void ED_view3d_draw_offscreen(struct Depsgraph *depsgraph, - struct Scene *scene, + const struct Scene *scene, eDrawType drawtype, struct View3D *v3d, struct ARegion *region, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index dba95c5106e..3e416cd8057 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1124,7 +1124,9 @@ uiBut *uiDefIconButO_ptr(uiBlock *block, short width, short height, const char *tip); - +uiBut *uiDefButImage( + uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4]); +uiBut *uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height); uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, @@ -1805,7 +1807,7 @@ uiLayout *UI_block_layout(uiBlock *block, int size, int em, int padding, - struct uiStyle *style); + const struct uiStyle *style); void UI_block_layout_set_current(uiBlock *block, uiLayout *layout); void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y); @@ -2431,8 +2433,8 @@ int UI_fontstyle_height_max(const struct uiFontStyle *fs); void UI_draw_icon_tri(float x, float y, char dir, const float[4]); -struct uiStyle *UI_style_get(void); /* use for fonts etc */ -struct uiStyle *UI_style_get_dpi(void); /* DPI scaled settings for drawing */ +const struct uiStyle *UI_style_get(void); /* use for fonts etc */ +const struct uiStyle *UI_style_get_dpi(void); /* DPI scaled settings for drawing */ /* linker workaround ack! */ void UI_template_fix_linking(void); diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 6bf0cb8952d..a304c76bc9d 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -52,6 +52,17 @@ typedef struct IconFile { #define PREVIEW_DEFAULT_HEIGHT 128 +typedef enum eAlertIcon { + ALERT_ICON_WARNING = 0, + ALERT_ICON_QUESTION = 1, + ALERT_ICON_ERROR = 2, + ALERT_ICON_INFO = 3, + ALERT_ICON_BLENDER = 4, + ALERT_ICON_MAX, +} eAlertIcon; + +struct ImBuf *UI_alert_image(eAlertIcon icon); + /* * Resizable Icons for Blender */ diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index ecdae3ead6b..ff9719d4674 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -250,13 +250,17 @@ char UI_view2d_rect_in_scrollers(const struct ARegion *region, const struct rcti *rect); /* cached text drawing in v2d, to allow pixel-aligned draw as post process */ -void UI_view2d_text_cache_add( - struct View2D *v2d, float x, float y, const char *str, size_t str_len, const char col[4]); +void UI_view2d_text_cache_add(struct View2D *v2d, + float x, + float y, + const char *str, + size_t str_len, + const unsigned char col[4]); void UI_view2d_text_cache_add_rectf(struct View2D *v2d, const struct rctf *rect_view, const char *str, size_t str_len, - const char col[4]); + const unsigned char col[4]); void UI_view2d_text_cache_draw(struct ARegion *region); /* operators */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index a0a3d0a3b85..3d8c0da78ea 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -366,7 +366,7 @@ void UI_block_translate(uiBlock *block, int x, int y) static void ui_block_bounds_calc_text(uiBlock *block, float offset) { - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); uiBut *bt, *init_col_bt, *col_bt; int i = 0, j, x1addval = offset; @@ -4439,6 +4439,48 @@ uiBut *uiDefBut(uiBlock *block, return but; } +uiBut *uiDefButImage( + uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4]) +{ + uiBut *but = ui_def_but( + block, UI_BTYPE_IMAGE, 0, "", x, y, width, height, imbuf, 0, 0, 0, 0, ""); + if (color) { + copy_v4_v4_uchar(but->col, color); + } + else { + but->col[0] = 255; + but->col[1] = 255; + but->col[2] = 255; + but->col[3] = 255; + } + ui_but_update(but); + return but; +} + +uiBut *uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height) +{ + struct ImBuf *ibuf = UI_alert_image(icon); + + if (icon == ALERT_ICON_BLENDER) { + return uiDefButImage(block, ibuf, x, y, width, height, NULL); + } + else { + uchar icon_color[4]; + ThemeColorID color_id = TH_INFO_WARNING; + if (icon == ALERT_ICON_ERROR) { + color_id = TH_INFO_ERROR; + } + else if (icon == ALERT_ICON_INFO) { + color_id = TH_INFO_INFO; + } + else if (icon == ALERT_ICON_QUESTION) { + color_id = TH_INFO_PROPERTY; + } + UI_GetThemeColorType4ubv(color_id, SPACE_INFO, icon_color); + return uiDefButImage(block, ibuf, x, y, width, height, icon_color); + } +} + /** * if \a _x_ is a power of two (only one bit) return the power, * otherwise return -1. diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index c9a46e00520..f6da9663daf 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -169,7 +169,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *region, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); IDProperty *prop; const char *idname = shortcut_get_operator_property(C, but, &prop); @@ -225,7 +225,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); int kmi_id; IDProperty *prop; const char *idname = shortcut_get_operator_property(C, but, &prop); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index e8e74e77425..2800d808889 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -707,9 +707,6 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), return; } - float facx = 1.0f; - float facy = 1.0f; - int w = BLI_rcti_size_x(rect); int h = BLI_rcti_size_y(rect); @@ -722,10 +719,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), # endif GPU_blend(true); + /* Combine with premultiplied alpha. */ + GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); if (w != ibuf->x || h != ibuf->y) { - facx = (float)w / (float)ibuf->x; - facy = (float)h / (float)ibuf->y; + /* We scale the bitmap, rather than have OGL do a worse job. */ + IMB_scaleImBuf(ibuf, w, h); + } + + float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + if (but->col[3] != 0) { + /* Optionally use uiBut's col to recolor the image. */ + rgba_uchar_to_float(col, but->col); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); @@ -738,11 +743,14 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect, - facx, - facy, - NULL); + 1.0f, + 1.0f, + col); GPU_blend(false); + /* Reset default. */ + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); # if 0 // restore scissortest diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 833631f871d..f4dd114c312 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -58,6 +58,7 @@ #include "BKE_unit.h" #include "BKE_paint.h" #include "BKE_curveprofile.h" +#include "BKE_movieclip.h" #include "IMB_colormanagement.h" @@ -2847,10 +2848,9 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data) */ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x) { - uiStyle *style = UI_style_get(); // XXX pass on as arg - uiFontStyle *fstyle = &style->widget; + /* XXX pass on as arg. */ + uiFontStyle fstyle = UI_style_get()->widget; const float aspect = but->block->aspect; - const short fstyle_points_prev = fstyle->points; float startx = but->rect.xmin; float starty_dummy = 0.0f; @@ -2860,13 +2860,13 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con ui_block_to_window_fl(data->region, but->block, &startx, &starty_dummy); - ui_fontscale(&fstyle->points, aspect); + ui_fontscale(&fstyle.points, aspect); - UI_fontstyle_set(fstyle); + UI_fontstyle_set(&fstyle); - if (fstyle->kerning == 1) { + if (fstyle.kerning == 1) { /* for BLF_width */ - BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); + BLF_enable(fstyle.uifont_id, BLF_KERNING_DEFAULT); } ui_but_text_password_hide(password_str, but, false); @@ -2888,7 +2888,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con while (i > 0) { if (BLI_str_cursor_step_prev_utf8(str, but->ofs, &i)) { /* 0.25 == scale factor for less sensitivity */ - if (BLF_width(fstyle->uifont_id, str + i, (str_last - str) - i) > (startx - x) * 0.25f) { + if (BLF_width(fstyle.uifont_id, str + i, (str_last - str) - i) > (startx - x) * 0.25f) { break; } } @@ -2912,7 +2912,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con but->pos = pos_prev = ((str_last - str) - but->ofs); while (true) { - cdist = startx + BLF_width(fstyle->uifont_id, str + but->ofs, (str_last - str) - but->ofs); + cdist = startx + BLF_width(fstyle.uifont_id, str + but->ofs, (str_last - str) - but->ofs); /* check if position is found */ if (cdist < x) { @@ -2944,13 +2944,11 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con } } - if (fstyle->kerning == 1) { - BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); + if (fstyle.kerning == 1) { + BLF_disable(fstyle.uifont_id, BLF_KERNING_DEFAULT); } ui_but_text_password_hide(password_str, but, true); - - fstyle->points = fstyle_points_prev; } static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, const float x) @@ -7339,8 +7337,10 @@ static bool ui_numedit_but_TRACKPREVIEW( } if (!scopes->track_locked) { - if (scopes->marker->framenr != scopes->framenr) { - scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr); + const MovieClip *clip = CTX_data_edit_movieclip(C); + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scopes->framenr); + if (scopes->marker->framenr != clip_framenr) { + scopes->marker = BKE_tracking_marker_ensure(scopes->track, clip_framenr); } scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3e07023e52d..a37b49f5b6e 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -177,6 +177,30 @@ static const IconType icontypes[] = { # include "UI_icons.h" }; +/* ********** Alert Icons ********** */ + +# define ALERT_IMG_SIZE 256 + +ImBuf *UI_alert_image(eAlertIcon icon) +{ +# ifdef WITH_HEADLESS + return NULL +# else + ImBuf *ibuf; + icon = MIN2(icon, ALERT_ICON_MAX - 1); + const int left = icon * ALERT_IMG_SIZE; + const rcti crop = {left, left + ALERT_IMG_SIZE - 1, 0, ALERT_IMG_SIZE - 1}; + ibuf = IMB_ibImageFromMemory((const uchar *)datatoc_alert_icons_png, + datatoc_alert_icons_png_size, + IB_rect, + NULL, + "alert_icon"); + IMB_rect_crop(ibuf, &crop); + IMB_premultiply_alpha(ibuf); + return ibuf; +# endif +} + /* **************************************************** */ static DrawInfo *def_internal_icon( diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index a2e239884a3..e2b4e8f2958 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -839,7 +839,7 @@ const struct uiWidgetColors *ui_tooltip_get_theme(void); void ui_draw_widget_menu_back_color(const rcti *rect, bool use_shadow, const float color[4]); void ui_draw_widget_menu_back(const rcti *rect, bool use_shadow); -void ui_draw_tooltip_background(struct uiStyle *UNUSED(style), uiBlock *block, rcti *rect); +void ui_draw_tooltip_background(const struct uiStyle *UNUSED(style), uiBlock *block, rcti *rect); extern void ui_draw_but( const struct bContext *C, ARegion *region, struct uiStyle *style, uiBut *but, rcti *rect); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 1aa2670942f..64ff9d02cdc 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -91,7 +91,7 @@ typedef struct uiLayoutRoot { uiMenuHandleFunc handlefunc; void *argv; - uiStyle *style; + const uiStyle *style; uiBlock *block; uiLayout *layout; } uiLayoutRoot; @@ -499,7 +499,7 @@ static void ui_item_array(uiLayout *layout, bool compact, bool show_text) { - uiStyle *style = layout->root->style; + const uiStyle *style = layout->root->style; uiBut *but; PropertyType type; PropertySubType subtype; @@ -3707,7 +3707,7 @@ static void ui_litem_layout_root(uiLayout *litem) /* box layout */ static void ui_litem_estimate_box(uiLayout *litem) { - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; ui_litem_estimate_column(litem, true); @@ -3722,7 +3722,7 @@ static void ui_litem_estimate_box(uiLayout *litem) static void ui_litem_layout_box(uiLayout *litem) { uiLayoutItemBx *box = (uiLayoutItemBx *)litem; - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; uiBut *but; int w, h; @@ -3767,7 +3767,7 @@ static void ui_litem_layout_box(uiLayout *litem) /* multi-column layout, automatically flowing to the next */ static void ui_litem_estimate_column_flow(uiLayout *litem) { - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; uiItem *item; int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; @@ -3832,7 +3832,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) static void ui_litem_layout_column_flow(uiLayout *litem) { - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; @@ -4071,7 +4071,7 @@ static void ui_litem_grid_flow_compute(ListBase *items, static void ui_litem_estimate_grid_flow(uiLayout *litem) { - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; const int space_x = style->columnspace; @@ -4199,7 +4199,7 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) static void ui_litem_layout_grid_flow(uiLayout *litem) { int i; - uiStyle *style = litem->root->style; + const uiStyle *style = litem->root->style; uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; uiItem *item; @@ -5092,8 +5092,15 @@ static void ui_layout_add_padding_button(uiLayoutRoot *root) } } -uiLayout *UI_block_layout( - uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style) +uiLayout *UI_block_layout(uiBlock *block, + int dir, + int type, + int x, + int y, + int size, + int em, + int padding, + const uiStyle *style) { uiLayout *layout; uiLayoutRoot *root; diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 70d64ff26ab..1f5855aed9e 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -434,7 +434,7 @@ void UI_panel_end( static void ui_offset_panel_block(uiBlock *block) { - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); /* compute bounds and offset */ ui_block_bounds_calc(block); @@ -1938,7 +1938,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) // #define USE_FLAT_INACTIVE const bool is_left = RGN_ALIGN_ENUM_FROM_MASK(region->alignment != RGN_ALIGN_RIGHT); View2D *v2d = ®ion->v2d; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; const int fontid = fstyle->uifont_id; short fstyle_points = fstyle->points; diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c index f75f4c054a3..062a8383061 100644 --- a/source/blender/editors/interface/interface_region_menu_pie.c +++ b/source/blender/editors/interface/interface_region_menu_pie.c @@ -104,13 +104,12 @@ static float ui_pie_menu_title_width(const char *name, int icon) uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const wmEvent *event) { - uiStyle *style; + const uiStyle *style = UI_style_get_dpi(); uiPieMenu *pie; short event_type; wmWindow *win = CTX_wm_window(C); - style = UI_style_get_dpi(); pie = MEM_callocN(sizeof(*pie), "pie menu"); pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS); diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c index 1d066b6bbb1..9ceb864b278 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.c +++ b/source/blender/editors/interface/interface_region_menu_popup.c @@ -310,7 +310,7 @@ uiPopupBlockHandle *ui_popup_menu_create( bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg) { wmWindow *window = CTX_wm_window(C); - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); uiPopupBlockHandle *handle; uiPopupMenu *pup; @@ -380,7 +380,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C, const char *block_name, int icon) { - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index 4e4854c8209..d3cd1ebd837 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -94,7 +94,7 @@ static void ui_popover_create_block(bContext *C, uiPopover *pup, int opcontext) { BLI_assert(pup->ui_size_x != 0); - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS); UI_block_flag_enable(pup->block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER); diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index 4481ad54d1a..89eb0658d5e 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -498,7 +498,7 @@ static void ui_searchbox_region_free_cb(ARegion *region) ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but) { wmWindow *win = CTX_wm_window(C); - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); static ARegionType type; ARegion *region; uiSearchboxData *data; diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index c18c78c22a6..02c69e5cef6 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -1158,7 +1158,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, wmWindow *win = CTX_wm_window(C); const int winx = WM_window_pixels_x(win); const int winy = WM_window_pixels_y(win); - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); static ARegionType type; ARegion *region; int fonth, fontw; diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 192571044b9..fa1f222d27f 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -351,7 +351,7 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs, /* ************** helpers ************************ */ /* XXX: read a style configure */ -uiStyle *UI_style_get(void) +const uiStyle *UI_style_get(void) { #if 0 uiStyle *style = NULL; @@ -364,9 +364,9 @@ uiStyle *UI_style_get(void) } /* for drawing, scaled with DPI setting */ -uiStyle *UI_style_get_dpi(void) +const uiStyle *UI_style_get_dpi(void) { - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); static uiStyle _style; _style = *style; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b752a1a1429..f11e3a1f5f0 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -591,11 +591,9 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) DEG_relations_tag_update(bmain); } else { - if (id) { - Main *bmain = CTX_data_main(C); - id_single_user(C, id, &template_ui->ptr, template_ui->prop); - DEG_relations_tag_update(bmain); - } + Main *bmain = CTX_data_main(C); + id_single_user(C, id, &template_ui->ptr, template_ui->prop); + DEG_relations_tag_update(bmain); } } break; @@ -1137,7 +1135,7 @@ static void template_ID_tabs(bContext *C, const int but_height = UI_UNIT_Y * 1.1; uiBlock *block = uiLayoutGetBlock(layout); - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); ListBase ordered; BKE_id_ordered_list(&ordered, template->idlb); @@ -3049,7 +3047,7 @@ static void colorband_tools_dofunc(bContext *C, void *coba_v, int event) static uiBlock *colorband_tools_func(bContext *C, ARegion *region, void *coba_v) { - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); ColorBand *coba = coba_v; uiBlock *block; short yco = 0, menuwidth = 10 * UI_UNIT_X; @@ -7135,7 +7133,7 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C) uiLayout *ui_abs; uiBlock *block; uiBut *but; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); int width; int icon; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 31a1c150b12..b61d54e6cff 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -4990,22 +4990,37 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) { uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4ubv(wcol->inner); + + const bool is_down = (direction == UI_DIR_DOWN); + const int sign = is_down ? 1 : -1; + float y = is_down ? rect->ymax : rect->ymin; + GPU_blend(true); immBegin(GPU_PRIM_TRIS, 3); - if (direction == UI_DIR_DOWN) { - const float y = rect->ymax; - immVertex2f(pos, cent_x - unit_half, y); - immVertex2f(pos, cent_x + unit_half, y); - immVertex2f(pos, cent_x, y + unit_half); - } - else { - const float y = rect->ymin; - immVertex2f(pos, cent_x - unit_half, y); - immVertex2f(pos, cent_x + unit_half, y); - immVertex2f(pos, cent_x, y - unit_half); - } + immUniformColor4ub(UNPACK3(wcol->outline), 166); + immVertex2f(pos, cent_x - unit_half, y); + immVertex2f(pos, cent_x + unit_half, y); + immVertex2f(pos, cent_x, y + sign * unit_half); immEnd(); + + y = y - sign * round(U.pixelsize * 1.41); + + GPU_blend(false); + immBegin(GPU_PRIM_TRIS, 3); + immUniformColor4ub(0, 0, 0, 0); + immVertex2f(pos, cent_x - unit_half, y); + immVertex2f(pos, cent_x + unit_half, y); + immVertex2f(pos, cent_x, y + sign * unit_half); + immEnd(); + + GPU_blend(true); + immBegin(GPU_PRIM_TRIS, 3); + immUniformColor4ubv(wcol->inner); + immVertex2f(pos, cent_x - unit_half, y); + immVertex2f(pos, cent_x + unit_half, y); + immVertex2f(pos, cent_x, y + sign * unit_half); + immEnd(); + immUnbindProgram(); } @@ -5235,7 +5250,7 @@ void ui_draw_widget_menu_back(const rcti *rect, bool use_shadow) ui_draw_widget_back_color(UI_WTYPE_MENU_BACK, use_shadow, rect, NULL); } -void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *UNUSED(block), rcti *rect) +void ui_draw_tooltip_background(const uiStyle *UNUSED(style), uiBlock *UNUSED(block), rcti *rect) { uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP); wt->state(wt, 0, 0); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index af32143df33..ad2e32149d8 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -243,7 +243,7 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) { bool tot_changed = false, do_init; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); do_init = (v2d->flag & V2D_IS_INITIALISED) == 0; @@ -2146,7 +2146,7 @@ static MemArena *g_v2d_strings_arena = NULL; static View2DString *g_v2d_strings = NULL; void UI_view2d_text_cache_add( - View2D *v2d, float x, float y, const char *str, size_t str_len, const char col[4]) + View2D *v2d, float x, float y, const char *str, size_t str_len, const uchar col[4]) { int mval[2]; @@ -2177,7 +2177,7 @@ void UI_view2d_text_cache_add( /* no clip (yet) */ void UI_view2d_text_cache_add_rectf( - View2D *v2d, const rctf *rect_view, const char *str, size_t str_len, const char col[4]) + View2D *v2d, const rctf *rect_view, const char *str, size_t str_len, const uchar col[4]) { rcti rect; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 7eea9e6a697..2c9803d1dd3 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -2155,7 +2155,7 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot) static int reset_exec(bContext *C, wmOperator *UNUSED(op)) { - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; int winx, winy; diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 1c4bc33240a..cd91aa1e491 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -80,6 +80,9 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C); + ED_object_sculptmode_exit(C, depsgraph); + BKE_sculpt_mask_layers_ensure(ob, NULL); Mesh *mesh = ob->data; @@ -209,6 +212,11 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) Object *new_ob = ED_object_add_type(C, OB_MESH, NULL, ob->loc, ob->rot, false, local_view_bits); BKE_mesh_nomain_to_mesh(new_mesh, new_ob->data, new_ob, &CD_MASK_EVERYTHING, true); + /* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object. + * TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */ + Mesh *new_ob_mesh = new_ob->data; + CustomData_free_layers(&new_ob_mesh->pdata, CD_SCULPT_FACE_SETS, new_ob_mesh->totpoly); + if (RNA_boolean_get(op->ptr, "apply_shrinkwrap")) { BKE_shrinkwrap_mesh_nearest_surface_deform(C, new_ob, ob); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index a4546780dd9..3a1781b941a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3382,11 +3382,9 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) if (use_add) { /* In add mode, we add relative shape key offset. */ - if (kb) { - const float *rco = CustomData_bmesh_get_n( - &em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative); - sub_v3_v3v3(co, co, rco); - } + const float *rco = CustomData_bmesh_get_n( + &em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative); + sub_v3_v3v3(co, co, rco); madd_v3_v3fl(eve->co, co, blend); } diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index edc2f15813c..f06b6a4db2a 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -282,7 +282,9 @@ static bool ed_object_mode_generic_exit_ex(struct Main *bmain, ED_object_posemode_exit_ex(bmain, ob); } } - else if ((ob->type == OB_GPENCIL) && ((ob->mode & OB_MODE_OBJECT) == 0)) { + else if (ob->type == OB_GPENCIL) { + /* Accounted for above. */ + BLI_assert((ob->mode & OB_MODE_OBJECT) == 0); if (only_test) { return true; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index bac40b35102..31c4f96693c 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -686,7 +686,7 @@ static int modifier_apply_obdata( } if (mmd && mmd->totlvl && mti->type == eModifierTypeType_OnlyDeform) { - if (!multiresModifier_reshapeFromDeformModifier(depsgraph, mmd, ob, md_eval)) { + if (!multiresModifier_reshapeFromDeformModifier(depsgraph, ob, mmd, md_eval)) { BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply"); return 0; } @@ -1375,26 +1375,25 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot) static int multires_subdivide_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_active_context(C); + Object *object = ED_object_active_context(C); MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get( - op, ob, eModifierType_Multires); + op, object, eModifierType_Multires); if (!mmd) { return OPERATOR_CANCELLED; } - multiresModifier_subdivide(mmd, scene, ob, 0, mmd->simple); + multiresModifier_subdivide(object, mmd); ED_object_iter_other( - CTX_data_main(C), ob, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl); + CTX_data_main(C), object, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl); - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object); - if (ob->mode & OB_MODE_SCULPT) { + if (object->mode & OB_MODE_SCULPT) { /* ensure that grid paint mask layer is created */ - BKE_sculpt_mask_layers_ensure(ob, mmd); + BKE_sculpt_mask_layers_ensure(object, mmd); } return OPERATOR_FINISHED; @@ -1614,19 +1613,19 @@ void OBJECT_OT_multires_external_pack(wmOperatorType *ot) /********************* multires apply base ***********************/ static int multires_base_apply_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_active_context(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Object *object = ED_object_active_context(C); MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get( - op, ob, eModifierType_Multires); + op, object, eModifierType_Multires); if (!mmd) { return OPERATOR_CANCELLED; } - multiresModifier_base_apply(mmd, scene, ob); + multiresModifier_base_apply(depsgraph, object, mmd); - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, object); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index c7bba43758f..29bf9e88853 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1586,7 +1586,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&ob_dst->id, ID_RECALC_COPY_ON_WRITE); break; case MAKE_LINKS_MODIFIERS: - BKE_object_link_modifiers(scene, ob_dst, ob_src); + BKE_object_link_modifiers(ob_dst, ob_src); DEG_id_tag_update(&ob_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); break; diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 8d268be5a78..631cd961e66 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -207,7 +207,6 @@ typedef enum eSymmetryAxes { typedef struct QuadriFlowJob { /* from wmJob */ struct Object *owner; - struct Main *bmain; short *stop, *do_update; float *progress; @@ -318,13 +317,13 @@ static void quadriflow_update_job(void *customdata, float progress, int *cancel) *(qj->progress) = progress; } -static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, eSymmetryAxes symmetry_axes) +static Mesh *remesh_symmetry_bisect(Mesh *mesh, eSymmetryAxes symmetry_axes) { MirrorModifierData mmd = {{0}}; mmd.tolerance = QUADRIFLOW_MIRROR_BISECT_TOLERANCE; Mesh *mesh_bisect, *mesh_bisect_temp; - mesh_bisect = BKE_mesh_copy(bmain, mesh); + mesh_bisect = BKE_mesh_copy_for_eval(mesh, false); int axis; float plane_co[3], plane_no[3]; @@ -342,12 +341,12 @@ static Mesh *remesh_symmetry_bisect(Main *bmain, Mesh *mesh, eSymmetryAxes symme mesh_bisect = BKE_mesh_mirror_bisect_on_mirror_plane( &mmd, mesh_bisect, axis, plane_co, plane_no); if (mesh_bisect_temp != mesh_bisect) { - BKE_id_free(bmain, mesh_bisect_temp); + BKE_id_free(NULL, mesh_bisect_temp); } } } - BKE_id_free(bmain, mesh); + BKE_id_free(NULL, mesh); return mesh_bisect; } @@ -405,10 +404,10 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update /* Run Quadriflow bisect operations on a copy of the mesh to keep the code readable without * freeing the original ID */ - bisect_mesh = BKE_mesh_copy(qj->bmain, mesh); + bisect_mesh = BKE_mesh_copy_for_eval(mesh, false); /* Bisect the input mesh using the paint symmetry settings */ - bisect_mesh = remesh_symmetry_bisect(qj->bmain, bisect_mesh, qj->symmetry_axes); + bisect_mesh = remesh_symmetry_bisect(bisect_mesh, qj->symmetry_axes); new_mesh = BKE_mesh_remesh_quadriflow_to_mesh_nomain( bisect_mesh, @@ -424,7 +423,7 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update quadriflow_update_job, (void *)qj); - BKE_id_free(qj->bmain, bisect_mesh); + BKE_id_free(NULL, bisect_mesh); if (new_mesh == NULL) { *do_update = true; @@ -501,7 +500,6 @@ static int quadriflow_remesh_exec(bContext *C, wmOperator *op) QuadriFlowJob *job = MEM_mallocN(sizeof(QuadriFlowJob), "QuadriFlowJob"); job->owner = CTX_data_active_object(C); - job->bmain = CTX_data_main(C); job->target_faces = RNA_int_get(op->ptr, "target_faces"); job->seed = RNA_int_get(op->ptr, "seed"); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index cff7052ca58..a083675ca01 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -2351,7 +2351,7 @@ static void ed_panel_draw(const bContext *C, int em, bool vertical) { - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); /* draw panel */ uiBlock *block = UI_block_begin(C, region, pt->idname, UI_EMBOSS); @@ -2734,7 +2734,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *region) void ED_region_header_layout(const bContext *C, ARegion *region) { - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); uiBlock *block; uiLayout *layout; HeaderType *ht; @@ -2960,7 +2960,7 @@ void ED_region_info_draw_multiline(ARegion *region, const bool full_redraw) { const int header_height = UI_UNIT_Y; - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); int fontid = style->widget.uifont_id; int scissor[4]; int num_lines = 0; @@ -3175,7 +3175,6 @@ static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const ctx.fontid = fontid; ctx.xmin = xmin; ctx.ymin = ymin; - ctx.vertical_offset = vertical_offset; ctx.current_y = ofs_y; ctx.vertical_offset = vertical_offset; IMB_metadata_foreach(ibuf, metadata_custom_draw_fields, &ctx); @@ -3266,7 +3265,7 @@ void ED_region_image_metadata_draw( { float box_y; rctf rect; - uiStyle *style = UI_style_get_dpi(); + const uiStyle *style = UI_style_get_dpi(); if (!ibuf->metadata) { return; @@ -3521,7 +3520,7 @@ void ED_region_cache_draw_background(ARegion *region) void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y) { - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); int fontid = style->widget.uifont_id; char numstr[32]; float font_dims[2] = {0.0f, 0.0f}; diff --git a/source/blender/editors/screen/area_query.c b/source/blender/editors/screen/area_query.c index f8a6b301911..2cccd9a2ba5 100644 --- a/source/blender/editors/screen/area_query.c +++ b/source/blender/editors/screen/area_query.c @@ -61,6 +61,18 @@ bool ED_region_overlap_isect_xy(const ARegion *region, const int event_xy[2]) ED_region_overlap_isect_y(region, event_xy[1])); } +bool ED_region_overlap_isect_any_xy(const ScrArea *area, const int event_xy[2]) +{ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (ED_region_is_overlap(area->spacetype, region->regiontype)) { + if (ED_region_overlap_isect_xy(region, event_xy)) { + return true; + } + } + } + return false; +} + bool ED_region_panel_category_gutter_calc_rect(const ARegion *region, rcti *r_ar_gutter) { *r_ar_gutter = region->winrct; diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index f497b80e0f4..de9e70f8e06 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -59,8 +59,8 @@ set(SRC paint_vertex_weight_ops.c paint_vertex_weight_utils.c sculpt.c - sculpt_multiplane_scrape.c sculpt_cloth.c + sculpt_multiplane_scrape.c sculpt_pose.c sculpt_undo.c sculpt_uv.c diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5a830a90092..79c4becd405 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -356,9 +356,6 @@ static void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_se if (ss->face_sets[vert_map->indices[j]] > 0) { ss->face_sets[vert_map->indices[j]] = abs(face_set); } - else { - ss->face_sets[vert_map->indices[j]] = -abs(face_set); - } } } break; case PBVH_BMESH: @@ -628,6 +625,10 @@ static bool sculpt_vertex_is_boundary(SculptSession *ss, const int index) return false; } + if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) { + return false; + } + for (int i = 0; i < vert_map->count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; unsigned f_adj_v[2]; @@ -836,7 +837,7 @@ void SCULPT_floodfill_execute( sculpt_vertex_duplicates_and_neighbors_iter_begin(ss, from_v, ni) { const int to_v = ni.index; - if (flood->visited_vertices[to_v] == 0) { + if (flood->visited_vertices[to_v] == 0 && SCULPT_vertex_visible_get(ss, to_v)) { flood->visited_vertices[to_v] = 1; if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) { @@ -1633,17 +1634,11 @@ static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *a #define EDGE_DISTANCE_INF -1 -static float *sculpt_boundary_edges_automasking_init(Sculpt *sd, - Object *ob, +static float *sculpt_boundary_edges_automasking_init(Object *ob, + int propagation_steps, float *automask_factor) { SculptSession *ss = ob->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - const int propagation_steps = brush->automasking_boundary_edges_propagation_steps; - - if (!sculpt_automasking_enabled(ss, brush)) { - return NULL; - } if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) { BLI_assert(!"Boundary Edges masking: pmap missing"); @@ -1693,6 +1688,10 @@ static void sculpt_automasking_init(Sculpt *sd, Object *ob) Brush *brush = BKE_paint_brush(&sd->paint); const int totvert = SCULPT_vertex_count_get(ss); + if (!sculpt_automasking_enabled(ss, brush)) { + return; + } + ss->cache->automask = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss), "automask_factor"); @@ -1711,7 +1710,8 @@ static void sculpt_automasking_init(Sculpt *sd, Object *ob) if (brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) { SCULPT_vertex_random_access_init(ss); - sculpt_boundary_edges_automasking_init(sd, ob, ss->cache->automask); + sculpt_boundary_edges_automasking_init( + ob, brush->automasking_boundary_edges_propagation_steps, ss->cache->automask); } } @@ -3401,7 +3401,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.index, tls->thread_id); - if (fade > 0.05f && SCULPT_vertex_all_face_sets_visible_get(ss, vd.index)) { + if (fade > 0.05f) { SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set); } } @@ -3662,6 +3662,10 @@ void SCULPT_relax_vertex(SculptSession *ss, if (count > 0) { mul_v3_fl(smooth_pos, 1.0f / (float)count); } + else { + copy_v3_v3(r_final_pos, vd->co); + return; + } float plane[4]; float smooth_closest_plane[3]; @@ -3672,6 +3676,12 @@ void SCULPT_relax_vertex(SculptSession *ss, else { copy_v3_v3(vno, vd->fno); } + + if (is_zero_v3(vno)) { + copy_v3_v3(r_final_pos, vd->co); + return; + } + plane_from_point_normal_v3(plane, vd->co, vno); closest_to_plane_v3(smooth_closest_plane, plane, smooth_pos); sub_v3_v3v3(final_disp, smooth_closest_plane, vd->co); @@ -9143,6 +9153,10 @@ static void sculpt_filter_cache_free(SculptSession *ss) if (ss->filter_cache->prev_face_set) { MEM_freeN(ss->filter_cache->prev_face_set); } + if (ss->filter_cache->automask) { + MEM_freeN(ss->filter_cache->automask); + } + MEM_freeN(ss->filter_cache); ss->filter_cache = NULL; } @@ -9310,7 +9324,8 @@ static void mesh_filter_task_cb(void *__restrict userdata, break; } case MESH_FILTER_RELAX: { - SCULPT_relax_vertex(ss, &vd, clamp_f(fade, 0.0f, 1.0f), false, val); + SCULPT_relax_vertex( + ss, &vd, clamp_f(fade * ss->filter_cache->automask[vd.index], 0.0f, 1.0f), false, val); sub_v3_v3v3(disp, val, vd.co); break; } @@ -9443,6 +9458,16 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y; ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z; + if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_RELAX) { + const int totvert = SCULPT_vertex_count_get(ss); + ss->filter_cache->automask = MEM_mallocN(totvert * sizeof(float), + "Relax filter edge automask"); + for (int i = 0; i < totvert; i++) { + ss->filter_cache->automask[i] = 1.0f; + } + sculpt_boundary_edges_automasking_init(ob, 1, ss->filter_cache->automask); + } + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -10844,7 +10869,7 @@ static int sculpt_face_set_create_invoke(bContext *C, wmOperator *op, const wmEv if (mode == SCULPT_FACE_SET_VISIBLE) { for (int i = 0; i < tot_vert; i++) { - if (SCULPT_vertex_visible_get(ss, i) && SCULPT_vertex_all_face_sets_visible_get(ss, i)) { + if (SCULPT_vertex_visible_get(ss, i)) { SCULPT_vertex_face_set_set(ss, i, next_face_set); } } @@ -11017,6 +11042,18 @@ static int sculpt_face_sets_change_visibility_invoke(bContext *C, SCULPT_face_sets_visibility_invert(ss); } + /* For modes that use the cursor active vertex, update the rotation origin for viewport + * navigation. */ + if (ELEM(mode, SCULPT_FACE_SET_VISIBILITY_TOGGLE, SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE)) { + UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; + float location[3]; + copy_v3_v3(location, SCULPT_active_vertex_co_get(ss)); + mul_m4_v3(ob->obmat, location); + copy_v3_v3(ups->average_stroke_accum, location); + ups->average_stroke_counter = 1; + ups->last_stroke_valid = true; + } + /* Sync face sets visibility and vertex visibility. */ SCULPT_visibility_sync_all_face_sets_to_vertices(ss); @@ -11084,12 +11121,13 @@ static int sculpt_face_sets_randomize_colors_invoke(bContext *C, int totnode; Mesh *mesh = ob->data; - int new_seed = BLI_hash_int(PIL_check_seconds_timer_i() & UINT_MAX); - mesh->face_sets_color_seed = new_seed; + mesh->face_sets_color_seed += 1; if (ss->face_sets) { - mesh->face_sets_color_default = ss->face_sets[0]; + const int random_index = clamp_i( + ss->totpoly * BLI_hash_int_01(mesh->face_sets_color_seed), 0, max_ii(0, ss->totpoly - 1)); + mesh->face_sets_color_default = ss->face_sets[random_index]; } - BKE_pbvh_face_sets_color_set(pbvh, new_seed, mesh->face_sets_color_default); + BKE_pbvh_face_sets_color_set(pbvh, mesh->face_sets_color_seed, mesh->face_sets_color_default); BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); for (int i = 0; i < totnode; i++) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 7f90f86edd4..4e36ae7aa5e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -663,6 +663,9 @@ typedef struct FilterCache { float *prev_mask; float mask_expand_initial_co[3]; + /* Used to prevent undesired results on certain mesh filters. */ + float *automask; + int new_face_set; int *prev_face_set; diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 34b4967beaf..6b9d3fd054a 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -259,8 +259,6 @@ typedef struct { MovieTrackingTrack *track; MovieTrackingMarker *marker; - /** current frame number */ - int framenr; /** position of marker in pixel coords */ float marker_pos[2]; /** position and dimensions of marker pattern in pixel coords */ @@ -283,14 +281,12 @@ static void to_pixel_space(float r[2], float a[2], int width, int height) static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) { MarkerUpdateCb *cb = (MarkerUpdateCb *)arg_cb; - MovieTrackingMarker *marker; if (!cb->compact) { return; } - marker = BKE_tracking_marker_ensure(cb->track, cb->framenr); - + MovieTrackingMarker *marker = cb->marker; marker->flag = cb->marker_flag; WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); @@ -299,14 +295,12 @@ static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) static void marker_block_handler(bContext *C, void *arg_cb, int event) { MarkerUpdateCb *cb = (MarkerUpdateCb *)arg_cb; - MovieTrackingMarker *marker; int width, height; bool ok = false; BKE_movieclip_get_size(cb->clip, cb->user, &width, &height); - marker = BKE_tracking_marker_ensure(cb->track, cb->framenr); - + MovieTrackingMarker *marker = cb->marker; if (event == B_MARKER_POS) { marker->pos[0] = cb->marker_pos[0] / width; marker->pos[1] = cb->marker_pos[1] / height; @@ -452,7 +446,8 @@ void uiTemplateMarker(uiLayout *layout, user = userptr->data; track = trackptr->data; - marker = BKE_tracking_marker_get(track, user->framenr); + int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr); + marker = BKE_tracking_marker_get(track, clip_framenr); cb = MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb"); cb->compact = compact; @@ -461,7 +456,6 @@ void uiTemplateMarker(uiLayout *layout, cb->track = track; cb->marker = marker; cb->marker_flag = marker->flag; - cb->framenr = user->framenr; if (compact) { block = uiLayoutGetBlock(layout); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index e5c82a4a80e..72c140011a9 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -296,7 +296,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) SpaceClip *sc = CTX_wm_space_clip(C); View2D *v2d = ®ion->v2d; MovieClip *clip = ED_space_clip_get_clip(sc); - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); int fontid = style->widget.uifont_id; if (!clip) { diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 1332eb51baa..d7682a41570 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -170,7 +170,6 @@ static void file_draw_string(int sx, eFontStyle_Align align, const uchar col[4]) { - uiStyle *style; uiFontStyle fs; rcti rect; char fname[FILE_MAXFILE]; @@ -179,7 +178,7 @@ static void file_draw_string(int sx, return; } - style = UI_style_get(); + const uiStyle *style = UI_style_get(); fs = style->widgetlabel; BLI_strncpy(fname, string, FILE_MAXFILE); @@ -382,7 +381,6 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) char filename[FILE_MAX + 12]; wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); - ScrArea *sa = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); BLI_join_dirfile(orgname, sizeof(orgname), sfile->params->dir, oldname); @@ -410,7 +408,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) } /* to make sure we show what is on disk */ - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); } ED_region_tag_redraw(region); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index d72bc31e656..169abfb9a10 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1649,10 +1649,9 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused)) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - ScrArea *sa = CTX_wm_area(C); struct FSMenu *fsmenu = ED_fsmenu_get(); - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); /* refresh system directory menu */ fsmenu_refresh_system_category(fsmenu); @@ -1988,7 +1987,6 @@ int file_directory_new_exec(bContext *C, wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - ScrArea *sa = CTX_wm_area(C); const bool do_diropen = RNA_boolean_get(op->ptr, "open"); if (!sfile->params) { @@ -2047,13 +2045,13 @@ int file_directory_new_exec(bContext *C, wmOperator *op) /* set timer to smoothly view newly generated file */ /* max 30 frs/sec */ if (sfile->smoothscroll_timer != NULL) { - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); + WM_event_remove_timer(wm, CTX_wm_window(C), sfile->smoothscroll_timer); } sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0); sfile->scroll_offset = 0; /* reload dir to make sure we're seeing what's in the directory */ - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); if (do_diropen) { BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); @@ -2302,11 +2300,10 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused)) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - ScrArea *sa = CTX_wm_area(C); if (sfile->params) { sfile->params->flag ^= FILE_HIDE_DOT; - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -2491,7 +2488,6 @@ int file_delete_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - ScrArea *sa = CTX_wm_area(C); int numfiles = filelist_files_ensure(sfile->files); const char *error_message = NULL; @@ -2520,7 +2516,7 @@ int file_delete_exec(bContext *C, wmOperator *op) } } - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 903698b1ace..188f3417ddc 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -268,6 +268,12 @@ typedef struct FileListEntryPreview { ImBuf *img; } FileListEntryPreview; +/* Dummy wrapper around FileListEntryPreview to ensure we do not access freed memory when freeing + * tasks' data (see T74609). */ +typedef struct FileListEntryPreviewTaskData { + FileListEntryPreview *preview; +} FileListEntryPreviewTaskData; + typedef struct FileListFilter { uint64_t filter; uint64_t filter_id; @@ -1254,7 +1260,8 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, int UNUSED(threadid)) { FileListEntryCache *cache = BLI_task_pool_userdata(pool); - FileListEntryPreview *preview = taskdata; + FileListEntryPreviewTaskData *preview_taskdata = taskdata; + FileListEntryPreview *preview = preview_taskdata->preview; ThumbSource source = 0; @@ -1283,10 +1290,8 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source); IMB_thumb_path_unlock(preview->path); - /* Used to tell free func to not free anything. - * Note that we do not care about cas result here, - * we only want value attribution itself to be atomic (and memory barier).*/ - atomic_cas_uint32(&preview->flags, preview->flags, 0); + /* That way task freeing function won't free th preview, since it does not own it anymore. */ + atomic_cas_ptr((void **)&preview_taskdata->preview, preview, NULL); BLI_thread_queue_push(cache->previews_done, preview); // printf("%s: End (%d)...\n", __func__, threadid); @@ -1296,16 +1301,18 @@ static void filelist_cache_preview_freef(TaskPool *__restrict UNUSED(pool), void *taskdata, int UNUSED(threadid)) { - FileListEntryPreview *preview = taskdata; + FileListEntryPreviewTaskData *preview_taskdata = taskdata; + FileListEntryPreview *preview = preview_taskdata->preview; - /* If preview->flag is empty, it means that preview has already been generated and - * added to done queue, we do not own it anymore. */ - if (preview->flags) { + /* preview_taskdata->preview is atomically set to NULL once preview has been processed and sent + * to previews_done queue. */ + if (preview != NULL) { if (preview->img) { IMB_freeImBuf(preview->img); } MEM_freeN(preview); } + MEM_freeN(preview_taskdata); } static void filelist_cache_preview_ensure_running(FileListEntryCache *cache) @@ -1322,11 +1329,10 @@ static void filelist_cache_preview_ensure_running(FileListEntryCache *cache) static void filelist_cache_previews_clear(FileListEntryCache *cache) { - FileListEntryPreview *preview; - if (cache->previews_pool) { BLI_task_pool_cancel(cache->previews_pool); + FileListEntryPreview *preview; while ((preview = BLI_thread_queue_pop_timeout(cache->previews_done, 0))) { // printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path, // preview->img); @@ -1374,9 +1380,13 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img); filelist_cache_preview_ensure_running(cache); + + FileListEntryPreviewTaskData *preview_taskdata = MEM_mallocN(sizeof(*preview_taskdata), + __func__); + preview_taskdata->preview = preview; BLI_task_pool_push_ex(cache->previews_pool, filelist_cache_preview_runf, - preview, + preview_taskdata, true, filelist_cache_preview_freef, TASK_PRIORITY_LOW); @@ -3057,12 +3067,12 @@ void filelist_readjob_start(FileList *filelist, const bContext *C) WM_jobs_start(CTX_wm_manager(C), wm_job); } -void filelist_readjob_stop(wmWindowManager *wm, ScrArea *sa) +void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene) { - WM_jobs_kill_type(wm, sa, WM_JOB_TYPE_FILESEL_READDIR); + WM_jobs_kill_type(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR); } -int filelist_readjob_running(wmWindowManager *wm, ScrArea *sa) +int filelist_readjob_running(wmWindowManager *wm, Scene *owner_scene) { - return WM_jobs_test(wm, sa, WM_JOB_TYPE_FILESEL_READDIR); + return WM_jobs_test(wm, owner_scene, WM_JOB_TYPE_FILESEL_READDIR); } diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 654a86b1702..e39594bf1da 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -129,8 +129,8 @@ bool filelist_islibrary(struct FileList *filelist, char *dir, char **group); void filelist_freelib(struct FileList *filelist); void filelist_readjob_start(struct FileList *filelist, const struct bContext *C); -void filelist_readjob_stop(struct wmWindowManager *wm, struct ScrArea *sa); -int filelist_readjob_running(struct wmWindowManager *wm, struct ScrArea *sa); +void filelist_readjob_stop(struct wmWindowManager *wm, struct Scene *owner_scene); +int filelist_readjob_running(struct wmWindowManager *wm, struct Scene *owner_scene); bool filelist_cache_previews_update(struct FileList *filelist); void filelist_cache_previews_set(struct FileList *filelist, const bool use_previews); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index c0b859122a8..d07db12eeac 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -639,7 +639,7 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d, float file_string_width(const char *str) { - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); float width; UI_fontstyle_set(&style->widget); @@ -661,12 +661,12 @@ float file_font_pointsize(void) #if 0 float s; char tmp[2] = "X"; - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); UI_fontstyle_set(&style->widget); s = BLF_height(style->widget.uifont_id, tmp); return style->widget.points; #else - uiStyle *style = UI_style_get(); + const uiStyle *style = UI_style_get(); UI_fontstyle_set(&style->widget); return style->widget.points * UI_DPI_FAC; #endif @@ -829,10 +829,9 @@ void ED_file_change_dir(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - ScrArea *sa = CTX_wm_area(C); if (sfile->params) { - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, CTX_data_scene(C), sfile); /* Clear search string, it is very rare to want to keep that filter while changing dir, * and usually very annoying to keep it actually! */ @@ -951,11 +950,11 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) return match; } -void ED_fileselect_clear(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) +void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile) { /* only NULL in rare cases - [#29734] */ if (sfile->files) { - filelist_readjob_stop(wm, sa); + filelist_readjob_stop(wm, owner_scene); filelist_freelib(sfile->files); filelist_clear(sfile->files); } @@ -964,7 +963,7 @@ void ED_fileselect_clear(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL); } -void ED_fileselect_exit(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) +void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfile) { if (!sfile) { return; @@ -990,7 +989,7 @@ void ED_fileselect_exit(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) folderlist_free(sfile->folders_next); if (sfile->files) { - ED_fileselect_clear(wm, sa, sfile); + ED_fileselect_clear(wm, owner_scene, sfile); filelist_free(sfile->files); MEM_freeN(sfile->files); sfile->files = NULL; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 11d759b5b75..50ee64da9c8 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -191,7 +191,7 @@ static void file_exit(wmWindowManager *wm, ScrArea *sa) sfile->previews_timer = NULL; } - ED_fileselect_exit(wm, sa, sfile); + ED_fileselect_exit(wm, NULL, sfile); } static SpaceLink *file_duplicate(SpaceLink *sl) @@ -301,7 +301,7 @@ static void file_refresh(const bContext *C, ScrArea *sa) sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir); if (filelist_force_reset(sfile->files)) { - filelist_readjob_stop(wm, sa); + filelist_readjob_stop(wm, CTX_data_scene(C)); filelist_clear(sfile->files); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 34ff61749b2..c62fd53431b 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2351,7 +2351,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) else { BKE_reportf(reports, RPT_WARNING, - "Packed library image: %s from library %s can't be saved", + "Packed library image can't be saved: \"%s\" from \"%s\"", ima->id.name + 2, ima->id.lib->name); } @@ -2359,7 +2359,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) else if (!is_format_writable) { BKE_reportf(reports, RPT_WARNING, - "Image %s can't be saved automatically, must use a different file format", + "Image can't be saved, use a different file format: \"%s\"", ima->id.name + 2); } else { @@ -2368,7 +2368,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) if (BLI_gset_haskey(unique_paths, ima->name)) { BKE_reportf(reports, RPT_WARNING, - "File path used by more than one saved image: %s", + "Multiple images can't be saved to an identical path: \"%s\"", ima->name); } else { @@ -2376,11 +2376,8 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) } } else { - BKE_reportf(reports, - RPT_WARNING, - "Image %s can't be saved, no valid file path: %s", - ima->id.name + 2, - ima->name); + BKE_reportf( + reports, RPT_WARNING, "Image can't be saved, no valid file path: \"%s\"", ima->name); } } } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index dc546e5baf5..42a8a746eef 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -262,18 +262,22 @@ static void image_keymap(struct wmKeyConfig *keyconf) } /* dropboxes */ -static bool image_drop_poll(bContext *UNUSED(C), +static bool image_drop_poll(bContext *C, wmDrag *drag, - const wmEvent *UNUSED(event), + const wmEvent *event, const char **UNUSED(tooltip)) { + ScrArea *area = CTX_wm_area(C); + if (ED_region_overlap_isect_any_xy(area, &event->x)) { + return false; + } if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { - return 1; + return true; } } - return 0; + return false; } static void image_drop_copy(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 0a5ca81484c..60170276a16 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -53,7 +53,7 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc, /* Zebra striping for background. */ int bg_id = (report->flag & SELECT) ? TH_INFO_SELECTED : TH_BACK; - int shade = tvc->iter_tmp % 2 ? 4 : -4; + int shade = (tvc->iter_tmp % 2) ? 4 : -4; UI_GetThemeColorShade4ubv(bg_id, shade, bg); /* Icon color and backgound depend of report type. */ @@ -61,7 +61,10 @@ static enum eTextViewContext_LineFlag report_line_data(TextViewContext *tvc, int icon_fg_id; int icon_bg_id; - if (report->type & RPT_ERROR_ALL) { + if (tvc->iter_char_begin != 0) { + *r_icon = ICON_NONE; + } + else if (report->type & RPT_ERROR_ALL) { icon_fg_id = TH_INFO_ERROR_TEXT; icon_bg_id = TH_INFO_ERROR; *r_icon = ICON_CANCEL; @@ -115,14 +118,13 @@ static void report_textview_init__internal(TextViewContext *tvc) { const Report *report = tvc->iter; const char *str = report->message; - const char *next_str = strchr(str + tvc->iter_char, '\n'); - - if (next_str) { - tvc->iter_char_next = (int)(next_str - str); - } - else { - tvc->iter_char_next = report->len; + for (int i = tvc->iter_char_end - 1; i >= 0; i -= 1) { + if (str[i] == '\n') { + tvc->iter_char_begin = i + 1; + return; + } } + tvc->iter_char_begin = 0; } static int report_textview_skip__internal(TextViewContext *tvc) @@ -152,7 +154,8 @@ static int report_textview_begin(TextViewContext *tvc) tvc->iter_tmp = 0; if (tvc->iter && report_textview_skip__internal(tvc)) { /* init the newline iterator */ - tvc->iter_char = 0; + const Report *report = tvc->iter; + tvc->iter_char_end = report->len; report_textview_init__internal(tvc); return true; @@ -172,12 +175,13 @@ static int report_textview_step(TextViewContext *tvc) /* simple case, but no newline support */ const Report *report = tvc->iter; - if (report->len <= tvc->iter_char_next) { + if (tvc->iter_char_begin <= 0) { tvc->iter = (void *)((Link *)tvc->iter)->prev; if (tvc->iter && report_textview_skip__internal(tvc)) { tvc->iter_tmp++; - tvc->iter_char = 0; /* reset start */ + report = tvc->iter; + tvc->iter_char_end = report->len; /* reset start */ report_textview_init__internal(tvc); return true; @@ -188,7 +192,7 @@ static int report_textview_step(TextViewContext *tvc) } else { /* step to the next newline */ - tvc->iter_char = tvc->iter_char_next + 1; + tvc->iter_char_end = tvc->iter_char_begin - 1; report_textview_init__internal(tvc); return true; @@ -198,8 +202,8 @@ static int report_textview_step(TextViewContext *tvc) static void report_textview_line_get(TextViewContext *tvc, const char **r_line, int *r_len) { const Report *report = tvc->iter; - *r_line = report->message + tvc->iter_char; - *r_len = tvc->iter_char_next - tvc->iter_char; + *r_line = report->message + tvc->iter_char_begin; + *r_len = tvc->iter_char_end - tvc->iter_char_begin; } static void info_textview_draw_rect_calc(const ARegion *region, diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h index 54b7c477791..8eef4ef5d56 100644 --- a/source/blender/editors/space_info/textview.h +++ b/source/blender/editors/space_info/textview.h @@ -65,10 +65,10 @@ typedef struct TextViewContext { void (*const_colors)(struct TextViewContext *tvc, unsigned char bg_sel[4]); const void *iter; int iter_index; - /** Char index, used for multi-line report display. */ - int iter_char; - /** Same as 'iter_char', next new-line. */ - int iter_char_next; + /** Used for internal multi-line iteration. */ + int iter_char_begin; + /** The last character (not inclusive). */ + int iter_char_end; /** Internal iterator use. */ int iter_tmp; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 905e3eddc97..56176c1cb92 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -604,7 +604,7 @@ static void nla_draw_strip_text(AnimData *adt, (nlt->flag & NLATRACK_SOLO) == 0); char str[256]; size_t str_len; - char col[4]; + uchar col[4]; /* just print the name and the range */ if (strip->flag & NLASTRIP_FLAG_TEMP_META) { @@ -652,7 +652,7 @@ static void nla_draw_strip_frames_text( NlaTrack *UNUSED(nlt), NlaStrip *strip, View2D *v2d, float UNUSED(yminc), float ymaxc) { const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */ - const char col[4] = {220, 220, 220, 255}; /* light gray */ + const uchar col[4] = {220, 220, 220, 255}; /* light gray */ char numstr[32]; size_t numstr_len; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 025de1c898c..f679bcc4e15 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2450,7 +2450,7 @@ void NODE_OT_tree_socket_move(wmOperatorType *ot) static bool node_shader_script_update_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - RenderEngineType *type = RE_engines_find(scene->r.engine); + const RenderEngineType *type = RE_engines_find(scene->r.engine); SpaceNode *snode = CTX_wm_space_node(C); bNode *node; Text *text; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 3e88a7a7b88..1b34f85f800 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2252,9 +2252,6 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case eGpencilModifierType_Armature: data.icon = ICON_MOD_ARMATURE; break; - case eGpencilModifierType_Vertexcolor: - data.icon = ICON_MOD_NORMALEDIT; - break; /* Default */ default: diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 4cd93b5d257..a99e1b63119 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -678,8 +678,8 @@ static void object_delete_cb(bContext *C, return; } - // check also library later - if ((ob->mode && OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) { + /* Check also library later. */ + if ((ob->mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) { ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA); } BKE_id_delete(bmain, ob); diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index b9e97a19b82..d2f2411c538 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -67,12 +67,12 @@ void SCRIPT_OT_python_file_run(wmOperatorType *ot) ot->name = "Run Python File"; ot->description = "Run Python file"; ot->idname = "SCRIPT_OT_python_file_run"; - ot->flag = OPTYPE_UNDO; /* api callbacks */ ot->exec = run_pyfile_exec; ot->poll = ED_operator_areaactive; + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "Path", ""); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index ef192f6c9db..864e518f182 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -542,7 +542,7 @@ static void draw_seq_handle(View2D *v2d, } if ((G.moving & G_TRANSFORM_SEQ) || (seq->flag & whichsel)) { - const char col[4] = {255, 255, 255, 255}; + const uchar col[4] = {255, 255, 255, 255}; char numstr[32]; size_t numstr_len; @@ -574,7 +574,7 @@ static void draw_seq_text(View2D *v2d, char str[32 + FILE_MAX]; size_t str_len; const char *name = seq->name + 2; - char col[4]; + uchar col[4]; /* note, all strings should include 'name' */ if (name[0] == '\0') { diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c index 48c522c5e1b..1e628bbc39b 100644 --- a/source/blender/editors/space_text/text_format_py.c +++ b/source/blender/editors/space_text/text_format_py.c @@ -291,7 +291,7 @@ static int txtfmt_py_literal_numeral(const char *string, char prev_fmt) } /* Previous was a number; if immediately followed by '.' it's a floating point decimal number. * Note: keep the decimal point, it's needed to allow leading zeros. */ - if ((prev_fmt == FMT_TYPE_NUMERAL) && (first == '.')) { + if (first == '.') { return txtfmt_py_find_numeral_inner(string); } /* "Imaginary" part of a complex number ends with 'j' */ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 8ec7d5a166b..020c58270fc 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -436,35 +436,50 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *region) ED_view3d_stop_render_preview(wm, region); } -static bool view3d_ob_drop_poll(bContext *UNUSED(C), +static bool view3d_drop_id_in_main_region_poll(bContext *C, + wmDrag *drag, + const wmEvent *event, + ID_Type id_type) +{ + ScrArea *area = CTX_wm_area(C); + if (ED_region_overlap_isect_any_xy(area, &event->x)) { + return false; + } + return WM_drag_ID(drag, id_type) != NULL; +} + +static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, - const wmEvent *UNUSED(event), + const wmEvent *event, const char **UNUSED(tooltip)) { - return WM_drag_ID(drag, ID_OB) != NULL; + return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB); } -static bool view3d_collection_drop_poll(bContext *UNUSED(C), +static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, - const wmEvent *UNUSED(event), + const wmEvent *event, const char **UNUSED(tooltip)) { - return WM_drag_ID(drag, ID_GR) != NULL; + return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR); } -static bool view3d_mat_drop_poll(bContext *UNUSED(C), +static bool view3d_mat_drop_poll(bContext *C, wmDrag *drag, - const wmEvent *UNUSED(event), + const wmEvent *event, const char **UNUSED(tooltip)) { - return WM_drag_ID(drag, ID_MA) != NULL; + return view3d_drop_id_in_main_region_poll(C, drag, event, ID_MA); } -static bool view3d_ima_drop_poll(bContext *UNUSED(C), +static bool view3d_ima_drop_poll(bContext *C, wmDrag *drag, - const wmEvent *UNUSED(event), + const wmEvent *event, const char **UNUSED(tooltip)) { + if (ED_region_overlap_isect_any_xy(CTX_wm_area(C), &event->x)) { + return false; + } if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c index 260546738f4..d812ed530ce 100644 --- a/source/blender/editors/space_view3d/view3d_camera_control.c +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -101,7 +101,7 @@ typedef struct View3DCameraControl { void *obtfm; } View3DCameraControl; -BLI_INLINE Object *view3d_cameracontrol_object(View3DCameraControl *vctrl) +BLI_INLINE Object *view3d_cameracontrol_object(const View3DCameraControl *vctrl) { return vctrl->root_parent ? vctrl->root_parent : vctrl->ctx_v3d->camera; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 087fce9e4fd..dbbbbc2af54 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -109,7 +109,7 @@ * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore */ void ED_view3d_update_viewmat(Depsgraph *depsgraph, - Scene *scene, + const Scene *scene, View3D *v3d, ARegion *region, float viewmat[4][4], @@ -208,7 +208,7 @@ static void view3d_main_region_setup_view(Depsgraph *depsgraph, } static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph, - Scene *scene, + const Scene *scene, View3D *v3d, ARegion *region, float viewmat[4][4], @@ -222,7 +222,10 @@ static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph, GPU_matrix_set(rv3d->viewmat); } -static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d) +static bool view3d_stereo3d_active(wmWindow *win, + const Scene *scene, + View3D *v3d, + RegionView3D *rv3d) { if ((scene->r.scemode & R_MULTIVIEW) == 0) { return false; @@ -842,7 +845,7 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo /* ******************** other elements ***************** */ /** could move this elsewhere, but tied into #ED_view3d_grid_scale */ -float ED_scene_grid_scale(Scene *scene, const char **grid_unit) +float ED_scene_grid_scale(const Scene *scene, const char **grid_unit) { /* apply units */ if (scene->unit.system) { @@ -863,13 +866,13 @@ float ED_scene_grid_scale(Scene *scene, const char **grid_unit) return 1.0f; } -float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) +float ED_view3d_grid_scale(const Scene *scene, View3D *v3d, const char **grid_unit) { return v3d->grid * ED_scene_grid_scale(scene, grid_unit); } #define STEPS_LEN 8 -void ED_view3d_grid_steps(Scene *scene, +void ED_view3d_grid_steps(const Scene *scene, View3D *v3d, RegionView3D *rv3d, float r_grid_steps[STEPS_LEN]) @@ -1562,7 +1565,7 @@ static void view3d_draw_view(const bContext *C, ARegion *region) DRW_draw_view(C); } -RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype) +RenderEngineType *ED_view3d_engine_type(const Scene *scene, int drawtype) { /* * Temporary viewport draw modes until we have a proper system. @@ -1606,7 +1609,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *region) * \{ */ static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph, - Scene *scene, + const Scene *scene, View3D *v3d, ARegion *region, float winmat[4][4], @@ -1630,7 +1633,7 @@ static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph, } void ED_view3d_draw_offscreen(Depsgraph *depsgraph, - Scene *scene, + const Scene *scene, eDrawType drawtype, View3D *v3d, ARegion *region, @@ -2395,7 +2398,7 @@ void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixSto * \note The info that this uses is updated in #ED_refresh_viewport_fps, * which currently gets called during #SCREEN_OT_animation_step. */ -void ED_scene_draw_fps(Scene *scene, int xoffset, int *yoffset) +void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset) { ScreenFrameRateInfo *fpsi = scene->fps_info; char printable[16]; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 2ced545a108..610c40c37eb 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -202,7 +202,7 @@ void view3d_winmatrix_set(struct Depsgraph *depsgraph, const View3D *v3d, const rcti *rect); void view3d_viewmatrix_set(struct Depsgraph *depsgraph, - Scene *scene, + const struct Scene *scene, const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2]); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index f6ec5c93e7f..e7153ddd361 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -586,8 +586,11 @@ bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionV } } -bool ED_view3d_camera_autokey( - Scene *scene, ID *id_key, struct bContext *C, const bool do_rotate, const bool do_translate) +bool ED_view3d_camera_autokey(const Scene *scene, + ID *id_key, + struct bContext *C, + const bool do_rotate, + const bool do_translate) { if (autokeyframe_cfra_can_key(scene, id_key)) { const float cfra = (float)CFRA; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 9b0c987c451..ee41b73ed16 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -807,7 +807,7 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) * \note don't set windows active in here, is used by renderwin too. */ void view3d_viewmatrix_set(Depsgraph *depsgraph, - Scene *scene, + const Scene *scene, const View3D *v3d, RegionView3D *rv3d, const float rect_scale[2]) diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 5f5a173932c..afa7b02a1f6 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -65,8 +65,6 @@ set(SRC transform_gizmo_3d.c transform_gizmo_extrude_3d.c transform_input.c - transform_ops.c - transform_orientations.c transform_mode.c transform_mode_align.c transform_mode_baketime.c @@ -98,6 +96,8 @@ set(SRC transform_mode_trackball.c transform_mode_translate.c transform_mode_vert_slide.c + transform_ops.c + transform_orientations.c transform_snap.c transform_snap_object.c diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index f93a3ec260b..4ccb97b7a00 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -830,25 +830,6 @@ bool FrameOnMouseSide(char side, float frame, float cframe) /* ********************* ACTION EDITOR ****************** */ -static int gpf_cmp_frame(void *thunk, const void *a, const void *b) -{ - const bGPDframe *frame_a = a; - const bGPDframe *frame_b = b; - - if (frame_a->framenum < frame_b->framenum) { - return -1; - } - if (frame_a->framenum > frame_b->framenum) { - return 1; - } - *((bool *)thunk) = true; - /* selected last */ - if ((frame_a->flag & GP_FRAME_SELECT) && ((frame_b->flag & GP_FRAME_SELECT) == 0)) { - return 1; - } - return 0; -} - static int masklay_shape_cmp_frame(void *thunk, const void *a, const void *b) { const MaskLayerShape *frame_a = a; @@ -881,7 +862,7 @@ static void posttrans_gpd_clean(bGPdata *gpd) bGPDframe *gpf, *gpfn; bool is_double = false; - BLI_listbase_sort_r(&gpl->frames, gpf_cmp_frame, &is_double); + BKE_gpencil_layer_frames_sort(gpl, &is_double); if (is_double) { for (gpf = gpl->frames.first; gpf; gpf = gpfn) { diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h index a8a930cc156..6180f6d3477 100644 --- a/source/blender/editors/transform/transform_mode.h +++ b/source/blender/editors/transform/transform_mode.h @@ -27,9 +27,9 @@ struct AnimData; struct LinkNode; -struct TransInfo; -struct TransDataContainer; struct TransData; +struct TransDataContainer; +struct TransInfo; struct wmOperator; /* header of TransDataEdgeSlideVert, TransDataEdgeSlideEdge */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 41bb51340fc..4623cc61d29 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3048,7 +3048,6 @@ static void UV_OT_select_linked(wmOperatorType *ot) ot->name = "Select Linked"; ot->description = "Select all UV vertices linked to the active UV map"; ot->idname = "UV_OT_select_linked"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* api callbacks */ ot->exec = uv_select_linked_exec; @@ -3485,6 +3484,10 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, /** \} */ +#define UV_SELECT_ISLAND_LIMIT \ + float limit[2]; \ + uvedit_pixel_to_float(sima, limit, 0.05f) + /* -------------------------------------------------------------------- */ /** \name Box Select Operator * \{ */ @@ -3518,6 +3521,8 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) pinned = RNA_boolean_get(op->ptr, "pinned"); + UV_SELECT_ISLAND_LIMIT; + bool changed_multi = false; uint objects_len = 0; @@ -3569,24 +3574,34 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { continue; } + bool has_selected = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) { - - /* UV_SYNC_SELECTION - can't do pinned selection */ - if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) { - uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - BM_elem_flag_enable(l->v, BM_ELEM_TAG); + if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) { + if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) { + /* UV_SYNC_SELECTION - can't do pinned selection */ + if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) { + uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); + BM_elem_flag_enable(l->v, BM_ELEM_TAG); + has_selected = true; + } } - } - else if (pinned) { - if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) { - uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - BM_elem_flag_enable(l->v, BM_ELEM_TAG); + else if (pinned) { + if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) { + uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); + BM_elem_flag_enable(l->v, BM_ELEM_TAG); + } } } } + if (has_selected && ts->uv_selectmode == UV_SELECT_ISLAND) { + UvNearestHit hit = { + .ob = obedit, + .efa = efa, + }; + uv_select_linked_multi( + scene, ima, objects, objects_len, limit, &hit, true, !select, false, false); + } } if (sima->sticky == SI_STICKY_VERTEX) { @@ -3681,6 +3696,8 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(®ion->v2d, x, y, &offset[0], &offset[1]); + UV_SELECT_ISLAND_LIMIT; + bool changed_multi = false; uint objects_len = 0; @@ -3728,14 +3745,29 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { + continue; + } + bool has_selected = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (uv_inside_circle(luv->uv, offset, ellipse)) { - changed = true; - uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - BM_elem_flag_enable(l->v, BM_ELEM_TAG); + if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (uv_inside_circle(luv->uv, offset, ellipse)) { + changed = true; + uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); + BM_elem_flag_enable(l->v, BM_ELEM_TAG); + has_selected = true; + } } } + if (has_selected && ts->uv_selectmode == UV_SELECT_ISLAND) { + UvNearestHit hit = { + .ob = obedit, + .efa = efa, + }; + uv_select_linked_multi( + scene, ima, objects, objects_len, limit, &hit, true, !select, false, false); + } } if (sima->sticky == SI_STICKY_VERTEX) { @@ -3809,6 +3841,8 @@ static bool do_lasso_select_mesh_uv(bContext *C, bool changed_multi = false; rcti rect; + UV_SELECT_ISLAND_LIMIT; + BLI_lasso_boundbox(&rect, mcords, moves); uint objects_len = 0; @@ -3857,22 +3891,33 @@ static bool do_lasso_select_mesh_uv(bContext *C, BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, obedit, ima, efa)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (UI_view2d_view_to_region_clip( - ®ion->v2d, luv->uv[0], luv->uv[1], &screen_uv[0], &screen_uv[1]) && - BLI_rcti_isect_pt_v(&rect, screen_uv) && - BLI_lasso_is_point_inside( - mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) { - uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - changed = true; - BM_elem_flag_enable(l->v, BM_ELEM_TAG); - } + if (!uvedit_face_visible_test(scene, obedit, ima, efa)) { + continue; + } + bool has_selected = false; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (UI_view2d_view_to_region_clip( + ®ion->v2d, luv->uv[0], luv->uv[1], &screen_uv[0], &screen_uv[1]) && + BLI_rcti_isect_pt_v(&rect, screen_uv) && + BLI_lasso_is_point_inside( + mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) { + uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); + changed = true; + BM_elem_flag_enable(l->v, BM_ELEM_TAG); + has_selected = true; } } } + if (has_selected && ts->uv_selectmode == UV_SELECT_ISLAND) { + UvNearestHit hit = { + .ob = obedit, + .efa = efa, + }; + uv_select_linked_multi( + scene, ima, objects, objects_len, limit, &hit, true, !select, false, false); + } } if (sima->sticky == SI_STICKY_VERTEX) { |